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