DIRECTORY CIFS USING [Close, Error, GetFC, Open, OpenFile, read], Environment USING [wordsPerPage], File USING [Capability, GetSize], Imager USING [black, ClipIntRectangle, Context, DrawBitmap, MaskCharacters, MaskIntRectangle, SetColor, SetIntCP, white], Icons, Rope USING [Concat, Fetch, Length, Map, ROPE, Substr], Space USING [Create, Delete, Handle, LongPointer, Map, PageCount, virtualMemory], UserProfile USING [Token], VFonts USING [EstablishFont, Font, FontAscent, RopeWidth]; IconsImpl: CEDAR MONITOR IMPORTS CIFS, File, Imager, Rope, Space, UserProfile, VFonts EXPORTS Icons = BEGIN OPEN Icons; DrawIcon: PUBLIC ENTRY DrawIconProc = BEGIN leading: INTEGER = 3; iconInfo: IconRef _ icons[LOOPHOLE[flavor]]; prefix: Rope.ROPE _ NIL; IF iconInfo.proc=NIL THEN BEGIN Imager.SetColor[context, Imager.white]; Imager.MaskIntRectangle[context, [0,0,iconW,iconH]]; Imager.SetColor[context, Imager.black]; TRUSTED {Imager.DrawBitmap[context, LOOPHOLE[iconInfo--bits first in record--], iconW/16, [x,y,iconW,iconH]]}; IF iconInfo.label THEN BEGIN iconFont: VFonts.Font; fontHeight: INTEGER; iy: INTEGER _ y+iconInfo.ly+iconInfo.lh; segments: LIST OF Rope.ROPE; IF VFonts.RopeWidth[label, bigIconFont] <= iconInfo.lw THEN BEGIN iconFont _ bigIconFont; fontHeight _ bigFontHeight; segments _ LIST[label]; END ELSE BEGIN iconFont _ smallIconFont; fontHeight _ smallFontHeight; segments _ Decompose[label, iconInfo.lw, iconFont]; END; Imager.ClipIntRectangle[context, [x+iconInfo.lx, y+iconInfo.ly, iconInfo.lw, iy-(y+iconInfo.ly)]]; IF iconInfo.invertLabel THEN Imager.SetColor[context, Imager.white]; WHILE segments#NIL DO segment: Rope.ROPE _ segments.first; suffix: Rope.ROPE _ IF segments.rest=NIL OR segment.Fetch[segment.Length[]-1]='\040 OR segments.rest.first.Fetch[0]='. THEN NIL ELSE "-"; iy _ iy-fontHeight; Imager.SetIntCP[context, [x+iconInfo.lx, iy]]; iy _ iy - leading; Imager.MaskCharacters[context, iconFont, prefix.Concat[segment.Concat[suffix]]]; prefix _ " "; segments _ segments.rest; ENDLOOP; END; END ELSE iconInfo.proc[flavor, context, x, y, label]; END; GetFonts: ENTRY PROC = BEGIN bigIconFont _ VFonts.EstablishFont["Helvetica", 8]; smallIconFont _ VFonts.EstablishFont["Helvetica", 7]; bigFontHeight _ VFonts.FontAscent[bigIconFont]; smallFontHeight _ VFonts.FontAscent[smallIconFont]; END; bigIconFont: VFonts.Font; bigFontHeight: INTEGER; smallIconFont: VFonts.Font; smallFontHeight: INTEGER; wSlop: INTEGER = 5; Decompose: PROC [name: Rope.ROPE, width: REAL, font: VFonts.Font] RETURNS [segments: LIST OF Rope.ROPE _ NIL] = BEGIN candidate, useMe: Rope.ROPE _ NIL; end: INT _ 0; len: INT _ Rope.Length[name]; haveExtension, inWord: BOOL _ FALSE; SkipToNextWord: PROC [c: CHAR] RETURNS [BOOL] = CHECKED { IF c IN ['A..'Z] OR c = '/ OR c IN ['0..'9] THEN { IF inWord THEN RETURN[TRUE] } ELSE inWord _ TRUE; IF c='. THEN RETURN[haveExtension _ TRUE]; end _ end+1; RETURN[FALSE]; }; Build: PROC[start: INT] RETURNS [LIST OF Rope.ROPE] = { IF start>=len THEN RETURN[NIL]; end _ start+1; inWord _ FALSE; IF haveExtension THEN end _ len ELSE [] _ Rope.Map[base: name, start: end, action: SkipToNextWord]; RETURN[CONS[name.Substr[start, end-start], Build[end]]]; }; Coalesce: PROC[segs: LIST OF Rope.ROPE] RETURNS [LIST OF Rope.ROPE] = { c: Rope.ROPE; IF segs=NIL OR segs.rest=NIL THEN RETURN[segs]; IF segs.rest.first.Fetch[0]#'. AND VFonts.RopeWidth[c _ segs.first.Concat[segs.rest.first], font]<=width THEN RETURN[Coalesce[CONS[c, segs.rest.rest]]]; RETURN[CONS[segs.first, Coalesce[segs.rest]]]; }; width _ width+wSlop; -- allow small amount of clipping. RETURN[Coalesce[Build[0]]]; END; maxIcons: CARDINAL = 64; icons: ARRAY [0..maxIcons) OF IconRef ; nextFlavor: IconFlavor _ document; NewFlavor: ENTRY PROC RETURNS [newFlavor: IconFlavor] = BEGIN newFlavor _ nextFlavor; nextFlavor _ SUCC[newFlavor]; IF LOOPHOLE[nextFlavor, CARDINAL] >= maxIcons THEN ERROR; END; NewIcon: PUBLIC PROC [info: IconRef] RETURNS [newFlavor: IconFlavor] = BEGIN newFlavor _ NewFlavor[]; icons[LOOPHOLE[newFlavor]] _ info; END; IconsFromFile: PROC [file: Rope.ROPE] RETURNS [first: IconFlavor, nRead: INTEGER] = TRUSTED BEGIN iconBase: LONG POINTER TO IconFileFormat; fh: CIFS.OpenFile; fileC: File.Capability; size: Space.PageCount; space: Space.Handle; fileC _ CIFS.GetFC[fh _ CIFS.Open[file, CIFS.read]]; size _ File.GetSize[fileC]; space _ Space.Create[size: size, parent: Space.virtualMemory]; Space.Map[space: space, window: [file: fileC, base: 1]]; -- first page is 1! iconBase _ Space.LongPointer[space]; first _ nextFlavor; nRead _ size/(SIZE[IconFileFormat]/Environment.wordsPerPage); FOR n: INTEGER IN [0..nRead) DO [] _ NewIcon[NEW[IconRep _ [iconBase.bits, iconBase.label, iconBase.invertLabel, 0--filler--, iconBase.lx, iconBase.ly, iconBase.lw, iconBase.lh]]]; iconBase _ iconBase+SIZE[IconFileFormat]; ENDLOOP; Space.Delete[space]; CIFS.Close[fh]; END; NewIconFromFile: PUBLIC PROC [file: Rope.ROPE, n: CARDINAL] RETURNS [newFlavor: IconFlavor] = TRUSTED BEGIN iconBase: LONG POINTER TO IconFileFormat; fh: CIFS.OpenFile; fileC: File.Capability; space: Space.Handle; fileC _ CIFS.GetFC[fh _ CIFS.Open[file, CIFS.read]]; space _ Space.Create[size: File.GetSize[fileC], parent: Space.virtualMemory]; Space.Map[space: space, window: [file: fileC, base: 1]]; -- first page is 1! iconBase _ Space.LongPointer[space] + (n*SIZE[IconFileFormat]); newFlavor _ NewIcon[NEW[IconRep _ [iconBase.bits, iconBase.label, iconBase.invertLabel, 0--filler--, iconBase.lx, iconBase.ly, iconBase.lw, iconBase.lh]]]; Space.Delete[space]; CIFS.Close[fh]; END; iconFile: Rope.ROPE _ UserProfile.Token["Icons", "/Indigo/CedarViewers/Viewers/Standard.icons"]; GetFonts[]; [] _ IconsFromFile[iconFile ! CIFS.Error => -- maybe IVY has something we can use {iconFile _ "/Ivy/CedarViewers/Viewers/Standard.icons"; RETRY}]; END. ΌIconsImpl.mesa; Written by S. McGregor Edited by McGregor on August 8, 1983 9:46 am Last Edited by: Maxwell, January 3, 1983 12:53 pm Last Edited by: Plass, April 20, 1983 10:00 am Κ– "cedar" style˜JšΟc&™&Jš,™,J™1J™.J˜šΟk ˜ Jšžœžœ-˜7Jšœ žœ˜!Jšœžœ˜!Jšœžœm˜yJ˜Jšœžœžœ ˜6JšœžœF˜QJšœ žœ ˜Jšœžœ.˜:J˜—Jšœ ž ˜J˜Jšžœžœ0˜Jšœ9˜LJ˜$J˜Jšœžœ+˜=šžœžœžœ ž˜šœ žœ@˜PJšœ œ8˜C—Jšœžœ˜)Jšžœ˜—J˜Jšžœ ˜Jšžœ˜J˜—š Ÿœžœžœ žœžœžœ˜]Jšž ˜ Jšœ žœžœžœ˜)Jšœžœ ˜J˜J˜Jšœžœ žœ žœ˜4J˜MJšœ9˜LJšœ)žœ˜?šœžœ@˜WJšœ œ8˜C—J˜Jšžœ ˜Jšžœ˜J˜—JšœžœM˜`J˜J˜ J˜šœžœ &˜RJšœ8žœ˜@J˜—Jšžœ˜J˜J˜—…—Τ―