// November 3, 1978 5:50 PM *** overlay C *** //Edited by Lyle Ramshaw, September 5, 1980 9:28 AM: // played with positioning of text strings in press file; added // "isArrows" flag code. get "zpDefs.bcpl" get "zpPressDf.bcpl" get "time.d" // outgoing procedures: external [ writePressFile ] // outgoing statics: external [ // for debugging @showValues @showObjects @previousColor // for EL data @ELtable @ELtableLength @objectCount @rectangleCount // color maps @hueTable @saturationTable @brightnessTable // page size @pageLeft @pageRight @pageBottom @pageTop ] static [ @showValues=0 @showObjects=0 @previousColor @ELtable @ELtableLength @objectCount @rectangleCount @hueTable @saturationTable @brightnessTable @pageLeft @pageRight @pageBottom @pageTop ] // incoming procedures: external [ Puts // SYSTEM Gets Closes WriteBlock ReadBlock MoveBlock Zero ReadCalendar DoubleAdd confirm // ZPUTIL openWrite typeForm WriteDLspline // ZPOBJECT WriteDLdot // ZPPIECE WriteDLline UNPACKDT // TIME package CONVUDT PutObjectInELtable // ZPPUTS PutRectangleInELtable PutColorInELtable PutNewColorInELtable DPadd OutsideThePage RectangleSpline PrintFpValues ArrowsMicaAdjust // ZPARROWS ] // incoming statics: external [ keys // SYSTEM UserName @splineTable // ZPINIT @textTable @maxSplineID @maxTextID @fontDefTable @lineThicknessTable @fontFile @font @dspFont @bitmap @height @width @scanlineWidth @bitmapSize @Xmax @Ymax @dashOn // ZPDRAW @dashOff ] // local static: static [ @useAlternative=-1 ] //**************************************************************** // Output PRESS file //**************************************************************** let writePressFile() be [writePressFile // -------------------- PRESS file tables: let DLdotsCommands=table [ #400+0; 0; 0; // zero for size of bitmap 1; 0; 0; 0; 0; // same for setwindow #1000+3 // bit-dir to right; line-dir down 2; 0; 0; // size left zero 3 ] // dots follow let dotsEntityTrailer=table [ 0;0;0;0;0;0;0;0;0;0;0;0 ] let objectEntityTrailer=table [ 0;0;0;0;0;0;0;0;0;0;0;0 ] let textEntityTrailer=table [ 0;0;0;0;0;0;0;0;0;0;0;0 ] let FDIRentry=table [ FDIRlen; 0; 127; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0 ] let documentDirectory=table [ 27183; 0; 0; 0; 1; 0; -1; -1; 1; 1; $S ] manifest [ lDocDir=11 ] let defLineThicknessTable=table [ defThickness0; defThickness1; defThickness2; defThickness3 ] test lineThicknessTable eq 0 ifso lineThicknessTable=defLineThicknessTable ifnot for t=0 to 3 do if lineThicknessTable!t eq 0 then lineThicknessTable!t=defLineThicknessTable!t // color tables are indexed by color (0 to 7): // white, cyan, magenta, blue (violet), yellow, green, red, black hueTable= table [ EsetHue; EsetHue+120; EsetHue+200; EsetHue+160; EsetHue+40; EsetHue+80; EsetHue; EsetHue ] saturationTable= table [ EsetSaturation; EsetSaturation+255; EsetSaturation+255; EsetSaturation+255; EsetSaturation+255; EsetSaturation+255; EsetSaturation+255; EsetSaturation ] brightnessTable= table [ EsetBrightness+255; EsetBrightness+255; EsetBrightness+255; EsetBrightness+255; EsetBrightness+255; EsetBrightness+255; EsetBrightness+255; EsetBrightness ] unless textTable!0 % splineTable!0 then [ typeForm(0, "Sorry, no picture to print!*N") return ] // -------------------- Go ahead: let pressFileName=nil let pressFile=openWrite("*NWrite PRESS file: ", wordItem, lv pressFileName) unless pressFile return let record=vec 256 Zero(record, 256) let partDirectory=vec (5*PDIRlen) Zero(partDirectory, 5*PDIRlen) let partEntry=partDirectory let Rbegin=0 // page coordinates of low left corner of screen let screenX0=(1270*17-Xmax*scaleFactor)/2 let screenY0=(1270*22-Ymax*scaleFactor)/2 // screen coordinates of page border, plus some margin pageLeft=-screenX0/scaleFactor pageRight=(1270*17-screenX0)/scaleFactor pageBottom=-screenY0/scaleFactor pageTop=(1270*22-screenY0)/scaleFactor let fontUsed=vec maxFont Zero(fontUsed, maxFont) // find the minimum text window let twLeft, twRight, twTop, twBottom = Xmax, 0, 0, Ymax if textTable!0 then for t=1 to maxTextID do [ let textPointer=textTable!t unless textPointer loop let f=textPointer>>TEXT.font if fontFile>>FONTFILE.length^f eq 0 then f=dspFont fontUsed!f=true let tLeft=textPointer>>TEXT.left let tRight=textPointer>>TEXT.right let tTop=textPointer>>TEXT.top let tBottom=textPointer>>TEXT.bottom let outside=OutsideThePage(tLeft, tRight, tTop, tBottom) if outside then [ typeForm(0, "WARNING: caption #", 10, t, 0, " lies outside the printed page, on the ", 0, outside, 0, ".*NIt should be deleted before printing. Type any character to continue.*N") Gets(keys) loop ] if twLeft gr tLeft then twLeft=tLeft if twRight ls tRight then twRight=tRight if twTop ls tTop then twTop=tTop if twBottom gr tBottom then twBottom=tBottom ] let tXe=screenX0 + twLeft*scaleFactor let tYe=screenY0 + twBottom*scaleFactor // find the minimum spline window (for objects & rectangles) let swLeft, swRight, swTop, swBottom = Xmax, 0, 0, Ymax if splineTable!0 then for id=1 to maxSplineID do [ let splinePointer=splineTable!id unless splinePointer loop let sLeft=splinePointer>>SPLINE.left let sRight=splinePointer>>SPLINE.right let sTop=splinePointer>>SPLINE.top let sBottom=splinePointer>>SPLINE.bottom let outside=OutsideThePage(sLeft, sRight, sTop, sBottom) if outside then [ typeForm(0, "WARNING: line or curve #", 10, id, 0, " lies outside the printed page, on the ", 0, outside, 0, ".*NIt should be deleted before printing. Type any character to continue.*N") Gets(keys) loop ] if swLeft gr sLeft then swLeft=sLeft if swRight ls sRight then swRight=sRight if swTop ls sTop then swTop=sTop if swBottom gr sBottom then swBottom=sBottom ] let sXe=screenX0 + swLeft*scaleFactor let sYe=screenY0 + swBottom*scaleFactor // find the minimum bitmap window (for dots) let bwLeft, bwRight, bwTop, bwBottom=Xmax, 0, 0, Ymax if splineTable!0 then for id=1 to maxSplineID do [ let splinePointer=splineTable!id unless splinePointer loop if RectangleSpline(splinePointer) loop let bLeft=splinePointer>>SPLINE.left - 16 let bRight=splinePointer>>SPLINE.right + 16 let bTop=splinePointer>>SPLINE.top + 16 let bBottom=splinePointer>>SPLINE.bottom - 16 if bwLeft gr bLeft then bwLeft=bLeft if bwRight ls bRight then bwRight=bRight if bwTop ls bTop then bwTop=bTop if bwBottom gr bBottom then bwBottom=bBottom ] if bwRight gr Xmax then bwRight=Xmax if bwLeft ls 0 then bwLeft=0 if bwTop gr Ymax then bwTop=Ymax if bwBottom ls 0 then bwBottom=0 let someDots=(bwLeft ls Xmax) & (bwRight gr 0) & (bwBottom ls Ymax) & (bwTop gr 0) let bwWordLeft=bwLeft/16 bwLeft=bwWordLeft*16 let bwWordRight=bwRight/16 bwRight=bwWordRight*16 let bwWordWidth=bwWordRight-bwWordLeft+1 let bwWidth=bwWordWidth*16 let bwHeight=bwTop-bwBottom+1 let bXe=screenX0 + bwLeft*scaleFactor let bYe=screenY0 + bwBottom*scaleFactor // WARNING: bitmap is used as temporary storage for Entity List Table !!!! ELtable=bitmap let wordCount=vec 2 wordCount!0=0; wordCount!1=0 // information about objects (number of objects, word count for each object) ELtableLength=0 objectCount=0 rectangleCount=0 //------------------------------------------------------ DATA LIST //............................................. DL dots manifest [ DLdummyWordCount=3 ] let DLdotWordCount=0 if someDots then [ //................. dummy object alternative if useAlternative then [ let dummyObject= table [ Dmove; 0; 0 ] WriteBlock(pressFile, dummyObject, DLdummyWordCount) DLdotWordCount=DLdotWordCount + DLdummyWordCount ] //................. dots commands DLdotsCommands>>DLDC.dots=bwWidth DLdotsCommands>>DLDC.lines=bwHeight DLdotsCommands>>DLDC.pl=0 DLdotsCommands>>DLDC.dl=bwHeight DLdotsCommands>>DLDC.pb=0 DLdotsCommands>>DLDC.db=bwWidth DLdotsCommands>>DLDC.width=scaleFactor*bwWidth DLdotsCommands>>DLDC.height=scaleFactor*bwHeight WriteBlock(pressFile, DLdotsCommands, DLDClen) //................. bitmap let dbm=bitmap+margin+(Ymax-bwTop)*scanlineWidth+bwWordLeft for sl=1 to bwHeight do [ WriteBlock(pressFile, dbm, bwWordWidth) dbm=dbm+scanlineWidth ] DLdotWordCount=DLdotWordCount + DLDClen + bwWordWidth*bwHeight ] DPadd(wordCount, DLdotWordCount) //............................................. DL object let DLobjectWordCount=0 if splineTable!0 then for id=1 to maxSplineID do [ let splinePointer=splineTable!id unless splinePointer loop if OutsideThePage( splinePointer>>SPLINE.left, splinePointer>>SPLINE.right, splinePointer>>SPLINE.top, splinePointer>>SPLINE.bottom) loop PutColorInELtable(splinePointer>>SPLINE.color) DLobjectWordCount=DLobjectWordCount + selecton splinePointer>>SPLINE.nKnots into [ case 1: WriteDLdot(pressFile, splinePointer, swLeft, swBottom); case 2: WriteDLline(pressFile, splinePointer, swLeft, swBottom); default: WriteDLspline(pressFile, splinePointer, swLeft, swBottom) ] typeForm(1, $|) ] DPadd(wordCount, DLobjectWordCount) //............................................. DL text let DLtextWordCount=0 if textTable!0 then for id=1 to maxTextID do [ let textPointer=textTable!id unless textPointer loop if OutsideThePage( textPointer>>TEXT.left, textPointer>>TEXT.right, textPointer>>TEXT.top, textPointer>>TEXT.bottom) loop let textString=textPointer+TEXTblockSize let wCount=(textString>>STRING.length)/2+1 WriteBlock(pressFile, textString, wCount) DLtextWordCount=DLtextWordCount+wCount ] DPadd(wordCount, DLtextWordCount) //............................................. DL spline let DLsplineWordCount=0 if splineTable!0 then [ Puts(pressFile, splineTable!0) DLsplineWordCount=1 for id=1 to maxSplineID do [ let splinePointer=splineTable!id unless splinePointer loop let nKnots=splinePointer>>SPLINE.nKnots test splinePointer>>SPLINE.cyclic ifso Puts(pressFile, (-nKnots)) ifnot Puts(pressFile, nKnots) Puts(pressFile, ((splinePointer>>SPLINE.shape) lshift 8) % (splinePointer>>SPLINE.thickness)) test splinePointer>>SPLINE.dashed ifso Puts(pressFile, (dashOn lshift 8) % dashOff) ifnot Puts(pressFile, 0) let knotCount= 4 * nKnots WriteBlock(pressFile, splinePointer+SPLINEknotBase, knotCount) DLsplineWordCount=DLsplineWordCount + knotCount + 3 ] ] DPadd(wordCount, DLsplineWordCount) //------------------------------------------------------ ENTITY LIST Puts(pressFile, 0) DPadd(wordCount, 1) Zero(dotsEntityTrailer, ETlen) Zero(objectEntityTrailer, ETlen) Zero(textEntityTrailer, ETlen) //............................................. EL dots if someDots then [ let ELdotWordCount=0 //........................................ dummy (object) alternative if useAlternative then [ let dummyAlternative= table [ EnopLeft+Ealternative; EobjectAlternative; 0; 4; 0; 2*DLdummyWordCount; EnopLeft+EshowObject; DLdummyWordCount ] WriteBlock(pressFile, dummyAlternative, 8) ELdotWordCount=ELdotWordCount + 8 ] //........................................ dots alternative let dotsAlternative= table [ EnopLeft+Ealternative; EdotsAlternative; 0; 14; 0; 0; EnopLeft+EsetX; 0; EnopLeft+EsetY; 0; EnopLeft+EshowDots; 0; 0 ] dotsAlternative!5=2*DLdotWordCount dotsAlternative!12=DLdotWordCount test useAlternative ifso [ WriteBlock(pressFile, dotsAlternative, 13) ELdotWordCount=ELdotWordCount + 13 ] ifnot [ WriteBlock(pressFile, dotsAlternative+6, 7) ELdotWordCount=ELdotWordCount + 7 ] //........................................ end alternative if useAlternative then [ let endAlternative= table [ EnopLeft+Ealternative; 0; 0; 0; 0; 0 ] WriteBlock(pressFile, endAlternative, 6) ELdotWordCount=ELdotWordCount + 6 ] //........................................ trailer ELdotWordCount=ELdotWordCount + ETlen DPadd(lv dotsEntityTrailer>>ET.Blength, DLdotWordCount) DPadd(lv dotsEntityTrailer>>ET.Blength, DLdotWordCount) dotsEntityTrailer>>ET.Elength=ELdotWordCount dotsEntityTrailer>>ET.Xe=bXe dotsEntityTrailer>>ET.Ye=bYe dotsEntityTrailer>>ET.left=bwLeft*scaleFactor dotsEntityTrailer>>ET.bottom=bwBottom*scaleFactor dotsEntityTrailer>>ET.width=bwWidth*scaleFactor dotsEntityTrailer>>ET.height=bwHeight*scaleFactor WriteBlock(pressFile, dotsEntityTrailer, ETlen) DPadd(wordCount, ELdotWordCount) ] //............................................. EL objects & rectangles if splineTable!0 then [ //........................................ commands WriteBlock(pressFile, ELtable, ELtableLength) let ELobjectWordCount=ELtableLength //........................................ skip splines if DLsplineWordCount ne 0 then [ Puts(pressFile, EnopLeft+EskipControl) Puts(pressFile, DLsplineWordCount) Puts(pressFile, EskipTypeLeft+Enop) ELobjectWordCount=ELobjectWordCount+3 ] //........................................ trailer ELobjectWordCount=ELobjectWordCount + ETlen objectEntityTrailer>>ET.Bbegin=dotsEntityTrailer>>ET.Bbegin objectEntityTrailer>>ET.BbeginLSB=dotsEntityTrailer>>ET.BbeginLSB DoubleAdd(lv objectEntityTrailer>>ET.Bbegin, lv dotsEntityTrailer>>ET.Blength) objectEntityTrailer>>ET.BlengthLSB=2*DLobjectWordCount objectEntityTrailer>>ET.Elength=ELobjectWordCount objectEntityTrailer>>ET.Xe=sXe objectEntityTrailer>>ET.Ye=sYe objectEntityTrailer>>ET.left=swLeft*scaleFactor objectEntityTrailer>>ET.bottom=swBottom*scaleFactor objectEntityTrailer>>ET.width=(swRight-swLeft+1)*scaleFactor objectEntityTrailer>>ET.height=(swTop-swBottom+1)*scaleFactor WriteBlock(pressFile, objectEntityTrailer, ETlen) DPadd(wordCount, ELobjectWordCount) ] //............................................. EL text if textTable!0 then [ //........................................ commands let ELtextWordCount=0 for id=1 to maxTextID do [ let textPointer=textTable!id unless textPointer loop if OutsideThePage( textPointer>>TEXT.left, textPointer>>TEXT.right, textPointer>>TEXT.top, textPointer>>TEXT.bottom) loop let textString=textPointer+TEXTblockSize let count=textString>>STRING.length let f=textPointer>>TEXT.font if fontFile>>FONTFILE.length^f eq 0 then f=dspFont let color=textPointer>>TEXT.color Puts(pressFile, hueTable!color) Puts(pressFile, saturationTable!color) Puts(pressFile, brightnessTable!color) Puts(pressFile, (Efont+f) lshift 8 + EsetX) let xMicas=scaleFactor*(textPointer>>TEXT.left - twLeft) let yMicas=scaleFactor*(textPointer>>TEXT.top - fontFile>>FONTFILE.baseline^f - twBottom) if (textString>>STRING.length eq 1) & (fontDefTable!f>>FONTDEF.isArrows eq 1) then ArrowsMicaAdjust(textString>>STRING.char^1, lv xMicas, lv yMicas) Puts(pressFile, xMicas) Puts(pressFile, EskipOneCharLeft+EsetY) Puts(pressFile, yMicas) Puts(pressFile, EshowCharLeft+count) ELtextWordCount=ELtextWordCount+8 unless count rem 2 then [ Puts(pressFile, EnopLeft+EskipOneChar) ELtextWordCount=ELtextWordCount+1 ] ] //........................................ trailer ELtextWordCount=ELtextWordCount + ETlen textEntityTrailer>>ET.Bbegin=objectEntityTrailer>>ET.Bbegin textEntityTrailer>>ET.BbeginLSB=objectEntityTrailer>>ET.BbeginLSB DoubleAdd(lv textEntityTrailer>>ET.Bbegin, lv objectEntityTrailer>>ET.Blength) textEntityTrailer>>ET.BlengthLSB=2*DLtextWordCount textEntityTrailer>>ET.Elength=ELtextWordCount textEntityTrailer>>ET.Xe=tXe textEntityTrailer>>ET.Ye=tYe textEntityTrailer>>ET.left=twLeft*scaleFactor textEntityTrailer>>ET.bottom=twBottom*scaleFactor textEntityTrailer>>ET.width=(twRight-twLeft+1)*scaleFactor textEntityTrailer>>ET.height=(twTop-twBottom+1)*scaleFactor WriteBlock(pressFile, textEntityTrailer, ETlen) DPadd(wordCount, ELtextWordCount) ] //............................................. DL/EL padding let padWords=256-((wordCount!1) & #377) if padWords eq 256 then padWords=0 Zero(record, 256) WriteBlock(pressFile, record, padWords) //............................................. Part Directory Entry let Rlength=(wordCount!1 rshift 8) % (wordCount!0 lshift 8) if padWords ne 0 then Rlength=Rlength+1 partEntry>>PDIR.type=0 partEntry>>PDIR.Rbegin=Rbegin partEntry>>PDIR.Rlength=Rlength partEntry>>PDIR.Plength=padWords Rbegin=Rbegin+Rlength partEntry=partEntry+PDIRlen typeForm(10, objectCount, 0, " objects & ", 10, rectangleCount, 0, " rectangles.*N") //------------------------------------------------------ FONT DIRECTORY let nf=0 // assume it fits in one record if textTable!0 then for f=0 to maxFont-1 do [ if fontFile>>FONTFILE.length^f eq 0 & f ne dspFont loop unless fontUsed!f loop let fontEntry=fontDefTable!f FDIRentry>>FDIR.font=f MoveBlock(FDIRentry+3, fontEntry, FONTDEFnameLength/2+1) FDIRentry>>FDIR.face=fontEntry>>FONTDEF.face FDIRentry>>FDIR.ptSize=fontEntry>>FONTDEF.ptSize MoveBlock(record+nf*FDIRlen, FDIRentry, FDIRlen) nf=nf+1 ] WriteBlock(pressFile, record, 256) partEntry>>PDIR.type=1 partEntry>>PDIR.Rbegin=Rbegin partEntry>>PDIR.Rlength=1 partEntry>>PDIR.Plength=0 Rbegin=Rbegin+1 //------------------------------------------------------ PART DIRECTORY Zero(record, 256) MoveBlock(record, partDirectory, 2*PDIRlen) WriteBlock(pressFile, record, 256) //------------------------------------------------------ DOCUMENT DIRECTORY documentDirectory!1=Rbegin+2 documentDirectory!2=2 documentDirectory!3=Rbegin // date for Press width ReadCalendar(documentDirectory+6) Zero(record, 256) MoveBlock(record, documentDirectory, lDocDir) MoveBlock(record + #200, pressFileName, 20) // creator's name let creatorsName=record + #232 MoveBlock(creatorsName, UserName, 16) if creatorsName>>STRING.length gr 31 then creatorsName>>STRING.length=31 // creation date let creationDate= record + #252 let utv=vec lenUTV CONVUDT(creationDate, UNPACKDT(0, utv)) WriteBlock(pressFile, record, 256) Closes(pressFile) typeForm(0, "Done!*N") ]writePressFile