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
DIRECTORY
CheckMarks,
TilerMenu USING [Register],
TokenIO USING [ReadInt, WriteInt],
TerminalIO USING [WriteRope],
CDSequencer USING [Command, ImplementCommand],
CD,
CDBasics USING [AddPoints],
CDApplications USING [NewApplicationI],
CDOps USING [IncludeApplication],
CheckMarksImpl:
CEDAR
PROGRAM
IMPORTS TilerMenu, 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: 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, $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];
TilerMenu.Register["Add Check Mark", $AddCheckMark];
END;
END.