DIRECTORY CIFS USING [Close, ConnectionErrors, Error, GetFC, Open, OpenFile, read], Environment USING [wordsPerPage], File USING [Capability, GetSize], Graphics USING [ClipBox, Context, DrawRope, FontRef, RopeWidth, SetColor, SetCP, white], GraphicsOps USING [BitmapRep, DrawBitmap], Icons, Rope USING [Concat, Fetch, Length, Map, ROPE, Substr], SafeStorage USING [NewZone], Space USING [Create, Delete, Handle, LongPointer, Map, PageCount, virtualMemory], VFonts USING [EstablishFont, Font, FontAscent, GraphicsFont]; IconsImpl: CEDAR MONITOR IMPORTS CIFS, File, Graphics, GraphicsOps, Rope, SafeStorage, Space, VFonts EXPORTS Icons = BEGIN OPEN Icons; iZ: ZONE _ SafeStorage.NewZone[quantized]; DrawIcon: PUBLIC ENTRY DrawIconProc = BEGIN leading: INTEGER = 3; iconInfo: IconRef _ icons[LOOPHOLE[flavor]]; prefix: Rope.ROPE _ NIL; IF iconInfo.proc=NIL THEN BEGIN iconBitmap.base _ iconInfo; -- bits guaranteed first in record!!! Graphics.SetCP[context, x, y+iconH]; GraphicsOps.DrawBitmap[context, iconBitmap, iconW, iconH]; IF iconInfo.label THEN BEGIN iconFont: Graphics.FontRef; fontHeight: INTEGER; iy: INTEGER _ y+iconInfo.ly+iconInfo.lh; segments: LIST OF Rope.ROPE; IF Graphics.RopeWidth[bigIconFont, label].xw <= 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; Graphics.ClipBox[context, [x+iconInfo.lx, y+iconInfo.ly, x+iconInfo.lx+iconInfo.lw, iy]]; IF iconInfo.invertLabel THEN Graphics.SetColor[context, Graphics.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; Graphics.SetCP[context, x+iconInfo.lx, iy]; iy _ iy - leading; Graphics.DrawRope[self: context, font: iconFont, rope: 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 bigFont: VFonts.Font _ VFonts.EstablishFont["Helvetica", 8]; smallFont: VFonts.Font _ VFonts.EstablishFont["Helvetica", 7]; bigFontHeight _ VFonts.FontAscent[bigFont]; smallFontHeight _ VFonts.FontAscent[smallFont]; bigIconFont _ VFonts.GraphicsFont[bigFont]; smallIconFont _ VFonts.GraphicsFont[smallFont]; END; bigIconFont: Graphics.FontRef; bigFontHeight: INTEGER; smallIconFont: Graphics.FontRef; smallFontHeight: INTEGER; wSlop: INTEGER = 5; Decompose: PROC [name: Rope.ROPE, width: REAL, font: Graphics.FontRef] 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 Graphics.RopeWidth[font, c _ segs.first.Concat[segs.rest.first]].xw<=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; iconBitmap: REF GraphicsOps.BitmapRep _ NEW[GraphicsOps.BitmapRep _ [NIL, iconW/16, iconW, iconH]]; 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[iZ.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[iZ.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 _ "Standard.icons"; GetFonts[]; [] _ IconsFromFile[iconFile ! CIFS.Error => CHECKED {IF code IN CIFS.ConnectionErrors OR code = noSuchFile THEN {iconFile _ "/Ivy/CedarViewers/Viewers/Standard.icons"; RETRY}}]; END. ¨IconsImpl.mesa; Edited by McGregor on October 20, 1982 4:28 pm Last Edited by: Maxwell, January 3, 1983 12:53 pm Last Edited by: Plass, April 20, 1983 10:00 am ΚC– "Mesa" style˜JšΟc™Jš.™.J™1J™.šΟk ˜ Jšžœžœ?˜IJšœ žœ˜!Jšœžœ˜!Jšœ žœJ˜XJšœ žœ˜*J˜Jšœžœžœ ˜6Jšœ žœ ˜JšœžœF˜QJšœžœ1˜=J˜—Jšœ ž ˜J˜Jšžœžœ?˜KJ˜Jšžœ˜J˜Jšžœžœ˜J˜Jšœžœ"˜*J˜šœ žœžœž˜+Jšœ žœ˜Jšœžœ ˜,Jšœ žœžœ˜šžœžœžœž˜Jšœ%˜AJ˜$J˜:šžœžœž˜J˜Jšœ žœ˜Jšœžœ˜(Jšœ žœžœžœ˜šžœ:žœž˜FJ˜J˜Jšœ žœ˜Jšž˜—šžœž˜ J˜J˜J˜3Jšžœ˜—˜8J˜ —Jšžœžœ,˜Hšžœ žœž˜Jšœžœ˜$šœ žœžœžœž˜+šœ(ž˜*Jšœ žœžœžœ˜2——J˜J˜+J˜˜0J˜-—J˜ J˜Jšžœ˜—Jšžœ˜—Jšž˜—Jšžœ-˜1Jšžœ˜J˜—šΟnœžœžœž˜J˜J˜+J˜/J˜+J˜/Jšžœ˜J˜—J˜Jšœžœ˜J˜J˜ Jšœžœ˜J˜Jšœžœ˜J˜šŸ œžœ žœ žœžœ žœžœžœžœ˜tJšž˜Jšœžœžœ˜"Jšœžœ˜ Jšœžœ˜Jšœžœžœ˜$š Ÿœžœžœžœžœžœ˜9Jšžœžœ žœžœžœ žœžœžœžœžœ˜PJšžœ žœ˜Jšžœžœžœžœ˜*Jšœ žœžœ˜—šŸœžœžœžœžœžœžœ˜7Jšžœ žœžœžœ˜J˜Jšœ žœ˜Jšžœžœ ˜Jšžœ?˜CJšžœžœ0˜;—šŸœžœžœžœžœžœžœžœžœ˜GJšœžœ˜ Jš žœžœžœ žœžœžœ˜/šžœž˜"J˜J—Jšžœžœ žœ˜/Jšžœžœ&˜1—Jšœ"˜7Jšžœ˜Jšžœ˜J˜—Jšœ žœžœžœ˜cJ˜Jšœ žœ˜J˜Jšœžœžœ ˜'J˜J˜"š Ÿ œžœžœžœž˜=J˜Jšœ žœ ˜Jš žœžœ žœžœžœ˜9Jšžœ˜J˜—š Ÿœžœžœžœž˜LJ˜Jšœžœ˜"Jšžœ˜J˜—š Ÿ œžœ žœžœžœ˜SJšž ˜ Jšœ žœžœžœ˜)Jšœžœ ˜J˜J˜J˜Jšœžœ žœ žœ˜4J˜J˜>Jšœ9˜LJ˜$J˜Jšœžœ+˜=šžœžœžœ ž˜šœžœ@˜SJšœ œ8˜C—Jšœžœ˜)Jšžœ˜—J˜Jšžœ ˜Jšžœ˜J˜—š Ÿœžœžœ žœžœžœ˜]Jšž ˜ Jšœ žœžœžœ˜)Jšœžœ ˜J˜J˜Jšœžœ žœ žœ˜4J˜MJšœ9˜LJšœ)žœ˜?šœžœ@˜ZJšœ œ8˜C—J˜Jšžœ ˜Jšžœ˜J˜—Jšœžœ˜'J˜J˜ J˜šœžœ žœžœžœžœžœž˜oJšœ8žœ˜AJ˜—Jšžœ˜J˜J˜—…—Έ£