-- Compiler Refresh/n -- m.stone January 29, 1981 4:45 PM -- Last Edited by: Stone, February 14, 1983 3:16 pm DIRECTORY GriffinDefs: FROM "GriffinDefs", ObjectDefs: FROM "ObjectDefs", ScreenDefs: FROM "ScreenDefs", PointDefs: FROM "PointDefs", RefreshDefs: FROM "RefreshDefs", XFormDefs: FROM "XFormDefs", MergeDefs: FROM "MergeDefs", GriffinViewer USING [PaintProc, DoPaint], GriffinMemoryDefs USING [CZone]; Refresh: PROGRAM IMPORTS ObjectDefs,ScreenDefs,GriffinMemoryDefs, MergeDefs, GriffinViewer EXPORTS RefreshDefs = BEGIN OPEN ObjectDefs,PointDefs,GriffinMemoryDefs; Frame: TYPE = REF FrameType; FrameType: TYPE = RECORD [next: Frame, back: Frame, tl,br: ScrPt, obj: ObjectHandle, useNext: BOOLEAN]; newFrameH,newFrameT,bFrameH,bFrameT,tFrameH,tFrameT: Frame _ NIL; EraseAndSave: PUBLIC PROCEDURE[obj: ObjectHandle]= BEGIN tl,br: ScrPt; IF obj=NIL THEN RETURN; tl _ obj.tl; br _ obj.br; IF obj.objectType#token AND obj.objectType#menu THEN BEGIN tl _ [tl[X]-selW,tl[Y]-selW]; br _ [br[X]+selW,br[Y]+selW]; END; EraseAndSaveBox[tl,br]; END; EraseAndSaveBox: PUBLIC PROCEDURE[tl,br: ScrPt]= BEGIN ScreenDefs.EraseBox[tl,br, NIL]; [tl,br] _ ScreenDefs.ClipToScreen[tl,br]; IF br[X]>=tl[X] AND br[Y]>=tl[Y] THEN AddFrame[tl,br,newFrameT]; END; PlotAndMark: PUBLIC PROCEDURE[obj: ObjectHandle]= BEGIN newframe: Frame _ NIL; IF obj=NIL THEN RETURN; IF ~obj.validEncoding THEN ObjectDefs.PlotOneObject[obj,write]; newframe _ MakeBox[obj.tl,obj.br,obj]; newframe.useNext _ TRUE; newframe.obj _ obj; END; MarkBox: PUBLIC PROCEDURE[tl,br: ScrPt, obj: ObjectHandle]= BEGIN newframe: Frame _ NIL; IF obj=NIL THEN RETURN; newframe _ MakeBox[tl,br,obj]; newframe.obj _ obj; END; MakeBox: PROCEDURE[tl,br: ScrPt, obj: ObjectHandle] RETURNS[newFrame: Frame]= BEGIN IF obj=NIL THEN RETURN[NIL]; --space for select token IF obj.objectType=shape OR obj.objectType=caption THEN BEGIN tl _ [tl[X]-selW,tl[Y]-selW]; br _ [br[X]+selW,br[Y]+selW]; END; [tl,br] _ ScreenDefs.ClipToScreen[tl,br]; IF br[X]>=tl[X] AND br[Y]>=tl[Y] THEN AddFrame[tl,br,newFrameT]; RETURN[newFrameT.back]; END; EraseAndSaveAllCPs: PUBLIC PROCEDURE= BEGIN EraseCPs: ObjectDefs.ObjectProc = BEGIN WITH token: obj SELECT FROM token=> IF token.tokenType=CP OR token.tokenType=open THEN EraseAndSave[obj]; ENDCASE; END; ObjectDefs.ForAllVisibleObjects[EraseCPs]; END; RestoreScreen: PUBLIC PROCEDURE= BEGIN frame,tptr: Frame; area: MergeDefs.AreaDescriptor _ MergeDefs.AreaCreate[]; paint: GriffinViewer.PaintProc = { FOR frame_ bFrameH.next, frame_frame.next UNTIL frame=bFrameT DO IF frame.obj=NIL THEN ReplotBox[frame.tl,frame.br, dc] ELSE ReplotBoxFromObject[frame.tl,frame.br,frame.obj, dc]; ENDLOOP; }; saveBox: PROC [tl,br: ScrPt, z: INTEGER] = { -- ScreenDefs.EraseBox[tl,br]; AddFrame[tl,br,bFrameT]; }; frame _ newFrameH.next; UNTIL frame=newFrameT DO IF frame.obj=NIL THEN { MergeDefs.AreaNewBox[area,frame.tl,frame.br,0]; frame _ DeleteFrame[frame]} ELSE frame _ frame.next; ENDLOOP; MergeDefs.AreaGenerate[area,saveBox]; MergeDefs.AreaDestroy[area]; --now have non-intersecting set of erase frames --clip the overlapping areas and add outside pieces to eraseFrames frame _ newFrameH.next; UNTIL frame=newFrameT DO tptr _ frame.next; --ClipAndAdd deletes ClipAndAdd[frame]; frame _ tptr; ENDLOOP; --bFrameH is the head of all the areas to be cleaned up YSort[bFrameH,bFrameT]; GriffinViewer.DoPaint[paint]; --do it in a paint proc frame _ bFrameH.next; UNTIL frame=bFrameT DO frame _ DeleteFrame[frame]; ENDLOOP; END; --take the new frame and compare it to the list headed by bFrameH --take outside pieces and add them to bFrameH ClipAndAdd: PROC [frame: Frame, start: Frame _ bFrameH.next] = { rover: Frame _ NIL; FOR rover _ start, rover.next UNTIL rover=bFrameT DO SELECT TRUE FROM Inside[frame,rover] => {frame _ DeleteFrame[frame]; RETURN}; Outside[frame,rover] => LOOP; --now have to clip the frame against rover, then Clip and add all the pieces ENDCASE => { ClipBox[frame,rover]; --returns a list and Deletes frame FOR frame _ tFrameT.back, tFrameT.back UNTIL frame=tFrameH DO ClipAndAdd[frame,rover]; ENDLOOP; RETURN; }; ENDLOOP; --if we get here, frame did not intersect anything. Add it to bFrameH AddFrameH[frame.tl,frame.br,bFrameH]; frame _ DeleteFrame[frame]; RETURN; }; ClipBox: PROC[frame,clipper: Frame] = { DO SELECT TRUE FROM Inside[frame,clipper] => {[] _ DeleteFrame[frame]; EXIT}; frame.tl[Y] { AddFrameH[frame.tl,[frame.br[X],clipper.tl[Y]-1], tFrameH]; frame.tl[Y] _ clipper.tl[Y]; }; frame.br[Y]>clipper.br[Y] => { AddFrameH[[frame.tl[X],clipper.br[Y]+1], frame.br, tFrameH]; frame.br[Y] _ clipper.br[Y]; }; ENDCASE => SELECT TRUE FROM frame.tl[X] { AddFrameH[frame.tl,[clipper.tl[X]-1,frame.br[Y]], tFrameH]; frame.tl[X] _ clipper.tl[X]; }; frame.br[X]>clipper.br[X] => { AddFrameH[[clipper.br[X]+1,frame.tl[Y]],frame.br, tFrameH]; frame.br[X] _ clipper.br[X]; }; ENDCASE; ENDLOOP; YSort[tFrameH,tFrameT]; }; YSort: PROC[head,tail: Frame] = { --sort in Y rover: Frame _ NIL; switches: INTEGER; DO switches _ 0; rover _ head.next; UNTIL rover=tail DO IF rover.tl[Y]>rover.next.tl[Y] THEN { Switch[rover,rover.next]; switches _ switches+1;} ELSE rover _ rover.next; ENDLOOP; IF switches=0 THEN EXIT; ENDLOOP; }; Inside: PROC[frame,clipper: Frame] RETURNS [BOOLEAN] = INLINE { RETURN[PointInside[frame.tl,clipper.tl,clipper.br] AND PointInside[frame.br,clipper.tl,clipper.br]]; }; PointInside: PROC[pt,tl,br: ScrPt] RETURNS [BOOLEAN] = INLINE { RETURN[pt[X] IN [tl[X]..br[X]] AND pt[Y] IN [tl[Y]..br[Y]]]; }; Outside: PROC[frame,clipper: Frame] RETURNS [BOOLEAN] = INLINE { RETURN[frame.tl[Y]>clipper.br[Y] OR frame.br[Y]clipper.br[X] OR frame.br[X]