DIRECTORY CDInstances, CDCurves, CDTexts, CD, CDBasics, CDLayers, CDIO, CDOps, Imager, ImagerPath, Rope, TokenIO, Vector2; CDCurvesImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDLayers, CDIO, CDOps, Imager, ImagerPath, Rope, TokenIO EXPORTS CDCurves = BEGIN CurvePtr: TYPE = CDCurves.CurvePtr; CurveRec: TYPE = CDCurves.CurveRec; LoP: TYPE = LIST OF CD.Position; splineClass: PUBLIC CD.ObjectClass _ CD.RegisterObjectClass[$Spline0, [ drawMe: DrawSpline, quickDrawMe: DrawSpline, hitInside: HitInsideCurve, describe: Describe, internalRead: ReadCurve, internalWrite: WriteCurve, description: "spline" ]]; lineClass: PUBLIC CD.ObjectClass _ CD.RegisterObjectClass[$Line0, [ drawMe: DrawSpline, quickDrawMe: DrawSpline, hitInside: HitInsideCurve, describe: Describe, internalRead: ReadCurve, internalWrite: WriteCurve, description: "line" ]]; polygonClass: PUBLIC CD.ObjectClass _ CD.RegisterObjectClass[$Polygon0, [ drawMe: DrawFilledCurve, quickDrawMe: DrawFilledCurve, hitInside: HitInsideCurve, describe: Describe, internalRead: ReadCurve, internalWrite: WriteCurve, description: "polygon" ]]; filledCurveClass: PUBLIC CD.ObjectClass _ CD.RegisterObjectClass[$FilledCurve0, [ drawMe: DrawFilledCurve, quickDrawMe: DrawFilledCurve, hitInside: HitInsideCurve, describe: Describe, internalRead: ReadCurve, internalWrite: WriteCurve, description: "filled curve" ]]; CopyList: PROC [points: LoP, w: CD.Number_0] RETURNS [copy: LoP_NIL, r: CD.Rect, leng: INT_0] = BEGIN min: CD.Position _ CDBasics.highposition; max: CD.Position _ CDBasics.minposition; FOR class: LoP _ points, class.rest WHILE class#NIL DO leng _ leng+1; min _ CDBasics.MinPoint[min, class.first]; max _ CDBasics.MaxPoint[max, class.first]; ENDLOOP; min _ [min.x-w, min.y-w]; max _ [max.x+w, max.y+w]; FOR class: LoP _ points, class.rest WHILE class#NIL DO copy _ CONS[CDBasics.SubPoints[class.first, min], copy]; ENDLOOP; r _ CDBasics.ToRect[min, max]; IF (r.x2-r.x1)>LAST[NAT] OR (r.y2-r.y1)>LAST[NAT] THEN CD.Error[callingError, "size out of range"]; END; CreatePolygon: PUBLIC PROC [points: LIST OF CD.Position, layer: CD.Layer] RETURNS [ob: CD.Object_NIL, offset: CD.Position_[0, 0]] = BEGIN r: CD.Rect; leng: INT; cp: CurvePtr = NEW[CurveRec]; [cp.points, r, leng] _ CopyList[points, 0]; IF leng<3 THEN RETURN; cp.path _ ImagerPath.MoveTo[[cp.points.first.x, cp.points.first.y]]; FOR class: LoP _ cp.points.rest, class.rest WHILE class#NIL DO cp.path _ ImagerPath.LineTo[cp.path, [class.first.x, class.first.y]]; ENDLOOP; ob _ NEW[CD.ObjectRep_[ size: CDBasics.MaxPoint[[1, 1], CDBasics.SizeOfRect[r]], layer: CDLayers.AbstractToPaint[layer], class: polygonClass, specificRef: cp ]]; offset _ CDBasics.BaseOfRect[r]; END; CreateFilledCurve: PUBLIC PROC [points: LIST OF CD.Position, layer: CD.Layer] RETURNS [ob: CD.Object_NIL, offset: CD.Position_[0, 0]] = BEGIN r: CD.Rect; leng: INT; pl: LoP; cp: CurvePtr = NEW[CurveRec]; [cp.points, r, leng] _ CopyList[points, 0]; IF leng<4 THEN RETURN; cp.path _ ImagerPath.MoveTo[[cp.points.first.x, cp.points.first.y]]; pl _ cp.points.rest; WHILE pl # NIL DO p1, p2, p3: Vector2.VEC; p1 _ [pl.first.x, pl.first.y]; IF pl.rest#NIL THEN pl _ pl.rest; p2 _ [pl.first.x, pl.first.y]; IF pl.rest#NIL THEN pl _ pl.rest; p3 _ [pl.first.x, pl.first.y]; pl _ pl.rest; cp.path _ ImagerPath.CurveTo[cp.path, p1, p2, p3]; ENDLOOP; ob _ NEW[CD.ObjectRep_[ size: CDBasics.MaxPoint[[1, 1], CDBasics.SizeOfRect[r]], layer: CDLayers.AbstractToPaint[layer], class: filledCurveClass, specificRef: cp ]]; offset _ CDBasics.BaseOfRect[r]; END; CreateSpline: PUBLIC PROC [points: LIST OF CD.Position, w: CD.Number, layer: CD.Layer] RETURNS [ob: CD.Object_NIL, offset: CD.Position_[0, 0]] = BEGIN r: CD.Rect; leng: INT; pl: LoP; cp: CurvePtr = NEW[CurveRec]; w2: INT _ MAX[1, (w+1)/2]; [cp.points, r, leng] _ CopyList[points, w2]; IF leng<1 THEN RETURN; cp.w _ w2*2; cp.path _ ImagerPath.MoveTo[[cp.points.first.x, cp.points.first.y]]; pl _ cp.points.rest; WHILE pl # NIL DO p1, p2, p3: Vector2.VEC; p1 _ [pl.first.x, pl.first.y]; IF pl.rest#NIL THEN pl _ pl.rest; p2 _ [pl.first.x, pl.first.y]; IF pl.rest#NIL THEN pl _ pl.rest; p3 _ [pl.first.x, pl.first.y]; pl _ pl.rest; cp.path _ ImagerPath.CurveTo[cp.path, p1, p2, p3]; ENDLOOP; ob _ NEW[CD.ObjectRep_[ size: CDBasics.MaxPoint[[cp.w, cp.w], CDBasics.SizeOfRect[r]], layer: CDLayers.AbstractToPaint[layer], class: splineClass, specificRef: cp ]]; offset _ CDBasics.BaseOfRect[r]; END; CreateLine: PUBLIC PROC [points: LIST OF CD.Position, w: CD.Number, layer: CD.Layer] RETURNS [ob: CD.Object_NIL, offset: CD.Position_[0, 0]] = BEGIN r: CD.Rect; leng: INT; pl: LoP; cp: CurvePtr = NEW[CurveRec]; w2: INT _ MAX[1, (w+1)/2]; [cp.points, r, leng] _ CopyList[points, w2]; IF leng<1 THEN RETURN; cp.w _ w2*2; cp.path _ ImagerPath.MoveTo[[cp.points.first.x, cp.points.first.y]]; pl _ cp.points.rest; WHILE pl # NIL DO p1: Vector2.VEC _ [pl.first.x, pl.first.y]; pl _ pl.rest; cp.path _ ImagerPath.LineTo[cp.path, p1]; ENDLOOP; ob _ NEW[CD.ObjectRep_[ size: CDBasics.MaxPoint[[cp.w, cp.w], CDBasics.SizeOfRect[r]], layer: CDLayers.AbstractToPaint[layer], class: lineClass, specificRef: cp ]]; offset _ CDBasics.BaseOfRect[r]; END; HitInsideCurve: PROC [ob: CD.Object, hitRect: CD.Rect] RETURNS [yes: BOOL] = { RETURN [ CDBasics.Intersect[ob.class.interestRect[ob], hitRect] ]; }; DrawFilledCurve: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN FilledCurveInContext: PROC [context: Imager.Context, ob: CD.Object, layer: CD.Layer] = { Imager.ClipRectangleI[context, 0, 0, ob.size.x, ob.size.y]; Imager.MaskFillTrajectory[context, NARROW[ob.specificRef, CurvePtr].path, TRUE]; }; pr.drawContext[pr, FilledCurveInContext, inst.ob, pos, orient, inst.ob.layer] END; DrawSpline: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN SplineInContext: PROC [context: Imager.Context, ob: CD.Object, layer: CD.Layer] = { Imager.ClipRectangleI[context, 0, 0, ob.size.x, ob.size.y]; Imager.SetStrokeWidth[context: context, strokeWidth: NARROW[ob.specificRef, CurvePtr].w]; Imager.SetStrokeEnd[context: context, strokeEnd: square]; Imager.MaskStrokeTrajectory[context, NARROW[ob.specificRef, CurvePtr].path, FALSE]; }; pr.drawContext[pr, SplineInContext, inst.ob, pos, orient, inst.ob.layer] END; Describe: PROC[me: CD.Object] RETURNS [Rope.ROPE] = { RETURN [Rope.Cat[me.class.description, " ", CDOps.LayerName[me.layer]]] }; WriteCurve: CD.InternalWriteProc -- PROC [me: Object] -- = BEGIN Length: PROC [points: LIST OF CD.Position] RETURNS [n: NAT _ 0] = { FOR l: LIST OF CD.Position _ points, l.rest WHILE l#NIL DO n _ n+1 ENDLOOP }; cp: CurvePtr = NARROW[me.specificRef]; l: NAT _ Length[cp.points]; CDIO.WriteLayer[me.layer]; SELECT me.class FROM lineClass => {TokenIO.WriteInt[0]; TokenIO.WriteInt[cp.w]}; polygonClass => TokenIO.WriteInt[1]; splineClass => {TokenIO.WriteInt[2]; TokenIO.WriteInt[cp.w]}; filledCurveClass => TokenIO.WriteInt[3]; ENDCASE => ERROR; TokenIO.WriteInt[l]; FOR pl: LoP _ cp.points, pl.rest WHILE pl#NIL DO CDIO.WritePos[pl.first]; ENDLOOP; END; ReadCurve: CD.InternalReadProc --PROC [] RETURNS [Object]-- = BEGIN ob: CD.Object _ NIL; kind, w, leng: INT; layer: CD.Layer; points: LoP _ NIL; layer _ CDIO.ReadLayer[]; SELECT kind _ TokenIO.ReadInt[] FROM 0, 2 => w _ TokenIO.ReadInt[]; ENDCASE => NULL; leng _ TokenIO.ReadInt[]; FOR i: INT IN [1..leng] DO points _ CONS[CDIO.ReadPos[], points]; ENDLOOP; SELECT kind FROM 0 => ob _ CreateLine[points, w, layer].ob; 1 => ob _ CreatePolygon[points, layer].ob; 2 => ob _ CreateSpline[points, w, layer].ob; 3 => ob _ CreateFilledCurve[points, layer].ob; ENDCASE; RETURN [ob] END; END. ΖCDCurvesImpl.mesa Copyright c 1985, 1986 by Xerox Corporation. All rights reserved. by Christian Jacobi, March 30, 1985 12:19:40 pm PST Last Edited by: Jacobi June 19, 1986 12:52:31 pm PDT Κ }˜codešœ™Kšœ Οmœ7™BKšœ4™4K™4K™—šΟk ˜ Kšœ ˜ Kšœ ˜ K˜Kšžœ˜Kšœ ˜ Kšœ ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜Kšœ˜Kšœ˜—K˜šΡbln œžœžœ˜Kšžœžœžœ*˜NKšžœ ˜—Kšž˜K˜Kšœ žœ˜#Kšœ žœ˜#Kš œžœžœžœžœ ˜ K˜šœ ž œžœ ˜GKšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—šœ ž œžœ˜CKšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—šœžœžœžœ!˜IKšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—šœž œžœ%˜QKšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—K˜š Οnœžœžœ žœžœ žœ˜_Kšž˜Kšœžœ"˜)Kšœžœ!˜(šžœ!žœžœžœ˜7Kšœ˜Kšœ*˜*Kšœ*˜*Kšžœ˜—K˜K˜šžœ!žœžœžœ˜7Kšœžœ-˜8Kšžœ˜—Kšœ˜Kšžœ žœžœžœ žœžœžœžœ*˜cKšžœ˜—K˜š  œžœžœ žœžœžœžœžœžœžœ žœ˜„Kšž˜Kšœžœ žœ˜Kšœžœ ˜Kšœ+˜+Kšžœžœžœ˜KšœD˜Dšžœ)žœžœžœ˜?KšœE˜EKšž˜—šœžœžœ ˜Kšœ8˜8Kšœ'˜'Kšœ˜Kšœ˜Kšœ˜—Kšœ ˜ Kšžœ˜—K˜š œžœžœ žœžœžœžœžœžœžœ žœ˜ˆKšž˜Kšœžœ žœ ˜Kšœžœ ˜Kšœ+˜+Kšžœžœžœ˜KšœD˜DKšœ˜šžœžœž˜Kšœžœ˜Kšœžœ žœžœ˜@Kšœžœ žœžœ˜@Kšœ,˜,Kšœ2˜2Kšžœ˜—šœžœžœ ˜Kšœ8˜8Kšœ'˜'Kšœ˜Kšœ˜Kšœ˜—Kšœ ˜ Kšžœ˜—K˜š  œžœžœ žœžœžœžœžœžœžœžœ žœ˜‘Kšž˜Kšœžœ žœ ˜ Kšœžœ ˜Kšœžœžœ ˜Kšœ,˜,Kšžœžœžœ˜Kšœ ˜ KšœD˜DKšœ˜šžœžœž˜Kšœžœ˜Kšœžœ žœžœ˜@Kšœžœ žœžœ˜@Kšœ,˜,Kšœ2˜2Kšžœ˜—šœžœžœ ˜Kšœ>˜>Kšœ'˜'Kšœ˜Kšœ˜Kšœ˜—Kšœ ˜ Kšžœ˜—K˜š  œžœžœ žœžœžœžœžœžœžœžœ žœ˜Kšž˜Kšœžœ žœ ˜ Kšœžœ ˜Kšœžœžœ ˜Kšœ,˜,Kšžœžœžœ˜Kšœ ˜ KšœD˜DKšœ˜šžœžœž˜Kšœ žœž˜,Kšœ ˜ Kšœ)˜)Kšžœ˜—šœžœžœ ˜Kšœ>˜>Kšœ'˜'Kšœ˜Kšœ˜Kšœ˜—Kšœ ˜ Kšžœ˜—K˜K˜š  œžœžœžœžœžœ˜NKšžœ<˜BKšœ˜K˜—K˜š  œžœžœžœžœžœ ˜eKšž˜š œžœžœžœ ˜XKšœ;˜;Kšœ#žœ!žœ˜PKšœ˜—KšœM˜MKšžœ˜—K˜š   œžœžœžœžœžœ ˜`Kšž˜š œžœžœžœ ˜SKšœ;˜;Kšœ5žœ˜YKšœ9˜9Kšœ%žœ!žœ˜SKšœ˜—KšœH˜HKšžœ˜—K˜K˜š  œžœžœ žœžœ˜5KšžœB˜HKšœ˜—K˜K˜šΠbn œžœΟcœ˜:Kšž˜š œžœ žœžœžœ žœžœ ˜CKšžœžœžœžœžœžœžœ ž˜JKšœ˜—Kšœžœ˜&Kšœžœ˜Kšžœ˜šžœ ž˜Kšœ;˜;Kšœ$˜$Kšœ=˜=Kšœ(˜(Kšžœžœ˜—Kšœ˜šžœžœžœžœ˜1Kšžœ˜Kšž˜—Kšžœ˜—K˜K˜š‘ œžœ’œ˜=Kšž˜Kš œžœ žœžœ žœ˜9Kšœžœ˜Kšœžœ ˜šžœžœž˜$Kšœ˜Kšžœžœ˜—Kšœ˜šžœžœžœ ž˜Kšœ žœžœ˜&Kšžœ˜—šžœž˜Kšœ*˜*Kšœ*˜*Kšœ,˜,Kšœ.˜.Kšžœ˜—Kšžœ˜ Kšžœ˜—K˜Kšžœ˜K˜K˜—…—)_