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, RoundLI], 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; pressFontFileName: Rope.ROPE _ "/Indigo/Fonts/TeX/Fonts.Widths"; ShowPressError: PUBLIC ERROR[code: Code] = CODE; Open: PUBLIC PROCEDURE [fileName: Rope.ROPE] RETURNS [show: Handle _ NIL] = { pressFile: PressReader.Handle; pressFontFile: PressFontReader.Handle _ PressFontReader.FromFile[pressFontFileName]; 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 (ABS[fontRec.size - REAL[sizeInMicas]*(1.0E-5)] < 0.00002)) 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]; 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 { IF currentFont.pressFont # NIL THEN { charInfo _ PressFontReader.GetCharInfo[currentFont.pressFont, c]; xw _ xw+Real.Fix[charInfo.widthX*currentFont.size]; yw _ yw+Real.Fix[charInfo.widthY*currentFont.size]; } ELSE xw _ yw _ 0; }; 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 { IF currentFont.pressFont # NIL THEN { 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]; } ELSE dx _ dy _ 0; }; 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 currentSpaceX _ currentSpaceY _ 0 ELSE 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; cubic: CGCubic.Coeffs; bezier: CGCubic.Bezier; [lpX, lpY] _ Graphics.LastPoint[path]; cubic _ [ c0: GraphicsBasic.Vec[lpX, lpY], c1: GraphicsBasic.Vec[aX, aY], c2: GraphicsBasic.Vec[bX, bY], c3: GraphicsBasic.Vec[cX, cY] ]; bezier _ CGCubic.CoeffsToBezier[cubic]; Graphics.CurveTo[self: path, x1: Real.RoundLI[bezier.b1.x], y1: Real.RoundLI[bezier.b1.y], x2: Real.RoundLI[bezier.b2.x], y2: Real.RoundLI[bezier.b2.y], x3: Real.RoundLI[bezier.b3.x], y3: Real.RoundLI[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 Copyright c 1985 by Xerox Corporation. All rights reserved. Last edited by Shore; December 7, 1982 1:38 pm Last Edited by: Beach, September 13, 1983 5:54 pm Last Edited by: Plass, February 14, 1984 11:27:58 am PST Last Edited by: Beach, March 11, 1985 3:43:08 pm PST 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; ]; IF pressFont = NIL THEN ERROR ShowPressError[CantFindFonts]; 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 Edited on February 14, 1984 11:26:48 am PST, by Plass changes to: drawCurveProc to handle spline outlines correctly Beach, March 11, 1985 3:43:10 pm PST changes to: DIRECTORY, ShowPressImpl, IMPORTS, EXPORTS, SHARES, =, Open, FontInitProc (local of Open), VisitFontProc (local of FontInitProc, local of Open), DrawPressPage, PageProc (local of DrawPressPage), EntityProc (local of PageProc, local of DrawPressPage), showCharactersProc (local of EntityProc, local of PageProc, local of DrawPressPage), fontProc (local of EntityProc, local of PageProc, local of DrawPressPage), positionProc (local of EntityProc, local of PageProc, local of DrawPressPage), spacingProc (local of EntityProc, local of PageProc, local of DrawPressPage), spaceProc (local of EntityProc, local of PageProc, local of DrawPressPage), colorProc (local of EntityProc, local of PageProc, local of DrawPressPage), showRectangleProc (local of EntityProc, local of PageProc, local of DrawPressPage), alternativeProc (local of EntityProc, local of PageProc, local of DrawPressPage), showObjectProc (local of EntityProc, local of PageProc, local of DrawPressPage), moveToProc (local of showObjectProc, local of EntityProc, local of PageProc, local of DrawPressPage), drawToProc (local of showObjectProc, local of EntityProc, local of PageProc, local of DrawPressPage), drawCurveProc (local of showObjectProc, local of EntityProc, local of PageProc, local of DrawPressPage), showDotsProc (local of EntityProc, local of PageProc, local of DrawPressPage), setCodingProc (local of showDotsProc, local of EntityProc, local of PageProc, local of DrawPressPage), setModeProc (local of showDotsProc, local of EntityProc, local of PageProc, local of DrawPressPage), setWindowProc (local of showDotsProc, local of EntityProc, local of PageProc, local of DrawPressPage), setSizeProc (local of showDotsProc, local of EntityProc, local of PageProc, local of DrawPressPage), dotsFollowProc (local of showDotsProc, local of EntityProc, local of PageProc, local of DrawPressPage), SkipFonts (local of DrawPressPage), Close, FontInitProc (local of Open), showCharactersProc (local of EntityProc, local of PageProc, local of DrawPressPage), spacingProc (local of EntityProc, local of PageProc, local of DrawPressPage), END "E "cedar" stylecode "cedar" stylecK "cedar" style m1>K "cedar" styleK "cedar" style "cedar" style $K "cedar" style "cedar" style K "cedar" style4K "cedar" style5K "cedar" style6K "cedar" style6K "cedar" styleK "cedar" styleK "cedar" style "cedar" style $K "cedar" styleK "cedar" style "cedar" styleK "cedar" style"K "cedar" style0K "cedar" style0K "cedar" styleK "cedar" style>>K "cedar" style""K "cedar" style "cedar" style#4K "cedar" styleK "cedar" styleAK "cedar" style "cedar" style!0 "cedar" style 7K "cedar" style"'K "cedar" style1K "cedar" styleK "cedar" style "cedar" style .K "cedar" style)K "cedar" style mK "cedar" style hr "cedar" style ,K "cedar" style K "cedar" styleK "cedar" styleK "cedar" style&& "cedar" style K "cedar" style K "cedar" styleK "cedar" styleK "cedar" styleK "cedar" styleK "cedar" style'' "cedar" styleK "cedar" style==K "cedar" style==K "cedar" styleAAK "cedar" styleK "cedar" styleK "cedar" styleBBK "cedar" style9?K "cedar" style "cedar" style *K "cedar" style^fK "cedar" style&K "cedar" styleK "cedar" styleK "cedar" style- "cedar" style -K "cedar" styleK "cedar" style//K "cedar" style00K "cedar" styleK "cedar" style /: "cedar" style ,K "cedar" styleK "cedar" styleK "cedar" styleK "cedar" styleK "cedar" style "cedar" style (K "cedar" style(K "cedar" style*K "cedar" style "cedar" style .K "cedar" styleK "cedar" styleK "cedar" styleKK "cedar" styleaa "cedar" styleK "cedar" style'K0K K%-EKK "cedar" style""K "cedar" styleK "cedar" styleK "cedar" styleK "cedar" styleK "cedar" style K "cedar" styleK "cedar" styleK "cedar" styleK "cedar" styleK "cedar" style "cedar" styleK "cedar" style*K "cedar" styleK "cedar" style6K "cedar" style**K "cedar" style K "cedar" style "cedar" styleK "cedar" styleK "cedar" styleK "cedar" styleK "cedar" style' "cedar" style4K "cedar" style''K "cedar" styleK "cedar" styleK "cedar" styleK "cedar" styleK "cedar" styleK "cedar" style%K "cedar" style!K "cedar" styleK "cedar" styleK "cedar" styleK "cedar" style K "cedar" styleK "cedar" style#K "cedar" style K "cedar" style,, "cedar" style K "cedar" styleCK "cedar" style&K "cedar" style99K "cedar" styleKStartOfExpansion[]K)/K "cedar" style99K "cedar" style "cedar" style *K "cedar" style K "cedar" style*K "cedar" styleK "cedar" styleK "cedar" styleK "cedar" styleK "cedar" style "cedar" style K "cedar" style3K "cedar" style "cedar" style+K "cedar" style1K+KK,,K-K$$K.K rF 5@K5K $=KK$K6 I' ,A AA A A AAAA Z ZZAX XX XX A AKK,]