File: CheckMarksImpl.mesa   
Copyright © 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:55:33 pm PST
Last Edited by: Jacobi, December 19, 1984 8:33:38 pm PST
DIRECTORY
CheckMarks,
TokenIO USING [ReadInt, WriteInt],
TerminalIO USING [WriteRope],
CDSequencer USING [Command, ImplementCommand],
CD,
CDBasics USING [AddPoints],
CDApplications USING [NewApplicationI],
CDMenus USING [CreateEntry],
CDOps USING [IncludeApplication],
Rope USING [ROPE];
CheckMarksImpl: CEDAR PROGRAM    
IMPORTS CDMenus, CD, TerminalIO, TokenIO, CDOps, CDApplications, CDBasics, CDSequencer EXPORTS CheckMarks =  
BEGIN OPEN CheckMarks;
markRadius: INT = 2;
versionNumber: INT ~ 1; -- version number of our file format
objAtom: PUBLIC ATOM ← $CheckMark;
myLevel: CD.Level;
objsProcs: REF CD.ObjectProcs;
-- Utilities
-- find the origin of a mark application relative to the containing cell's origin
AptrToCheck: PUBLIC PROC [aptr: CD.ApplicationPtr] RETURNS [REF CD.Position] = BEGIN
IF aptr.ob.p.objectType # objAtom THEN RETURN[NIL];
RETURN[NEW[CD.Position ← CDBasics.AddPoints[aptr.location, [markRadius, markRadius]]] ];
END;
-- make a mark
MakeCheckAptr: PUBLIC PROC [markPos: CD.Position] RETURNS [CD.ApplicationPtr] = BEGIN
obj: CD.ObPtr ← NEW[CD.ObjectDefinition];
obj.p ← objsProcs;
obj.size ← [markRadius * 2, markRadius * 2];
obj.specificRef ← NIL;
obj.level ← myLevel;
RETURN[CDApplications.NewApplicationI[obj, markPos]];
END;
-- add a mark to a Design at absolute coordinates
Place: PUBLIC PROC [into: CD.Design, markPos: CD.Position] = BEGIN
CDOps.IncludeApplication[into, MakeCheckAptr[markPos]];
END;
-- Find all check marks in a cell.
FindList: PUBLIC PROC [ob: CD.ObPtr] RETURNS [LIST OF CD.Position] = BEGIN
list: CD.ApplicationList;
checks: LIST OF CD.Position ← 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 {
checks ← CONS[AptrToCheck[a.first]^, checks];
};
ENDLOOP;
RETURN[checks];
END;
-- routines for interactive editing of marks
DrawCheckMark: CD.DrawProc = BEGIN
-- PROC [aptr: ApplicationPtr, pos: DesignPosition, orient: Orientation, pr: REF DrawInformation];
-- draw the mark
pr.outLineProc[ [pos.x, pos.y, pos.x + 2 * markRadius, pos.y + 2 * markRadius], pr];
pr.drawRect[ [pos.x, pos.y, pos.x + markRadius, pos.y + markRadius], aptr.ob.level, pr];
pr.drawRect[ [pos.x + markRadius, pos.y + markRadius, pos.x + 2 * markRadius, pos.y + 2 * markRadius], aptr.ob.level, pr];
END;
AddCheckMark: PROC [comm: CDSequencer.Command] = BEGIN
Place[comm.design, comm.pos];
END;
WriteMark: CD.InternalWriteProc -- PROC [me: ObPtr] -- = BEGIN
TokenIO.WriteInt[versionNumber];
END;
ReadMark: CD.InternalReadProc -- PROC [] RETURNS [ObPtr] -- = BEGIN
version: INT;
obj: CD.ObPtr ← NEW[CD.ObjectDefinition];
obj.p ← objsProcs;
obj.size ← [markRadius * 2, markRadius * 2];
obj.specificRef ← NIL;
obj.level ← myLevel;
version ← TokenIO.ReadInt[];
SELECT version FROM
1 => NULL;
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
RETURN["tiler check mark"];
END;
-- Top-level command routines
Init: PROC[] = BEGIN
error: BOOLFALSE;
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, $CheckMarkLevel];
objsProcs ← tmp;
}
ELSE {
error ← FALSE;
objsProcs ← CD.FetchObjectProcs[objAtom! CD.Error => {error ← TRUE; CONTINUE}];
myLevel ← CD.FetchLevel[NIL, $CheckMarkLevel ! CD.Error => {error ← TRUE; CONTINUE}];
IF error THEN objsProcs ← NIL;
};
IF objsProcs = NIL THEN {
TerminalIO.WriteRope["Error: Can't register check-mark object procs.\n"];
RETURN;
};
objsProcs.drawMe ← DrawCheckMark;
objsProcs.internalWrite ← WriteMark;
objsProcs.internalRead ← ReadMark;
objsProcs.describe ← DescribeMark;
objsProcs.inDirectory ← FALSE;
objsProcs.wireTyped ← FALSE;
CDSequencer.ImplementCommand[$AddCheckMark, AddCheckMark];
CDMenus.CreateEntry[menu: $ModuleMenu, entry: "Add Check Mark", key: $AddCheckMark];
END;
-- Main body
Init[];
END.