<> <> <> DIRECTORY CGCubic USING [Bezier, Coeffs, CoeffsToBezier], Graphics, GraphicsBasic USING [Vec], GraphicsColor USING [HSVToColor], PressImage USING [DrawPressImage, MakePressImage, PressImage, PressImageError], PressReader, PressFontReader USING [CharInfo, Close, EnumerateDirectory, Font, FromFile, GetCharInfo, Handle, VisitFontProc], Real USING [Fix, RoundC], Rope USING [Equal, Fetch, Length, ROPE], ShowPress, VFonts USING [EstablishFont, Font, GraphicsFont]; ShowPressImpl: PROGRAM IMPORTS CGCubic, Graphics, GraphicsColor, PressImage, PressReader, PressFontReader, Real, Rope, VFonts EXPORTS ShowPress SHARES Graphics = BEGIN OPEN ShowPress; micasPerPoint: REAL = 2540.0/72.0; pointsPerMica: REAL = 72.0/2540.0; ShowPressError: PUBLIC ERROR[code: Code] = CODE; Open: PUBLIC PROCEDURE [fileName: Rope.ROPE] RETURNS [show: Handle _ NIL] = { pressFile: PressReader.Handle; pressFontFile: PressFontReader.Handle _ PressFontReader.FromFile["/Indigo/Fonts/Fonts.Widths"]; FontInitProc: PressReader.FontEntryProc = { -- build a list of needed fonts sizeInPoints: CARDINAL; sizeInMicas: REAL; font: VFonts.Font; pressFont: PressFontReader.Font; screenFontFamily: Rope.ROPE; VisitFontProc: PressFontReader.VisitFontProc = { IF Rope.Equal[fontRec.family, fontDirectoryEntry.family, FALSE] AND (fontRec.face = fontDirectoryEntry.face.encoding) AND ((fontRec.size = 0) OR (fontRec.size = REAL[sizeInMicas]*(1.0E-5))) AND ((fontRec.rotation = fontDirectoryEntry.rotation) OR ((fontRec.rotation = 0) AND (fontDirectoryEntry.rotation MOD 5400 = 0))) THEN RETURN[quit: TRUE]; }; IF fontDirectoryEntry.size > 0 THEN { sizeInPoints _ fontDirectoryEntry.size; sizeInMicas _ (REAL[fontDirectoryEntry.size]*2540.0)/72.0; } ELSE { sizeInPoints _ Real.RoundC[(REAL[-fontDirectoryEntry.size]*72.0)/2540.0]; sizeInMicas _ REAL[-fontDirectoryEntry.size]; }; < Laurel -> (Timesroman) inconsistency in Cedar/Tioga screen fonts and the current Tioga TSetter. BE IT KNOWN: I'm ashamed of myself!!!>> IF Rope.Equal[fontDirectoryEntry.family, "LAUREL", FALSE] THEN { fontDirectoryEntry.family _ "TIMESROMAN"; screenFontFamily _ "TIOGA"; } ELSE screenFontFamily _ fontDirectoryEntry.family; font _ VFonts.EstablishFont[ family: screenFontFamily, size: sizeInPoints, bold: (fontDirectoryEntry.face.weight = bold), italic: (fontDirectoryEntry.face.slope = italic), defaultOnFailure: TRUE ]; < SELECT code FROM>> < ERROR ShowPressError[CantFindFonts, viewer];>> < ERROR;>> <<];>> pressFont _ show.pressFontFile.EnumerateDirectory[VisitFontProc]; IF pressFont = NIL THEN ERROR ShowPressError[CantFindFonts]; show.fontTable[fontDirectoryEntry.fontSet*16+fontDirectoryEntry.font] _ [ screenFont: VFonts.GraphicsFont[font], pressFont: pressFont, size: sizeInMicas, rotation: REAL[fontDirectoryEntry.rotation]/60.0 ]; }; -- FontInitProc pressFile _ PressReader.OpenPressFile[fileName ! PressReader.PressReaderError => { SELECT errorCode FROM FileNotAvailableForRead, FileNotAPressFile => ERROR ShowPressError[CantReadFile]; ENDCASE => REJECT; } ]; show _ NEW[PressFileRec _ [pressFile: pressFile, pressFontFile: pressFontFile, lastPart: pressFile.GetDocumentDirectory[].nParts]]; show.pressFile.GetFonts[FontInitProc]; }; -- Open DrawPressPage: PUBLIC PROCEDURE [context: Graphics.Context, show: Handle, pageNumber: INT, tinyPaint: BOOL _ FALSE] = { PageProc: PressReader.PageProc = { EntityProc: PressReader.EntityProc = { -- Xe, Ye, fontSet x: INT _ entityTrailer.Xe; y: INT _ entityTrailer.Ye; currentFont: FontRec; -- will be established by setFont currentFontYMin, currentFontYMax: REAL; -- for faster culling of characters currentSpaceX, currentSpaceY: INT; -- will be established by setFont hue: REAL _ 0.0; saturation: REAL _ 1.0; brightness: REAL _ 0.0; skipAlternative, inAlternative: BOOL _ FALSE; showCharactersProc: PressReader.ShowCharactersProc = { c: CHAR; i: INT; charInfo: PressFontReader.CharInfo; dx, dy: INT; IF skipAlternative THEN RETURN; IF tinyPaint THEN { xw, yw: INT _ 0; path: Graphics.Path; FOR i IN [0..text.Length[]) DO c _ text.Fetch[i]; IF c = ' THEN { xw _ xw+currentSpaceX; yw _ yw+currentSpaceY; } ELSE { charInfo _ PressFontReader.GetCharInfo[currentFont.pressFont, c]; xw _ xw+Real.Fix[charInfo.widthX*currentFont.size]; yw _ yw+Real.Fix[charInfo.widthY*currentFont.size]; }; ENDLOOP; Graphics.MoveTo[path, x, y]; SELECT currentFont.rotation FROM 0.0 => { x _ x+xw; y _ y+yw }; 90.0 => { x _ x-yw; y _ y+xw }; 180.0 => { x _ x-xw; y _ y-yw }; 270.0 => { x _ x+yw; y _ y-xw }; ENDCASE => ERROR; Graphics.LineTo[path, x, y]; Graphics.DrawStroke[context, path]; } ELSE { <> IF currentFont.rotation = 0.0 THEN { box: Graphics.Box _ Graphics.GetBounds[context]; cpX, cpY: REAL; [cpX, cpY] _ Graphics.GetCP[context]; IF box.ymax < cpY+currentFontYMin OR box.ymin > cpY+currentFontYMax THEN RETURN; }; FOR i IN [0..text.Length[]) DO c _ text.Fetch[i]; IF c = ' THEN { dx _ currentSpaceX; dy _ currentSpaceY; } ELSE { mark: Graphics.Mark _ Graphics.Save[context]; charInfo _ PressFontReader.GetCharInfo[currentFont.pressFont, c]; Graphics.Scale[context, micasPerPoint, micasPerPoint]; Graphics.Rotate[context, currentFont.rotation]; Graphics.DrawChar[context, c, currentFont.screenFont]; Graphics.Restore[context, mark]; dx _ Real.Fix[charInfo.widthX*currentFont.size]; dy _ Real.Fix[charInfo.widthY*currentFont.size]; }; SELECT currentFont.rotation FROM 0.0 => { x _ x+dx; y _ y+dy }; 90.0 => { x _ x-dy; y _ y+dx }; 180.0 => { x _ x-dx; y _ y-dy }; 270.0 => { x _ x+dy; y _ y-dx }; ENDCASE => ERROR; Graphics.SetCP[context, x, y]; ENDLOOP; }; }; -- showCharactersProc fontProc: PressReader.FontProc = { IF skipAlternative THEN RETURN; currentFont _ show.fontTable[entityTrailer.fontSet*16+font]; IF currentFont.screenFont # NIL THEN { [ymin: currentFontYMin, ymax: currentFontYMax] _ Graphics.FontBox[currentFont.screenFont]; currentFontYMin _ micasPerPoint * currentFontYMin; currentFontYMax _ micasPerPoint * currentFontYMax; } ELSE { currentFontYMin _ FIRST[INTEGER]; currentFontYMax _ LAST[INTEGER]; }; IF currentFont.pressFont = NIL THEN RETURN; spacingProc[resetSpace, 0]; }; positionProc: PressReader.PositionProc = { IF skipAlternative THEN RETURN; IF opCode = setX THEN x _ entityTrailer.Xe + value ELSE y _ entityTrailer.Ye + value; Graphics.SetCP[context, x, y]; }; spacingProc: PressReader.SpacingProc = { IF skipAlternative THEN RETURN; IF currentFont.pressFont = NIL THEN ERROR; SELECT opCode FROM setSpaceX, setSpaceXShort => currentSpaceX _ value; setSpaceY, setSpaceYShort => currentSpaceY _ value; resetSpace => { charInfo: PressFontReader.CharInfo _ PressFontReader.GetCharInfo[currentFont.pressFont, ' ]; currentSpaceX _ Real.Fix[charInfo.widthX*currentFont.size]; currentSpaceY _ Real.Fix[charInfo.widthY*currentFont.size]; }; ENDCASE => ERROR; }; spaceProc: PressReader.SpaceProc = { IF skipAlternative THEN RETURN; SELECT currentFont.rotation FROM 0.0 => { x _ x+currentSpaceX; y _ y+currentSpaceY }; 90.0 => { x _ x-currentSpaceY; y _ y+currentSpaceX }; 180.0 => { x _ x-currentSpaceX; y _ y-currentSpaceY }; 270.0 => { x _ x+currentSpaceY; y _ y-currentSpaceX }; ENDCASE => ERROR; Graphics.SetCP[context, x, y]; }; colorProc: PressReader.ColorProc = { color: Graphics.Color; IF skipAlternative THEN RETURN; SELECT opCode FROM setHue => hue _ REAL[value]/255.0; setSaturation => saturation _ REAL[value]/255.0; setBrightness => brightness _ REAL[value]/255.0; ENDCASE => ERROR; color _ GraphicsColor.HSVToColor[hue, saturation, brightness]; Graphics.SetColor[context, color]; }; showRectangleProc: PressReader.ShowRectangleProc = { IF skipAlternative THEN RETURN; Graphics.DrawBox[context, Graphics.Box[x, y, x+width, y+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 = { path: Graphics.Path _ Graphics.NewPath[]; moveToProc: PressReader.MoveToProc = {Graphics.MoveTo[self: path, x: x+entityTrailer.Xe, y: y+entityTrailer.Ye, flush: FALSE];}; drawToProc: PressReader.DrawToProc = {Graphics.LineTo[self: path, x: x+entityTrailer.Xe, y: y+entityTrailer.Ye];}; drawCurveProc: PressReader.DrawCurveProc = { lpX, lpY: REAL; bezier: CGCubic.Bezier; [lpX, lpY] _ Graphics.LastPoint[path]; bezier _ CGCubic.CoeffsToBezier[CGCubic.Coeffs[ c0: GraphicsBasic.Vec[lpX, lpY], c1: GraphicsBasic.Vec[cX+entityTrailer.Xe, cY+entityTrailer.Ye], c2: GraphicsBasic.Vec[bX+entityTrailer.Xe, bY+entityTrailer.Ye], c3: GraphicsBasic.Vec[aX+entityTrailer.Xe, aY+entityTrailer.Ye]]]; Graphics.CurveTo[self: path, x1: bezier.b1.x, y1:bezier.b1.y, x2: bezier.b2.x, y2: bezier.b2.y, x3: bezier.b3.x, y3: bezier.b3.y]; }; IF skipAlternative THEN RETURN; show.pressFile.GetObject[[moveToProc, drawToProc, drawCurveProc]]; Graphics.DrawArea[self: context, path: path, parityFill: TRUE]; }; -- showObjectProc showDotsProc: PressReader.ShowDotsProc = { codingType, dotsPerLine, scanLines, scanMode, passDots, displayDots, passLines, displayLines: INT _ 0; windowWidth, windowHeight: REAL _ 0.0; dotInfo: PressReader.Dots; image: PressImage.PressImage; mark: Graphics.Mark _ Graphics.Save[context]; 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 _ REAL[width]*pointsPerMica; windowHeight _ REAL[height]*pointsPerMica; }; dotsFollowProc: PressReader.DotsFollowProc = { dotInfo _ dots; }; IF skipAlternative THEN RETURN; show.pressFile.GetDots[[setCodingProc, setModeProc, setWindowProc, setSizeProc, dotsFollowProc]]; { <> box: Graphics.Box _ Graphics.GetBounds[context]; cpX, cpY: REAL; [cpX, cpY] _ Graphics.GetCP[context]; IF box.ymax < cpY OR box.ymin > cpY+(windowHeight*micasPerPoint) THEN RETURN; }; image _ PressImage.MakePressImage[ sampleType: codingType, dots: dotsPerLine, lines: scanLines, mode: scanMode, pd: passDots, dd: displayDots, pl: passLines, dl: displayLines, width: windowWidth, height: windowHeight, bits: dotInfo ! PressImage.PressImageError => GOTO Quit ]; Graphics.Scale[context, micasPerPoint, micasPerPoint]; PressImage.DrawPressImage[context, image]; Graphics.Restore[context, mark]; EXITS Quit => RETURN; }; -- showDotsProc fontProc[0]; -- SetFont 0; ResetSpace; show.pressFile.GetCommands[PressReader.CommandProcs[ showCharactersProc: showCharactersProc, fontProc: fontProc, positionProc: positionProc, spacingProc: spacingProc, spaceProc: spaceProc, colorProc: colorProc, showRectangleProc: showRectangleProc, alternativeProc: alternativeProc, showObjectProc: showObjectProc, showDotsProc: showDotsProc]]; }; -- EntityProc show.pressFile.GetPage[EntityProc]; }; -- PageProc SkipFonts: PressReader.FontDirectoryProc = { pageNumber _ IF pageNumber = show.lastPart THEN ERROR ShowPressError[NoSuchPage] ELSE MIN[pageNumber+1, show.lastPart]; show.pressFile.GetParts[pageNumber, PageProc, SkipFonts]; }; [] _ Graphics.SetFat[self: context, fat: TRUE]; show.pressFile.GetParts[pageNumber, PageProc, SkipFonts]; }; -- DrawPressPage Close: PUBLIC PROCEDURE [show: Handle] = { show.pressFile.ClosePressFile[]; PressFontReader.Close[show.pressFontFile]; }; END. <> <> <<>> <> <> <<>> <> <> <<>> <> <> <> <<>> <> <> <<>> <<>> <<>>