-- Compiler PressObjs/n
-- Stone October 15, 1981 7:06 PM
-- Last Edited by: Stone, April 26, 1985 8:42:03 am PST
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 EXPORTS ObjectDefs =
BEGIN OPEN ObjectDefs,PointDefs,GriffinMemoryDefs;
ROPE: TYPE = Rope.ROPE;
pressXscale: REAL 𡤁
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.