-- Compiler DrawOps/n --m.stone December 2, 1981 11:24 PM --Tiberi December 11, 1979 8:42 PM -- Last Edited by: Stone, December 29, 1983 11:15 am DIRECTORY GriffinDefs: FROM "GriffinDefs", MenuDefs: FROM "MenuDefs", ObjectDefs: FROM "ObjectDefs", GriffinFontDefs: FROM "GriffinFontDefs", ControllerDefs: FROM "ControllerDefs", RefreshDefs: FROM "RefreshDefs", StyleDefs: FROM "StyleDefs", PointDefs: FROM "PointDefs", GriffinMemoryDefs USING [CZone], SplineDefs: FROM "SplineDefs", Rope USING [ROPE, Equal, Cat], GriffinColor USING [ColorToString], GriffinMenusInterface, ControllerMenuDefs: FROM "ControllerMenuDefs"; DrawOps: PROGRAM IMPORTS GriffinDefs, MenuDefs, ObjectDefs, ControllerMenuDefs, GriffinMemoryDefs, PointDefs, ControllerDefs,RefreshDefs, Rope, GriffinColor EXPORTS GriffinDefs, GriffinMenusInterface = BEGIN OPEN ObjectDefs,PointDefs,GriffinMemoryDefs; newObj: REF shape Object _ NIL; spline: SplineDefs.SplineType _ naturalAL; Fitting: TYPE = {lines,curve}; fitting: Fitting; ROPE: TYPE = Rope.ROPE; SetStyle: PROCEDURE[style: StyleDefs.StyleHandle] = BEGIN fd: GriffinFontDefs.FontDescriptorHandle; name: ROPE; BugItemByString[ControllerMenuDefs.colorMenu, StringOfColor[style.fillcolor]]; BugItemByString[ControllerMenuDefs.lineColorMenu, StringOfColor[style.color]]; BugItemByString[ControllerMenuDefs.colorControlMenu, SELECT TRUE FROM style.filled AND style.outlined => "Both", style.filled => "Filled", style.outlined => "Outlined", ENDCASE => ERROR]; BugItemByString[ControllerMenuDefs.textMenu, SELECT style.orientation FROM or0 => "0 d", or90 => "90 d", or180 => "180 d", or270 => "270 d", ENDCASE => ERROR]; fd _ ControllerDefs.FontWithNumber [style.fontid]; BugItemByString[ControllerMenuDefs.charMenu, SELECT fd.rotation FROM GriffinFontDefs.Rot0Degrees => "0 char d", GriffinFontDefs.Rot90Degrees => "90 char d", GriffinFontDefs.Rot180Degrees => "180 char d", GriffinFontDefs.Rot270Degrees => "270 char d", ENDCASE => ERROR]; name _ GriffinDefs.AppendNumber[fd.name, fd.points]; SELECT fd.face FROM 3 => name _ Rope.Cat[name, "BI"]; 2 => name _ Rope.Cat[name, "B"]; 1 => name _ Rope.Cat[name, "I"]; ENDCASE; BugItemByString[ControllerMenuDefs.fontMenu, name]; BugItemByString[ControllerMenuDefs.centerMenu, SELECT style.anchor FROM left => "left", center => "centered", right => "right", ENDCASE => ERROR]; BugItemByString[ControllerMenuDefs.thickMenu, SELECT ObjValToScrVal[style.width] FROM 1 => "1 pt", 2 => "2 pt", 3 => "3 pt", 4 => "4 pt", ENDCASE => ERROR]; END; BugItemByString: PROCEDURE[menu: MenuDefs.MenuHandle, string: ROPE]= BEGIN OPEN MenuDefs; menuItem: MenuItemHandle _ NARROW[menu.head]; IsThisItem: MenuProc = { IF Rope.Equal[MenuString[item], string, FALSE] THEN menuItem _ item}; ForAllMenuItems[menu, IsThisItem]; BugItem[menuItem] END; ExpandShape: PUBLIC MenuDefs.MenuProc = BEGIN OPEN ControllerMenuDefs; IF MenuDefs.IsSelected[item] THEN UnDisplayShapeMenu[] ELSE DisplayShapeMenu[]; IF MenuDefs.IsSelected[item] THEN MenuDefs.Deselect[item] ELSE MenuDefs.Select[item]; RefreshDefs.RestoreScreen; END; ExpandColor: PUBLIC MenuDefs.MenuProc = BEGIN OPEN ControllerMenuDefs; IF MenuDefs.IsSelected[item] THEN UnDisplayColorMenu[] ELSE DisplayColorMenu[]; IF MenuDefs.IsSelected[item] THEN MenuDefs.Deselect[item] ELSE MenuDefs.Select[item]; RefreshDefs.RestoreScreen; END; ExpandText: PUBLIC MenuDefs.MenuProc = BEGIN OPEN ControllerMenuDefs; IF MenuDefs.IsSelected[item] THEN UnDisplayCaptionMenu[] ELSE DisplayCaptionMenu[]; IF MenuDefs.IsSelected[item] THEN MenuDefs.Deselect[item] ELSE MenuDefs.Select[item]; RefreshDefs.RestoreScreen; END; ApplyStyle: PUBLIC MenuDefs.MenuProc = BEGIN OPEN ControllerMenuDefs; --called with a selected object ChangeObj: PROCEDURE[obj: ObjectHandle]=BEGIN --if the object doesn't get any bigger, then don't need to erase it first new: StyleDefs.StyleHandle _ ControllerDefs.CurrentStyle[]; IF Rope.Equal[new.name, obj.style.name, FALSE] THEN RETURN; --same style IF obj.objectType=caption THEN IF new.anchor#obj.style.anchor OR new.orientation#obj.style.orientation OR new.fontid#obj.style.fontid THEN { obj.validEncoding_FALSE; --flag to recompute bounding box RefreshDefs.EraseAndSaveBox[obj.tl,obj.br]; }; IF obj.objectType=shape THEN IF new.width > obj.style.width OR (new.outlined # obj.style.outlined) OR (new.filled # obj.style.filled) THEN RefreshDefs.EraseAndSaveBox[obj.tl,obj.br]; obj.style _ new; RefreshDefs.PlotAndMark[obj]; END; ForAllSelectedDo[ChangeObj]; RefreshDefs.RestoreScreen[]; END; IndicateStyle: PUBLIC MenuDefs.MenuProc = BEGIN style: StyleDefs.StyleHandle _ NIL; SetSelectedStyle: PROCEDURE [s: ObjectDefs.ObjectHandle] = BEGIN style _ s.style END; ObjectDefs.ForAllSelectedDo [SetSelectedStyle]; IF style#NIL THEN SetStyle[style]; END; StringOfColor: PROCEDURE[color: StyleDefs.Color] RETURNS[ROPE]= BEGIN RETURN[GriffinColor.ColorToString[color]]; END; FittingType: PUBLIC MenuDefs.MenuProc = BEGIN string: ROPE _ MenuDefs.MenuString[item]; fitting _ SELECT TRUE FROM Rope.Equal[string,"Straight",FALSE] => lines, Rope.Equal[string,"Curved",FALSE] => curve, ENDCASE => ERROR; MenuDefs.SelectOnly[item]; END; ExpandSplines: PUBLIC MenuDefs.MenuProc = BEGIN IF MenuDefs.IsSelected[item] THEN MenuDefs.HideMenu[splineMenu] ELSE MenuDefs.ShowMenu[splineMenu]; IF MenuDefs.IsSelected[item] THEN MenuDefs.Deselect[item] ELSE MenuDefs.Select[item]; RefreshDefs.RestoreScreen; END; SplineType: PUBLIC MenuDefs.MenuProc = BEGIN string: ROPE _ MenuDefs.MenuString[item]; IF newObj#NIL THEN GriffinDefs.UserMessage["Only one spline type per object"]; spline _ SELECT TRUE FROM Rope.Equal[string,"Natural: Arc Length",FALSE] => naturalAL, Rope.Equal[string,"Natural: Unit Length",FALSE] => naturalUM, Rope.Equal[string,"Bezier Curve",FALSE] => bezier, Rope.Equal[string,"B-Spline",FALSE] => bspline, Rope.Equal[string,"Catmull-Rom Curve",FALSE] => crspline, ENDCASE => ERROR; MenuDefs.SelectOnly[item]; END; SetSplineType: PROCEDURE[splinetype: SplineDefs.SplineType] = BEGIN string: ROPE _ SELECT splinetype FROM naturalAL => "Natural: Arc Length", naturalUM => "Natural: Unit Length", bezier => "Bezier Curve", bspline => "B-Spline", crspline => "Catmull-Rom Curve", ENDCASE => ERROR; BugItemByString[splineMenu, string]; END; NewLink: PUBLIC MenuDefs.MenuProc = BEGIN tempLink: REF Link _ NIL; lastPt: PointDefs.ScrPt; cps: PointDefs.ObjPtSequence; IF spline=bspline OR spline=crspline THEN GriffinDefs.UserMessage["B-Splines and Catmull-Rom Curves cannot be used in linked objects"]; cps _ ReadCPs[]; IF cps=NIL OR cps.length <=1 THEN RETURN; lastPt _ PointDefs.ObjToScr[cps[cps.length-1]]; tempLink _ MakeLink[fitting=lines,cps]; IF newObj=NIL THEN BEGIN newObj _ LOOPHOLE[StartObject[shape]]; newObj.body _ shape[FALSE,CZone.NEW[Trajectory[linked] _ [spline,linked[tempLink]]],NIL,NIL]; newObj.style _ ControllerDefs.CurrentStyle[]; newObj.cluster _ OpenCluster; END ELSE AddLink[newObj,tempLink]; RefreshDefs.EraseAndSaveAllCPs[]; DeleteAllCPs[]; WriteLink[newObj,tempLink]; AddToken[lastPt,open]; RefreshDefs.RestoreScreen[]; END; MakeLink: PROCEDURE[isLines: BOOLEAN,cps: PointDefs.ObjPtSequence]RETURNS[newLink: REF Link] = BEGIN newLink _ CZone.NEW[Link]; newLink^ _ [NIL, (IF isLines THEN D1 ELSE D3), cps]; END; BackLink: PUBLIC MenuDefs.MenuProc = BEGIN lastLink: REF Link _ GetNewObjectLinks[]; RefreshDefs.EraseAndSaveAllCPs[]; DeleteAllCPs[]; --case of nil object. Shouldn't happen; IF lastLink = NIL THEN BEGIN [] _ DeleteObject[newObj]; newObj _ NIL; RefreshDefs.RestoreScreen[]; RETURN; END; --case of one link IF lastLink.link = NIL THEN BEGIN ShowKnots[lastLink.knots,FALSE]; RefreshDefs.EraseAndSave[newObj]; [] _ DeleteObject[newObj]; newObj _ NIL; RefreshDefs.RestoreScreen[]; RETURN; END; UNTIL lastLink.link=NIL DO lastLink _ lastLink.link; ENDLOOP; ShowLinkKnots[lastLink.knots,FALSE]; DeleteLink[newObj,lastLink]; --does an erase too RefreshDefs.RestoreScreen[]; END; ShowLinkKnots: PROCEDURE[knots: PointDefs.ObjPtSequence, exceptLast: BOOLEAN] = BEGIN i: CARDINAL; lastknot: CARDINAL _ knots.length-1; cps: PointDefs.ObjPtSequence _ ReadCPs[]; DeleteAllCPs[]; IF exceptLast THEN lastknot _ lastknot-1; AddToken[ObjToScr[knots[0]], open]; FOR i IN [1..lastknot] DO AddToken[ObjToScr[knots[i]], CP]; ENDLOOP; IF cps#NIL THEN BEGIN FOR i IN [0..cps.length) DO AddToken[ObjToScr[cps[i]], CP]; ENDLOOP; END; END; GetNewObjectLinks: PROCEDURE RETURNS [link: REF Link]= BEGIN IF newObj=NIL THEN RETURN[NIL]; WITH traj: newObj.trajectory SELECT FROM linked => link _ traj.links; ENDCASE => ERROR; RETURN; END; Draw: PUBLIC MenuDefs.MenuProc = BEGIN DrawObject[newObj,FALSE]; END; Close: PUBLIC MenuDefs.MenuProc = BEGIN DrawObject[newObj,TRUE]; END; Box: PUBLIC MenuDefs.MenuProc = BEGIN cps: PointDefs.ObjPtSequence; pt: ObjPt; cps _ ReadCPs[]; IF cps=NIL OR cps.length #2 THEN SIGNAL GriffinDefs.UserMessage["Exactly 2 points for a box"]; DeleteAllCPs[]; AddToken[ObjToScr[cps[0]],CP]; pt _ [cps[0][X],cps[1][Y]]; AddToken[ObjToScr[pt],CP]; AddToken[ObjToScr[cps[1]],CP]; pt _ [cps[1][X],cps[0][Y]]; AddToken[ObjToScr[pt],CP]; BugItemByString[shapeMenu,"Straight"]; DrawObject[newObj,TRUE]; END; Modify: PUBLIC MenuDefs.MenuProc = BEGIN selected: ObjectHandle _ NIL; FindLastSelected: PROCEDURE[obj: ObjectHandle]=BEGIN selected _ obj; END; IF newObj#NIL THEN RETURN; --don't modify while drawing or modifying ForAllSelectedDo[FindLastSelected]; IF selected=NIL THEN RETURN; WITH obj: selected SELECT FROM shape => BEGIN SetStyle[selected.style]; SetSplineType[obj.trajectory.splineType]; DeSelectObject[selected]; --will get selected again when finished EraseObject[selected]; ShowCPs[selected]; END; caption => BEGIN token: ObjectHandle _ ReturnSelected[selected]; IF token#NIL THEN EraseObject[token]; DeSelectObject[selected]; --will get selected again when finished SetStyle[selected.style]; GriffinDefs.TypeIntoCaption[selected]; END; ENDCASE => RETURN; END; ShowCPs: PROCEDURE[object: ObjectHandle] = BEGIN obj: REF shape Object _NIL; IF object=NIL THEN RETURN; WITH foo: object SELECT FROM shape => obj _ @foo; ENDCASE => ERROR; WITH traj: obj.trajectory SELECT FROM linked => BEGIN link: REF Link _ traj.links; IF link = NIL THEN ERROR; --object with one link IF link.link=NIL THEN BEGIN ShowKnots[link.knots,obj.closed]; IF link.degree=D1 THEN BugItemByString[shapeMenu,"Straight"] ELSE BugItemByString[shapeMenu,"Curved"]; [] _ DeleteObject[obj]; END --multiple links. Order here is important ELSE BEGIN closed: BOOLEAN _ obj.closed; newObj _ obj; newObj.closed _ FALSE; newObj.cluster _ OpenCluster; --delete last link FOR link _ traj.links , link.link UNTIL link.link=NIL DO ENDLOOP; --link is now last link in the object ShowLinkKnots[link.knots,closed]; IF link.degree=D1 THEN BugItemByString[shapeMenu,"Straight"] ELSE BugItemByString[shapeMenu,"Curved"]; DeleteLink[obj,link]; --plot the rest FOR link _ traj.links , link.link UNTIL link=NIL DO WriteLink[obj,link]; ENDLOOP; END; END; cyclic => BEGIN ShowKnots[traj.knots, FALSE]; BugItemByString[shapeMenu,"Curved"]; [] _ DeleteObject[obj]; END; ENDCASE; END; ShowKnots: PROCEDURE[knots: PointDefs.ObjPtSequence, exceptLast: BOOLEAN] = BEGIN i: CARDINAL; lastknot: CARDINAL _ knots.length-1; IF exceptLast THEN lastknot _ lastknot-1; FOR i IN [0..lastknot] DO AddToken[ObjToScr[knots[i]], CP]; ENDLOOP; END; DrawObject: PROCEDURE[object: ObjectHandle, closed: BOOLEAN] = BEGIN shapeObj: REF shape Object _ NIL; cps: PointDefs.ObjPtSequence _ ReadCPs[]; IF object=NIL AND (cps=NIL OR cps.length<1) THEN RETURN; IF object = NIL THEN BEGIN object _ StartObject[shape]; object.body _ shape[closed,CZone.NEW[Trajectory[linked] _ [spline,linked[NIL]]],NIL,NIL]; object.style _ ControllerDefs.CurrentStyle[]; END; --loophole the elegant way WITH obj: object SELECT FROM shape => shapeObj _ @obj; ENDCASE; shapeObj.closed _ closed; WITH traj: shapeObj.trajectory SELECT FROM cyclic => shapeObj.trajectory _CZone.NEW[Trajectory[cyclic] _ [spline,cyclic[cps]]]; linked => IF traj.links=NIL AND closed AND fitting=curve THEN shapeObj.trajectory _ CZone.NEW[Trajectory[cyclic] _[spline,cyclic[cps]]] ELSE BEGIN --assume linked from here on down link: REF Link; IF closed THEN BEGIN IF traj.links=NIL THEN AddToken[ObjToScr[cps[0]],CP] ELSE AddToken[ObjToScr[traj.links.knots[0]],CP]; cps _ ReadCPs[]; shapeObj.closed _ TRUE; END; link _ MakeLink[fitting=lines,cps]; AddLink[shapeObj,link]; WriteLink[shapeObj,link]; END; ENDCASE; object.cluster _ 0; RefreshDefs.PlotAndMark[object]; [] _ ObjectDefs.SelectObject[object]; RefreshDefs.RestoreScreen[]; RefreshDefs.EraseAndSaveAllCPs[]; DeleteAllCPs[]; RefreshDefs.RestoreScreen[]; newObj _ NIL; END; editMenu: PUBLIC MenuDefs.MenuHandle_NIL; styleMenu: PUBLIC MenuDefs.MenuHandle_NIL; shapeMenu: PUBLIC MenuDefs.MenuHandle_NIL; splineMenu: PUBLIC MenuDefs.MenuHandle_NIL; default: MenuDefs.MenuItemHandle_NIL; showstyle: MenuDefs.MenuItemHandle_NIL; newLink: MenuDefs.MenuItemHandle_NIL; StartDrawMenus: PUBLIC PROC = { editMenu _ MenuDefs.CreateMenu[horizontal, [100,500], NIL]; []_MenuDefs.AddMenuItem[editMenu,"Draw",Draw]; []_MenuDefs.AddMenuItem[editMenu,"Close",Close]; []_MenuDefs.AddMenuItem[editMenu,"Draw link",NewLink]; []_MenuDefs.AddMenuItem[editMenu,"Modify",Modify]; []_MenuDefs.AddMenuItem[editMenu,"Back link",BackLink]; []_MenuDefs.AddMenuItem[editMenu,"Box",Box]; []_MenuDefs.AddMenuItem[editMenu,"Spline Type",ExpandSplines]; shapeMenu _ MenuDefs.CreateMenu[vertical, [100,550], NIL]; default _MenuDefs.AddMenuItem[shapeMenu,"Straight",FittingType]; []_MenuDefs.AddMenuItem[shapeMenu,"Curved",FittingType]; MenuDefs.BugItem[default]; splineMenu _ MenuDefs.CreateMenu[vertical, [200,550], NIL]; default _MenuDefs.AddMenuItem[splineMenu,"Natural: Arc Length",SplineType]; []_MenuDefs.AddMenuItem[splineMenu,"Natural: Unit Length",SplineType]; []_MenuDefs.AddMenuItem[splineMenu,"Bezier Curve",SplineType]; []_MenuDefs.AddMenuItem[splineMenu,"B-Spline",SplineType]; []_MenuDefs.AddMenuItem[splineMenu,"Catmull-Rom Curve",SplineType]; MenuDefs.BugItem[default]; styleMenu _ MenuDefs.CreateMenu[vertical, [400,200], NIL]; []_MenuDefs.AddMenuItem [styleMenu, "Indicate", IndicateStyle]; []_MenuDefs.AddMenuItem [styleMenu, "Apply", ApplyStyle]; []_MenuDefs.AddMenuItem [styleMenu, "Shape Style", ExpandShape]; []_MenuDefs.AddMenuItem [styleMenu, "Color Style", ExpandColor]; []_MenuDefs.AddMenuItem [styleMenu, "Text Style", ExpandText]; }; END. Ź˜JšņĻc•œĻk œžœžœžœ!žœ%žœ!žœžœžœ!žœžœžœžœžœ?žœ!žœžœ†žœ'žœžœ2žœžœ6žœ$žœžœžœĻnœž œ!žœ1žœÖžœžœžœžœVžœžœ1žœžœHžœžœdžœ žœ¼žœžœ8žœ žœjžœfžœžœ=žœžœ2žœžœ>žœžœžœŸœž œ$žœžœžœ&žœ'žœ&žœžœHžœĻb œžœžœžœžœžœžœžœžœžœ3žœ  œžœžœžœžœžœžœžœžœžœ3žœ  œžœžœžœžœžœžœžœžœžœ3žœ  œžœžœžœ Ÿ œž œžœJœ>žœ&žœžœžœĻi œžœžœžœžœ'žœžœžœ” œ7žœžœžœ%žœ#žœ_žœ<žœ  œžœžœ!žœŸœž œ!žœžœ2žœžœžœžœŸ œž œžœžœžœžœ%žœ  œžœžœ žœ(žœžœžœžœ(žœ žœžœžœ  œžœžœžœžœžœ žœžœžœ3žœ  œžœžœ žœžœžœžœFžœžœžœ+žœ;žœ2žœ+žœ5žœžœžœžœŸ œž œ&žœ žœžœ žœ¤žœžœ'žœ œžœžœ žœžœ9žœžœžœsžœžœžœžœžœZžœžœžœžœ žœ+žœžœ1žœžœRžœžœžœŸœž œ žœžœ žœ žœžœžœžœ žœžœ žœ žœžœ žœO)žœ žœžœžœ'žœ!žœžœžœžœžœžœžœLžœ!žœžœžœžœžœžœžœ œžœŸ œž œ-žœžœžœ žœMžœ žœ<žœžœžœžœžœžœžœžœžœžœžœžœžœžœžœžœŸœž œžœžœžœžœžœžœžœžœžœžœžœ žœžœžœžœ žœžœžœžœ žœžœžœžœžœžœ;žœžœžœžœžœbžœžœ žœžœžœžœ žœžœ<žœžœ žœžœžœŸœž œžœžœžœžœžœžœ*œ$žœ žœžœžœžœžœžœ žœb(œ-žœ žœ3žœžœžœ0(œDžœžœžœžœŸœž œžœžœžœžœžœžœžœžœ žœžœžœžœžœžœžœ žœžœžœžœžœžœœžœ žœžœžœ'žœžœ)žœBžœ+œžœžœ žœ1žœ"œžœžœ žœžœžœ&œ&žœžœ)žœ>œžœžœžœžœžœžœžœ žœžœCžœžœžœŸ œž œ-žœžœžœ žœžœ žœžœžœžœžœžœžœŸ œž œžœžœ žœžœ-žœžœžœžœžœžœžœžœ žœžœžœAžœ%žœžœžœ4žœžœ žœžœžœžœžœžœ&žœ8žœ žœžœžœžœžœ,žœžœ"œžœ žœžœžœžœ žœžœžœžœ(žœ,žœžœ`žœžœŅžœžœ žœžœ žœžœ žœžœžœžœ%žœ&žœ$žœŸœžœžœ<žœ²žœŌžœÆžœÉžœ˜‚s—…—9„Až