DIRECTORY GriffinColor USING [ColorToConstantColor], GriffinData USING [DataRec], GriffinDisplay USING [BkgndColor, TokenType], GriffinEncoding USING [EdgeEncoding, WalkEdge], GriffinGrid USING [Grid], GriffinKernel USING [ClipBox, DataRec], GriffinObject USING [Object, TokenType], GriffinPoint USING [ObjToScr, ObjValToScrVal, ScrPt, ScrRealPt, X, Y], GriffinStyle USING [StyleHandle], Imager USING [Context, DoSave, MaskBits, MaskFill, MaskRectangleI, MaskStroke, PathProc, RotateT, SetColor, SetFont, SetSampledColor, SetStrokeWidth, SetXY, ShowRope, TranslateT], ImagerBackdoor USING [DrawBits, invert], ImagerFont USING [FontBoundingBox, RopeWidth], Rope USING [Length, ROPE], Vector2 USING [VEC]; GriffinDisplayImpl: CEDAR PROGRAM IMPORTS GriffinColor, GriffinEncoding, GriffinGrid, GriffinPoint, Imager, ImagerBackdoor, ImagerFont, Rope EXPORTS GriffinDisplay, GriffinKernel = BEGIN Data: TYPE = REF DataRec; DataRec: PUBLIC TYPE = GriffinData.DataRec; -- exported to GriffinKernel Context: TYPE = Imager.Context; ClipBox: TYPE = GriffinKernel.ClipBox; ROPE: TYPE = Rope.ROPE; ScrPt: TYPE = GriffinPoint.ScrPt; ScrRealPt: TYPE = GriffinPoint.ScrRealPt; StyleHandle: TYPE = GriffinStyle.StyleHandle; EdgeEncoding: TYPE = GriffinEncoding.EdgeEncoding; TokenType: TYPE = GriffinDisplay.TokenType; --{cp, open}; X: NAT = GriffinPoint.X; Y: NAT = GriffinPoint.Y; screenLimit: INT = 10000; -- used by ClearScreen as "big enough" DrawFastStroke: PUBLIC PROC [edge: EdgeEncoding, clip: ClipBox, dc: Context] = { PathProc: Imager.PathProc = {GriffinEncoding.WalkEdge[edge, moveTo, lineTo, curveTo]}; Proc: PROC = TRUSTED { Imager.SetStrokeWidth[dc, 0]; Imager.MaskStroke[dc, PathProc, FALSE]; }; Imager.DoSave[dc, Proc]; }; DrawStroke: PUBLIC PROC [edge: EdgeEncoding, style: StyleHandle, clip: ClipBox, dc: Context] = { PathProc: Imager.PathProc = {GriffinEncoding.WalkEdge[edge, moveTo, lineTo, curveTo]}; Proc: PROC = { Imager.SetStrokeWidth[dc, GriffinPoint.ObjValToScrVal[style.width]]; Imager.SetColor[dc, GriffinColor.ColorToConstantColor[style.color]]; Imager.MaskStroke[dc, PathProc, FALSE]; }; Imager.DoSave[dc, Proc]; }; DrawArea: PUBLIC PROC [edge: EdgeEncoding, style: StyleHandle, clip: ClipBox, dc: Context] = { PathProc: Imager.PathProc = {GriffinEncoding.WalkEdge[edge, moveTo, lineTo, curveTo]}; Proc: PROC = { IF style.filled THEN { Imager.SetColor[dc, GriffinColor.ColorToConstantColor[style.fillcolor]]; Imager.MaskFill[dc, PathProc]; }; IF style.outlined THEN { Imager.SetStrokeWidth[dc, GriffinPoint.ObjValToScrVal[style.width]]; Imager.SetColor[dc, GriffinColor.ColorToConstantColor[style.color]]; Imager.MaskStroke[dc, PathProc, TRUE]; }; }; Imager.DoSave[dc, Proc]; }; DrawCaption: PUBLIC PROC [anchor: ScrRealPt, rope: ROPE, style: StyleHandle, clip: ClipBox, dc: Context] = { width: Vector2.VEC _ ImagerFont.RopeWidth[style.font, rope]; ascent: REAL _ ImagerFont.FontBoundingBox[style.font].ascent; point: Vector2.VEC _ SELECT style.anchor FROM --assumes anchor at origin when used left => [0, 0-ascent], center => [0-width.x/2.0, 0-ascent], right => [0-width.x, 0-ascent], ENDCASE => ERROR; Proc: PROC = { dc.SetColor[GriffinColor.ColorToConstantColor[style.color]]; dc.SetFont[style.font]; dc.TranslateT[[anchor[X], anchor[Y]]]; SELECT style.stringRotation FROM or90 => dc.RotateT[90.0]; or180 => dc.RotateT[180.0]; or270 => dc.RotateT[270.0]; ENDCASE; dc.SetXY[point]; dc.ShowRope[rope: rope, len: Rope.Length[rope]]; }; Imager.DoSave[dc, Proc]; }; ClearScreen: PUBLIC PROC [clip: ClipBox, bkgnd: GriffinDisplay.BkgndColor, dc: Context] = { Proc: PROC = { IF bkgnd.constant#NIL THEN Imager.SetColor[dc, bkgnd.constant] ELSE Imager.SetSampledColor[context: dc, m: bkgnd.scale, pa: bkgnd.pa, colorOperator: bkgnd.op]; Imager.MaskRectangleI[dc, -screenLimit, -screenLimit, 2*screenLimit, 2*screenLimit]; }; Imager.DoSave[dc, Proc]; }; DrawToken: PUBLIC PROC [pt: ScrPt, type: TokenType, clip: ClipBox, dc: Context] = { Proc: PROC = TRUSTED { ImagerBackdoor.DrawBits[context: dc, base: IF type=cp THEN @RuntimeBitmaps[0] ELSE @RuntimeBitmaps[1], wordsPerLine: 1, sMin: 0, fMin: 0, sSize: 9, fSize: 9, tx: pt[X]-4, ty: pt[Y]+4]; }; Imager.DoSave[dc, Proc]; }; DrawHGrid: PUBLIC PROC [data: Data, hg: REF GriffinObject.Object[token], dc: Context] = { lx: INTEGER _ hg.tl[X]; p0: GriffinPoint.ScrPt _ GriffinPoint.ObjToScr[hg.p0]; ty: INTEGER _ GriffinGrid.Grid[data, p0][Y]+1; ngridpieces: INTEGER _ (hg.br[X]-hg.tl[X])/16 - 1; Proc: PROC = TRUSTED { THROUGH [0..ngridpieces] DO Imager.MaskBits[context: dc, base: BASE[hgridbits], wordsPerLine: 1, sMin: 0, fMin: 0, sSize: 3, fSize: 16, tx: lx, ty: ty]; lx _ lx+16; ENDLOOP; }; IF hg.tokenType#hgrid THEN ERROR; Imager.DoSave[dc, Proc]; }; DrawVGrid: PUBLIC PROC [data: Data, vg: REF GriffinObject.Object[token], dc: Context] = { by: INTEGER _ vg.br[Y]+17; -- +17 makes it look right on the screen p0: GriffinPoint.ScrPt _ GriffinPoint.ObjToScr[vg.p0]; lx: INTEGER _ GriffinGrid.Grid[data, p0][X]-1; ngridpieces: INTEGER _ (vg.tl[Y]-vg.br[Y])/16 - 1; Proc: PROC = TRUSTED { THROUGH [0..ngridpieces] DO Imager.MaskBits[context: dc, base: BASE[vgridbits], wordsPerLine: 1, sMin: 0, fMin: 0, sSize: 16, fSize: 3, tx: lx, ty: by]; by _ by+16; ENDLOOP; }; IF vg.tokenType#vgrid THEN ERROR; Imager.DoSave[dc, Proc]; }; DrawFrame: PUBLIC PROC [data: Data, frame: REF GriffinObject.Object[token], dc: Context] = { PathProc: Imager.PathProc = { halfwidth: INTEGER _ GriffinPoint.ObjValToScrVal[frame.style.width]/2; moveTo[p: [x: frame.tl[X]+halfwidth, y: frame.tl[Y]-halfwidth] ]; lineTo[p1: [x: frame.br[X]-halfwidth, y: frame.tl[Y]-halfwidth] ]; lineTo[p1: [x: frame.br[X]-halfwidth, y: frame.br[Y]+halfwidth] ]; lineTo[p1: [x: frame.tl[X]+halfwidth, y: frame.br[Y]+halfwidth] ]; }; Proc: PROC = TRUSTED { Imager.SetStrokeWidth[dc, GriffinPoint.ObjValToScrVal[frame.style.width]]; Imager.SetColor[dc, GriffinColor.ColorToConstantColor[frame.style.color]]; Imager.MaskStroke[dc, PathProc, TRUE]; }; IF frame.tokenType#frame THEN ERROR; Imager.DoSave[dc, Proc]; }; DrawSelection: PUBLIC PROC [pt: ScrPt, covered, clustered: BOOLEAN, clip: ClipBox, dc: Context] = { base: LONG POINTER; Proc: PROC = TRUSTED { SELECT TRUE FROM NOT covered AND NOT clustered => base _ @SelectBitmaps[0]; covered AND NOT clustered => base _ @SelectBitmaps[1]; NOT covered AND clustered => base _ @SelectBitmaps[2]; covered AND clustered => base _ @SelectBitmaps[3]; ENDCASE => ERROR; ImagerBackdoor.DrawBits[context: dc, base: base, wordsPerLine: 1, sMin: 0, fMin: 3, sSize: 10, fSize: 10, tx: pt[X]-5, ty: pt[Y]+5]; }; Imager.DoSave[dc, Proc]; }; BoxFill: PUBLIC PROC [tl,br: ScrPt, bkgnd: GriffinDisplay.BkgndColor, clip: ClipBox, dc: Context] = { Proc: PROC = { IF bkgnd.constant#NIL THEN Imager.SetColor[dc, bkgnd.constant] ELSE Imager.SetSampledColor[context: dc, m: bkgnd.scale, pa: bkgnd.pa, colorOperator: bkgnd.op]; Imager.MaskRectangleI[dc, tl[X], br[Y], br[X]-tl[X], tl[Y]-br[Y]]; }; Imager.DoSave[dc, Proc]; }; InvertBox: PUBLIC PROC [tl,br: ScrPt, clip: ClipBox, dc: Context] = { Proc: PROC = { Imager.SetColor[dc, ImagerBackdoor.invert]; Imager.MaskRectangleI[dc, tl[X], br[Y], br[X]-tl[X], tl[Y]-br[Y]]; }; Imager.DoSave[dc, Proc]; }; SetClipEdges: PUBLIC PROC [data: Data, tl, br: ScrPt] = { data.clipBox^ _ [enable: TRUE, x: tl[X], y: br[Y], w: br[X]-tl[X], h: tl[Y]-br[Y]]; }; ResetClipEdges: PUBLIC PROC [data: Data] = { data.clipBox.enable _ FALSE; }; RuntimeBitmaps: ARRAY [0..3] OF ARRAY [0..8] OF CARDINAL; SelectBitmaps: ARRAY [0..3] OF ARRAY [0..15] OF CARDINAL; vgridbits: PACKED ARRAY [0..16) OF CARDINAL _ ALL[040000B]; hgridbits: PACKED ARRAY [0..8) OF CARDINAL _ ALL[100200B]; vgridbits[0] _ vgridbits[8] _ 120000B; --rest are "040000B" hgridbits[1] _ hgridbits[4] _ 77577B; --rest are "100200B" RuntimeBitmaps[0] _ [16000B,12000B,12000B,173600B,104200B,173600B,12000B,12000B,16000B]; --CP RuntimeBitmaps[1] _ [37000B,61400B,140600B,100200B,104200B,100200B,140600B,61400B,37000B]; --open SelectBitmaps[0] _ [17770B,17770B,14030B,14030B,14630B,14630B,14030B, 14030B,17770B,17770B,0,0,0,0,0,0]; --selected not hidden. SelectBitmaps[1] _ [17770B,17770B,17030B,17430B,15630B,14730B,14370B, 14170B,17770B,17770B,0,0,0,0,0,0]; --selected and hidden. SelectBitmaps[2] _ [17770B,17770B,14030B,15730B,15030B,15030B,15730B, 14030B,17770B,17770B,0,0,0,0,0,0]; --selected not hidden cluster. SelectBitmaps[3] _ [17770B,17770B,14070B,15730B,15230B,15430B,15730B, 16030B,17770B,17770B,0,0,0,0,0,0]; --selected and hidden cluster. END. ΒGriffinDisplayImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Created by: Maureen Stone, September 19, 1985 1:55:05 pm PDT Last Edited by: Ken Pier, November 13, 1985 4:29:28 pm PST IF clip.enable THEN Imager.ClipRectangleI[dc, clip.x, clip.y, clip.w, clip.h]; IF clip.enable THEN Imager.ClipRectangleI[dc, clip.x, clip.y, clip.w, clip.h]; IF clip.enable THEN Imager.ClipRectangleI[dc, clip.x, clip.y, clip.w, clip.h]; IF clip.enable THEN Imager.ClipRectangleI[dc, clip.x, clip.y, clip.w, clip.h]; IF clip.enable THEN Imager.ClipRectangleI[dc, clip.x, clip.y, clip.w, clip.h]; IsCull: PUBLIC PROC [tl, br: ScrPt, clip: ClipBox, dc: Context] RETURNS [cull: BOOLEAN] = { Action: PROC = {cull _ FALSE}; IF clip.enable AND (clip.x+clip.w < tl[X] OR clip.x > br[X] OR clip.y+clip.h < br[Y] OR clip.y > tl[Y]) THEN RETURN[TRUE]; --test for inside local clipper, if enabled cull _ TRUE; ImagerBackdoor.DoIfVisible[dc, [x: tl[X], y: br[Y], w: br[X]-tl[X], h: tl[Y]-br[Y]], Action]; }; IF clip.enable THEN Imager.ClipRectangleI[dc, clip.x, clip.y, clip.w, clip.h]; IF clip.enable THEN Imager.ClipRectangleI[dc, clip.x, clip.y, clip.w, clip.h]; IF clip.enable THEN Imager.ClipRectangleI[dc, clip.x, clip.y, clip.w, clip.h]; halfwidth is needed becaus the frames BBox doesn't allow for style width (4 pts) IF clip.enable THEN Imager.ClipRectangleI[dc, clip.x, clip.y, clip.w, clip.h]; IF clip.enable THEN Imager.ClipRectangleI[dc, clip.x, clip.y, clip.w, clip.h]; IF clip.enable THEN Imager.ClipRectangleI[dc, clip.x, clip.y, clip.w, clip.h]; IF clip.enable THEN Imager.ClipRectangleI[dc, clip.x, clip.y, clip.w, clip.h]; The following work in Screen Points. Partial pixels would only be a nuisance for us. Κ ?˜codešœ™Kšœ Οmœ1™Kšžœ\˜`K˜TK˜—K˜K˜K˜—š ‘œžœžœ-žœžœ™[Kš‘œžœ žœ™Kšžœ žœžœžœžœžœžœžœ +™¦Kšœžœ™ K™]K™K™—š‘ œžœžœ>˜Tš’œžœžœ˜Kšžœ žœ;™N˜$Kšœžœ žœžœ˜AK˜K˜K˜K˜—K˜—K˜K˜K˜—š‘ œžœžœžœ/˜ZKšœžœ ˜K˜6Kšœžœ#˜.Kšœ žœ˜2š’œžœžœ˜Kšžœ žœ;™Nšžœž˜˜Kšœžœ ˜K˜K˜K˜K˜—K˜ Kšžœ˜—K˜—Kšžœžœžœ˜!K˜K˜K˜—š‘ œžœžœžœ/˜ZKšœžœ (˜CKšœ6˜6Kšœžœ#˜.Kšœ žœ˜2š’œžœžœ˜Kšžœ žœ;™Nšžœž˜˜Kšœžœ ˜K˜K˜K˜K˜—K˜ Kšžœ˜—K˜—Kšžœžœžœ˜!K˜K˜K˜—š‘ œžœžœžœ.˜\šŸœ˜K™PKšœ žœ4˜FKšœA˜AKšœB˜BKšœB˜BKšœB˜BKšœ˜—š’œžœžœ˜Kšžœ žœ;™NKšœJ˜JK˜JKšœ žœ˜&K˜—Kšžœžœžœ˜$K˜K˜K˜K˜—š‘ œžœžœ!žœ"˜dKšœžœžœ˜š’œžœžœ˜šžœžœž˜Kšžœ žœžœ'˜:Kšœžœžœ'˜6Kšžœ žœ'˜6Kšœžœ'˜2Kšžœžœ˜—Kšžœ žœ;™N˜$K˜ K˜K˜K˜K˜—K˜—K˜K˜K˜—š‘œžœžœQ˜eš’œžœ˜Kšžœ žœ;™NKšžœžœžœ$˜>Kšžœ\˜`K˜BK˜—K˜K˜K˜—š‘ œžœžœ/˜Eš’œžœ˜Kšžœ žœ;™NK˜+K˜BK˜—K˜K˜—™KšœU™U—š‘ œžœžœ ˜9Kšœžœ6˜SK˜K˜—š‘œžœžœ˜,Kšœžœ˜K˜—K˜Kš œžœžœžœžœžœ˜9Kš œžœžœžœ žœžœ˜9Kš œ žœžœ žœžœžœ ˜;Kš œ žœžœžœžœžœ ˜:Kšœ' ˜;Kšœ& ˜:˜KšœF ˜J—Kšœ\ ˜b˜EKšœ# ˜9—˜EKšœ# ˜9—˜EKšœ$ ˜B—˜EKšœ$ ˜BK˜——Kšžœ˜—…—!N1O