-- Compiler Press/nb
-- last modified by m. stone December 2, 1981 9:31 PM
-- implementing module for press file creation
-- Last Edited by: Stone, December 28, 1983 4:35 pm

DIRECTORY
 PressDefs: FROM "PressDefs",
 PointDefs: FROM "PointDefs",
 StyleDefs: FROM "StyleDefs",
 GriffinFontDefs: FROM "GriffinFontDefs",
 SirPress,
 Real USING[RoundLI],
 Rope USING[ROPE,ToRefText,Cat,FromChar,Length];


Press: PROGRAM
IMPORTS SirPress, GriffinFontDefs, Rope, Real
EXPORTS PressDefs =

BEGIN OPEN PressDefs;

X: INTEGER=PointDefs.X;
Y: INTEGER=PointDefs.Y;

PressError: PUBLIC SIGNAL = CODE;
PressState: TYPE = {notInObject, inObject};
pressState: PressState ← notInObject;

-- these variables reflect the current press state
pressHandle: SirPress.PressHandle ← NIL;

BeginPress: PUBLIC PROCEDURE [filestring: Rope.ROPE] = BEGIN
IF pressHandle#NIL THEN SIGNAL PressError;
 filestring ← Rope.Cat[filestring, ".Press"];
 pressHandle ← SirPress.NewPressHandle[filestring];
END;

EndPress: PUBLIC PROCEDURE = BEGIN
IF pressHandle=NIL THEN SIGNAL PressError;
 SirPress.ClosePress[pressHandle];
 pressHandle←NIL;
END;

ShowText: PUBLIC PROCEDURE [color: ColorDescriptor, textstring: Rope.ROPE, presscoords: PressCoords, orientation: StyleDefs.Orientation,anchor: StyleDefs.Anchor, font: GriffinFontDefs.FontDescriptorHandle] =
BEGIN OPEN GriffinFontDefs;
i: CARDINAL;
rotation: CARDINAL=font.rotation;
pt,showpt: PointDefs.ObjPt;
char: CHARACTER;
chheight,chwidth,height, width, baseline, maxHeight, maxWidth, twiddle: REAL;
aligned, vertical: BOOLEAN;
textdirection: CARDINAL = SELECT orientation FROM
 or0 => Rot0Degrees,
 or90 => Rot90Degrees,
 or180 => Rot180Degrees,
 or270 => Rot270Degrees,
ENDCASE => ERROR;
slen: CARDINAL = Rope.Length[textstring];
IF pressHandle=NIL THEN SIGNAL PressError;
IF slen = 0 THEN RETURN;
SetColor [color];
SetFont [font];

height ← StringHeight[textstring, font, orientation];
width ← StringWidth[textstring, font, orientation];
maxHeight ← MaxHeight[font];
maxWidth ← MaxWidth[font];
baseline ← MaxPosExtent[font];
pt ← TopLeft[[presscoords[X],presscoords[Y]], height, width, anchor,orientation, font.rotation];
vertical ← orientation = or90 OR orientation = or270;
aligned ← IF vertical
THEN rotation = Rot0Degrees OR rotation = Rot180Degrees
ELSE rotation = Rot90Degrees OR rotation = Rot270Degrees;

SELECT orientation FROM -- move to end if going backwards
or180 => pt[X] ← pt[X]+width;
or90 => pt[Y] ← pt[Y]-height;
ENDCASE;

IF textdirection = font.rotation THEN -- easy
BEGIN
SELECT rotation FROM
 Rot0Degrees=> pt[Y] ← pt[Y]-baseline;
 Rot90Degrees=> pt[X] ← pt[X]+baseline;
 Rot180Degrees=> pt[Y] ← pt[Y]-(maxHeight-baseline);
 Rot270Degrees=> pt[X] ← pt[X]+(maxHeight-baseline);
ENDCASE;
 SirPress.PutText[pressHandle,textstring,ToPress[pt[X]],ToPress[pt[Y]]];
END

