-- WriteStringImpl.mesa
-- last modified by McCreight, November 8, 1982 5:44 PM
-- written by Hilton, August 4, 1982 1:42 PM
DIRECTORY
ppdddefs,
ppddefs,
ppdefs,
ppoutdefs,
String,
WriteStringDefs;
WriteStringImpl: PROGRAM
IMPORTS ppdddefs, ppddefs, ppdefs,
ppoutdefs, String
EXPORTS WriteStringDefs SHARES WriteStringDefs =
BEGIN OPEN ppdddefs, ppddefs, ppdefs, ppoutdefs, String, WriteStringDefs;
NoFont: PUBLIC SIGNAL = CODE;
font: PUBLIC LONG POINTER TO cList ← NIL;
CellPtr: TYPE = LONG POINTER TO cell object ← NIL;
StringToRectangles: PUBLIC PROCEDURE [s: STRING ← NIL, proc:
PROCEDURE [r: Rect]] =
BEGIN
fileOpened: BOOLEAN ← TRUE;
mustRestore: BOOLEAN ← FALSE;
xOffset, yOffset, charWidth, totWidth: CARDINAL ← 0;
cp: CellPtr ← NIL;
lp: listPtr ← NIL;
IF s = NIL OR s.length=0 THEN RETURN;
FOR i: CARDINAL IN [0..s.length) DO
charWidth ← xOffset ← yOffset ← 0;
cp ← GetChar[s[i]]; -- returns object ptr --
yOffset ← cp.size[1]; -- default
xOffset ← 0;
charWidth ← cp.size[0] + 12;
FOR lp ← cp.ptr, lp.nxt WHILE lp # NIL DO
-- find poly baseline record --
IF lp.ob # NIL AND lp.ob.l = pol THEN
BEGIN
yOffset ← lp.ly;
xOffset ← lp.lx;
charWidth ← lp.ob.size[Rot90[lp]];
EXIT;
END;
ENDLOOP;
FOR lp ← cp.ptr, lp.nxt WHILE lp # NIL DO
-- enumerate the metal rectangles forming the character
IF lp.ob.l=met THEN
proc[[x1: lp.lx-xOffset+totWidth,
y1: lp.ly-yOffset,
x2: lp.lx-xOffset+totWidth+lp.ob.size[Rot90[lp]],
y2: lp.ly-yOffset+lp.ob.size[1-Rot90[lp]]]];
ENDLOOP; -- one character --
totWidth ← totWidth + charWidth;
ENDLOOP;
END; -- of StringToRectangles --
GetChar: PROCEDURE [char: CHARACTER] RETURNS [cell: CellPtr]=
BEGIN
name: STRING ← [20];
name.length ← 0;
SELECT char FROM
IN [’0 .. ’9] =>
{name[0] ← ’N; name[1] ← char; name.length ← 2};
IN [’a .. ’z] =>
{name[0] ← ’L; name[1] ← char-’a+’A; name.length ← 2};
IN [’A .. ’Z] =>
{name[0] ← ’U; name[1] ← char; name.length ← 2};
’ => AppendString[to: name, from: "SPACE"L];
’. => AppendString[to: name, from: "PERIOD"L];
’, => AppendString[to: name, from: "COMMA"L];
’( => AppendString[to: name, from: "LEFTPAREN"L];
’) => AppendString[to: name, from: "RIGHTPAREN"L];
’/ => AppendString[to: name, from: "SLASH"L];
’@ => AppendString[to: name, from: "COPYRIGHT"L];
ENDCASE => AppendString[to: name, from: "PERIOD"L];
cell ← NIL;
WHILE font=NIL DO ReadFont[] ENDLOOP;
FOR cp: LONG POINTER TO cList ← font, cp.nxt WHILE cp # NIL DO
IF EqualString[cp.name, name] THEN
BEGIN
WITH dob: cp.ob SELECT FROM
cell => {cell ← @dob; EXIT};
ENDCASE => NULL;
END;
ENDLOOP;
END; -- of GetChar --
Rot90: PROCEDURE[lp: listPtr] RETURNS[[0..1]] =
{RETURN[IF (lp.idx MOD 8)<4 THEN 0 ELSE 1]};
ReadFont: PUBLIC PROCEDURE =
BEGIN
IF font=NIL THEN
BEGIN
lp: listPtr;
WHILE NOT openIfile["font.chip"] DO SIGNAL NoFont ENDLOOP;
[lp, font] ← readAll[];
closeFile[];
flushDel[lp];
END;
END; -- of ReadFont --
ReleaseFont: PUBLIC PROCEDURE =
BEGIN
WHILE font#NIL DO
cp: LONG POINTER TO cList ← font;
font ← font.nxt;
IF cp.ob#NIL THEN
BEGIN
cp.ob.returnable ← TRUE;
cp.ob.p.release[cp.ob]; -- release cell --
END;
FreeString[cp.name];
FreeSpace[cp];
ENDLOOP;
END; -- of ReleaseFont --
MakeCell: PUBLIC PROCEDURE[lpp: listPtr]
RETURNS[ob: CellPtr, min: Point] =
BEGIN
lp: listPtr;
max: Point ← [FIRST[locNum], FIRST[locNum]];
min ← [LAST[locNum], LAST[locNum]];
FOR lp ← lpp, lp.nxt WHILE lp # NIL DO
min ← [MIN[min.x, lp.lx], MIN[min.y, lp.ly]];
max ← [
MAX[max.x, lp.lx + lp.ob.size[Rot90[lp]]],
MAX[max.y, lp.ly + lp.ob.size[1 - Rot90[lp]]]];
ENDLOOP;
FOR lp ← lpp, lp.nxt WHILE lp # NIL DO
lp.lx ← lp.lx - min.x; lp.ly ← lp.ly - min.y; lp.selected ← FALSE;
ENDLOOP;
ob ← makeCell[sx: max.x - min.x, sy: max.y - min.y, cnt: 0, ptr: lpp];
END; -- of MakeCell --
DrawOb: PUBLIC PROCEDURE[ob: obPtr, min: Point] =
BEGIN
lp: listPtr ← makeList[ob, min.x, min.y, 0, 0];
masterList ← insertList[masterList, lp];
selNewThing[masterList, lp, TRUE];
putMark[min.x, min.y];
reDrawRect[r: getRect[lp], whenErase: 0, bw: TRUE,
col: TRUE, all: FALSE];
anyChanges ← sinceIOchanges ← TRUE;
END; -- of DrawOb --
END. -- of StringToRectImpl --