DIRECTORY PS, Vector2; PSPathImpl: CEDAR PROGRAM IMPORTS PS, Vector2 ~ BEGIN OPEN PS; CurrentPoint: PROC [path: Path] RETURNS [VEC] ~ { IF path=NIL THEN ERROR Error[nocurrentpoint]; RETURN [path.first.point]; }; MoveTo: PROC [path: Path, p: VEC] RETURNS [Path] ~ { IF path#NIL AND path.first.type=move THEN path _ path.rest; RETURN [CONS[[move, p], path]]; }; LineTo: PROC [path: Path, p: VEC] RETURNS [Path] ~ { IF path=NIL THEN ERROR Error[nocurrentpoint]; RETURN [CONS[[line, p], path]]; }; CurveTo: PROC [path: Path, p1, p2, p3: VEC] RETURNS [Path] ~ { IF path=NIL THEN ERROR Error[nocurrentpoint]; RETURN [CONS[[curve, p3], CONS[[curve, p2], CONS[[curve, p1], path]]]]; }; ArcTo: PROC [path: Path, p0: VEC, r: REAL, ang1, ang2: REAL, neg: BOOL] RETURNS [Path] ~ { p1: VEC ~ Vector2.Add[p0, Vector2.Mul[[RealFns.CosDeg[ang1], RealFns.SinDeg[ang1]], r]]; p2: VEC ~ Vector2.Add[p0, Vector2.Mul[[RealFns.CosDeg[ang2], RealFns.SinDeg[ang2]], r]]; g.path _ (IF g.path=NIL THEN MoveTo ELSE LineTo)[g.path, Transform[g.CTM, p1]]; }; ClosePath: PROC [path: Path] RETURNS [Path] ~ { IF path=NIL OR path.first.type=close THEN RETURN [path]; FOR each: Path _ path, path.rest UNTIL path=NIL DO SELECT each.first.type FROM move, close => RETURN [CONS[[close, each.first.point], path]]; ENDCASE; ENDLOOP; RETURN [path]; -- should never happen }; MapPath: PROC [path: Path, moveTo: PROC [p: VEC], lineTo: PROC [p: VEC], curveTo: PROC [p1, p2, p3: VEC], closePath: PROC ] ~ { prev: Path _ NIL; IF path=NIL THEN RETURN; prev _ path.rest; IF path.first.type=curve THEN THROUGH [0..2) DO IF prev=NIL OR prev.first.type#curve THEN ERROR; prev _ prev.rest; ENDLOOP; IF prev#NIL THEN MapPath[prev, moveTo, lineTo, curveTo, closePath]; SELECT path.first.type FROM move => moveTo[path.first.point]; line => lineTo[path.first.point]; curve => curveTo[path.rest.rest.first.point, path.rest.first.point, path.first.point]; close => closePath[]; ENDCASE => ERROR; }; Pnewpath: PROC [self: Root] ~ { g: GState ~ self.graphics; g.path _ NIL; }; Pcurrentpoint: PROC [self: Root] ~ { g: GState ~ self.graphics; PushVec[self, ITransform[g.CTM, CurrentPoint[g.path]]]; }; Pmoveto: PROC [self: Root] ~ { g: GState ~ self.graphics; p: VEC ~ PopVec[self]; tp: VEC ~ Transform[g.CTM, p]; g.path _ MoveTo[g.path, tp]; }; Prmoveto: PROC [self: Root] ~ { g: GState ~ self.graphics; d: VEC ~ PopVec[self]; td: VEC ~ DTransform[g.CTM, d]; c: VEC ~ CurrentPoint[g.path]; g.path _ MoveTo[g.path, Vector2.Add[c, td]]; }; Plineto: PROC [self: Root] ~ { g: GState ~ self.graphics; p: VEC ~ PopVec[self]; tp: VEC ~ Transform[g.CTM, p]; g.path _ LineTo[g.path, tp]; }; Prlineto: PROC [self: Root] ~ { g: GState ~ self.graphics; d: VEC ~ PopVec[self]; td: VEC ~ DTransform[g.CTM, d]; c: VEC ~ CurrentPoint[g.path]; g.path _ LineTo[g.path, Vector2.Add[c, td]]; }; Parc: PROC [self: Root] ~ { g: GState ~ self.graphics; ang2: REAL ~ PopReal[self]; ang1: REAL ~ PopReal[self]; r: REAL ~ PopReal[self]; p0: VEC ~ PopVec[self]; p1: VEC ~ Vector2.Add[p0, Vector2.Mul[[RealFns.CosDeg[ang1], RealFns.SinDeg[ang1]], r]]; p2: VEC ~ Vector2.Add[p0, Vector2.Mul[[RealFns.CosDeg[ang2], RealFns.SinDeg[ang2]], r]]; g.path _ (IF g.path=NIL THEN MoveTo ELSE LineTo)[g.path, Transform[g.CTM, p1]]; }; Parcn: PROC [self: Root] ~ { }; Parcto: PROC [self: Root] ~ { }; Pcurveto: PROC [self: Root] ~ { g: GState ~ self.graphics; p3: VEC ~ PopVec[self]; p2: VEC ~ PopVec[self]; p1: VEC ~ PopVec[self]; tp3: VEC ~ Transform[g.CTM, p3]; tp2: VEC ~ Transform[g.CTM, p2]; tp1: VEC ~ Transform[g.CTM, p1]; g.path _ CurveTo[g.path, tp1, tp2, tp3]; }; Prcurveto: PROC [self: Root] ~ { g: GState ~ self.graphics; d3: VEC ~ PopVec[self]; d2: VEC ~ PopVec[self]; d1: VEC ~ PopVec[self]; td3: VEC ~ Transform[g.CTM, d3]; td2: VEC ~ Transform[g.CTM, d2]; td1: VEC ~ Transform[g.CTM, d1]; c: VEC ~ CurrentPoint[g.path]; g.path _ CurveTo[g.path, Vector2.Add[c, td1], Vector2.Add[c, td2], Vector2.Add[c, td3]]; }; Pclosepath: PROC [self: Root] ~ { g: GState ~ self.graphics; g.path _ ClosePath[g.path]; }; Pflattenpath: PROC [self: Root] ~ { }; Preversepath: PROC [self: Root] ~ { }; Pstrokepath: PROC [self: Root] ~ { }; Pcharpath: PROC [self: Root] ~ { }; Pclippath: PROC [self: Root] ~ { }; Ppathbbox: PROC [self: Root] ~ { g: GState ~ self.graphics; min, max, b0, b1, b2, b3: VEC; IF g.path=NIL THEN ERROR Error[nocurrentpoint]; min _ max _ g.path.first.point; FOR each: Path _ g.path.rest, each.rest UNTIL each=NIL DO p: VEC ~ each.first.point; IF p.xmax.x THEN max.x _ p.x; IF p.ymax.y THEN max.y _ p.y; ENDLOOP; b0 _ ITransform[g.CTM, [min.x, min.y]]; b1 _ ITransform[g.CTM, [max.x, min.y]]; b2 _ ITransform[g.CTM, [max.x, max.y]]; b3 _ ITransform[g.CTM, [min.x, max.y]]; PushReal[self, MIN[b0.x, b1.x, b2.x, b3.x]]; PushReal[self, MIN[b0.y, b1.y, b2.y, b3.y]]; PushReal[self, MAX[b0.x, b1.x, b2.x, b3.x]]; PushReal[self, MAX[b0.y, b1.y, b2.y, b3.y]]; }; Ppathforall: PROC [self: Root] ~ { g: GState ~ self.graphics; close: Any ~ PopAny[self]; curve: Any ~ PopAny[self]; line: Any ~ PopAny[self]; move: Any ~ PopAny[self]; moveTo: PROC [p: VEC] ~ { PushVec[self, ITransform[g.CTM, p]]; Execute[self, move]; }; lineTo: PROC [p: VEC] ~ { PushVec[self, ITransform[g.CTM, p]]; Execute[self, line]; }; curveTo: PROC [p1, p2, p3: VEC] ~ { PushVec[self, ITransform[g.CTM, p1]]; PushVec[self, ITransform[g.CTM, p2]]; PushVec[self, ITransform[g.CTM, p3]]; Execute[self, curve]; }; closePath: PROC [] ~ { Execute[self, close]; }; MapPath[g.path, moveTo, lineTo, curveTo, closePath ! Exit => CONTINUE]; }; Pinitclip: PROC [self: Root] ~ { }; Pclip: PROC [self: Root] ~ { }; Peoclip: PROC [self: Root] ~ { }; PathPrimitives: PROC [self: Root] ~ { Register[self, "newpath", Pnewpath]; Register[self, "currentpoint", Pcurrentpoint]; Register[self, "moveto", Pmoveto]; Register[self, "rmoveto", Prmoveto]; Register[self, "lineto", Plineto]; Register[self, "rlineto", Prlineto]; Register[self, "arc", Parc]; Register[self, "arcn", Parcn]; Register[self, "arcto", Parcto]; Register[self, "curveto", Pcurveto]; Register[self, "rcurveto", Prcurveto]; Register[self, "closepath", Pclosepath]; Register[self, "flattenpath", Pflattenpath]; Register[self, "reversepath", Preversepath]; Register[self, "strokepath", Pstrokepath]; Register[self, "charpath", Pcharpath]; Register[self, "clippath", Pclippath]; Register[self, "pathbbox", Ppathbbox]; Register[self, "pathforall", Ppathforall]; Register[self, "initclip", Pinitclip]; Register[self, "clip", Pclip]; Register[self, "eoclip", Peoclip]; }; RegisterPrimitives[PathPrimitives]; END. ΦPSPathImpl.mesa Copyright Σ 1986, 1987 by Xerox Corporation. All rights reserved. Doug Wyatt, April 2, 1987 4:56:20 pm PST PostScript implementation: path operators. Path construction operators Primitives Κ ,˜codešœ™KšœB™BK™(—K˜K™*K™šΟk ˜ Kšœ˜K˜—K˜KšΟn œœ˜Kšœœ ˜Kšœœœœ˜head™šž œœœœ˜1Kšœœœœ˜-Kšœ˜K˜K˜—šžœœœœ ˜4Kšœœœœ˜;Kšœœ˜K˜K˜—šžœœœœ ˜4Kšœœœœ˜-Kšœœ˜K˜K˜—šžœœœœ ˜>Kšœœœœ˜-Kšœœœœ˜GK˜K˜—šžœœœœœœœ ˜ZKšœœQ˜XKšœœQ˜XKš œ œœœœœ˜OK˜K˜—šž œœœ ˜/Kš œœœœœ˜8šœœœ˜2šœ˜Kšœœœ#˜>Kšœ˜—Kšœ˜—Kšœ Οc˜%K˜K˜—šžœœ ˜Kšœœœ˜Kšœœœ˜Kšœ œœ˜ Kšœ ˜Kšœ˜Kšœ œ˜Kšœœœœ˜K˜šœœœ˜/Kš œœœœœ˜0K˜Kšœ˜—Kšœœœ3˜Cšœ˜K˜!Kšœ!˜!KšœV˜VKšœ˜Kšœœ˜—K˜K˜—K˜—™ šžœœ˜K˜Kšœ œ˜ K˜K˜—šž œœ˜$K˜Kšœœ˜7K˜K˜—šžœœ˜K˜Kšœœ˜Kšœœœ˜Kšœ˜K˜K˜—šžœœ˜K˜Kšœœ˜Kšœœœ˜Kšœœ˜Kšœ,˜,K˜K˜—šžœœ˜K˜Kšœœ˜Kšœœœ˜Kšœ˜K˜K˜—šžœœ˜K˜Kšœœ˜Kšœœœ˜Kšœœ˜Kšœ,˜,K˜K˜—šžœœ˜K˜Kšœœ˜Kšœœ˜Kšœœ˜Kšœœ˜KšœœQ˜XKšœœQ˜XKš œ œœœœœ˜OK˜K˜—šžœœ˜K˜K˜—šžœœ˜K˜K˜—šžœœ˜K˜Kšœœ˜Kšœœ˜Kšœœ˜Kšœœœ˜ Kšœœœ˜ Kšœœœ˜ Kšœ(˜(K˜K˜—šž œœ˜ K˜Kšœœ˜Kšœœ˜Kšœœ˜Kšœœœ˜ Kšœœœ˜ Kšœœœ˜ Kšœœ˜KšœX˜XK˜K˜—šž œœ˜!K˜Kšœ˜K˜K˜—šž œœ˜#K˜K˜—šž œœ˜#K˜K˜—šž œœ˜"K˜K˜—šž œœ˜ K˜K˜—šž œœ˜ K˜K˜—šž œœ˜ K˜Kšœœ˜Kšœœœœ˜/K˜šœ%œœ˜9Kšœœ˜Kš œ œ œœ œ ˜AKš œ œ œœ œ ˜AKšœ˜—Kšœœ˜'Kšœœ˜'Kšœœ˜'Kšœœ˜'Kšœœ˜,Kšœœ˜,Kšœœ˜,Kšœœ˜,K˜K˜—šž œœ˜"K˜K˜K˜K˜K˜šœœœ˜Kšœœ˜$K˜K˜—šœœœ˜Kšœœ˜$K˜K˜—šœ œœ˜#Kšœœ˜%Kšœœ˜%Kšœœ˜%K˜K˜—šœ œ˜K˜K˜—Kšœ=œ˜GK˜K˜—šž œœ˜ K˜K˜—šžœœ˜K˜K˜—šžœœ˜K˜K˜—šžœœ˜%Kšœ$˜$Kšœ.˜.Kšœ"˜"Kšœ$˜$Kšœ"˜"Kšœ$˜$Kšœ˜Kšœ˜Kšœ ˜ Kšœ$˜$Kšœ&˜&Kšœ(˜(Kšœ,˜,Kšœ,˜,Kšœ*˜*Kšœ&˜&Kšœ&˜&Kšœ&˜&Kšœ*˜*Kšœ&˜&Kšœ˜Kšœ"˜"J˜J˜—J˜#—J˜Jšœ˜—…—φ#ψ