-- PressObjects.mesa -- Written by Joe Maleson -- Last changed by Doug Wyatt, December 8, 1980 1:49 PM --bad news: have to do fontwidths to input text, in case --you have SetX,SetY,ShowChars,ShowChars.... DIRECTORY AltoFileDefs USING [eofDA,FP,LD,vDA], DirectoryDefs USING [DirectoryLookup], DiscoDefs USING[ReadPageFromVDA,IndexFile,TransferBytes,DiskPosition], InlineDefs, MiscDefs, Mopcodes USING [zLDIV], PressDefs USING [EntityCommandTrailer,PartEntry,Page,Font, ExternalFileDirectory,PressPassword,DocDir,ELCommand, PressFileDescriptor,PressFontEntry,SetColor,SetFont,PutText, PutRectangle,SetSpaceX,SetSpaceY,LookupFontName,missingWidth, PutPressDotsData,WriteCommand,ResetSpace, PressObject,PressPage,PressFont,PressDotsData, ELShowCharactersShort,ELSkipCharactersShort, ELShowCharactersAndSkip,ELSetSpaceXShort, ELSetSpaceYShort,ELFont, ELSkipControlBytesImmediate,ELAlternative,ELOnlyOnCopy,ELSetX,ELSetY, ELShowCharacters,ELSkipCharacters,ELSkipControlBytes, ELShowCharacterImmediate,ELSetSpaceX,ELSetSpaceY,ELResetSpace, ELSpace,ELSetBrightness,ELSetHue,ELSetSaturation,ELShowObject, ELShowDots,ELShowDotsOpaque,ELShowRectangle,ELNop, DLSetCoding,DLSetMode,DLSetWindow,DLSetSize,DLMoveTo,DLDrawTo, DLDrawCurve,DLDotsFollow,DLGetDotsFromFile, DLGetDotsFromPressFile,DLSetSamplingProperties,DLSSPInputIntensity, DLSSPOutputIntensity,DLSSPScreen,DLSSPDot,PressFilePointers], StreamDefs USING [WriteBlock,StreamHandle,DiskHandle, NewWordStream,Read,GetIndex], StringDefs USING [EquivalentString,AppendChar,AppendString,AppendDecimal], SystemDefs USING [AllocateSegment,FreeSegment,AllocateHeapNode, FreeHeapNode,AllocateHeapString,FreeHeapString,PruneHeap]; (635)\f1 PressObjects: PROGRAM IMPORTS DirectoryDefs, InlineDefs, MiscDefs, PressDefs, SystemDefs, StreamDefs, StringDefs, DiscoDefs EXPORTS PressDefs = BEGIN OPEN AltoFileDefs, DirectoryDefs, DiscoDefs, PressDefs, StreamDefs, SystemDefs; \f1b12B PrintWidthError: BOOLEAN _ FALSE; --generally useless error message --Stuff to handle flaky ShowCharacterImmediate ELCommandBase: CARDINAL; ELCommandOffset: CARDINAL; LongDiv32: PROCEDURE[CARDINAL,CARDINAL,CARDINAL] RETURNS[CARDINAL] = MACHINE CODE BEGIN Mopcodes.zLDIV;END; GetPressDotsData: PUBLIC PROCEDURE [obj: POINTER TO PressObject,dots: POINTER TO PressDotsData] = BEGIN dp: POINTER TO DiscoDefs.DiskPosition _ @dots.diskPosition; data: PACKED ARRAY [0..1] OF [0..377B]; dataWord: POINTER TO CARDINAL _ LOOPHOLE[@data]; Read1: PROCEDURE RETURNS [UNSPECIFIED] = BEGIN TransferBytes[dp: dp,nBytes:1,data: LOOPHOLE[@data]]; RETURN[data[0]]; END; Read2: PROCEDURE RETURNS [UNSPECIFIED] = BEGIN TransferBytes[dp: dp,nBytes:2,data: LOOPHOLE[@data]]; RETURN[dataWord^]; END; IF (obj.command # ELShowDots) AND (obj.command # ELShowDotsOpaque) THEN ERROR; dots.fileName _ NIL; dots.opaque _ obj.command = ELShowDotsOpaque; dots.haveDot _ FALSE; dots.frequency _ dots.min _ dots.max _ 0; dots.diskPosition _ obj.diskPosition; --will be updated by Reads DO SELECT Read1[] FROM DLSetCoding => BEGIN dots.nBitsPerPixel _ Read1[]; dots.displayPixels _ dots.nPixels _ Read2[]; dots.displayLines _ dots.nLines _ Read2[]; dots.passPixels _ dots.passLines _ 0; END; DLSetMode => dots.mode _ Read1[]; 0 => --all the full word commands SELECT Read1[] FROM DLSetWindow=> BEGIN dots.passPixels _ Read2[]; dots.displayPixels _ Read2[]; dots.passLines _ Read2[]; dots.displayLines _ Read2[]; END; DLSetSize=> BEGIN dots.micaWidth _ Read2[]; dots.micaHeight _ Read2[]; END; DLDotsFollow=> EXIT; DLGetDotsFromFile=> BEGIN offset: CARDINAL _ Read2[]; nameLen: CARDINAL _ Read1[]; fileName: STRING _ AllocateHeapString[nameLen]; i: CARDINAL; FOR i IN [0..nameLen) DO fileName[i] _ Read1[];ENDLOOP; fileName.length _ nameLen; dots.fileName _ fileName; EXIT; END; DLGetDotsFromPressFile=> EXIT; DLSetSamplingProperties=> BEGIN nWords: INTEGER _ Read2[]; UNTIL nWords <= 0 DO SELECT Read2[] FROM DLSSPInputIntensity => BEGIN dots.min _ Read2[]; dots.max _ Read2[]; nWords _ nWords-3; END; DLSSPOutputIntensity => nWords _ nWords-4; DLSSPScreen => BEGIN dots.angle _ Read2[]; [] _ Read2[]; dots.frequency _ Read2[]; nWords _ nWords-4; END; DLSSPDot=> BEGIN nCells: CARDINAL; dots.dotPosition _ dp^; nCells _ Read2[]; [] _ Read2[];[] _ Read2[]; --skip nLines,nShifts THROUGH [0..nCells) DO [] _ Read2[];ENDLOOP; --pass data nWords _ nWords - (nCells+4); END; ENDCASE; ENDLOOP; --parsing DLSetSamplingProperties END; --case DLSetSamplingProperties ENDCASE; --SELECT word commands ENDCASE; --byte commands ENDLOOP; -- for all DotsData END; PutPressPage: PUBLIC PROCEDURE[pfd: POINTER TO PressFileDescriptor,p: POINTER TO PressPage,dx: CARDINAL _ 0,dy: CARDINAL _ 0] = BEGIN obj: POINTER TO PressObject _ p.ObjectList; UNTIL obj = NIL DO SetColor[pfd,obj.hue,obj.sat,obj.br]; SELECT obj.command FROM ELShowCharacters=> BEGIN string: STRING _ AllocateHeapString[obj.nDataBytes]; font: POINTER TO PressFont _ p.FontDir[obj.font]; dp: DiscoDefs.DiskPosition _ obj.diskPosition; TransferBytes[dp: @dp,nBytes: obj.nDataBytes,data: LOOPHOLE[@string.text]]; string.length _ obj.nDataBytes; IF obj.spaceX = 177777B THEN BEGIN IF obj.spaceY = 177777B THEN ResetSpace[pfd]; END ELSE SetSpaceX[pfd,obj.spaceX]; IF obj.spaceY # 177777B THEN SetSpaceY[pfd,obj.spaceY]; SetFont[pfd,font.Family,font.PointSize,font.Face,font.Rotation]; PutText[pfd,string,obj.micaX+dx,obj.micaY+dy]; FreeHeapString[string]; END; ELShowObject=> BEGIN param: ARRAY [0..6) OF CARDINAL; dp: DiscoDefs.DiskPosition _ obj.diskPosition; data: POINTER TO ARRAY [0..0) OF CARDINAL _ SystemDefs.AllocateSegment[(obj.nDataBytes+1)/2]; s: StreamDefs.StreamHandle _ pfd.outStream; commIndex: CARDINAL _ 0; IF InlineDefs.BITAND[StreamDefs.GetIndex[s].byte,1] = 1 THEN BEGIN s.put[s,0];param[0]_1; WriteCommand[pfd,ELSkipCharactersShort,@param]; END; param[0] _ obj.nDataBytes/2; WriteCommand[pfd,ELShowObject,@param]; DiscoDefs.TransferBytes[dp: @dp,nBytes: obj.nDataBytes,data: LOOPHOLE[data]]; UNTIL commIndex >= obj.nDataBytes/2 DO SELECT data[commIndex] FROM DLMoveTo,DLDrawTo => BEGIN data[commIndex+1] _ obj.micaX+dx+data[commIndex+1]; data[commIndex+2] _ obj.micaY+dy+data[commIndex+2]; commIndex _ commIndex+3; END; DLDrawCurve => commIndex _ commIndex+13; ENDCASE => MiscDefs.CallDebugger["bad object"]; ENDLOOP; [] _ StreamDefs.WriteBlock[s,data,obj.nDataBytes/2]; SystemDefs.FreeSegment[data]; END; ELShowDots,ELShowDotsOpaque=> BEGIN dots: POINTER TO PressDotsData _ LOOPHOLE[obj+SIZE[PressObject]]; pixelsPerWord: CARDINAL _ 16/MAX[1,dots.nBitsPerPixel]; ScanInit[dots.diskPosition,dots.nPixels/pixelsPerWord]; PutPressDotsData[pfd,obj.micaX+dx,obj.micaY+dy,dots,nextScanLine]; ScanClose[]; END; ELShowRectangle=> BEGIN PutRectangle[pfd,obj.micaX+dx,obj.micaY+dy,obj.spaceX,obj.spaceY]; END; ENDCASE=> NULL; obj _ obj.link; ENDLOOP; END; dp: DiscoDefs.DiskPosition; nw: CARDINAL; sl: POINTER _ NIL; ScanInit: PROCEDURE [diskPosition: DiscoDefs.DiskPosition, nWordsPerLine: CARDINAL ]= BEGIN dp _ diskPosition; nw _ nWordsPerLine; sl _ SystemDefs.AllocateSegment[nWordsPerLine]; END; nextScanLine: PROCEDURE RETURNS [POINTER] = BEGIN DiscoDefs.TransferBytes[@dp,nw*2,sl]; RETURN[sl]; END; ScanClose: PROCEDURE = BEGIN SystemDefs.FreeSegment[sl]; sl_NIL END; GetPressPage: PUBLIC PROCEDURE[fileName: STRING,pageNumber: CARDINAL,p: POINTER TO PressPage] = BEGIN fp: FP; p.ObjectList _ NIL; IF NOT DirectoryLookup[fp: @fp,name: fileName,create: FALSE] THEN RETURN; GetPressPageFromFP[@fp,pageNumber,p]; END; GetPressPageFromFP: PUBLIC PROCEDURE [fp: POINTER TO FP,pageNumber: CARDINAL,p: POINTER TO PressPage,userProc: UNSPECIFIED _ 0] = BEGIN pfp: PressFilePointers; nPages: CARDINAL _ OpenPressFileFromFP[fp,@pfp]; p.leftX _ p.bottomY _ 77777B; p.rightX _ p.topY _ 0; p.ObjectList _ NIL; p.FontDir _ ALL[NIL]; IF pageNumber > nPages THEN RETURN; ReadPressPage[@pfp,pageNumber,p,userProc]; ReleasePressFilePointers[@pfp]; END; ReleasePressFilePointers: PUBLIC PROCEDURE [pfp: POINTER TO PressFilePointers] = BEGIN OPEN pfp; --free up storage FreeSegment[PartDir]; FreeSegment[vDAs]; FreeSegment[FontDir]; fontWidthsStream.destroy[fontWidthsStream]; WHILE PruneHeap[] DO ENDLOOP; END; ReadPressPage: PUBLIC PROCEDURE [pfp: POINTER TO PressFilePointers,pageNumber: CARDINAL,p: POINTER TO PressPage,userProc: UNSPECIFIED _ 0] = BEGIN OPEN pfp; i: CARDINAL; partDir: PartEntry _ PartDir[pageNumber-1]; nRecs,firstRec,currentRec: CARDINAL; trailer: EntityCommandTrailer; ectPointer: POINTER TO EntityCommandTrailer; thisELend: CARDINAL; buffer: ARRAY[0..512) OF UNSPECIFIED; ELSize,ELDataTail,currentNWords: CARDINAL; commands: POINTER; nRecs _ 1; firstRec _ partDir.RecordStart+partDir.RecordLength; IF partDir.PaddingLength+SIZE[EntityCommandTrailer] > 256 THEN BEGIN nRecs _ nRecs + 1;firstRec _ firstRec - 1;END; FOR i IN [0..nRecs) DO ReadPageFromVDA[@buffer+i*256,vDAs[firstRec+i]];ENDLOOP; thisELend _ nRecs*256 - partDir.PaddingLength; ectPointer _ LOOPHOLE[@buffer+thisELend-SIZE[EntityCommandTrailer]]; currentRec _ firstRec; WHILE ectPointer.EntityLen # 0 DO trailer _ ectPointer^; ELSize _ trailer.EntityLen-SIZE[EntityCommandTrailer]; ELDataTail _ thisELend-SIZE[EntityCommandTrailer]; commands _ AllocateSegment[ELSize]; DO currentNWords _ MIN[ELDataTail,ELSize]; InlineDefs.COPY[from: @buffer+ELDataTail-currentNWords,nwords: currentNWords,to:commands+ELSize-currentNWords]; IF ELDataTail >= ELSize THEN EXIT; ELSize _ ELSize - currentNWords; currentRec _ currentRec-1; ReadPageFromVDA[@buffer,vDAs[currentRec]]; ELDataTail _ 256; ENDLOOP; --Stuff to handle flaky ShowCharacterImmediate ELCommandBase _ currentRec; ELCommandOffset _ (ELDataTail-currentNWords)*2; ProcessCommands[pfp,commands,@trailer,p,@partDir,userProc]; SystemDefs.FreeSegment[commands]; firstRec _ firstRec - (255 + trailer.EntityLen - thisELend)/256; thisELend _ (thisELend - trailer.EntityLen) MOD 256; nRecs _ 1; IF thisELend 256 pages"]; END ELSE --good hint BEGIN vDAs _ AllocateSegment[leaderPage.eofFA.page*SIZE[vDA]]; IndexFile[fp.leaderDA,leaderPage.eofFA.page,vDAs]; END; fontWidthsStream _ NewWordStream["Fonts.WIDTHS",Read]; --read docDir ReadPageFromVDA[@docDir,vDAs[leaderPage.eofFA.page-1]]; IF docDir.Password # PressPassword THEN MiscDefs.CallDebugger["bad password"]; --read PartDir PartDir _ AllocateSegment[256*docDir.partLength]; FOR i IN [1..docDir.partLength] DO ReadPageFromVDA[PartDir+(i-1)*256,vDAs[docDir.partDirStart+i]]; ENDLOOP; --interpret PartDir, reading fontDir nPages _ 0; FOR i IN [0..docDir.nParts) DO SELECT PartDir[i].Type FROM Page=> BEGIN nPages_nPages+1; END; Font=> BEGIN fontDirIndex _ i; FontDir _ AllocateSegment[256*PartDir[i].RecordLength]; FOR j IN [1..PartDir[i].RecordLength] DO ReadPageFromVDA[FontDir+(j-1)*256,vDAs[PartDir[i].RecordStart+j]]; ENDLOOP; END; ExternalFileDirectory=>BEGIN END; ENDCASE; ENDLOOP; IF FontDir = NIL THEN MiscDefs.CallDebugger["no font dir in Press file"]; IF fontDirIndex # docDir.nParts THEN --reorganize BEGIN savedFontDir: PressDefs.PartEntry _ PartDir[fontDirIndex]; FOR i IN [fontDirIndex..docDir.nParts-1) DO PartDir[i] _ PartDir[i+1];ENDLOOP; PartDir[docDir.nParts-1] _ savedFontDir; END; RETURN[nPages]; END; ReleasePressPage: PUBLIC PROCEDURE [pressPage: POINTER TO PressPage] = BEGIN x: POINTER TO PressObject; i: CARDINAL _ 0; UNTIL pressPage.ObjectList = NIL DO x _ pressPage.ObjectList.link; IF pressPage.ObjectList.command IN [ELShowDots..ELShowDotsOpaque] THEN BEGIN pdd: POINTER TO PressDotsData _ LOOPHOLE[pressPage.ObjectList+ SIZE[PressObject]]; IF pdd.fileName#NIL THEN SystemDefs.FreeHeapString[pdd.fileName]; END; FreeHeapNode[pressPage.ObjectList]; pressPage.ObjectList _ x; ENDLOOP; UNTIL pressPage.FontDir[i] = NIL DO FreeSegment[pressPage.FontDir[i].Widths]; FreeHeapString[pressPage.FontDir[i].Family]; FreeHeapNode[pressPage.FontDir[i]]; i _ i+1; ENDLOOP; END; GetFont: PUBLIC PROCEDURE [pfp: POINTER TO PressFilePointers,n: CARDINAL,pressPage: POINTER TO PressPage] RETURNS [index: CARDINAL,widths: POINTER TO ARRAY CHARACTER [0C..377C] OF INTEGER] = BEGIN fontIndex: CARDINAL _ 0; i,j: CARDINAL; f: POINTER TO PressFont; bufx,bufy: POINTER; str: STRING; --look through font entries FOR i _ 0,i+1 UNTIL pfp.FontDir[i].EntryLength = 0 DO IF pfp.FontDir[i].Family[0] = 0C THEN BEGIN MiscDefs.CallDebugger["character entry in font part"]; LOOP; END; IF n # CARDINAL[pfp.FontDir[i].FontSet*16 + pfp.FontDir[i].Font] THEN LOOP; --first, look through already processed fonts str _ AllocateHeapString[LOOPHOLE[pfp.FontDir[i].Family[0]]]; FOR j IN [1..LOOPHOLE[pfp.FontDir[i].Family[0],CARDINAL]] DO StringDefs.AppendChar[str,pfp.FontDir[i].Family[j]]; ENDLOOP; UNTIL pressPage.FontDir[fontIndex] = NIL DO --note that pressPage.FontDir[fontIndex].n may not have any --relation to the desired font number "n", since they may come --from different press files --IF pressPage.FontDir[fontIndex].n = n THEN IF StringDefs.EquivalentString[str,pressPage.FontDir[fontIndex].Family] AND pfp.FontDir[i].Face = pressPage.FontDir[fontIndex].Face AND pfp.FontDir[i].Size = pressPage.FontDir[fontIndex].PointSize AND pfp.FontDir[i].Rotation = pressPage.FontDir[fontIndex].Rotation THEN --SAME!!!! BEGIN SystemDefs.FreeHeapString[str]; RETURN[fontIndex,pressPage.FontDir[fontIndex].Widths]; END; fontIndex _ fontIndex + 1; ENDLOOP; IF fontIndex = 16 THEN ERROR; --too many fonts f _ AllocateHeapNode[SIZE[PressFont]]; f^ _ [Family: str,Widths:,Face: LOOPHOLE[pfp.FontDir[i].Face], PointSize: pfp.FontDir[i].Size,Rotation: pfp.FontDir[i].Rotation]; f.Widths _ AllocateSegment[256]; SELECT f.Rotation/60 FROM 90,270 => BEGIN bufx _ NIL;bufy _ LOOPHOLE[f.Widths];END; ENDCASE => BEGIN bufx _ LOOPHOLE[f.Widths];bufy _ NIL;END; IF NOT LookupFontName[s: pfp.fontWidthsStream,famstr: f.Family, face: f.Face,siz: f.PointSize,rot: f.Rotation, bufx:bufx,bufy:bufy,boundbox:NIL] THEN { IF PrintWidthError THEN { errorString: STRING _ [100]; StringDefs.AppendString[to:errorString, from:"LookupFontName failed: ("]; StringDefs.AppendString[to:errorString, from: f.Family]; StringDefs.AppendDecimal[s:errorString,n:f.PointSize]; StringDefs.AppendString[to:errorString, from:"). Widths will be wrong if you Proceed"]; MiscDefs.CallDebugger[errorString]; }; MiscDefs.Zero[f.Widths,256]; }; pressPage.FontDir[fontIndex] _ f; RETURN[fontIndex,f.Widths]; ENDLOOP; IF n # 0 THEN --bogus first call in Entity MiscDefs.CallDebugger["font not found"]; --can't happen RETURN[0,NIL]; END; ProcessCommands: PROCEDURE[pfp: POINTER TO PressFilePointers,EL: POINTER TO PACKED ARRAY [0..0) OF ELCommand,trailer: POINTER TO EntityCommandTrailer,pressPage: POINTER TO PressPage,partDir: POINTER TO PartEntry,userProc: UNSPECIFIED _ 0] = BEGIN Proc: PROCEDURE [p: POINTER TO PressPage] _ userProc; vDAs: POINTER TO ARRAY [0..0) OF vDA _ pfp.vDAs; i: CARDINAL; currentDLRecord: CARDINAL _ 177777B; spaceX: CARDINAL _ 177777B; spaceY: CARDINAL _ 177777B; DLRecordStart: CARDINAL _ partDir.RecordStart+ LongDiv32[trailer.BeginByte[1],trailer.BeginByte[0],512]+1; DLRecordOffset: CARDINAL _ trailer.BeginByte[1] MOD 512; DL: PACKED ARRAY [0..512) OF [0..377B]; nELBytes: CARDINAL = 2*(trailer.EntityLen-SIZE[EntityCommandTrailer]); micaX: CARDINAL _ trailer.Xe; micaY: CARDINAL _ trailer.Ye; currentFontIndex: CARDINAL; currentWidth: POINTER TO ARRAY CHARACTER [0C..377C] OF INTEGER; currentFontRotated: BOOLEAN; currentHeight: CARDINAL; currentSat,currentHue,currentBr: CARDINAL _ 0; AlternativeOn: BOOLEAN _ FALSE; lastLink: POINTER TO PressObject; Width: PROCEDURE[c: CHARACTER] RETURNS[INTEGER] = INLINE { w: INTEGER=currentWidth[c]; RETURN[IF w=missingWidth THEN 0 ELSE w]; }; DoCharImmediate: PROCEDURE = BEGIN ELOff: CARDINAL _ ELCommandOffset+i; ELBase: CARDINAL _ ELCommandBase+ELOff/512; ELByte: CARDINAL _ ELOff MOD 512; ch: CHARACTER _ LOOPHOLE[EL[i]]; IF currentFontRotated THEN BEGIN IF ch = ' AND spaceY # 177777B THEN micaY _ micaY + spaceY ELSE micaY _ micaY + Width[ch]; END ELSE BEGIN IF ch = ' AND spaceX # 177777B THEN micaX _ micaX + spaceX ELSE micaX _ micaX + Width[ch]; END; AddPressObject[ELShowCharacters,1]; lastLink.diskPosition _ [VDA:vDAs[ELBase],beginByte: ELByte]; END; DoChars: PROCEDURE[n: CARDINAL] = BEGIN ch: CHARACTER; --note: only rotation=90 will work with this bad code xoff: CARDINAL _ IF currentFontRotated THEN currentHeight ELSE 0; yoff: CARDINAL _ IF currentFontRotated THEN 0 ELSE currentHeight; AddPressObject[ELShowCharacters,n]; pressPage.leftX _ MIN[pressPage.leftX,micaX-xoff]; pressPage.bottomY _ MIN[pressPage.bottomY,micaY]; pressPage.topY _ MAX[pressPage.topY,micaY+yoff]; THROUGH [0..n) DO ch _ Read[]; IF currentFontRotated THEN BEGIN IF ch = ' AND spaceY # 177777B THEN micaY _ micaY + spaceY ELSE micaY _ micaY + Width[ch]; END ELSE BEGIN IF ch = ' AND spaceX # 177777B THEN micaX _ micaX + spaceX ELSE micaX _ micaX + Width[ch]; END; ENDLOOP; pressPage.rightX _ MAX[pressPage.rightX,micaX]; pressPage.topY _ MAX[pressPage.topY,micaY+yoff]; END; Read: PROCEDURE RETURNS[rslt: UNSPECIFIED] = BEGIN rslt _ DL[DLRecordOffset]; Skip[1]; END; AddPressObject: PROCEDURE[c: ELCommand,nDataBytes: CARDINAL] = BEGIN newObj: POINTER TO PressObject; dot: BOOLEAN = c IN [ELShowDots..ELShowDotsOpaque]; --error check for space saving data structure kludge IF (nDataBytes > 7777B) OR (currentFontIndex > 17B) THEN ERROR; newObj _ AllocateHeapNode[SIZE[PressObject]+ (IF dot THEN SIZE[PressDotsData] ELSE 0)]; newObj^ _ [link: NIL,micaX: micaX,micaY: micaY,command: c, hue: currentHue,sat: currentSat,br: currentBr,spaceX: spaceX,spaceY: spaceY, font: currentFontIndex,nDataBytes: nDataBytes, diskPosition: [VDA:vDAs[currentDLRecord],beginByte: DLRecordOffset]]; IF pressPage.ObjectList = NIL THEN BEGIN pressPage.ObjectList _ newObj; lastLink _ newObj; END ELSE BEGIN lastLink.link _ newObj; lastLink _ newObj; END; END; Skip: PROCEDURE[n: CARDINAL] = BEGIN DLRecordOffset _ DLRecordOffset+n; IF DLRecordOffset >= 512 THEN BEGIN currentDLRecord _ currentDLRecord + DLRecordOffset/512; DLRecordOffset _ DLRecordOffset MOD 512; ReadPageFromVDA[@DL,vDAs[currentDLRecord]]; END; END; lastLink _ pressPage.ObjectList; IF lastLink # NIL THEN UNTIL lastLink.link = NIL DO lastLink _ lastLink.link;ENDLOOP; [currentFontIndex,currentWidth] _ GetFont[pfp,trailer.FontSet*16,pressPage]; IF currentWidth=NIL THEN { currentFontRotated _ FALSE; currentHeight _ 0; } ELSE { deg: CARDINAL _ pressPage.FontDir[currentFontIndex].Rotation/60; currentFontRotated _ SELECT deg FROM 90,270 => TRUE, ENDCASE => FALSE; currentHeight _ pressPage.FontDir[currentFontIndex].PointSize*(2540/72); }; IF currentDLRecord # DLRecordStart THEN BEGIN currentDLRecord _ DLRecordStart; ReadPageFromVDA[@DL,vDAs[currentDLRecord]]; END; FOR i IN [0..nELBytes) DO SELECT EL[i] FROM IN [ELShowCharactersShort..ELSkipCharactersShort)=> DoChars[EL[i]+1-ELShowCharactersShort]; IN [ELSkipCharactersShort..ELShowCharactersAndSkip)=> Skip[1+EL[i]-ELSkipCharactersShort]; IN [ELShowCharactersAndSkip..ELSetSpaceXShort)=> BEGIN DoChars[EL[i]+1-ELShowCharactersAndSkip]; Skip[1]; END; IN [ELSetSpaceXShort..ELSetSpaceYShort)=> BEGIN i_i+1;spaceX_(EL[i-1]-ELSetSpaceXShort)*256+EL[i];END; IN [ELSetSpaceYShort..ELFont)=> BEGIN i_i+2;spaceY_(EL[i-1]-ELSetSpaceYShort)*256+EL[i];END; IN [ELFont..ELFont+16)=> BEGIN [currentFontIndex,currentWidth] _ GetFont[pfp,trailer.FontSet*16+EL[i]-ELFont,pressPage]; currentFontRotated _ SELECT pressPage.FontDir[currentFontIndex].Rotation/60 FROM 90,270 => TRUE, ENDCASE => FALSE; currentHeight _ pressPage.FontDir[currentFontIndex].PointSize*(2540/72); END; ELSkipControlBytesImmediate=> i_i+EL[i+1]+1; ELAlternative=> IF AlternativeOn THEN BEGIN last: BOOLEAN _ TRUE; j: CARDINAL; FOR j IN [1..10] DO IF EL[j]#0 THEN BEGIN last_FALSE;EXIT;END;ENDLOOP; IF last THEN AlternativeOn _ FALSE; Skip[EL[i+9]*256+EL[i+10]]; i_i+10+EL[i+5]*256+EL[i+6]; END ELSE BEGIN AlternativeOn _ TRUE;i_i+10; END; ELOnlyOnCopy=> MiscDefs.CallDebugger["ELOnlyOnCopy"]; ELSetX=> BEGIN i_i+2;micaX_trailer.Xe+EL[i-1]*256+EL[i];END; ELSetY=> BEGIN i_i+2;micaY_trailer.Ye+EL[i-1]*256+EL[i];END; ELShowCharacters=> BEGIN i_i+1; DoChars[EL[i]]; END; ELSkipCharacters=> BEGIN i_i+1;Skip[EL[i]];END; ELSkipControlBytes=> BEGIN Skip[EL[i+1]*256+EL[i+2]];i_i+3;END; ELShowCharacterImmediate=> BEGIN i_i+1;DoCharImmediate[];END; ELSetSpaceX=> BEGIN i_i+2;spaceX_EL[i-1]*256+EL[i];END; ELSetSpaceY=> BEGIN i_i+2;spaceY_EL[i-1]*256+EL[i];END; ELResetSpace=> spaceX_177777B; ELSpace=> BEGIN micaX _ micaX+spaceX;micaY_micaY+spaceY;END; ELSetBrightness=> BEGIN currentBr _ EL[i+1];i_i+1;END; ELSetHue=> BEGIN currentHue _ EL[i+1];i_i+1;END; ELSetSaturation=> BEGIN currentSat _ EL[i+1];i_i+1;END; ELShowObject=> BEGIN nWords: CARDINAL _ EL[i+1]*256 + EL[i+2]; savedMicaX: CARDINAL _ micaX; savedMicaY: CARDINAL _ micaY; micaX _ trailer.Xe;micaY _ trailer.Ye; AddPressObject[ELShowObject,nWords*2]; UNTIL nWords <= 0 DO IF Read[] # 0 THEN ERROR; SELECT Read[] FROM DLMoveTo,DLDrawTo => BEGIN x: CARDINAL _ micaX + Read[]*256 + Read[]; y: CARDINAL _ micaY + Read[]*256 + Read[]; pressPage.leftX _ MIN[pressPage.leftX,x]; pressPage.bottomY _ MIN[pressPage.bottomY,y]; pressPage.rightX _ MAX[pressPage.rightX,x]; pressPage.topY _ MAX[pressPage.topY,y]; nWords _ nWords-3; END; DLDrawCurve => BEGIN Skip[12*2]; nWords _ nWords-13; END; ENDCASE => ERROR; ENDLOOP; micaX _ savedMicaX;micaY _ savedMicaY; i_i+2; END; ELShowDots,ELShowDotsOpaque=> --EL[i] tells which BEGIN DotsData: POINTER TO PressDotsData; nWords: CARDINAL _ EL[i+3]*256 + EL[i+4]; AddPressObject[EL[i],0]; --nDataBytes not used for dots DotsData _ LOOPHOLE[lastLink+SIZE[PressObject]]; --double skip (Skip works on bytes) to handle larger files Skip[nWords]; Skip[nWords]; THROUGH [1..EL[i+2]] DO Skip[100000B]; Skip[100000B]; Skip[100000B]; Skip[100000B]; ENDLOOP; i_i+4; --find bounding box GetPressDotsData[lastLink,DotsData]; pressPage.leftX _ MIN[pressPage.leftX,lastLink.micaX]; pressPage.bottomY _ MIN[pressPage.bottomY,lastLink.micaY]; pressPage.rightX _ MAX[pressPage.rightX,lastLink.micaX+DotsData.micaWidth]; pressPage.topY _ MAX[pressPage.topY,lastLink.micaY+DotsData.micaHeight]; END; ELShowRectangle=> BEGIN width: CARDINAL _ EL[i+1]*256+EL[i+2]; height: CARDINAL _ EL[i+3]*256+EL[i+4]; AddPressObject[ELShowRectangle,0]; lastLink.spaceX _ width; lastLink.spaceY _ height; i_i+4; pressPage.leftX _ MIN[pressPage.leftX,micaX]; pressPage.bottomY _ MIN[pressPage.bottomY,micaY]; pressPage.rightX _ MAX[pressPage.rightX,micaX+width]; pressPage.topY _ MAX[pressPage.topY,micaY+height]; END; ELNop=> NULL; ENDCASE=>NULL; IF userProc # 0 THEN Proc[pressPage]; ENDLOOP; --for all EL commands END; END. \f1b177B100b16B238b5B123b5B2244b12B1158b159B1089b2B26b2B12b2B17b8B177b12B94b9B61b12B238b18B406b24B235b13B1386b127B633b13B259b19B1995b16B676b7B275b1B13b1B2417b15B1042b5B133b15B22b121B338b65B8b7B868b4B97b14B146b117B548b4B2690b39B