<> <> DIRECTORY PressReader, Real, Rope, SirPress, TSArtwork, TSOutputPress, TextNode, TSGraphic, IO, TSOutput, TSTypes USING [Dimn, zeroDimn, RealDimn, DimnRatio, bp, Dimensions]; TSIncludePressImpl: CEDAR PROGRAM IMPORTS PressReader, Real, Rope, SirPress, TSArtwork, TextNode, IO, TSTypes = BEGIN OPEN TSTypes; bytesPerPage: NAT ~ 512; -- as per press file format. micasPerPoint: REAL = 2540.0/72.0; pointsPerMica: REAL = 72.0/2540.0; ObjectFromBranchProc: TYPE = TSArtwork.ObjectFromBranchProc; ROPE: TYPE = Rope.ROPE; IncludePressRec: TYPE = RECORD [pressFileName: ROPE, topMargin, leftMargin, height, width: REAL]; Break: PROC [char: CHAR] RETURNS [IO.CharClass] = { IF char = ': THEN RETURN [break]; IF char = ' OR char = ' OR char = ', OR char = '; OR char = '\n THEN RETURN [sepr]; RETURN [other]; }; GetName: PROC [stream: IO.STREAM] RETURNS [name: ROPE] ~ { name _ NIL; name _ IO.GetTokenRope[stream, Break ! IO.EndOfStream => CONTINUE].token; }; GetBP: PROC [stream: IO.STREAM] RETURNS [REAL] = { r: REAL _ IO.GetReal[stream]; unit: ROPE _ GetName[stream]; multipler: REAL _ SELECT TRUE FROM unit.Equal["in"] => 72.0, unit.Equal["pt"] => 72.0/72.27, unit.Equal["cm"] => 72.0/2.54, unit.Equal["mm"] => 72.0/25.4, unit.Equal["bp"] => 1.0, ENDCASE => 0.0; IF multipler = 0.0 THEN ERROR; RETURN [r*multipler]; }; IncludePressFromBranch: ObjectFromBranchProc = { data: REF IncludePressRec _ NEW[IncludePressRec]; textNode: TextNode.RefTextNode _ TextNode.NarrowToTextNode[node]; nodeContents: ROPE _ textNode.rope; stream: IO.STREAM _ IO.RIS[nodeContents]; data.pressFileName _ GetName[stream]; FOR i: NAT IN [0..4) DO keyword: ROPE _ GetName[stream]; colon: ROPE _ GetName[stream]; IF colon.Equal[":"] THEN NULL ELSE ERROR; SELECT TRUE FROM keyword.Equal["TopMargin", FALSE] => data.topMargin _ GetBP[stream]; keyword.Equal["LeftMargin", FALSE] => data.leftMargin _ GetBP[stream]; keyword.Equal["Height", FALSE] => data.height _ GetBP[stream]; keyword.Equal["Width", FALSE] => data.width _ GetBP[stream]; ENDCASE => ERROR; ENDLOOP; object _ NEW[TSGraphic.ObjectRec]; object.paintProc _ IncludePressPaint; object.layoutProc _ IncludePressLayout; object.data _ data; }; IncludePressLayout: TSGraphic.LayoutProc = { data: REF IncludePressRec _ NARROW[self.data]; extent _ [zeroDimn, RealDimn[data.width, bp], zeroDimn, RealDimn[data.height, bp]]; }; IncludePressPaint: TSGraphic.PaintProc = { data: REF IncludePressRec _ NARROW[self.data]; handle: TSOutput.Handle _ NARROW[context]; pressState: TSOutputPress.PressState _ NARROW[handle.outputState]; pressHandle: SirPress.PressHandle _ pressState.pressHandle; pressFile: PressReader.Handle _ PressReader.OpenPressFile[data.pressFileName]; fontTable: REF ARRAY [0..6*16) OF PressReader.FontDirectoryEntry _ NEW[ARRAY [0..6*16) OF PressReader.FontDirectoryEntry]; xTranslate: INT _ Real.RoundLI[(DimnRatio[originX, bp] - data.leftMargin)*micasPerPoint]; yTranslate: INT _ Real.RoundLI[(DimnRatio[originY, bp] - (11*72-data.topMargin))*micasPerPoint]; FontInitProc: PressReader.FontEntryProc = { -- build a list of needed fonts fontTable[fontDirectoryEntry.fontSet*16 + fontDirectoryEntry.font] _ fontDirectoryEntry; }; -- FontInitProc PageProc: PressReader.PageProc = { EntityProc: PressReader.EntityProc = { -- Xe, Ye, fontSet xe: INT _ entityTrailer.Xe + xTranslate; ye: INT _ entityTrailer.Ye + yTranslate; x: INT _ xe; y: INT _ ye; currentFont: PressReader.FontDirectoryEntry; -- will be established by setFont currentSpaceX, currentSpaceY: INT; -- will be established by setFont hue: REAL _ 0.0; saturation: REAL _ 1.0; brightness: REAL _ 0.0; skipAlternative, inAlternative: BOOL _ FALSE; reposition: BOOLEAN _ FALSE; showCharactersProc: PressReader.ShowCharactersProc = { IF skipAlternative THEN RETURN; IF reposition THEN {pressHandle.PutText[text, x, y]; reposition _ FALSE} ELSE pressHandle.PutTextHere[text]; }; -- showCharactersProc fontProc: PressReader.FontProc = { IF skipAlternative THEN RETURN; currentFont _ fontTable[entityTrailer.fontSet*16+font]; IF currentFont.family.Length # 0 THEN pressHandle.SetFont[currentFont.family, currentFont.size, currentFont.face.encoding, currentFont.rotation]; }; positionProc: PressReader.PositionProc = { IF skipAlternative THEN RETURN; IF opCode = setX THEN x _ xe + value ELSE y _ ye + value; reposition _ TRUE; }; spacingProc: PressReader.SpacingProc = { IF skipAlternative THEN RETURN; SELECT opCode FROM setSpaceX, setSpaceXShort => currentSpaceX _ value; setSpaceY, setSpaceYShort => currentSpaceY _ value; resetSpace => { currentSpaceX _ 200; currentSpaceY _ 0; }; ENDCASE => ERROR; IF opCode = resetSpace THEN pressHandle.ResetSpace ELSE pressHandle.SetSpace[currentSpaceX, currentSpaceY]; }; spaceProc: PressReader.SpaceProc = { showCharactersProc[showCharacterImmediate, 1, " "]; }; colorProc: PressReader.ColorProc = { IF skipAlternative THEN RETURN; SELECT opCode FROM setHue => pressHandle.SetHue[value]; setSaturation => pressHandle.SetSaturation[value]; setBrightness => pressHandle.SetBrightness[value]; ENDCASE => ERROR; }; showRectangleProc: PressReader.ShowRectangleProc = { IF skipAlternative THEN RETURN; pressHandle.PutRectangle[x, y, width, height]; }; alternativeProc: PressReader.AlternativeProc = { IF (types = 0) AND (elBytes = 0) AND (dlBytes = 0) THEN inAlternative _ skipAlternative _ FALSE ELSE IF inAlternative THEN skipAlternative _ TRUE ELSE inAlternative _ TRUE; }; showObjectProc: PressReader.ShowObjectProc = { moveToProc: PressReader.MoveToProc = {pressHandle.PutMoveTo[x: x+xe, y: y+ye]}; drawToProc: PressReader.DrawToProc = {pressHandle.PutDrawTo[x: x+xe, y: y+ye]}; drawCurveProc: PressReader.DrawCurveProc = { pressHandle.PutCubic[cX, cY, bX, bY, aX, aY]; }; IF skipAlternative THEN RETURN; pressHandle.StartOutline; pressFile.GetObject[moveToProc, drawToProc, drawCurveProc]; pressHandle.EndOutline; }; -- showObjectProc showDotsProc: PressReader.ShowDotsProc = { codingType, dotsPerLine, scanLines, passDots, displayDots, passLines, displayLines: INT _ 0; scanMode: CARDINAL _ 0; windowWidth, windowHeight: INT _ 0; dotInfo: PressReader.Dots; samplingInfo: LIST OF PressReader.SamplingProperty _ NIL; setCodingProc: PressReader.SetCodingProc = { codingType _ code; windowWidth _ dotsPerLine _ displayDots _ dots; windowHeight _ scanLines _ displayLines _ lines; }; setModeProc: PressReader.SetModeProc = {scanMode _ mode}; setWindowProc: PressReader.SetWindowProc = { passDots _ pd; displayDots _ dd; passLines _ pl; displayLines _ dl; }; setSizeProc: PressReader.SetSizeProc = { windowWidth _ width; windowHeight _ height; }; setSamplingPropertiesProc: PressReader.SetSamplingPropertiesProc = { samplingInfo _ samplingProperties; }; dotsFollowProc: PressReader.DotsFollowProc = { dotInfo _ dots; }; ScratchRec: TYPE ~ RECORD [SEQUENCE length: NAT OF WORD]; scratch: REF ScratchRec; bytesPerLine: INT _ 0; IF skipAlternative THEN RETURN; pressFile.GetDots[setCodingProc, setModeProc, setWindowProc, setSizeProc, setSamplingPropertiesProc, dotsFollowProc]; scratch _ NEW[ScratchRec[(dotsPerLine+3)/2]]; pressHandle.BeginScannedRectangle[ x: x, y: y, dotsPerLine: dotsPerLine, numberOfLines: scanLines, width: windowWidth, height: windowHeight, nextLineDirection: LOOPHOLE[scanMode MOD 4], nextDotDirection: LOOPHOLE[scanMode / 4], coding: SELECT codingType FROM 0 => bitMap, 1 => bitSampled, 2 => bitBitSampled, 4 => nybbleSampled, 8 => byteSampled, ENDCASE => ERROR ]; bytesPerLine _ (MAX[codingType, 1] * dotsPerLine + 7)/8; scratch[bytesPerLine/2] _ 0; -- make sure array is big enough dotInfo.file.SetIndex[INT[dotInfo.pageNumber]*bytesPerPage+dotInfo.byteOffset]; FOR i: INT IN [0..scanLines) DO TRUSTED {[] _ dotInfo.file.UnsafeGetBlock[[base: (LOOPHOLE[@scratch[0]]), startIndex: 0, count: bytesPerLine]]}; TRUSTED {pressHandle.UnsafeShowLine[@scratch[0]]}; ENDLOOP; pressHandle.EndScannedRectangle; }; -- showDotsProc fontProc[0]; pressHandle.SetColor[0, 0, 0]; pressFile.GetCommands[ showCharactersProc: showCharactersProc, fontProc: fontProc, positionProc: positionProc, spacingProc: spacingProc, spaceProc: spaceProc, colorProc: colorProc, showRectangleProc: showRectangleProc, alternativeProc: alternativeProc, showObjectProc: showObjectProc, showDotsProc: showDotsProc ]; }; -- EntityProc pressFile.GetPage[EntityProc]; }; -- PageProc SkipFonts: PressReader.FontDirectoryProc = { }; pressFile.GetFonts[FontInitProc]; pressFile.GetParts[pageNumber, PageProc, SkipFonts]; pressFile.ClosePressFile[]; }; pageNumber: INT _ 1; TSArtwork.Register["IncludePress", IncludePressFromBranch]; END.