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, June 11, 1985 10:06:47 am PDT
DIRECTORY
CDInstances,
CDPolygons,
CDTexts,
CD,
CDBasics,
CDDefaultsExtras,
CDIO,
CDOps,
Imager,
ImagerPath,
Rope,
TokenIO;
CDPolygonsImpl: CEDAR PROGRAM
IMPORTS CD, CDInstances, CDBasics, CDDefaultsExtras, CDIO, CDOps, Imager, ImagerPath, Rope, TokenIO
EXPORTS CDPolygons =
BEGIN
PolygonPtr: TYPE = CDPolygons.PolygonPtr;
PolygonRec: TYPE = CDPolygons.PolygonRec;
PList: TYPE = LIST OF CD.Position;
pForPolygon: REF CD.ObjectClass = CD.RegisterObjectClass[$Polygon];
CopyList: PROC [points: PList] RETURNS [copy: PList←NIL, r: CD.Rect, leng: INT𡤀] =
BEGIN
min: CD.Position ← CDBasics.highposition;
max: CD.Position ← CDBasics.minposition;
FOR class: PList ← points, class.rest WHILE class#NIL DO
leng ← leng+1;
min ← CDBasics.MinPoint[min, class.first];
max ← CDBasics.MaxPoint[max, class.first];
ENDLOOP;
FOR class: PList ← points, class.rest WHILE class#NIL DO
copy ← CONS[CDBasics.SubPoints[class.first, min], copy];
ENDLOOP;
r ← CDBasics.ToRect[min, max]
END;
CreatePolygon: PUBLIC PROC [points: LIST OF CD.Position, lev: CD.Layer]
RETURNS [ob: CD.Object←NIL, offset: CD.Position←[0, 0]] =
BEGIN
pp: PolygonPtr = NEW[PolygonRec];
r: CD.Rect;
leng: INT;
[pp.points, r, leng] ← CopyList[points];
IF leng<3 THEN RETURN;
pp.path ← ImagerPath.MoveTo[[pp.points.first.x, pp.points.first.y]];
FOR class: PList ← pp.points.rest, class.rest WHILE class#NIL DO
pp.path ← ImagerPath.LineTo[pp.path, [class.first.x, class.first.y]];
ENDLOOP;
ob ← NEW[CD.ObjectRep←[
size: CDBasics.MaxPoint[[1, 1], CDBasics.SizeOfRect[r]],
layer: CDDefaultsExtras.PureLayer[lev],
class: 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 class: LIST OF CD.Position ← points, class.rest WHILE class#NIL DO
l ← l+1
ENDLOOP
END;
--Works only after Cedar 6 because of crazy colors
ShowPolygonSelection: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation,
pr: CD.DrawRef] =
BEGIN
DrawPolygonInContext: PROC [context: Imager.Context, ob: CD.Object, layer: CD.Layer] =
BEGIN
context.DrawStroke[path: NARROW[ob.specificRef, PolygonPtr].path, closed: TRUE];
END;
pr.drawContext[pr, DrawPolygonInContext, inst.ob, pos, orient, 0]
END;
HitInsidePolygon: PROC [ob: CD.Object, hitRect: CD.Rect] RETURNS [yes: BOOL] =
BEGIN
yes ← CDBasics.Intersect[ob.class.interestRect[ob], hitRect];
--is sick
IF yes THEN {
pp: PolygonPtr = NARROW[inst.ob.specificRef];
cont: Imager.Context ← Imager.NewContext[];
r: CD.Rect ← hitRect;
Imager.ClipArea[cont, pp.path];
Imager.ClipBox[cont, Imager.Box[xmin: r.x1, ymin: r.y1, xmax: r.x2, ymax: r.y2]];
yes ← Imager.Visible[cont];
cont ← NIL;
};
END;
DrawMeForPolygon: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation,
pr: CD.DrawRef] =
BEGIN
DrawPolygonInContext: PROC [context: Imager.Context, ob: CD.Object, layer: CD.Layer] =
BEGIN
Imager.MaskFillTrajectory[context, NARROW[ob.specificRef, PolygonPtr].path, TRUE];
END;
pr.drawContext[pr, DrawPolygonInContext, inst.ob, pos, orient, inst.ob.layer]
END;
Describe: PROC[me: CD.Object] RETURNS [Rope.ROPE] =
BEGIN
RETURN [Rope.Concat["polygon ", CDOps.LayerName[me.layer]]]
END;
WritePolygon: CD.InternalWriteProc -- PROC [me: Object] -- =
BEGIN
pp: PolygonPtr = NARROW[me.specificRef];
l: NAT ← Length[pp.points];
CDIO.WriteLayer[me.layer];
TokenIO.WriteInt[l];
FOR class: PList ← pp.points, class.rest WHILE class#NIL DO
TokenIO.WriteInt[class.first.x];
TokenIO.WriteInt[class.first.y];
ENDLOOP
END;
ReadPolygon: CD.InternalReadProc --PROC [] RETURNS [Object]-- =
BEGIN
ob: CD.Object;
lev: CD.Layer = CDIO.ReadLayer[];
leng: INT = TokenIO.ReadInt[];
points: PList ← NIL;
FOR i: INT IN [1..leng] DO
class: CD.Position;
class.x ← TokenIO.ReadInt[];
class.y ← TokenIO.ReadInt[];
points ← CONS[class, points];
ENDLOOP;
--reorder??
ob ← CreatePolygon[points, lev].ob;
RETURN [ob]
END;
Init[];
END.