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.