// April 14, 1978 3:38 PM *** overlay C *** get "zpDefs.bcpl" get "zpPressDf.bcpl" // outgoing procedures: external [ WriteDLline WriteDLdot GetThickness ScaleKnotTable MakeCubic ComputeNormal ] // incoming procedures: external [ Puts // SYSTEM Gets WriteBlock MoveBlock FLD; FLDI; FST // FLOAT FTR; FML; FDV FAD; FNEG; FSB; FCM; FSN FSTDP; FLDDP; DPAD confirm // ZPUTIL sTypeForm typeForm getLine SquareRoot obtainBlock // ZPBLOCK putBlock giveUp PutsCurve // ZPPUTS PutsMove PutsLine PutsRoundTip PutObjectInELtable // ZPPRESS PutRectangleInELtable PrintFpValues ] // local statics // incoming statics: external [ keys // SYSTEM @dashOn // ZPDRAW @dashOff @lineThicknessTable // ZPINIT1 @showValues // ZPPRESS ] // local floating point registers manifest [ t0=0; t1=1; t2=2; t3=3; t4=4 ] let WriteDLdot(pressFile, splinePointer, sLeft, sBottom) = valof [ let xTable=vec 4 let yTable=xTable+2 MoveBlock(xTable, splinePointer+SPLINEknotBase, 4) ScaleKnotTable(xTable, yTable, 1, scaleFactor, sLeft, sBottom) resultis WriteDotObject(pressFile, xTable, yTable, splinePointer>>SPLINE.shape, GetThickness(splinePointer)) ] and WriteDotObject(pressFile, xTable, yTable, brushShape, thickness) = valof [ FLDI(t0, thickness) if brushShape eq rBrush then [ // dot has a circular shape // circle approximation is obtained by the following cubic parametrization // cos(pi/2 t)= .4298 t↑3 - 1.4666 t↑2 + 0.0368 t + 1 // sin(pi/2 t)= - .4298 t↑3 - .1772 t↑2 + 1.6070 t FLD(t1, xTable); FAD(t1, t0); let x0=FTR(t1) FLD(t1, yTable); let y0=FTR(t1) FLDI(t2, 10000); FDV(t0, t2) let xa=vec 2; FLDI(t1, 4298); FML(t1, t0); FST(t1, xa) let ya=vec 2; FNEG(t1); FST(t1, ya) let nxb=vec 2; FLDI(t1, 14666); FML(t1, t0); FST(t1, nxb) let xb=vec 2; FNEG(t1); FST(t1, xb) let nyb=vec 2; FLDI(t1, 1772); FML(t1, t0); FST(t1, nyb) let yb=vec 2; FNEG(t1); FST(t1, yb) let xc=vec 2; FLDI(t1, 368); FML(t1, t0); FST(t1, xc) let nxc=vec 2; FNEG(t1); FST(t1, nxc) let yc=vec 2; FLDI(t1, 16070); FML(t1, t0); FST(t1, yc) let nyc=vec 2; FNEG(t1); FST(t1, nyc) resultis WriteCircleObject(pressFile, x0, y0, xa, ya, xb, yb, xc, yc, nxb, nyb, nxc, nyc) ] // dot has a rectangular shape let dX=vec 2; let dY=vec 2 FLDI(t1, lineThicknessTable!0) switchon brushShape into [ case sBrush: FST(t0, dX); FST(t0, dY) endcase case hBrush: FST(t0, dX); FST(t1, dY) endcase case vBrush: FST(t0, dY); FST(t1, dX) endcase default: FLDI(t0, 0); FST(t0, dX); FST(t0, dY) endcase ] // x0=x1=x+dx FLD(t0, xTable); FAD(t0,dX); let x0=FTR(t0) // x2=x3=x-dx FLD(t0, xTable); FSB(t0,dX); let x2=FTR(t0) // y0=y3=y+dy FLD(t0, yTable); FAD(t0,dY); let y0=FTR(t0) // y1=y2=y-dy FLD(t0, yTable); FSB(t0,dY); let y1=FTR(t0) resultis WriteStripeObject(pressFile, x0, y0, x0, y1, x2, y1, x2, y0) ] and WriteCircleObject(pressFile, x0, y0, xa, ya, xb, yb, xc, yc, nxb, nyb, nxc, nyc) = valof [WriteCircleObject // CIRCULAR OBJECT // x0 & y0 are starting point of circle (integer) // xa,...,yc are cubic coefficients (floating point) // nxb,...,nyc are the negative of the same coefficients // (exception: xa=-ya) let objectWordCount=0 PutsMove(pressFile, lv objectWordCount, x0, y0) PutsCurve(pressFile, lv objectWordCount, xc, yc, xb, yb, xa, ya) PutsCurve(pressFile, lv objectWordCount, nyc, xc, nyb, xb, xa, xa) PutsCurve(pressFile, lv objectWordCount, nxc, nyc, nxb, nyb, ya, xa) PutsCurve(pressFile, lv objectWordCount, yc, nxc, yb, nxb, ya, ya) resultis PutObjectInELtable(objectWordCount) ]WriteCircleObject and WriteDLline(pressFile, splinePointer, sLeft, sBottom) = valof [ let thickness=GetThickness(splinePointer) let xTable=vec 4 let yTable=vec 4 MoveBlock(xTable, splinePointer+SPLINEknotBase, 4) MoveBlock(yTable, splinePointer+SPLINEknotBase+4, 4) ScaleKnotTable(xTable, yTable, 2, scaleFactor, sLeft, sBottom) let brushShape=splinePointer>>SPLINE.shape let splineType=splinePointer>>SPLINE.type FLD(t0, xTable); FLD(t1, yTable) if FCM(t0, xTable+2) eq 0 & FCM(t1, yTable+2) eq 0 then resultis WriteDotObject(pressFile, xTable, yTable, brushShape, thickness) test splinePointer>>SPLINE.dashed ifnot resultis WriteLineObject(pressFile, xTable, yTable, brushShape, splineType, thickness) ifso [ let objectWordCount=0 let Xon=vec 2; let Yon=vec 2; let Xoff=vec 2; let Yoff=vec 2 FLD(t0, xTable+2) let Xcomp=FCM(t0, xTable); FSB(t0, xTable); FLD(t2, t0); FML(t2, t0) FLD(t1, yTable+2) let Ycomp=FCM(t1, yTable); FSB(t1, yTable); FLD(t3, t1); FML(t3, t1) let temp=vec 2; FAD(t2, t3); FST(t2, temp); SquareRoot(temp) FDV(t0, temp); FDV(t1, temp); FLD(t2, t0); FLD(t3, t1) FLDI(t4, dashOn*scaleFactor) FML(t0, t4); FST(t0, Xon) FML(t1, t4); FST(t1, Yon) FLDI(t4, dashOff*scaleFactor) FML(t2, t4); FST(t2, Xoff) FML(t3, t4); FST(t3, Yoff) let xxTable=vec 4; let yyTable=vec 4 MoveBlock(xxTable, xTable, 4) MoveBlock(yyTable, yTable, 4) [ FLD(t0, xxTable); FAD(t0, Xon) FLD(t1, yyTable); FAD(t1, Yon) if (Xcomp & (FCM(t0, xTable+2) eq Xcomp)) % (Ycomp & (FCM(t1, yTable+2) eq Ycomp)) then [ FLD(t0, xTable+2); FLD(t1, yTable+2) ] FST(t0, xxTable+2); FST(t1, yyTable+2) objectWordCount=objectWordCount + WriteLineObject(pressFile, xxTable, yyTable, brushShape, splineType, thickness) FLD(t0, xxTable+2); FAD(t0, Xoff) FLD(t1, yyTable+2); FAD(t1, Yoff) if ((FCM(t0, xTable+2) eq 0) & (FCM(t1, yTable+2) eq 0)) % (Xcomp & (FCM(t0, xTable+2) eq Xcomp)) % (Ycomp & (FCM(t1, yTable+2) eq Ycomp)) resultis objectWordCount FST(t0, xxTable); FST(t1, yyTable) ] repeat ] ] and WriteLineObject(pressFile, xTable, yTable, brushShape, splineType, thickness) = valof [ let tX=vec 2; let tY=vec 2 let nX=vec 2; let nY=vec 2 let temp=vec 2 FLDI(t0,0); FST(t0,tX); FST(t0,tY); FST(t0,nX); FST(t0,nY) test (brushShape eq hBrush) & (splineType eq horSpline) ifso [ FLDI(t0, lineThicknessTable!0); FST(t0, nY) FLDI(t0, thickness) FLD(t1, xTable); FLD(t2, xTable+2) if FCM(t1, t2) eq 1 then FNEG(t0) FST(t0, tX) ] ifnot test (brushShape eq vBrush) & (splineType eq verSpline) ifso [ FLDI(t0, lineThicknessTable!0); FST(t0, nX) FLDI(t0, thickness) FLD(t1, yTable); FLD(t2, yTable+2) if FCM(t1, t2) eq 1 then FNEG(t0) FST(t0, tY) ] ifnot switchon brushShape into [ case rBrush: case sBrush: FLD(t0, xTable+2); FSB(t0, xTable) FLD(t1, yTable+2); FSB(t1, yTable) FLD(t2,t0); FML(t2,t0) FLD(t3,t1); FML(t3,t1) FAD(t2,t3); FST(t2,temp); SquareRoot(temp) FLDI(t2,thickness); FDV(t2,temp) FML(t0, t2); if brushShape eq sBrush then FST(t0, tX); FST(t0, nY) FML(t1, t2); if brushShape eq sBrush then FST(t1, tY); FNEG(t1); FST(t1, nX); endcase case hBrush: FLDI(t0,thickness); FST(t0,nX); endcase case vBrush: FLDI(t0,thickness); FST(t0,nY); endcase ] let x0, y0, x1, y1, x2, y2, x3, y3=nil, nil, nil, nil, nil, nil, nil, nil FLD(t0,xTable); FAD(t0,nX); FSB(t0,tX); x0=FTR(t0) FLD(t0,yTable); FAD(t0,nY); FSB(t0,tY); y0=FTR(t0) FLD(t0,xTable+2); FAD(t0,nX); FAD(t0,tX); x1=FTR(t0) FLD(t0,yTable+2); FAD(t0,nY); FAD(t0,tY); y1=FTR(t0) FLD(t0,xTable+2); FSB(t0,nX); FAD(t0,tX); x2=FTR(t0) FLD(t0,yTable+2); FSB(t0,nY); FAD(t0,tY); y2=FTR(t0) FLD(t0,xTable); FSB(t0,nX); FSB(t0,tX); x3=FTR(t0) FLD(t0,yTable); FSB(t0,nY); FSB(t0,tY); y3=FTR(t0) resultis brushShape eq rBrush ? WriteLinkObject(pressFile, x0, y0, x1, y1, x2, y2, x3, y3), WriteStripeObject(pressFile, x0, y0, x1, y1, x2, y2, x3, y3) ] and WriteStripeObject(pressFile, x0, y0, x1, y1, x2, y2 , x3, y3) = valof [WriteStripeObject // STRIPE (=paralleloid) OBJECT // first, check whether it is a vertical or horizontal rectangle if (x0 eq x1) & (x2 eq x3) & (y0 eq y3) & (y1 eq y2) then resultis PutRectangleInELtable( ((x0 ls x2) ? x0, x2), ((y0 ls y1) ? y0, y1), ((x0 ls x2) ? (x2-x0+1), (x0-x2+1)), ((y0 ls y1) ? (y1-y0+1), (y0-y1+1))) if (x0 eq x3) & (x1 eq x2) & (y0 eq y1) & (y2 eq y3) then resultis PutRectangleInELtable( ((x0 ls x1) ? x0, x1), ((y0 ls y2) ? y0, y2), ((x0 ls x1) ? (x1-x0+1), (x0-x1+1)), ((y0 ls y2) ? (y2-y0+1), (y0-y2+1))) // no, so let's make an object let objectWordCount=0 PutsMove(pressFile, lv objectWordCount, x0, y0) PutsLine(pressFile, lv objectWordCount, x1, y1) PutsLine(pressFile, lv objectWordCount, x2, y2) PutsLine(pressFile, lv objectWordCount, x3, y3) PutsLine(pressFile, lv objectWordCount, x0, y0) resultis PutObjectInELtable(objectWordCount) ]WriteStripeObject and WriteLinkObject(pressFile, x0, y0, x1, y1, x2, y2 , x3, y3) = valof [WriteLinkObject // LINK OBJECT (= stripe with rounded tips) let objectWordCount=0 PutsMove(pressFile, lv objectWordCount, x0, y0) PutsLine(pressFile, lv objectWordCount, x1, y1) PutsRoundTip(pressFile, lv objectWordCount, x1, y1, x2, y2) PutsLine(pressFile, lv objectWordCount, x3, y3) PutsRoundTip(pressFile, lv objectWordCount, x3, y3, x0, y0) resultis PutObjectInELtable(objectWordCount) ]WriteLinkObject and GetThickness(splinePointer) = lineThicknessTable!(splinePointer>>SPLINE.thickness) and ScaleKnotTable(xTable, yTable, n, factor, tx, ty) be [ let fpFactor=vec 2 FST(FLDI(t0, factor), fpFactor) let fpTx=vec 2 FST(FLDI(t0, tx), fpTx) let fpTy=vec 2 FST(FLDI(t0, ty), fpTy) for k=0 to n-1 do [ let kX=xTable+2*k let kY=yTable+2*k FST(FML(FSB(FLD(t0, kX), fpTx), fpFactor), kX) FST(FML(FSB(FLD(t0, kY), fpTy), fpFactor), kY) ] ] and ComputeNormal(thickness, dX, dY, nX, nY, tX, tY) = valof [ // compute & store "normalized" & scaled tangent & normal vectors // tX ← dX * t / sqrt(dX↑2 + dY↑2) // tY ← dY * t / sqrt(dX↑2 + dY↑2) // nX ← - tY // nY ← tX FAD(FML(FLD(t1, dX), dX), FML(FLD(t2, dY), dY)) unless FSN(t1) resultis 0 let temp=vec 2; FST(t1, temp); SquareRoot(temp) FDV(FLDI(t0, thickness), temp) FST(FNEG(FST(FML(FLD(t1, dY), t0), tY)), nX) FST(FST(FML(FLD(t1, dX), t0), tX), nY) if showValues then PrintFpValues("ComputeNormal: ", dX, dY, nX, nY, tX, tY) resultis true ] and MakeCubic(x0, x1, dx0, dx1, a, b) be [ // a = 2 (x0-x1) + x'0 + x'1 FLDI(t2, 2) FLD(t0, x0); FSB(t0, x1); FML(t0, t2) FAD(t0, dx0); FAD(t0, dx1); FST(t0, a) // b = 3 (x1-x0) - 2 x'0 - x'1 FLDI(t3, 3) FLD(t0, x1); FSB(t0, x0); FML(t0, t3) FSB(t0, dx1); FSB(t0, dx0); FSB(t0, dx0); FST(t0, b) if showValues then PrintFpValues("MakeCubic: ", x0, x1, dx0, dx1, a, b) ]