gourdol@imag.imag.fr (Gourdol Arnaud) (06/10/91)
Here is a small routine that display icons of the icon family (ICN#, icl4, icl8). Suggested improvements: gray color icons (like the Finder does), use ics#, ics4 and ics8 when required, C version (no, that's not an improvement :-) Arno. >It uses a library called HIK which provides >some utilies I used here, but I think you can >figure them by yourself and use some equivalents. > >Also, this unit is distributed under the GNU >copyleft distribution scheme. It means you can >use this code to your heart's content, but >should you make any improvement or adaptation >(suggestions: adapting it to MacApp, TCL, writting >it in C++) you have the (legal and moral) >obligation to send me a copy of the modified code, >provide appropriate credit and make it publicly >available. >Here it is, enjoy. > >Arno. {DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD} { GetPixelDepth } {DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD} function GetPixelDepth (globalRect: Rect): integer; { Returns the pixel depth of the screen which contain globalRect (in global coordinates) } var gDevice: GDHandle; begin if not gAppl.hasColorQD then GetPixelDepth := 3 else begin gDevice := GetMaxDevice(globalRect); GetPixelDepth := gDevice^^.gdPMap^^.pixelSize; end; end; {DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD} { PlotIcons } {DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD} procedure PlotIcons (wPtr: WindowPtr; bBox: Rect; id: integer; mode: integer); { Plot in the winodw wPtr in the rect bBox the icon id } { It's either an ICN#, an icl8 or an icl4, according to} { what's available on the machine } type { An ICN# resource contains the following : } { * A B&W icon 32x32} { * A mask 32x32 } ICNRecord = record icon: array[0..31] of longint; { Icon data } mask: array[0..31] of longint; { Icon mask } end; ICNPtr = ^ICNRecord; ICNHdl = ^ICNPtr; BitMapPtr = ^BitMap; var iconBm: BitMap; { BitMap for the B&W icon } maskBm: BitMap; { BitMap for the mask } srcRect: rect; { Rect enclosing the icon (0,0,32,32) } theICN: ICNHdl; oldPort: GrafPtr; hState: SignedByte; pixDepth: integer; function PlotIcl8: Boolean; var iconPm: PixMapHandle; { PixMap for the color icon } pixHandle: Handle; i: integer; begin {* Look if the appropriate resource is here } pixHandle := GetResource('icl8', id); if (pixHandle = nil) | (resError <> noErr) then begin PlotIcl8 := false; Exit(PlotIcl8); end else PlotIcl8 := true; {* Build the pixmap } iconPM := NewPixmap; HLock(pixHandle); with iconPM^^ do begin baseAddr := pixHandle^; rowBytes := $8000 + 32; { 32 bytes per row } bounds := srcRect; packType := 0; { No packing } packSize := 0; { Absolutely no packing } pixelType := 0; { Chunky } pixelSize := 8; { 8 bits/pixel } cmpCount := 1; { Indexed } cmpSize := 8; { By 8 bits } planeBytes := 0; { Only one plane } pmReserved := 0; { Must be set to 0 } end; DisposCTable(iconPM^^.pmTable); iconPM^^.pmTable := GetCTable(72); if mode = kHilitedIcon then begin {* Plot the icon as hilited } CopyBits(maskBm, wPtr^.portBits, srcRect, bBox, srcOr, nil); CopyBits(BitMapPtr(iconPM^)^, wPtr^.portBits, srcRect, bBox, srcBic, nil) end else if mode = kGrayIcon then begin end else begin {* Mode standard } CopyBits(maskBm, wPtr^.portBits, srcRect, bBox, srcBic, nil); CopyBits(BitMapPtr(iconPM^)^, wPtr^.portBits, srcRect, bBox, srcOr, nil) end; {* Dispose of the pixmap } HUnlock(pixHandle); ReleaseResource(pixHandle); DisposHandle(pixHandle); DisposPixMap(iconPM); end; function PlotIcl4: Boolean; var iconPm: PixMapHandle; { PixMap for the color icon } pixHandle: Handle; begin {* Look if the appropriate resource is here } pixHandle := GetResource('icl4', id); if (pixHandle = nil) | (resError <> noErr) then begin PlotIcl4 := false; Exit(PlotIcl4); end else PlotIcl4 := true; {* Build the pixmap } iconPM := NewPixmap; HLock(pixHandle); with iconPM^^ do begin baseAddr := pixHandle^; rowBytes := $8000 + 16; { 16 bytes per row } bounds := srcRect; packType := 0; { No packing } packSize := 0; { Absolutely no packing } pixelType := 0; { Chunky } pixelSize := 4; { 4 bits/pixel } cmpCount := 1; { Indexed } cmpSize := 4; { By 4 bits } planeBytes := 0; { Only one plane } pmReserved := 0; { Must be set to 0 } end; DisposCTable(iconPM^^.pmTable); iconPM^^.pmTable := GetCTable(68); if mode = kHilitedIcon then begin {* Plot the icon as hilited } CopyBits(maskBm, wPtr^.portBits, srcRect, bBox, srcOr, nil); CopyBits(BitMapPtr(iconPM^)^, wPtr^.portBits, srcRect, bBox, srcBic, nil) end else if mode = kGrayIcon then begin end else begin {* Mode standard } CopyBits(maskBm, wPtr^.portBits, srcRect, bBox, srcBic, nil); CopyBits(BitMapPtr(iconPM^)^, wPtr^.portBits, srcRect, bBox, srcOr, nil) end; {* Dispose of the pixmap } HUnlock(pixHandle); ReleaseResource(pixHandle); DisposHandle(pixHandle); DisposPixMap(iconPM); end; procedure PlotBW; var grayBM: BitMap; grayIcon: ICNRecord; i: integer; begin {* Just draw a B&W icon with a mask } with iconBM do begin baseAddr := @theICN^^.icon; rowBytes := 4; SetRect(bounds, 0, 0, 32, 32); end; if mode = kHilitedIcon then begin CopyBits(maskBm, wPtr^.portBits, srcRect, bBox, srcOr, nil); CopyBits(iconBM, wPtr^.portBits, srcRect, bBox, srcBic, nil) end else if mode = kGrayIcon then begin for i := 0 to 15 do begin grayIcon.icon[2 * i] := $AA; grayIcon.icon[2 * i + 1] := $55; end; with grayBM do begin baseAddr := @grayIcon.icon; rowBytes := 4; SetRect(bounds, 0, 0, 32, 32); end; CopyBits(maskBm, wPtr^.portBits, srcRect, bBox, srcBic, nil); CopyBits(iconBM, wPtr^.portBits, srcRect, bBox, srcOr, nil); CopyBits(grayBM, wPtr^.portBits, srcRect, bBox, srcBic, nil) end else begin {* Mode standard } CopyBits(maskBm, wPtr^.portBits, srcRect, bBox, srcBic, nil); CopyBits(iconBM, wPtr^.portBits, srcRect, bBox, srcOr, nil) end; end; begin {* Get the ICN# resource } theICN := ICNHdl(GetResource('ICN#', id)); if (ResError <> noErr) | (theICN = nil) then begin Exit(PlotIcons); end; GetPort(oldPort); SetPort(wPtr); {* Set the source rectangle of the icon } SetRect(srcRect, 0, 0, 32, 32); {* Lock the icon while we're drawing it } hState := HGetState(Handle(theICN)); HLock(Handle(theICN)); {* Build the mask Bitmap } with maskBm do begin baseAddr := @theICN^^.mask; rowBytes := 4; SetRect(bounds, 0, 0, 32, 32); end; if mode = kGray then PlotBW else begin pixDepth := GetPixelDepth(bBox); if pixDepth >= 8 then begin {* Draw an icl8 } if not PlotIcl8 & not PlotIcl4 then PlotBW; end else if pixDepth > 3 then begin {* Draw an icl4 } if not PlotIcl4 then PlotBW; end else PlotBW; end; {* Get rid of the ICN# } HSetState(Handle(theICN), hState); ReleaseResource(Handle(theICN)); DisposHandle(Handle(theICN)); SetPort(oldPort); end;-- /=============================//===================================/ / Arno Gourdol. // On the Netland: Gourdol@imag.fr / / "A keyboard ! How quaint !" -- Scott, Star Trek / /=============================//===================================/