CDPolygonsImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
by Christian Jacobi, March 30, 1985 12:19:40 pm PST
last edited by Christian Jacobi, April 11, 1985 9:16:16 am PST
DIRECTORY
CDApplications,
CDPolygons,
CDTexts,
CD,
CDBasics,
CDDefaultsExtras,
CDIO,
CDOps,
CDOrient,
Graphics,
Rope,
TokenIO;
CDPolygonsImpl: CEDAR PROGRAM
IMPORTS CD, CDApplications, CDBasics, CDDefaultsExtras, CDIO, CDOrient, CDOps, Graphics, Rope, TokenIO
EXPORTS CDPolygons =
BEGIN
PolygonPtr: TYPE = CDPolygons.PolygonPtr;
PolygonRec: TYPE = CDPolygons.PolygonRec;
PList: TYPE = LIST OF CD.DesignPosition;
pForPolygon: REF CD.ObjectProcs = CD.RegisterObjectType[$Polygon];
CopyList: PROC [points: PList] RETURNS [copy: PList←NIL, r: CD.DesignRect, leng: INT𡤀] =
BEGIN
min: CD.DesignPosition ← CDBasics.highposition;
max: CD.DesignPosition ← CDBasics.minposition;
FOR p: PList ← points, p.rest WHILE p#NIL DO
leng ← leng+1;
min ← CDBasics.MinPoint[min, p.first];
max ← CDBasics.MaxPoint[max, p.first];
ENDLOOP;
FOR p: PList ← points, p.rest WHILE p#NIL DO
copy ← CONS[CDBasics.SubPoints[p.first, min], copy];
ENDLOOP;
r ← CDBasics.ToRect[min, max]
END;
CreatePolygon: PUBLIC PROC [points: LIST OF CD.DesignPosition, lev: CD.Layer]
RETURNS [ob: CD.ObPtr←NIL, offset: CD.DesignPosition←[0, 0]] =
BEGIN
pp: PolygonPtr = NEW[PolygonRec];
r: CD.DesignRect;
leng: INT;
[pp.points, r, leng] ← CopyList[points];
IF leng<3 THEN RETURN;
pp.path ← Graphics.NewPath[leng];
Graphics.MoveTo[pp.path, pp.points.first.x, pp.points.first.y];
FOR p: PList ← pp.points.rest, p.rest WHILE p#NIL DO
Graphics.LineTo[pp.path, p.first.x, p.first.y];
ENDLOOP;
ob ← NEW[CD.ObjectDefinition←[
size: CDBasics.MaxPoint[[1, 1], CDBasics.SizeOfRect[r]],
layer: CDDefaultsExtras.PureLayer[lev],
p: pForPolygon,
specificRef: pp
]];
offset ← CDBasics.BaseOfRect[r];
END;
Init: PROC [] =
BEGIN
pForPolygon.drawMe ← pForPolygon.quickDrawMe ← DrawMeForPolygon;
--pForPolygon.showMeSelected ← ShowPolygonSelection;
pForPolygon.hitInside ← HitInsidePolygon;
pForPolygon.describe ← Describe;
pForPolygon.internalRead ← ReadPolygon;
pForPolygon.internalWrite ← WritePolygon;
END;
Length: PROC [points: LIST OF CD.Position] RETURNS [l: NAT ← 0] =
BEGIN
FOR p: LIST OF CD.Position ← points, p.rest WHILE p#NIL DO
l ← l+1
ENDLOOP
END;
--Works only after Cedar 6 because of crazy colors
ShowPolygonSelection: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation,
pr: CD.DrawRef] =
BEGIN
DrawPolygonInContext: PROC [context: Graphics.Context, ob: CD.ObPtr, layer: CD.Layer] =
BEGIN
context.DrawStroke[path: NARROW[ob.specificRef, PolygonPtr].path, closed: TRUE];
END;
pr.drawContext[pr, DrawPolygonInContext, aptr.ob, pos, orient, 0]
END;
HitInsidePolygon: PROC [aptr: CD.ApplicationPtr, hitRect: CD.DesignRect] RETURNS [yes: BOOL] =
BEGIN
yes ← CDBasics.Intersect[CDApplications.ARectI[aptr], hitRect];
--is sick
IF yes THEN {
pp: PolygonPtr = NARROW[aptr.ob.specificRef];
cont: Graphics.Context ← Graphics.NewContext[];
r: CD.DesignRect ← CDOrient.DeMapRect[
itemInWorld: hitRect,
cellSize: aptr.ob.size,
cellInstOrient: aptr.orientation,
cellInstPos: aptr.location
].itemInCell;
Graphics.ClipArea[cont, pp.path];
Graphics.ClipBox[cont, Graphics.Box[xmin: r.x1, ymin: r.y1, xmax: r.x2, ymax: r.y2]];
yes ← Graphics.Visible[cont];
cont ← NIL;
};
END;
DrawMeForPolygon: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation,
pr: CD.DrawRef] =
BEGIN
DrawPolygonInContext: PROC [context: Graphics.Context, ob: CD.ObPtr, layer: CD.Layer] =
BEGIN
context.DrawArea[path: NARROW[ob.specificRef, PolygonPtr].path, parityFill: TRUE];
END;
pr.drawContext[pr, DrawPolygonInContext, aptr.ob, pos, orient, aptr.ob.layer]
END;
Describe: PROC[me: CD.ObPtr] RETURNS [Rope.ROPE] =
BEGIN
RETURN [Rope.Concat["polygon ", CDOps.LayerName[me.layer]]]
END;
WritePolygon: CD.InternalWriteProc -- PROC [me: ObPtr] -- =
BEGIN
pp: PolygonPtr = NARROW[me.specificRef];
l: NAT ← Length[pp.points];
CDIO.WriteLayer[me.layer];
TokenIO.WriteInt[l];
FOR p: PList ← pp.points, p.rest WHILE p#NIL DO
TokenIO.WriteInt[p.first.x];
TokenIO.WriteInt[p.first.y];
ENDLOOP
END;
ReadPolygon: CD.InternalReadProc --PROC [] RETURNS [ObPtr]-- =
BEGIN
ob: CD.ObPtr;
lev: CD.Layer = CDIO.ReadLayer[];
leng: INT = TokenIO.ReadInt[];
points: PList ← NIL;
FOR i: INT IN [1..leng] DO
p: CD.DesignPosition;
p.x ← TokenIO.ReadInt[];
p.y ← TokenIO.ReadInt[];
points ← CONS[p, points];
ENDLOOP;
--reorder??
ob ← CreatePolygon[points, lev].ob;
RETURN [ob]
END;
Init[];
END.