-- Compiler PressObjs/n -- Stone October 15, 1981 7:06 PM -- Last Edited by: Stone, December 28, 1983 2:41 pm DIRECTORY SplineDefs: FROM "SplineDefs", PressDefs: FROM "PressDefs", GriffinMemoryDefs USING [CZone], PointDefs: FROM "PointDefs", StyleDefs: FROM "StyleDefs", Real: FROM "Real", ControllerDefs: FROM "ControllerDefs", PressLineDefs: FROM "PressLineDefs", ScreenDefs: FROM "ScreenDefs", Rope USING [ROPE], ObjectDefs: FROM "ObjectDefs"; PressObjs: PROGRAM IMPORTS ObjectDefs, PressDefs, SplineDefs, GriffinMemoryDefs,Real,ControllerDefs,PressLineDefs, ScreenDefs EXPORTS ObjectDefs = BEGIN OPEN ObjectDefs,PointDefs,GriffinMemoryDefs; ROPE: TYPE = Rope.ROPE; pressXscale: REAL _1; pressYscale: REAL _ 1; --magic centering numbers to center display on press page --the distance (in micas) is the difference between 32 micas/pixel and --2540 micas/inch for a full page. --Y is also shifted about 1/4 inch empirically --X is also shifted about 1/8 inch empirically xOffset: REAL _ 1067+327; yOffset: REAL _ 1042-635; currentColor: PressDefs.ColorDescriptor _ [0,0,0]; inObject: BOOLEAN _ FALSE; --makes a press file of all objects linked to obj PressAllObjects: PUBLIC PROCEDURE [s: ROPE]= BEGIN PressDefs.BeginPress[s]; ObjectDefs.ForAllObjects[PressObject]; PressDefs.EndPress[]; END; --calls the correct type of formatting routine PressObject: ObjectDefs.ObjectProc = BEGIN pcolor: PressDefs.ColorDescriptor; newTL,newBR: ScrPt; IF obj=NIL THEN RETURN; IF ~Visible[obj] THEN RETURN; --outside, other view, or deleted --partials also get tossed [newTL,newBR] _ ScreenDefs.ClipToScreen[obj.tl,obj.br]; IF (newTL#obj.tl OR newBR#obj.br) THEN RETURN; WITH object: obj SELECT FROM shape => IF ~object.closed THEN PlotTrajectory[object.trajectory,object.style,FALSE] ELSE BEGIN --areas have trajectories too. TRUE = closed IF object.style.filled THEN FillArea[object]; IF object.style.outlined THEN PlotTrajectory[object.trajectory,object.style,TRUE]; END; caption => BEGIN pcolor _ [hue: object.style.color.hue, saturation: object.style.color.saturation, brightness: object.style.color.brightness]; PressDefs.ShowText [pcolor, object.text, ObjToPress[object.p0], object.style.orientation,object.style.anchor, ControllerDefs.FontWithNumber [object.style.fontid]]; END; token => NULL; ENDCASE; END; --first set in second set BoxInsideBox: PROCEDURE[tl0,br0,tl1,br1: ScrPt] RETURNS [BOOLEAN]= BEGIN IF (tl0[X] IN [tl1[X]..br1[X]] AND br0[X] IN [tl1[X]..br1[X]] AND tl0[Y] IN [tl1[Y]..br1[Y]] AND br0[Y] IN [tl1[Y]..br1[Y]]) THEN RETURN[TRUE] ELSE RETURN[FALSE]; END; --Draws a trajectory PlotTrajectory: PROCEDURE [traj: REF Trajectory,style: REF StyleDefs.Style,closed: BOOLEAN] = BEGIN currentColor _ [hue: style.color.hue, saturation: style.color.saturation, brightness: style.color.brightness]; WITH traj SELECT FROM shape: REF Trajectory[linked] => BEGIN lshape: REF linked Trajectory _ FillGaps[shape,closed]; linkPtr: REF Link _ lshape.links; UNTIL linkPtr = NIL DO SELECT linkPtr.degree FROM D0 => PlotDots[linkPtr.knots]; D1 => PlotLines[linkPtr.knots,style]; D2 => NULL; D3 => PlotCurve[linkPtr.knots,style,lshape.splineType,FALSE]; ENDCASE; linkPtr _ linkPtr.link; ENDLOOP; --do something here about releasing the object made by FillGaps END; shape: REF Trajectory[cyclic] => PlotCurve[shape.knots,style,traj.splineType,TRUE]; ENDCASE; END; PressCurve: PROCEDURE [coeffs: SplineDefs.Coeffs,newObject: BOOLEAN] = BEGIN zeropt: ObjPt _ [0,0]; IF newObject THEN BEGIN IF inObject THEN PressDefs.EndObject[]; PressDefs.BeginObject[currentColor]; inObject _ TRUE; PressDefs.MoveTo[ObjToPress[coeffs.t0]]; END; IF coeffs.t3=coeffs.t2 AND coeffs.t2=zeropt THEN BEGIN pt: ObjPt _ [coeffs.t1[X]+coeffs.t0[X],coeffs.t1[Y]+coeffs.t0[Y]]; PressDefs.DrawTo[ObjToPress[pt]]; END ELSE BEGIN p: PressDefs.PressSpline _ CoeffsToPressSpline[coeffs]; PressDefs.DrawCurve[p]; END; END; --Plots Dots PlotDots: PROCEDURE [knots: PointDefs.ObjPtSequence] = BEGIN END; --Contours and Press's lines. Ignores the junction specification for now. PlotLines: PROCEDURE [knots: PointDefs.ObjPtSequence,style: REF StyleDefs.Style] = BEGIN i: INTEGER; p0,p1: ObjPt; end0,end1: PressLineDefs.End; lastknot: INTEGER _ knots.length-1; end0 _ (SELECT style.firstend.type FROM flat => flat, angled => square, ENDCASE => round); end1 _ round; p0 _ knots[0]; IF lastknot=0 THEN PressLineDefs.ContourLine[p0,p0,style.width/2,end0,end1,PressCurve]; FOR i IN [1..lastknot] DO p1 _ knots[i]; IF i=lastknot THEN end1 _ (SELECT style.lastend.type FROM flat => flat, angled => square, ENDCASE => round); PressLineDefs.ContourLine[p0,p1,style.width/2,end0,end1,PressCurve]; IF i = 0 THEN end0 _ round; p0 _ p1; ENDLOOP; PressDefs.EndObject[]; inObject _ FALSE; END; --Plots a curve. description is in the knots and the splinetype PlotCurve: PROCEDURE [knots: PointDefs.ObjPtSequence,style: REF StyleDefs.Style,type: SplineDefs.SplineType,cyclic: BOOLEAN] = BEGIN coeffs: SplineDefs.CoeffsSequence; end0,end1: PressLineDefs.End; lastseg: INTEGER; i: INTEGER _ 0; end0 _ (SELECT style.firstend.type FROM flat => square, angled => square, ENDCASE => round); end1 _ round; IF cyclic THEN end0 _ end1 _ round; coeffs _ IF cyclic THEN MakeCyclicSpline[knots,type] ELSE MakeSpline[knots,type ]; lastseg _ coeffs.length-1; FOR i IN [0..lastseg] DO IF i=lastseg THEN end1 _ (SELECT style.lastend.type FROM flat => square, angled => square, ENDCASE => round); PressLineDefs.ContourCubic[coeffs[i],style.width/2,end0,end1,PressCurve]; IF i = 0 THEN end0 _ round; ENDLOOP; PressDefs.EndObject[]; inObject _ FALSE; END; MakeCyclicSpline: PROCEDURE[knots: PointDefs.ObjPtSequence, type: SplineDefs.SplineType] RETURNS[coeffs: SplineDefs.CoeffsSequence]= BEGIN i: INTEGER; cycknots: SplineDefs.KnotSequence; numknots: INTEGER _ (IF knots=NIL THEN 0 ELSE knots.length); newLength: INTEGER; IF numknots <= 0 THEN RETURN[NIL]; SELECT type FROM naturalUM, naturalAL,bezier=> newLength _ numknots+1; bspline, crspline=> newLength _ numknots+3; ENDCASE; cycknots _ CZone.NEW[SplineDefs.KnotSequenceRec[newLength]]; FOR i IN [0..numknots) DO cycknots[i] _ knots[i]; ENDLOOP; cycknots[numknots] _ cycknots[0]; SELECT type FROM naturalUM=> type _ cyclicUM; naturalAL=> type _ cyclicAL; bspline=> BEGIN cycknots[numknots +1] _ cycknots[1]; cycknots[numknots+2] _ cycknots[2]; END; crspline=> BEGIN cycknots[numknots +1] _ cycknots[1]; cycknots[numknots+2] _ cycknots[2]; END; ENDCASE; coeffs _ SplineDefs.MakeSpline[cycknots,type]; RETURN; END; --type conversion routine MakeSpline: PROCEDURE[knots: PointDefs.ObjPtSequence, type: SplineDefs.SplineType] RETURNS[coeffs: SplineDefs.CoeffsSequence]= BEGIN splineknots: SplineDefs.KnotSequence; numknots: INTEGER _ (IF knots=NIL THEN 0 ELSE knots.length); IF numknots <= 0 THEN RETURN[NIL]; splineknots _ CZone.NEW[SplineDefs.KnotSequenceRec[numknots]]; FOR i: NAT IN [0..numknots) DO splineknots[i] _ knots[i]; ENDLOOP; coeffs _ SplineDefs.MakeSpline[splineknots,type]; RETURN; END; --makes a new linked trajectory with knuth splines in gaps FillGaps: PROCEDURE[traj: REF linked Trajectory,closed: BOOLEAN] RETURNS[REF linked Trajectory] = BEGIN RETURN[traj]; END; --Fills an area FillArea: PROCEDURE [area: shape Object] = BEGIN i: INTEGER; first: BOOLEAN _ TRUE; p: PressDefs.PressSpline; color: PressDefs.ColorDescriptor_ [hue: area.style.fillcolor.hue, saturation: area.style.fillcolor.saturation, brightness: area.style.fillcolor.brightness]; PressDefs.BeginObject[color]; WITH shape: area.trajectory SELECT FROM linked => BEGIN i: INTEGER; type: REF Link _ shape.links; UNTIL type = NIL DO SELECT type.degree FROM D0 => NULL; D1 => BEGIN IF first THEN PressDefs.MoveTo[ObjToPress[type.knots[0]]]; FOR i IN [1..type.knots.length) DO PressDefs.DrawTo [ObjToPress[type.knots[i]]]; ENDLOOP; END; D2 => NULL; D3 => BEGIN allCoeffs: SplineDefs.CoeffsSequence _ MakeSpline[type.knots,shape.splineType]; IF first THEN PressDefs.MoveTo[ObjToPress[allCoeffs[0].t0]]; FOR i IN [0..allCoeffs.length) DO p _ CoeffsToPressSpline[allCoeffs[i]]; PressDefs.DrawCurve[p]; ENDLOOP; END; ENDCASE; type _ type.link; first _ FALSE; ENDLOOP; --do something here about releasing the object made by FillGaps END; cyclic => BEGIN allCoeffs: SplineDefs.CoeffsSequence _ MakeCyclicSpline[shape.knots,shape.splineType]; PressDefs.MoveTo[ObjToPress[allCoeffs[0].t0]]; FOR i IN [0..allCoeffs.length) DO p _ CoeffsToPressSpline[allCoeffs[i]]; PressDefs.DrawCurve[p]; ENDLOOP; END; ENDCASE; PressDefs.EndObject[]; END; ObjToPress: PROCEDURE[pt: ObjPt] RETURNS[pc: PressDefs.PressCoords]= BEGIN pt[X] _ pt[X]+xOffset; pt[Y] _ pt[Y]+yOffset; pc[PressDefs.X] _ Real.RoundC[pt[X]]; pc[PressDefs.Y] _ Real.RoundC[pt[Y]]; END; CoeffsToPressSpline: PROCEDURE[coeffs: SplineDefs.Coeffs] RETURNS[p: PressDefs.PressSpline]= BEGIN p.x3 _ FloatToPressFloat[pressXscale*coeffs.t3[X]]; p.x2 _ FloatToPressFloat[pressXscale*coeffs.t2[X]]; p.x1 _ FloatToPressFloat[pressXscale*coeffs.t1[X]]; p.y3 _ FloatToPressFloat[pressYscale*coeffs.t3[Y]]; p.y2 _ FloatToPressFloat[pressYscale*coeffs.t2[Y]]; p.y1 _ FloatToPressFloat[pressYscale*coeffs.t1[Y]]; END; FloatToPressFloat: PUBLIC PROCEDURE [r: REAL] RETURNS [p: PressDefs.PressFloat] = INLINE BEGIN --hack for press. Will be ok since r is already scaled to press coords IF ABS[r] < (0.1) THEN RETURN[0]; --conversion done in SirPress RETURN[r]; END; END.