DIRECTORY AlignmentMarks, TilerMenu USING [Register], TerminalIO USING [WriteRope, RequestRope], CDSequencer USING [Command, ImplementCommand], CD, TokenIO USING [ReadRope, WriteRope, ReadInt, WriteInt], CDBasics USING [AddPoints, SubPoints], CDOps USING [IncludeApplication], CDOrient USING [MapPosition], CDApplications USING [NewApplicationI], Rope USING [ROPE, Concat, Equal], Graphics USING [Context, MoveTo, LineTo, DrawArea, NewPath, Path], Real USING [Fix]; AlignmentMarksImpl: CEDAR PROGRAM IMPORTS TilerMenu, CD, TerminalIO, CDOps, CDBasics, Rope, CDSequencer, TokenIO, CDOrient, CDApplications, Graphics, Real EXPORTS AlignmentMarks = BEGIN OPEN AlignmentMarks; MarkObj: TYPE = REF MarkObjRec; -- an object that can be put in a cell or design MarkObjRec: TYPE = RECORD [ name: Rope.ROPE ]; versionNumber: INT ~ 1; -- version of file format for alignment marks objAtom: PUBLIC ATOM _ $AlignmentMark; myLevel: CD.Level; objsProcs: REF CD.ObjectProcs; arrowSize: INT = 2 * CD.lambda; AptrToMark: PUBLIC PROC [aptr: CD.ApplicationPtr] RETURNS [REF Mark] = BEGIN mark: REF Mark _ NEW[Mark]; IF aptr.ob.p.objectType # objAtom THEN RETURN[NIL]; mark.name _ NARROW[aptr.ob.specificRef, MarkObj].name; mark.pos _ CDBasics.AddPoints[ CDOrient.MapPosition[ itemInCell: [x1: 0, y1: 0, x2: 0, y2: 0], cellSize: aptr.ob.size, cellInstOrient: aptr.orientation], aptr.location]; RETURN[mark]; END; MakeMarkAptr: PUBLIC PROC [mark: Mark, orient: CD.Orientation _ CD.original] RETURNS [CD.ApplicationPtr]= BEGIN aptr: CD.ApplicationPtr; pos: CD.Position _ mark.pos; obj: CD.ObPtr _ NEW[CD.ObjectDefinition]; markObj: MarkObj _ NEW[MarkObjRec]; markObj.name _ mark.name; obj.p _ objsProcs; obj.size _ [arrowSize, arrowSize]; obj.specificRef _ markObj; obj.level _ myLevel; aptr _ CDApplications.NewApplicationI[obj, pos, orient]; aptr.location _ CDBasics.SubPoints[aptr.location, CDBasics.SubPoints[AptrToMark[aptr].pos, aptr.location]]; RETURN[aptr]; END; FindList: PUBLIC PROC [ob: CD.ObPtr] RETURNS [LIST OF Mark] = BEGIN list: CD.ApplicationList; marks: LIST OF Mark _ NIL; SELECT ob.p.objectType FROM $Cell => list _ NARROW[ob.specificRef, CD.CellPtr].contents; ENDCASE => RETURN[NIL]; FOR a: CD.ApplicationList _ list, a.rest WHILE a # NIL DO IF a.first.ob.p.objectType = objAtom THEN { marks _ CONS[AptrToMark[a.first]^, marks]; }; ENDLOOP; RETURN[marks]; END; Find: PUBLIC PROC [ob: CD.ObPtr, name: Rope.ROPE] RETURNS [REF Mark] = BEGIN FOR a: LIST OF Mark _ FindList[ob], a.rest WHILE a # NIL DO IF Rope.Equal[a.first.name, name] THEN { RETURN[NEW[Mark _ a.first]]; }; ENDLOOP; RETURN[NIL]; END; Place: PUBLIC PROC [into: CD.Design, mark: Mark, orient: CD.Orientation _ CD.original] = BEGIN CDOps.IncludeApplication[into, MakeMarkAptr[mark, orient]]; END; DrawAlignMark: CD.DrawProc = BEGIN DrawArrow: PROC [context: Graphics.Context] = BEGIN MapPoint: PROC [p: CD.Position, cellSize: CD.Position, orient: CD.Orientation] RETURNS [CD.Position] = INLINE BEGIN RETURN[CDOrient.MapPosition[ itemInCell: [x1: p.x, y1: p.y, x2: p.x, y2: p.y], cellSize: cellSize, cellInstOrient: orient]]; END; MapReal: PROC[x, y: REAL] RETURNS [xi, yi: INT] = INLINE BEGIN orig: CD.Position; orig.x _ Real.Fix[x]; orig.y _ Real.Fix[y]; orig _ CDBasics.AddPoints[MapPoint[orig, aptr.ob.size, orient], pos]; RETURN[orig.x, orig.y]; END; RealPoint: TYPE = RECORD [x: REAL, y: REAL]; RealPointArray8: TYPE = ARRAY NAT[0..8) OF RealPoint; x, y: INT; sx1, sx2, sy1, sy2: INT; arrow: RealPointArray8 _ [ [0,0], [0,0.75], [0.25,0.5], [0.75,1], [1,0.75], [0.5,0.25], [0.75,0], [0,0] ]; path: Graphics.Path _ Graphics.NewPath[size: 8]; IF context = NIL THEN RETURN; [sx1, sy1] _ MapReal[0.0, 0.0]; [sx2, sy2] _ MapReal[arrowSize, arrowSize]; [x, y] _ MapReal[arrow[0].x * arrowSize, arrow[0].y * arrowSize]; Graphics.MoveTo[path, x, y, TRUE]; FOR i: INT IN [1..8) DO [x, y] _ MapReal[arrow[i].x * arrowSize, arrow[i].y * arrowSize]; Graphics.LineTo[path, x , y]; ENDLOOP; Graphics.DrawArea[self: context, path: path]; END; CD.DrawToContext[pr, DrawArrow, aptr.ob.level]; END; AddAlignMark: PROC [comm: CDSequencer.Command] = BEGIN mark: Mark; mark.name _ TerminalIO.RequestRope["Enter name of new alignment mark: "]; mark.pos _ comm.pos; Place[comm.design, mark]; END; WriteMark: CD.InternalWriteProc -- PROC [me: ObPtr] -- = BEGIN markObj: MarkObj = NARROW[me.specificRef]; TokenIO.WriteInt[versionNumber]; TokenIO.WriteRope[markObj.name]; END; ReadMark: CD.InternalReadProc -- PROC [] RETURNS [ObPtr] -- = BEGIN obj: CD.ObPtr _ NEW[CD.ObjectDefinition]; markObj: MarkObj _ NEW[MarkObjRec]; version: INT; obj.p _ objsProcs; obj.size _ [arrowSize, arrowSize]; obj.specificRef _ markObj; obj.level _ myLevel; version _ TokenIO.ReadInt[]; SELECT version FROM 1 => markObj.name _ TokenIO.ReadRope[]; ENDCASE => TerminalIO.WriteRope["File contained an unknown version of Alignment Marks\n"]; RETURN[obj]; END; DescribeMark: CD.DescribeProc -- PROC [me: ObPtr] RETURNS [Rope.ROPE] -- = BEGIN markObj: MarkObj = NARROW[me.specificRef]; RETURN[Rope.Concat["alignment mark ", markObj.name]]; END; Init: PROC[] = BEGIN error: BOOL _ FALSE; tmp: REF CD.ObjectProcs _ NIL; tmp _ CD.RegisterObjectType[objAtom ! CD.Error => error _ TRUE]; IF tmp = NIL THEN error _ TRUE; IF ~error THEN { myLevel _ CD.NewLevel[NIL, $AlignMarkLevel]; objsProcs _ tmp; } ELSE { error _ FALSE; objsProcs _ CD.FetchObjectProcs[objAtom! CD.Error => {error _ TRUE; CONTINUE}]; myLevel _ CD.FetchLevel[NIL, $AlignMarkLevel ! CD.Error => {error _ TRUE; CONTINUE}]; IF error THEN objsProcs _ NIL; }; IF objsProcs = NIL THEN { TerminalIO.WriteRope["Error: Can't register alignment-mark object procs.\n"]; RETURN; }; objsProcs.drawMe _ DrawAlignMark; objsProcs.internalWrite _ WriteMark; objsProcs.internalRead _ ReadMark; objsProcs.describe _ DescribeMark; objsProcs.inDirectory _ FALSE; objsProcs.wireTyped _ FALSE; CDSequencer.ImplementCommand[$AddAlignMark, AddAlignMark]; TilerMenu.Register["Add Alignment Mark", $AddAlignMark]; END; Init[]; END.  File: AlignmentMarksImpl.mesa Copyright c 1984 by Xerox Corporation. All rights reserved. Created by: Bob Mayo, June 8, 1984 12:28:34 pm PDT Last Edited by: Mayo, November 5, 1984 6:46:29 pm PST -- Utilities -- Make an application for a mark, but don't place it -- adjust location of mark for the orientation -- routines for interactive editing of marks -- Place a mark into a design. -- PROC [aptr: ApplicationPtr, pos: DesignPosition, orient: Orientation, pr: REF DrawInformation]; -- apply an orientation to a point -- draw the arrow -- draw the arrow & name CD.DrawToContext[pr, DrawName, aptr.ob.level]; -- Top-level command routines -- Main body Κy˜– "Cedar" stylešœ ™ Jšœ Οmœ1™J˜Jšœ,˜,JšœE˜EJšžœ˜Jšžœ˜——J˜Jš œ žœžœžœžœ˜,Jš œžœžœžœžœ ˜5Jšœžœ˜ Jšœžœ˜Jšœj˜jJ˜0Jšžœ žœžœžœ˜J™Jšœ˜Jšœ+˜+JšœA˜AJšœžœ˜"šžœžœžœž˜JšœA˜AJšœ˜Jšžœ˜—Jšœ-˜-Jšžœ˜—J˜Jšœ™Jšžœ-˜/Jšžœ,™.Jšžœ˜J˜—š‘ œžœž˜6J˜ J˜IJ˜Jšœ˜Jšžœ˜—J˜šŸ œžœ œž˜>Jšœžœ˜*J˜ Jšœ ˜ Jšžœ˜J˜—šŸœžœ œž˜CJšœžœ žœžœ˜)Jšœžœ ˜#Jšœ žœ˜ Jšœ˜Jšœ"˜"J˜Jšœ˜Jšœ˜šžœ ž˜Jšœ'˜'JšžœS˜Z—Jšžœ˜ Jšžœ˜J˜—š Ÿ œžœ Πck  ’ ’ œž˜PJšœžœ˜*Jšžœ0˜6Jšžœ˜—˜J˜——J™J™™J˜š‘œžœž˜Jšœžœžœ˜Jšœžœžœžœ˜Jšœžœžœžœ˜@Jšžœžœžœ žœ˜šžœžœ˜Jšœ žœ žœ˜,Jšœ˜J˜—šžœ˜Jšœžœ˜Jš œ žœžœžœžœ˜OJš œ žœ žœžœžœžœ˜UJšžœžœ žœ˜J˜—šžœ žœžœ˜J˜NJšžœ˜J˜—J˜!J˜$J˜"Jšœ"˜"Jšœžœ˜Jšœžœ˜Jšœ:˜:Jšœ8˜8Jšžœ˜—J˜—™ J™Jšœ˜—Jšžœ˜—…—„"