-- ALEPress.mesa
-- Edited by Sweet, 28-May-85 12:25:30
DIRECTORY
ALEOps,
Inline,
IODefs,
PressDefs,
Storage,
StreamDefs,
String;
ALEPress: PROGRAM IMPORTS
ALEOps, Inline, IODefs, PressDefs, Storage, StreamDefs, String
EXPORTS ALEOps =
BEGIN OPEN ALEOps;
marginX: Mica = 2540/4;
marginY: Mica = -2540/2;
PageTop: Mica = 2540 * 11;
scaleDen: CARDINAL ← 16;
Mica: TYPE = INTEGER;
singleWidth: Mica ← 30;
Sqrt: PUBLIC PROC [n: LONG CARDINAL] RETURNS [r: CARDINAL] =
BEGIN
r1: CARDINAL;
r ← 1;
DO
r1 ← (r + Inline.LongDiv[n, r])/2;
IF r1 = r THEN EXIT;
r ← r1;
ENDLOOP;
END;
maxPerCmd: CARDINAL ← 30;
JamPicture: PUBLIC PROC [file: STRING] =
BEGIN OPEN StreamDefs;
js: DiskHandle;
cmdNum: CARDINAL ← 1;
thisCmd: CARDINAL ← 0;
Another: PROC =
BEGIN
IF thisCmd >= maxPerCmd THEN
BEGIN
cmdNum ← cmdNum+1;
OutS["}.cvx .def
(draw-picture-"]; OutN[cmdNum];
OutS[") {
"];
END;
END;
OutS: PROC [s: STRING] =
BEGIN
FOR i: CARDINAL IN [0..s.length) DO
js.put[js, s[i]];
ENDLOOP;
END;
OutC: PROC [c: CHARACTER] =
BEGIN
js.put[js, c];
END;
OutN: PROC [n: CARDINAL] =
BEGIN
IODefs.OutNumber[js, n,
[base: 10, zerofill: FALSE, unsigned: TRUE, columns: 1]];
END;
OutF: PROC [f: CARDINAL] =
BEGIN
SELECT f FROM
0 => NULL;
1 => OutS[".0625"];
2 => OutS[".125"];
3 => OutS[".1875"];
4 => OutS[".25"];
5 => OutS[".3125"];
6 => OutS[".375"];
7 => OutS[".4375"];
8 => OutS[".5"];
9 => OutS[".5625"];
10 => OutS[".625"];
11 => OutS[".6875"];
12 => OutS[".75"];
13 => OutS[".8125"];
14 => OutS[".876"];
15 => OutS[".9375"];
16 => OutS["1.0"];
ENDCASE;
END;
OutD: PROC [ac: ADistance] =
BEGIN
f: CARDINAL;
IF ac < 0 THEN {OutC['-]; ac ← -ac};
f ← CARDINAL[Inline.LowHalf[ac]] MOD 16;
ac ← ac / 16;
IODefs.OutNumber[js, Inline.LowHalf[ac],
[base: 10, zerofill: FALSE, unsigned: TRUE, columns: 1]];
OutF[f];
END;
clw: INTEGER ← -1;
box: ABox ← [x1: 0, x2: LAST[ADistance], y1: 0, y2: LAST[ADistance]];
JamLabel: LabelScan =
BEGIN
labelString: STRING ← [100];
stringCommand: ARRAY FontSize OF ARRAY LabelMode OF STRING ← [
small: [portrait: "text-sm-ptr ", landscape: "text-sm-lnd "],
large: [portrait: "text-lrg-ptr ", landscape: "text-lrg-lnd "]];
desc: String.SubStringDescriptor;
pos: APosition ← lbh.pos;
delta: ADistance = ADistanceForDots[
IF lbh.font = small THEN smallFontAscent ELSE largeFontAscent, 1];
IF lbh.mode = landscape THEN pos.x ← pos.x + delta
ELSE pos.y ← pos.y + delta;
Another[];
SubStringForLabel[@desc, lb];
String.AppendSubString[labelString, @desc];
OutC['(]; OutS[labelString]; OutS[") "];
OutD[pos.x]; OutC[' ]; OutD[pos.y]; OutC[' ];
OutS[stringCommand[lbh.font][lbh.mode]];
RETURN [FALSE];
END;
minX: ADistance ← LAST[ADistance];
maxY: ADistance ← FIRST[ADistance];
FindMinMax: LineScan =
BEGIN
ChopUpLine[l, @box, NoteSegment];
RETURN [FALSE];
END;
NoteSegment: PROC[
pos1, pos2: APosition,
class: LineClass,
color: LineColor,
lWidth: LineWidth,
lengthen: [0..4],
box: POINTER TO ABox] =
BEGIN
minX ← MIN[minX, pos1.x, pos2.x];
maxY ← MAX[maxY, pos1.y, pos2.y];
END;
JamLine: LineScan =
BEGIN
IF lth.width # clw THEN {OutC['0 + lth.width]; OutS[" line-width "]};
clw ← lth.width;
ChopUpLine[l, @box, JamLineSegment];
RETURN [FALSE];
END;
JamLineSegment: PROC[
pos1, pos2: APosition,
class: LineClass,
color: LineColor,
lWidth: LineWidth,
lengthen: [0..4],
box: POINTER TO ABox] =
BEGIN
IF color = white THEN RETURN;
Another[];
OutD[pos1.x - minX]; OutC[' ];
OutD[maxY - pos1.y]; OutC[' ];
OutD[pos2.x - minX]; OutC[' ];
OutD[maxY - pos2.y];
OutS[" draw-line "]; OutC[IODefs.CR];
END;
js ← NewByteStream[file, Write+Append];
OutC['(]; OutS[file]; OutS[") =
(architect-scale) "]; OutF[state.sixteenthsPerFoot]; OutS[" .def
(scale) {architect-scale .mul 72 .mul 12 .div}.cvx .def
(scale2) {scale .exch scale .exch}.cvx .def
(line-width) {.setstrokewidth}.cvx .def
(text-sm-ptr) {{scale2 .translate 0 0 .setxy --set font-- .show}.cvx .dosave}.cvx .def
(text-sm-lnd) {{scale2 .translate 90 rotate 0 0 .setxy --set font-- .show}.cvx .dosave}.cvx .def
(text-lrg-ptr) {{scale2 .translate 0 0 .setxy --set font-- .show}.cvx .dosave}.cvx .def
(text-lrg-lnd) {{scale2 .translate 90 rotate 0 0 .setxy --set font-- .show}.cvx .dosave}.cvx .def
(draw-line) {scale2 .moveto scale2 .lineto .maskstroke} .cvx .def
(draw-picture-1) {
"];
[] ← LinesInABox[@box, FindMinMax];
[] ← LinesInABox[@box, JamLine];
[] ← AllLabels[JamLabel];
OutS["}.cvx .def
(draw-picture) {{"];
FOR i: CARDINAL IN [1..cmdNum] DO
OutS[" draw-picture-"]; OutN[i];
ENDLOOP;
OutS["}.cvx .dosave}.cvx .def
"];
js.destroy[js];
END;
PressPicture: PUBLIC PROC [file: STRING] =
BEGIN
PressPictureInABox[
file, [x1: 0, x2: LAST[ADistance], y1: 0, y2: LAST[ADistance]]];
END;
PressPictureInABox: PUBLIC PROC [file: STRING, box: ABox] =
BEGIN OPEN PressDefs;
scaleFactorDen: LONG INTEGER ← 16*12*scaleDen;
scaleFactorNum: LONG INTEGER = LONG[2540]*state.sixteenthsPerFoot;
currentFontSize: FontSize ← large;
currentMode: LabelMode ← portrait;
SetTheFont: PROC [font: FontSize, mode: LabelMode] =
BEGIN
IF font # currentFontSize OR mode # currentMode THEN
SetFont[
p: pfd,
Name: "Helvetica"L,
PointSize: IF font = small THEN 8 ELSE 14,
Rotation: IF mode = landscape THEN 5400 ELSE 0];
currentFontSize ← font; currentMode ← mode;
END;
Micas: PROC [dist: ADistance] RETURNS [Mica] =
BEGIN
longM: LONG INTEGER ← ALEOps.MulDiv[dist, scaleFactorNum, scaleFactorDen];
RETURN[Short[longM]];
END;
XMicas: PROC [dist: ADistance] RETURNS [Mica] =
BEGIN
longM: LONG INTEGER ←
ALEOps.MulDiv[(dist-box.x1), scaleFactorNum, scaleFactorDen];
RETURN[Short[longM + marginX]];
END;
YMicas: PROC [dist: ADistance] RETURNS [Mica] =
BEGIN
RETURN[PageTop - Micas[dist-box.y1] + marginY];
END;
LineMicaWidth: PROC [w: [0..4]] RETURNS [Mica] =
BEGIN
RETURN [(singleWidth*w)/state.blowup];
END;
PressLabel: LabelScan =
BEGIN
x,y: Mica;
labelString: STRING ← [100];
desc: String.SubStringDescriptor;
pos: APosition ← lbh.pos;
delta: ADistance = ADistanceForDots[
IF lbh.font = small THEN smallFontAscent ELSE largeFontAscent, 1];
IF pos.x ~IN [box.x1..box.x2] OR pos.y ~IN [box.y1..box.y2] THEN
RETURN[FALSE];
IF lbh.mode = landscape THEN pos.x ← pos.x + delta
ELSE pos.y ← pos.y + delta;
x ← XMicas[pos.x];
y ← YMicas[pos.y];
SubStringForLabel[@desc, lb];
String.AppendSubString[labelString, @desc];
SetTheFont[lbh.font,lbh.mode];
PutText[
p: pfd,
str: labelString,
xleft: x,
ybase: y];
RETURN[FALSE];
END;
PressLine: LineScan =
BEGIN
ChopUpLine[l, @box, DrawLineSegment];
RETURN[FALSE];
END;
DrawLineSegment: PROC[
pos1, pos2: APosition,
class: LineClass,
color: LineColor,
lWidth: LineWidth,
lengthen: [0..4],
box: POINTER TO ABox] =
BEGIN
w, h: Mica;
IF color = white THEN RETURN;
SELECT class FROM
horiz =>
BEGIN
x1: ADistance = MAX[pos1.x, box.x1];
x2: ADistance = MIN[pos2.x, box.x2];
IF pos1.y ~IN [box.y1..box.y2] THEN RETURN;
h ← LineMicaWidth[lWidth];
w ← Micas[x2 - x1] + LineMicaWidth[lengthen];
PutRectangle[
p: pfd,
xstart: XMicas[x1],
ystart: YMicas[pos1.y] - h,
xlen: w, ylen: h];
END;
vert =>
BEGIN
y1: ADistance = MAX[pos1.y, box.y1];
y2: ADistance = MIN[pos2.y, box.y2];
IF pos1.x ~IN [box.x1..box.x2] THEN RETURN;
w ← LineMicaWidth[lWidth];
h ← Micas[y2 - y1];
PutRectangle[
p: pfd,
xstart: XMicas[pos1.x],
ystart: YMicas[y1] - h,
xlen: w,
ylen: h];
END;
ENDCASE =>
BEGIN
x1: ADistance = MAX[pos1.x, box.x1];
x2: ADistance = MIN[pos2.x, box.x2];
y1, y2: ADistance;
startX, startY, endX, endY: Mica;
dx, dy: Mica;
t: Mica = LineMicaWidth[lWidth];
a, b: Mica;
ady: CARDINAL;
l: LONG INTEGER;
y1 ← pos1.y + ALEOps.MulDiv[(x1-pos1.x), (pos2.y-pos1.y), (pos2.x-pos1.x)];
y2 ← pos1.y + ALEOps.MulDiv[(x2-pos1.x), (pos2.y-pos1.y), (pos2.x-pos1.x)];
-- IF line is outside box THEN RETURN;
IF y2 < box.y1 OR y1 > box.y2 THEN RETURN;
startX ← XMicas[x1]; startY ← YMicas[y1];
endX ← XMicas[x2]; endY ← YMicas[y2];
dx ← endX-startX;
dy ← endY-startY;
ady ← ABS[dy];
l ← Sqrt[
Inline.LongMult[dx, dx]+Inline.LongMult[ady, ady]];
a ← Short[ALEOps.MulDiv[LONG[dy], LONG[t], l]];
b ← Short[ALEOps.MulDiv[LONG[dx], LONG[t], l]];
StartOutline[p: pfd, x0: startX, y0: startY];
PutDrawTo[p: pfd, xend: startX+a, yend: startY-b];
PutDrawTo[p: pfd, xend: endX + a, yend: endY - b];
PutDrawTo[p: pfd, xend: endX, yend: endY];
PutDrawTo[p: pfd, xend: startX, yend: startY];
EndOutline[pfd];
END;
RETURN;
END;
pfd: POINTER TO PressFileDescriptor =
Storage.Node[ SIZE[PressFileDescriptor]];
InitPressFileDescriptor[pfd, file];
SetTheFont[small, portrait]; -- to make it font 0
[] ← LinesInABox[@box, PressLine];
[] ← AllLabels[PressLabel];
WritePage[pfd];
ClosePressFile[pfd];
ClearText[];
END;
END.