ELSE BEGIN
text: REF TEXT ← Rope.ToRefText[textstring];
FOR i IN [0 .. slen) DO
 char ← text[i];
 chwidth ← Width[char, font];
 chheight ← Height[char, font];
 twiddle ← IF vertical THEN (maxWidth - chwidth)/2 ELSE (maxHeight - chheight)/2;
IF aligned THEN IF vertical
  THEN pt[X] ← pt[X] + twiddle
  ELSE pt[Y] ← pt[Y] - twiddle;
SELECT orientation FROM
  or90 => pt[Y] ← pt[Y] + chheight;
  or180 => pt[X] ← pt[X] - chwidth;
ENDCASE;
 showpt←pt;
SELECT rotation FROM
 Rot0Degrees=> showpt[Y] ← showpt[Y]-baseline;
 Rot90Degrees=>
  BEGIN
  showpt[X] ← showpt[X]+baseline;
  showpt[Y] ← showpt[Y]-chheight;
  END;
 Rot180Degrees=>
  BEGIN
  showpt[Y] ← showpt[Y]-(maxHeight-baseline);
  showpt[X] ← showpt[X]+chwidth;
  END;
 Rot270Degrees=>
  showpt[X] ← showpt[X]+(maxHeight-baseline);
ENDCASE;
 SirPress.PutText[pressHandle,Rope.FromChar[char], ToPress[showpt[X]],ToPress[showpt[Y]]];
SELECT orientation FROM
  or0 => pt[X] ← pt[X] + chwidth;
  or270 => pt[Y] ← pt[Y] - chheight;
ENDCASE;
IF aligned THEN IF vertical
  THEN pt[X] ← pt[X] - twiddle
  ELSE pt[Y] ← pt[Y] + twiddle;
ENDLOOP;
END;
END;

ToPress: PROC[v: REAL] RETURNS [INT] = {
RETURN[Real.RoundLI[v]];
 };

ShowRectangle: PUBLIC PROCEDURE [color: ColorDescriptor, presscoords: PressCoords, width, height: PressCoord] =
BEGIN
IF pressHandle=NIL THEN SIGNAL PressError;
 SetColor [color];
 SirPress.PutRectangle[pressHandle,presscoords[X],presscoords[Y],width, height];
END;




BeginObject: PUBLIC PROCEDURE [color: ColorDescriptor] =
BEGIN
IF pressHandle=NIL THEN SIGNAL PressError;
 SetColor [color];
 SirPress.StartOutline[pressHandle];
 pressState ← inObject;
END;




EndObject: PUBLIC PROCEDURE =
BEGIN
IF pressState # inObject THEN SIGNAL PressError ELSE pressState ← notInObject ;
 SirPress.EndOutline[pressHandle];
END;



MoveTo: PUBLIC PROCEDURE [presscoords: PressCoords] =
BEGIN
IF pressState # inObject THEN SIGNAL PressError;
 SirPress.PutMoveTo[pressHandle,presscoords[X],presscoords[Y]];
END;



DrawTo: PUBLIC PROCEDURE [presscoords: PressCoords] =
BEGIN
IF pressState # inObject THEN SIGNAL PressError;
 SirPress.PutDrawTo[pressHandle,presscoords[X],presscoords[Y]];
END;



DrawCurve: PUBLIC PROCEDURE [spline: PressSpline] =
BEGIN OPEN spline;
IF pressState # inObject THEN SIGNAL PressError;
 SirPress.PutCubic[pressHandle,x1,y1,x2,y2,x3,y3];
END;

SetColor: PROCEDURE [color: ColorDescriptor] =
BEGIN OPEN color;
IF pressHandle=NIL THEN SIGNAL PressError;
 SirPress.SetColor[pressHandle,hue, saturation, brightness];
END;

SetFont: PROCEDURE [font: GriffinFontDefs.FontDescriptorHandle] =
BEGIN
 SirPress.SetFont[p: pressHandle,
  family: font.name,
  size: font.points,
  face: font.face,
  rotation: font.rotation];
END;

END .