<> <> <> <> <> <> <<>> DIRECTORY FS USING [Error], GriffinData USING [DataRec], GriffinDisplay USING [ClearScreen, DrawArea, DrawCaption, DrawFastStroke, DrawFrame, DrawHGrid, DrawSelection, DrawStroke, DrawToken, DrawVGrid, ResetClipEdges, SetClipEdges], GriffinEncoding USING [EdgeEncoding, EncodeArea, EncodeCubicLink, EncodeEdge, EncodeLinearLink, Link, PointInArea, PointOnEdge], GriffinGrid USING [GetFrame], GriffinKernel USING [Box, DataRec], GriffinMenu USING [PlotMenu], GriffinObject USING [ForAllObjects, ForAllObjectsReversed, ForAllPictureObjects, GetTopPictureObj, Link, Object, ObjectHandle, ObjectProc, openCluster, ReturnSelectToken, tokenSize, Visible], GriffinPoint USING [ObjToScr, ObjToScrReal, ObjValToScrVal, ScrPt, ScrRealPt, ScrRealToScr, X, Y], GriffinRefresh USING [EraseAndSaveBox], GriffinStyle USING [StyleHandle], GriffinText USING [GetBoundingBox], GriffinUserMessage USING [UserMessage], GriffinViewer USING [DoPaint, PaintProc], Imager USING [ClipRectangleI, Context, metersPerPoint, ScaleT, SetPriorityImportant, SetStrokeEnd, SetStrokeJoint, TranslateT], ImagerBackdoor USING [DoIfVisible], ImagerInterpress USING [Close, Create, DoPage, Ref], Real USING [Fix], Rope USING [ROPE]; GriffinShowObjectImpl: CEDAR PROGRAM IMPORTS FS, GriffinDisplay, GriffinEncoding, GriffinGrid, GriffinMenu, GriffinObject, GriffinPoint, GriffinRefresh, GriffinText, GriffinUserMessage, GriffinViewer, Imager, ImagerBackdoor, ImagerInterpress, Real EXPORTS GriffinKernel, GriffinObject = BEGIN Data: TYPE = REF DataRec; DataRec: PUBLIC TYPE = GriffinData.DataRec; --exported to GriffinKernel Context: TYPE = Imager.Context; X: NAT = GriffinPoint.X; Y: NAT = GriffinPoint.Y; ReplotAllObjects: PUBLIC PROC [data: Data, dc: Context] = { Proc: GriffinObject.ObjectProc = { PlotObject[object, dc]; }; GriffinObject.ForAllObjects[data, Proc]; }; ObjectsToInterpress: PUBLIC PROC [data: Data, fileName: Rope.ROPE] = { Action: PROC [dc: Imager.Context] = { Proc: GriffinObject.ObjectProc = { PlotObject[object, dc]; }; frame: REF GriffinObject.Object[token] _ GriffinGrid.GetFrame[data: data]; Imager.ScaleT[dc, Imager.metersPerPoint]; Imager.SetPriorityImportant[dc, TRUE]; IF frame.visible THEN { Imager.TranslateT[context: dc, t: [x: -frame.tl[X], y: -frame.br[Y]] ]; GriffinDisplay.SetClipEdges[data, frame.tl, frame.br]; Imager.ClipRectangleI[dc, data.clipBox.x, data.clipBox.y, data.clipBox.w, data.clipBox.h]; }; Imager.SetStrokeEnd[dc, round]; Imager.SetStrokeJoint[dc, round]; GriffinObject.ForAllPictureObjects[data, Proc]; GriffinDisplay.ResetClipEdges[data: data]; }; <> ip: ImagerInterpress.Ref _ ImagerInterpress.Create[fileName ! FS.Error => { IF error.group=user AND error.code=$unknownFile THEN SIGNAL GriffinUserMessage.UserMessage["Unknown file"] ELSE IF error.group=user AND error.code=$globalCreation THEN SIGNAL GriffinUserMessage.UserMessage["Can't write on remote file"] ELSE SIGNAL GriffinUserMessage.UserMessage["FS file error"] };]; GriffinDisplay.ResetClipEdges[data]; ImagerInterpress.DoPage[ip, Action]; ImagerInterpress.Close[ip]; }; ReplotFromObject: PUBLIC PROC [startObject: GriffinObject.ObjectHandle, dc: Context] = { object: REF GriffinObject.Object _ startObject; UNTIL object=NIL DO PlotObject[object, dc]; object _ object.link; ENDLOOP; }; <> PlotObject: PUBLIC PROC [object: GriffinObject.ObjectHandle, dc: Context] = { IsCull: PROC RETURNS [BOOL] = { Action: PROC = {cull _ FALSE}; cull: BOOLEAN _ TRUE; clip: GriffinKernel.Box _ data.clipBox^; tl: GriffinPoint.ScrPt _ object.tl; br: GriffinPoint.ScrPt _ object.br; 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 ImagerBackdoor.DoIfVisible[dc, [x: tl[X], y: br[Y], w: br[X]-tl[X], h: tl[Y]-br[Y]], Action]; RETURN [cull]; <> <> <> <> < br[X] OR clip.y+clip.h < br[Y] OR clip.y > tl[Y]];>> }; data: Data; IF object=NIL OR ~GriffinObject.Visible[object] THEN RETURN; data _ object.data; IF IsCull[] THEN RETURN; <> <> WITH object SELECT FROM in: REF GriffinObject.Object[shape] => { IF NOT in.closed THEN { --Strokes IF in.cluster=GriffinObject.openCluster AND in.style.outlined=FALSE THEN GriffinDisplay.DrawFastStroke[in.edgeEncoding, data.clipBox, dc] ELSE GriffinDisplay.DrawStroke[in.edgeEncoding, in.style, data.clipBox, dc]; } ELSE GriffinDisplay.DrawArea[in.edgeEncoding, in.style, data.clipBox, dc]; }; in: REF GriffinObject.Object[caption] => GriffinDisplay.DrawCaption[GriffinPoint.ObjToScrReal[in.p0], in.text, in.style, data.clipBox, dc]; in: REF GriffinObject.Object[menu] => GriffinMenu.PlotMenu[in, dc]; in: REF GriffinObject.Object[selectToken] => DrawSelectToken[in, dc]; in: REF GriffinObject.Object[token] => SELECT in.tokenType FROM CP => GriffinDisplay.DrawToken[GriffinPoint.ObjToScr[in.p0], cp, data.clipBox, dc]; open => GriffinDisplay.DrawToken[GriffinPoint.ObjToScr[in.p0], open, data.clipBox, dc]; vgrid => GriffinDisplay.DrawVGrid[data, in, dc]; hgrid => GriffinDisplay.DrawHGrid[data, in, dc]; frame => GriffinDisplay.DrawFrame[data, in, dc]; ENDCASE; ENDCASE; }; DrawSelectToken: PROC [token: REF GriffinObject.Object[selectToken], dc: Context] = { covered, clustered: BOOLEAN _ FALSE; coverObj: GriffinObject.ObjectHandle _ NIL; selectedObject: GriffinObject.ObjectHandle; pt: GriffinPoint.ScrPt; data: Data; IF token=NIL OR NOT token.located THEN ERROR; --added check (KAP) data _ token.data; selectedObject _ token.selectedObj; pt _ GriffinPoint.ObjToScr[token.p0]; <> coverObj _ GetObjectHandleBetweenObjects[pt, GriffinObject.GetTopPictureObj[data], selectedObject]; covered _ coverObj#NIL; clustered _ selectedObject.cluster#0; GriffinDisplay.DrawSelection[pt, covered, clustered, data.clipBox, dc]; }; ReplotBoxFromObject: PUBLIC PROC [tl, br: GriffinPoint.ScrPt, object: GriffinObject.ObjectHandle, dc: Context] = { data: Data _ object.data; GriffinDisplay.SetClipEdges[data, tl, br]; Imager.ClipRectangleI[dc, data.clipBox.x, data.clipBox.y, data.clipBox.w, data.clipBox.h]; ReplotFromObject[object, dc]; GriffinDisplay.ResetClipEdges[data]; }; ReplotBox: PUBLIC PROC [data: Data, tl, br: GriffinPoint.ScrPt, dc: Context] = { GriffinDisplay.SetClipEdges[data, tl, br]; Imager.ClipRectangleI[dc, data.clipBox.x, data.clipBox.y, data.clipBox.w, data.clipBox.h]; ReplotAllObjects[data, dc]; GriffinDisplay.ResetClipEdges[data]; }; PlotOneObject: PUBLIC PROC [object: GriffinObject.ObjectHandle] = { PaintOne: GriffinViewer.PaintProc = { PlotObject[object, dc]; }; data: Data _ object.data; GriffinViewer.DoPaint[data.viewer, PaintOne]; }; EraseObject: PUBLIC PROC [erase: GriffinObject.ObjectHandle] = { select: REF GriffinObject.Object[selectToken] _ NIL; eraseData: Data; selectData: Data; Painter: GriffinViewer.PaintProc = { EraseSelectToken: GriffinViewer.PaintProc = { GriffinDisplay.SetClipEdges[selectData, select.tl, select.br]; Imager.ClipRectangleI[dc, selectData.clipBox.x, selectData.clipBox.y, selectData.clipBox.w, selectData.clipBox.h]; GriffinDisplay.ClearScreen[selectData.clipBox, selectData.bkgndColor, dc]; GriffinDisplay.ResetClipEdges[selectData]; }; Erase: GriffinViewer.PaintProc = { GriffinDisplay.SetClipEdges[eraseData, erase.tl, erase.br]; Imager.ClipRectangleI[dc, eraseData.clipBox.x, eraseData.clipBox.y, eraseData.clipBox.w, eraseData.clipBox.h]; GriffinDisplay.ClearScreen[eraseData.clipBox, eraseData.bkgndColor, dc]; GriffinObject.ForAllObjects[eraseData, Replot]; GriffinDisplay.ResetClipEdges[eraseData]; }; Replot: GriffinObject.ObjectProc = { IF object#erase AND object#select THEN PlotObject[object, dc]; }; IF erase.selected THEN { select _ GriffinObject.ReturnSelectToken[erase]; IF select = NIL THEN RETURN; selectData _ select.data; GriffinViewer.DoPaint[eraseData.viewer, EraseSelectToken]; }; GriffinViewer.DoPaint[eraseData.viewer, Erase]; }; IF erase=NIL THEN RETURN; IF NOT erase.validEncoding THEN ERROR; eraseData _ erase.data; GriffinViewer.DoPaint[eraseData.viewer, Painter]; }; PlotLink: PUBLIC PROC [data: Data, link: GriffinEncoding.Link, style: GriffinStyle.StyleHandle]= { PaintLink: GriffinViewer.PaintProc = { IF doFastStroke THEN GriffinDisplay.DrawFastStroke[encoding, data.clipBox, dc] ELSE GriffinDisplay.DrawStroke[encoding, style, data.clipBox, dc]; }; doFastStroke: BOOLEAN _ style=NIL OR style.outlined=FALSE; encoding: GriffinEncoding.EdgeEncoding _ GriffinEncoding.EncodeEdge[LIST[link]]; GriffinViewer.DoPaint[data.viewer, PaintLink]; --direct way to paint viewer client }; EraseLink: PUBLIC PROC [data: Data, link: GriffinEncoding.Link, style: GriffinStyle.StyleHandle] = { [newtl: link.tl, newbr: link.br] _ AdjustLinkForStyle[link: link, style: style]; GriffinRefresh.EraseAndSaveBox[data, GriffinPoint.ScrRealToScr[link.tl], GriffinPoint.ScrRealToScr[link.br]]; }; AdjustLinkForStyle: PROC [link: GriffinEncoding.Link, style: GriffinStyle.StyleHandle] RETURNS [newtl, newbr: GriffinPoint.ScrRealPt] = { w: INTEGER_ GriffinPoint.ObjValToScrVal[style.width/2]+GriffinObject.tokenSize; RETURN[ [link.tl[X]-w, link.tl[Y]+w], [link.br[X]+w, link.br[Y]-w] ]; }; EncodeObject: PUBLIC PROC [shape: REF GriffinObject.Object[shape]] = TRUSTED { WITH traj: shape.trajectory SELECT FROM cyclic => { link: GriffinEncoding.Link; traj.splineType _ SELECT traj.splineType FROM naturalUM => cyclicUM, naturalAL => cyclicAL, ENDCASE => traj.splineType; link _ GriffinEncoding.EncodeCubicLink[traj.knots, traj.splineType]; shape.edgeEncoding _ GriffinEncoding.EncodeEdge[LIST[link]]; }; linked => { list, rList: LIST OF GriffinEncoding.Link; FOR l: REF GriffinObject.Link _ traj.links, l.link UNTIL l=NIL DO new: GriffinEncoding.Link _ IF l.degree=D1 THEN GriffinEncoding.EncodeLinearLink[l.knots] ELSE GriffinEncoding.EncodeCubicLink[l.knots, traj.splineType]; list _ CONS[new, list]; ENDLOOP; FOR l: LIST OF GriffinEncoding.Link _ list, l.rest UNTIL l=NIL DO rList _ CONS[l.first, rList]; ENDLOOP; shape.edgeEncoding _ GriffinEncoding.EncodeEdge[rList]; }; ENDCASE; IF shape.closed THEN shape.areaEncoding _ GriffinEncoding.EncodeArea[shape.edgeEncoding]; shape.tl _ GriffinPoint.ScrRealToScr[shape.edgeEncoding.tl]; shape.br _ GriffinPoint.ScrRealToScr[shape.edgeEncoding.br]; shape.validEncoding _ TRUE; }; AdjustBoxForStyle: PUBLIC PROC [object: GriffinObject.ObjectHandle] = TRUSTED { WITH obj: object SELECT FROM shape => { -- notice that tokens are big enough to encompass style.widths obj.tl _ GriffinPoint.ScrRealToScr[[obj.edgeEncoding.tl[X]-GriffinObject.tokenSize, obj.edgeEncoding.tl[Y]+GriffinObject.tokenSize]]; obj.br _GriffinPoint.ScrRealToScr[[obj.edgeEncoding.br[X]+GriffinObject.tokenSize, obj.edgeEncoding.br[Y]-GriffinObject.tokenSize]]; }; caption => [obj.tl, obj.br] _ GriffinText.GetBoundingBox[obj.text, obj.style, obj.p0]; ENDCASE; }; <> GetObjectHandle: PUBLIC PROC [data: Data, pt: GriffinPoint.ScrPt] RETURNS [GriffinObject.ObjectHandle] = { Do: GriffinObject.ObjectProc = { IF HitTest[pt, object] THEN {found _ object; RETURN[TRUE]}; }; found: GriffinObject.ObjectHandle _ NIL; GriffinObject.ForAllObjectsReversed[data, Do]; IF found#NIL THEN WITH found SELECT FROM type: REF GriffinObject.Object[selectToken] => RETURN[type.selectedObj]; ENDCASE; RETURN[found]; }; GetObjectHandleBetweenObjects: PUBLIC PROC [pt: GriffinPoint.ScrPt, topObject, bottomObject: GriffinObject.ObjectHandle] RETURNS [GriffinObject.ObjectHandle] = { FOR object: GriffinObject.ObjectHandle _ topObject, object.backLink UNTIL object = bottomObject DO IF HitTest[pt, object] THEN RETURN[object]; ENDLOOP; RETURN[NIL]; }; HitTest: PROC [pt: GriffinPoint.ScrPt, object: GriffinObject.ObjectHandle] RETURNS [BOOLEAN] ~ TRUSTED { tol: REAL; IF ~GriffinObject.Visible[object] THEN RETURN[FALSE]; IF pt[X]object.br[X] OR pt[Y]>object.tl[Y] OR pt[Y]> WITH obj: object SELECT FROM caption, menu, selectToken => RETURN[TRUE]; shape => { tol _ MAX[1, GriffinPoint.ObjValToScrVal[obj.style.width/2.0]]; IF GriffinEncoding.PointOnEdge[pt, obj.edgeEncoding, tol] THEN RETURN[TRUE] ELSE IF obj.closed AND object.style.filled AND GriffinEncoding.PointInArea[pt, obj.areaEncoding, tol] THEN RETURN[TRUE]; }; token => { micasPerPoint: REAL = 32.0; Box: TYPE = RECORD[tl, br: GriffinPoint.ScrPt]; leftBox, rightBox, topBox, bottomBox: Box; width: INT; Inside: PROC [pt: GriffinPoint.ScrPt, box: Box] RETURNS [BOOL] = TRUSTED { RETURN[ ~ (pt[X]box.br[X] OR pt[Y]box.tl[Y]) ]; }; IF obj.tokenType#frame THEN RETURN[TRUE]; <> width _ Real.Fix[ object.style.width/micasPerPoint ]; -- line width in points leftBox _ [tl: obj.tl, br: [ obj.tl[X]+width, obj.br[Y] ]]; IF Inside[pt, leftBox] THEN RETURN[TRUE]; rightBox _ [tl: [ obj.br[X]-width, obj.tl[Y] ], br: obj.br ]; IF Inside[pt, rightBox] THEN RETURN[TRUE]; topBox _ [tl: obj.tl, br: [ obj.br[X]-width, obj.tl[Y]-width ] ]; IF Inside[pt, topBox] THEN RETURN[TRUE]; bottomBox _ [tl: [ obj.tl[X], obj.br[Y]+width ], br: obj.br ]; IF Inside[pt, bottomBox] THEN RETURN[TRUE]; }; ENDCASE; RETURN[FALSE]; }; END.