-- 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.