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]; }; 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 ]; 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. ShowPressImpl.mesa Last edited by Shore; December 7, 1982 1:38 pm Last Edited by: Beach, September 13, 1983 5:54 pm NOTE: the following code is a complete hack!!!! It is included only because of the Tioga -> Laurel -> (Timesroman) inconsistency in Cedar/Tioga screen fonts and the current Tioga TSetter. BE IT KNOWN: I'm ashamed of myself!!! ! VFonts.Error => SELECT code FROM VFonts.ErrorCode[fontNotFound] => ERROR ShowPressError[CantFindFonts, viewer]; ENDCASE => ERROR; ]; Cull unrotated characters obviously outside the context Cull dots obviously outside the context Change Log Created by Andrew Shore; September 13, 1982 6:45 pm Changed by Shore; October 14, 1982 10:03 pm converted to Cedar 3.4 (Graphics.Path operations) Changed by Shore; December 4, 1982 12:10 am converted to Cedar.Style Edited on December 7, 1982 1:37 pm, by Shore added Graphics.SetFat so thin lines will show changes to: DIRECTORY, DrawPressPage Edited on September 13, 1983 5:46 pm, by Beach changes to: showCharactersProc to provide faster culling of characters obviously outside the context, fontProc to establish the culling bounds for the current font, showDotsProc to provide faster culling of dots obviously outside the context  "cedar" stylehead1 "cedar" stylecJ "cedar" style..J "cedar" style1unit "cedar" stylek J "cedar" style"/J "cedar" style J "cedar" styleJ "cedar" style!J "cedar" style ?OJ "cedar" style J "cedar" style[pJ "cedar" styleJ "cedar" style(J "cedar" style J "cedar" style%1 "cedar" stylen J "cedar" style_fJ "cedar" style J "cedar" style J "cedar" styleJ "cedar" style J "cedar" styleJ "cedar" style"J "cedar" style"J "cedar" styleJ "cedar" style0 "cedar" style  MJ "cedar" styleJ "cedar" style_ "cedar" style !LJ "cedar" styleJ "cedar" style J "cedar" styleJ "cedar" style J "cedar" style "cedar" style #0J "cedar" style733 J "cedar" styleJ "cedar" style "cedar" style%J "cedar" style''J "cedar" style)< "cedar" styleJ "cedar" style)IJ "cedar" style0J "cedar" style "cedar" stylebJ "cedar" style "cedar" style1@J "cedar" style))J "cedar" styleJ "cedar" styleJ "cedar" style.2J "cedar" style "cedar" styleJ "cedar" styleJ "cedar" styleJ "cedar" style..J "cedar" style11 "cedar" style "cedar" style""J "cedar" style"'NJ "cedar" styleJ "cedar" styleJ "cedar" styleAJ "cedar" styleJ "cedar" style >J "cedar" styleJ "cedar" style "cedar" style $J "cedar" style "cedar" style J "cedar" style4J "cedar" style5J "cedar" style6J "cedar" style6J "cedar" styleJ "cedar" styleJ "cedar" style "cedar" style $J "cedar" styleJ "cedar" style "cedar" styleJ "cedar" style"J "cedar" style0J "cedar" style0J "cedar" styleJ "cedar" style>>J "cedar" style""J "cedar" style "cedar" style#4J "cedar" styleJ "cedar" styleAJ "cedar" style "cedar" style!0 "cedar" style 7J "cedar" style"'J "cedar" style1J "cedar" styleJ "cedar" style "cedar" style .J "cedar" style)L "cedar" style mL "cedar" style hr "cedar" style ,J "cedar" style J "cedar" styleJ "cedar" style&& "cedar" style/J "cedar" style J "cedar" style@@J "cedar" style@@J "cedar" styleBB "cedar" styleJ "cedar" style J "cedar" style!!J "cedar" style%%J "cedar" styleJ "cedar" styleJ "cedar" styleBBJ "cedar" style9?J "cedar" style "cedar" style *J "cedar" style^fJ "cedar" style&J "cedar" styleJ "cedar" styleJ "cedar" style- "cedar" style -J "cedar" styleJ "cedar" style//J "cedar" style00J "cedar" styleL "cedar" style /: "cedar" style ,J "cedar" styleJ "cedar" styleJ "cedar" styleJ "cedar" styleJ "cedar" style "cedar" style (J "cedar" style(J "cedar" style*J "cedar" style "cedar" style .J "cedar" styleJ "cedar" styleJ "cedar" styleJJ "cedar" styleaa "cedar" styleJ "cedar" style'J0J J%-EJJ "cedar" style""J "cedar" styleJ "cedar" styleJ "cedar" styleJ "cedar" styleJ "cedar" style J "cedar" styleJ "cedar" styleJ "cedar" styleJ "cedar" styleJ "cedar" style "cedar" styleJ "cedar" style*J "cedar" styleJ "cedar" style6J "cedar" style**J "cedar" style J "cedar" style "cedar" styleJ "cedar" styleJ "cedar" styleJ "cedar" styleJ "cedar" style' "cedar" style4J "cedar" style''J "cedar" styleJ "cedar" styleJ "cedar" styleJ "cedar" styleJ "cedar" styleJ "cedar" style%J "cedar" style!J "cedar" styleJ "cedar" styleJ "cedar" styleJ "cedar" style J "cedar" styleJ "cedar" style#J "cedar" style L "cedar" style,, "cedar" style J "cedar" styleCJ "cedar" style&J "cedar" style99J "cedar" styleJStartOfExpansion[]J)/J "cedar" style99J "cedar" style "cedar" style *J "cedar" style J "cedar" style*J "cedar" styleJ "cedar" styleJ "cedar" style "cedar" style J "cedar" style3J "cedar" style "cedar" style+J "cedar" style1J+JJ,,J-J$$J.J rF 5@JJJ+P