DIRECTORY AlignmentMarks, TilerMenu USING [Register], TerminalIO USING [WriteRope, WriteInt, RequestRope], CDSequencer USING [Command, ImplementCommand], CD, TokenIO USING [ReadRope, WriteRope, ReadInt, WriteInt], CDInline USING [AddPoints], CDOps USING [AddAnObject], CDOrient USING [MapPosition], Rope USING [ROPE, Concat], Graphics USING [Context, MoveTo, LineTo, DrawArea, NewPath, Path], Real USING [Fix]; AlignmentMarksImpl: CEDAR PROGRAM IMPORTS TilerMenu, CD, TerminalIO, CDOps, CDInline, Rope, CDSequencer, TokenIO, CDOrient, 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 markAtom: PUBLIC ATOM _ $AlignmentMark; myLevel: CD.Level; objsProcs: REF CD.ObjectProcs; arrowSize: INT = 2 * CD.lambda; FindName: PUBLIC PROC [aptr: CD.ApplicationPtr] RETURNS [Rope.ROPE] = BEGIN RETURN[ NARROW[aptr.ob.specificRef, MarkObj].name ]; END; FindOrigin: PUBLIC PROC [aptr: CD.ApplicationPtr] RETURNS [CD.Position] = BEGIN orig: CD.Position; orig _ CDInline.AddPoints[ CDOrient.MapPosition[ itemInCell: [x1: 0, y1: 0, x2: 0, y2: 0], cellSize: aptr.ob.size, cellInstOrient: aptr.orientation], aptr.location]; RETURN[orig]; END; OKCommand: PROC [comm: CDSequencer.Command] RETURNS[BOOL] = BEGIN IF comm.pos.x > 10000 OR comm.pos.y > 10000 OR comm.pos.x < -10000 OR comm.pos.y < -10000 THEN BEGIN TerminalIO.WriteRope["Warning: Huge position passed to AlignmentMarks from ChipNDale, maybe the TIP table is screwed up?\n"]; TerminalIO.WriteRope["comm.pos.x ="]; TerminalIO.WriteInt[comm.pos.x]; TerminalIO.WriteRope[" comm.pos.y ="]; TerminalIO.WriteInt[comm.pos.y]; [] _ TerminalIO.RequestRope["\nOperation will be aborted, type return ......"]; RETURN[FALSE]; END; RETURN[TRUE]; END; PlaceMark: PUBLIC PROC [into: CD.Design, markName: Rope.ROPE, markPos: CD.Position] = BEGIN obj: CD.ObPtr _ NEW[CD.ObjectDefinition]; markObj: MarkObj _ NEW[MarkObjRec]; markObj.name _ markName; obj.p _ objsProcs; obj.size _ [arrowSize, arrowSize]; obj.specificRef _ markObj; obj.level _ myLevel; CDOps.AddAnObject[design: into, ob: obj, location: markPos]; 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 _ CDInline.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 name: Rope.ROPE; IF ~OKCommand[comm] THEN RETURN[]; name _ TerminalIO.RequestRope["Enter name of new alignment mark: "]; PlaceMark[comm.design, name, comm.pos]; 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[markAtom ! 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[markAtom! 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.hasChildren _ 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, July 30, 1984 3:52:08 pm PDT -- Utilities -- Given a ChipNDale application that points to an alignment mark, return it's name. -- Returns some unspecified value if the application contains a different type of object. -- find the origin of a mark application relative to the containing cell's origin -- check a command for wierdness as it is possible to screw up the TIP table. -- routines for interactive editing of marks -- add a mark to a Design or Cell at absolute coordinates -- PROC [aptr: ApplicationPtr, pos: DesignPosition, orient: Orientation, pr: REF DrawInformation]; -- apply an orientation to a point -- draw the arrow DrawName: PROC [context: Graphics.Context] = BEGIN name: Rope.ROPE _ NARROW[aptr.ob.specificRef, MarkObj].name; allr: CD.Rect _ [x1: arrowSize * markScale, y1: 0, x2: markWidth * markScale, y2: markHeight * markScale]; r: CD.Rect; r _ CDInline.MoveRect[CDOrient.MapRect[allr, aptr.ob.size, orient], pos]; pr.drawComment[r, name, pr]; END; -- draw the arrow & name CD.DrawToContext[pr, DrawName, aptr.ob.level]; -- Top-level command routines -- Main body ΚΘ˜– "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šœ ˜ 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šœžœžœžœ˜AJšžœžœžœ žœ˜šžœžœ˜Jšœ žœ žœ˜,Jšœ˜J˜—šžœ˜Jšœžœ˜Jš œ žœžœžœžœ˜PJš œ žœ žœžœžœžœ˜UJšžœžœ žœ˜J˜—šžœ žœžœ˜J˜NJšžœ˜J˜—J˜!J˜$J˜"Jšœ"˜"Jšœžœ˜Jšœžœ˜Jšœ:˜:Jšœ8˜8Jšžœ˜—J˜—™ J™Jšœ˜—Jšžœ˜—…—΄"r