<> <> <> <> <<>> DIRECTORY CDInstances, CDPolygons, CDTexts, CD, CDBasics, CDLayers, CDIO, CDOps, Imager, ImagerPath, Rope, TokenIO; CDPolygonsImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDLayers, CDIO, CDOps, Imager, ImagerPath, Rope, TokenIO EXPORTS CDPolygons = BEGIN PolygonPtr: TYPE = CDPolygons.PolygonPtr; PolygonRec: TYPE = CDPolygons.PolygonRec; PList: TYPE = LIST OF CD.Position; polygonClass: PUBLIC CD.ObjectClass _ CD.RegisterObjectClass[$Polygon, [ drawMe: DrawMeForPolygon, quickDrawMe: DrawMeForPolygon, hitInside: HitInsidePolygon, describe: Describe, internalRead: ReadPolygon, internalWrite: WritePolygon ]]; CopyList: PROC [points: PList] RETURNS [copy: PList_NIL, r: CD.Rect, leng: INT_0] = 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: CDLayers.AbstractToPaint[lev], class: polygonClass, specificRef: pp ]]; offset _ CDBasics.BaseOfRect[r]; 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>> <> <> <> <<>> <> <> <> <> <<>> <> <> HitInsidePolygon: PROC [ob: CD.Object, hitRect: CD.Rect] RETURNS [yes: BOOL] = BEGIN yes _ CDBasics.Intersect[ob.class.interestRect[ob], hitRect]; <<--is sick>> <> <> <> <> <> <> <> <> <<};>> 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 pl: PList _ pp.points, pl.rest WHILE pl#NIL DO CDIO.WritePos[pl.first]; 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 points _ CONS[CDIO.ReadPos[], points]; ENDLOOP; <<--reorder??>> ob _ CreatePolygon[points, lev].ob; RETURN [ob] END; END.