DIRECTORY Convert USING [AppendInt], Imager USING [black, Context, DoSave, MaskFill, MaskRectangle, SetColor, SetFont, SetGray, SetXY, SetXRel, SetXYRel, SetYRel, Show, TranslateT], ImagerColor USING [ColorFromRGB, RGBFromHSV], ImagerBackdoor USING [GetCP, DoIfVisible], ImagerFont USING [Escapement, Extents, Find, Font, FontBoundingBox, Modify, Scale, XChar], ImagerPath USING [PathProc], ImagerTransformation USING [Rotate], PressImage USING [DrawPressImage, MakePressImage, PressImage, PressImageError], PressReader USING [AlternativeProc, ClosePressFile, ColorProc, Dots, DotsFollowProc, DrawCurveProc, DrawToProc, EntityProc, FontDirectoryProc, FontEntryProc, FontFace, FontProc, GetCommands, GetDocumentDirectory, GetDots, GetFonts, GetObject, GetPage, GetParts, Handle, MoveToProc, OpenPressFile, PageProc, PositionProc, PressReaderError, SetCodingProc, SetModeProc, SetSamplingPropertiesProc, SetSizeProc, SetWindowProc, ShowCharactersProc, ShowDotsProc, ShowObjectProc, ShowRectangleProc, SpaceProc, SpacingProc], Real USING [Round, LargestNumber], RefText USING [AppendChar, AppendRope, ObtainScratch, ReleaseScratch], Rope USING [Fetch, FromRefText, Map, ROPE, Size], ShowPress USING [FontRec, PressFileRec], Vector2 USING [Add, Div, Mul, Sub, VEC]; ShowPressImpl: CEDAR PROGRAM IMPORTS Convert, Imager, ImagerBackdoor, ImagerColor, ImagerFont, ImagerTransformation, PressImage, PressReader, Real, RefText, Rope, Vector2 EXPORTS ShowPress = BEGIN ROPE: TYPE ~ Rope.ROPE; Handle: TYPE ~ REF PressFileRec; PressFileRec: TYPE ~ ShowPress.PressFileRec; FontRec: TYPE ~ ShowPress.FontRec; nullReal: REAL _ -Real.LargestNumber; micasPerPoint: REAL _ 2540.0/72.0; pointsPerMica: REAL _ 72.0/2540.0; ShowPressError: PUBLIC ERROR [code: ATOM] = CODE; Coeffs: TYPE = RECORD [c0, c1, c2, c3: Vector2.VEC]; Bezier: TYPE = RECORD [b0, b1, b2, b3: Vector2.VEC]; SetHSV: PROC [context: Imager.Context, h, s, v: REAL] = { IF v = 0.0 THEN { Imager.SetColor[context, Imager.black]; } ELSE { IF s = 0.0 THEN { Imager.SetGray[context, 1.0-v]; } ELSE { Imager.SetColor[context, ImagerColor.ColorFromRGB[ImagerColor.RGBFromHSV[[H: h, S: s, V: v]]]]; }; }; }; CoeffsToBezier: PROC [coeffs: Coeffs] RETURNS [bezier: Bezier] = { bezier.b0 _ coeffs.c0; bezier.b1 _ coeffs.c0.Add[coeffs.c1.Div[3]]; bezier.b2 _ bezier.b1.Add[coeffs.c1.Add[coeffs.c2].Div[3]]; bezier.b3 _ coeffs.c0.Add[coeffs.c1].Add[coeffs.c2].Add[coeffs.c3]; RETURN[bezier]; }; BezierToCoeffs: PROC [bezier: Bezier] RETURNS [coeffs: Coeffs] = { t: Vector2.VEC _ bezier.b2.Sub[bezier.b1].Mul[3]; coeffs.c0 _ bezier.b0; coeffs.c1 _ bezier.b1.Sub[bezier.b0].Mul[3]; coeffs.c2 _ t.Sub[coeffs.c1]; coeffs.c3 _ bezier.b3.Sub[bezier.b0.Add[t]]; RETURN[coeffs]; }; NameFromPressFontID: PROC [family: ROPE, face: PressReader.FontFace] RETURNS [name: ROPE] ~ { t: REF TEXT _ RefText.ObtainScratch[100]; t _ RefText.AppendRope[t, "Xerox/Pressfonts/"]; t _ RefText.AppendRope[t, family]; IF face.texDesignSize > 0 THEN { t _ Convert.AppendInt[t, Real.Round[face.texDesignSize]]; } ELSE { t _ RefText.AppendChar[t, '-]; t _ RefText.AppendChar[t, SELECT face.weight FROM medium => 'M, bold => 'B, light => 'L, ENDCASE => 'M ]; t _ RefText.AppendChar[t, SELECT face.slope FROM regular => 'R, italic => 'I, ENDCASE => 'R ]; t _ RefText.AppendChar[t, SELECT face.expansion FROM regular => 'R, condensed => 'C, expanded => 'E, ENDCASE => 'R ]; }; name _ Rope.FromRefText[t]; RefText.ReleaseScratch[t]; }; Open: PUBLIC PROCEDURE [fileName: Rope.ROPE] RETURNS [show: Handle _ NIL] = { FontInitProc: PressReader.FontEntryProc = { -- build a list of needed fonts sizeInMicas: REAL ~ ( IF fontDirectoryEntry.size > 0 THEN ((REAL[fontDirectoryEntry.size]*2540.0)/72.0) ELSE (REAL[-fontDirectoryEntry.size]) ); name: ROPE ~ NameFromPressFontID[fontDirectoryEntry.family, fontDirectoryEntry.face]; imagerFont: ImagerFont.Font _ ImagerFont.Scale[ImagerFont.Find[name], sizeInMicas]; IF fontDirectoryEntry.rotation#0 THEN { degrees: REAL _ fontDirectoryEntry.rotation/60.0; imagerFont _ ImagerFont.Modify[imagerFont, ImagerTransformation.Rotate[degrees]]; }; show.fontTable[fontDirectoryEntry.fontSet*16+fontDirectoryEntry.font] _ [ imagerFont: imagerFont, family: fontDirectoryEntry.family, face: fontDirectoryEntry.face.encoding, size: sizeInMicas, rotation: REAL[fontDirectoryEntry.rotation]/60.0 ]; }; -- FontInitProc pressFile: PressReader.Handle _ PressReader.OpenPressFile[fileName ! PressReader.PressReaderError => { SELECT errorCode FROM FileNotAPressFile => ERROR ShowPressError[$CantReadFile]; ENDCASE => REJECT; } ]; show _ NEW[PressFileRec]; show.pressFile _ pressFile; show.lastPart _ pressFile.GetDocumentDirectory[].nParts; show.pressFile.GetFonts[FontInitProc]; }; DrawPressPage: PUBLIC PROCEDURE [context: Imager.Context, show: Handle, pageNumber: INT, tinyPaint: BOOL _ FALSE] = { skipAlternative: BOOL _ FALSE; hue: REAL _ 0.0; saturation: REAL _ 0.0; brightness: REAL _ 0.0; colorChanged: BOOL _ TRUE; ValidateColor: PROC ~ { IF colorChanged THEN { IF saturation = 0 THEN Imager.SetGray[context, 1.0-brightness] ELSE SetHSV[context, hue, saturation, brightness]; colorChanged _ FALSE; }; }; showObjectProc: PressReader.ShowObjectProc = { IF NOT skipAlternative THEN { Path: ImagerPath.PathProc ~ { lp: Vector2.VEC _ [0, 0]; moveToProc: PressReader.MoveToProc = {moveTo[lp _ [x, y]]}; drawToProc: PressReader.DrawToProc = {lineTo[lp _ [x, y]]}; drawCurveProc: PressReader.DrawCurveProc = { cubic: Coeffs ~ [c0: lp, c1: [cX, cY], c2: [bX, bY], c3: [aX, aY]]; bezier: Bezier ~ CoeffsToBezier[cubic]; curveTo[bezier.b1, bezier.b2, bezier.b3]; lp _ bezier.b3; }; show.pressFile.GetObject[moveToProc, drawToProc, drawCurveProc]; }; ValidateColor[]; Imager.MaskFill[context: context, path: Path, oddWrap: TRUE] }; }; -- showObjectProc PageProc: PressReader.PageProc = { EntityProc: PressReader.EntityProc = { -- Xe, Ye, fontSet currentFont: FontRec; -- will be established by setFont currentFontYMin, currentFontYMax: REAL; -- for faster culling of characters currentSpaceX: REAL; -- will be established by setFont currentSpaceY: REAL; -- will be established by setFont spaceChanged: BOOL _ FALSE; x, y: REAL _ 0.0; cpChanged: BOOL _ TRUE; inAlternative: BOOL _ FALSE; ValidateCP: PROC ~ { IF cpChanged THEN { IF x = nullReal THEN x _ ImagerBackdoor.GetCP[context].x; IF y = nullReal THEN y _ ImagerBackdoor.GetCP[context].y; Imager.SetXY[context, [x, y]]; cpChanged _ FALSE; }; }; showCharactersProc: PressReader.ShowCharactersProc = { ShowAction: PROC ~ { start: INT _ 0; size: INT ~ Rope.Size[text]; WHILE start { IF cpChanged THEN NULL ELSE IF x=nullReal THEN cpChanged _ TRUE ELSE Imager.SetXRel[context, value-x]; x _ value; }; setY => { IF cpChanged THEN NULL ELSE IF y=nullReal THEN cpChanged _ TRUE ELSE Imager.SetYRel[context, value-y]; y _ value; }; ENDCASE => ERROR; }; spacingProc: PressReader.SpacingProc = { IF skipAlternative THEN RETURN; IF opCode#resetSpace AND NOT spaceChanged THEN { IF currentFont.imagerFont=NIL THEN ERROR ShowPressError[$NoCurrentFont]; [[currentSpaceX, currentSpaceY]] _ ImagerFont.Escapement[currentFont.imagerFont, [set:0,code:ORD[' ]]]; spaceChanged _ TRUE; }; SELECT opCode FROM setSpaceX, setSpaceXShort => currentSpaceX _ value; setSpaceY, setSpaceYShort => currentSpaceY _ value; resetSpace => spaceChanged _ FALSE; ENDCASE => ERROR; }; spaceProc: PressReader.SpaceProc = { IF skipAlternative THEN RETURN; showCharactersProc[opCode: showCharacterImmediate, length: 1, text: "\040"]; }; colorProc: PressReader.ColorProc = { IF skipAlternative THEN RETURN; SELECT opCode FROM setHue => hue _ REAL[value MOD 240]/240.0; setSaturation => saturation _ REAL[value]/255.0; setBrightness => brightness _ REAL[value]/255.0; ENDCASE => ERROR; colorChanged _ TRUE; }; showRectangleProc: PressReader.ShowRectangleProc = { IF skipAlternative THEN RETURN; IF x = nullReal THEN x _ ImagerBackdoor.GetCP[context].x; IF y = nullReal THEN y _ ImagerBackdoor.GetCP[context].y; ValidateColor[]; Imager.MaskRectangle[context, [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; }; showDotsProc: PressReader.ShowDotsProc = { codingType, dotsPerLine, scanLines, scanMode, passDots, displayDots, passLines, displayLines: INT _ 0; windowWidth, windowHeight: REAL _ 0.0; dotInfo: PressReader.Dots; image: PressImage.PressImage; 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]; windowHeight _ REAL[height]; }; setSampling: PressReader.SetSamplingPropertiesProc = { }; dotsFollowProc: PressReader.DotsFollowProc = { dotInfo _ dots; }; IF skipAlternative THEN RETURN; show.pressFile.GetDots[setCodingProc, setModeProc, setWindowProc, setSizeProc, setSampling, dotsFollowProc]; { 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 ]; ValidateCP[]; PressImage.DrawPressImage[context, image]; }; EXITS Quit => RETURN; }; -- showDotsProc skipAlternative _ FALSE; hue _ saturation _ brightness _ 0.0; colorChanged _ TRUE; Imager.TranslateT[context, [entityTrailer.Xe, entityTrailer.Ye]]; fontProc[0]; -- SetFont 0; ResetSpace; Imager.SetXY[context, [0, 0]]; show.pressFile.GetCommands[ showCharactersProc: showCharactersProc, fontProc: fontProc, positionProc: positionProc, spacingProc: spacingProc, spaceProc: spaceProc, colorProc: colorProc, showRectangleProc: showRectangleProc, alternativeProc: alternativeProc, showObjectProc: showObjectProc, showDotsProc: showDotsProc ]; }; -- EntityProc OuterEntityProc: PressReader.EntityProc ~ { proc: PROC ~ {EntityProc[handle, entityTrailer]}; Imager.DoSave[context, proc]; }; show.pressFile.GetPage[OuterEntityProc]; }; -- 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]; }; show.pressFile.GetParts[pageNumber, PageProc, SkipFonts]; }; -- DrawPressPage Close: PUBLIC PROCEDURE [show: Handle] = TRUSTED { show.pressFile.ClosePressFile[]; }; END. ˜ShowPressImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Shore; December 7, 1982 1:38 pm Beach, September 13, 1983 5:54 pm Russ Atkinson (RRA) March 18, 1985 7:01:02 pm PST Michael Plass, June 22, 1985 9:11:58 pm PDT Doug Wyatt, December 2, 1985 2:58:56 pm PST Compute the bezier control points of the cubic These points form a convex hull of the curve b0 is the starting point, b3 is the ending point b0 _ c0; b1 _ c0 + c1/3; b2 _ c0 + 2*c1/3 + c2/3; [ = b1 + (c1+c2)/3 ] b3 _ c0 + c1 + c2 + c3; Compute the cubic coefficients from the Bezier points. c0 _ b0; c1 _ 3(b1-b0); c2 _ 3(b0-2b1+b2); [ = 3(b2-b1) - c1 ] c3 _ -b0 +3(b1-b2) + b3; [ = b3 - (b0 + 3(b2-b1)) ] Cull unrotated characters obviously outside the context mark: Graphics.Mark _ Graphics.Save[context]; [samplingProperties: LIST OF PressReader.SamplingProperty] ?? { -- Cull dots obviously outside the context 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; }; [] _ Graphics.SetFat[self: context, fat: TRUE]; 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 Michael Plass, April 3, 1985 5:50:57 pm PST Imager Conversion changes to: DIRECTORY, ShowPressImpl, CoeffsToBezier, BezierToCoeffs, Open, FontInitProc (local of Open), DrawPressPage, EntityProc (local of PageProc, local of DrawPressPage), showCharactersProc (local of EntityProc, local of PageProc, local of DrawPressPage), ShowAction (local of showCharactersProc, local of EntityProc, local of PageProc, local of DrawPressPage), XString (local of ShowAction, local of showCharactersProc, local of EntityProc, local of PageProc, local of DrawPressPage), action (local of XString, local of ShowAction, local of 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), showObjectProc (local of EntityProc, local of PageProc, local of DrawPressPage), Path (local of showObjectProc, local of EntityProc, local of PageProc, local of DrawPressPage), moveToProc (local of Path, local of showObjectProc, local of EntityProc, local of PageProc, local of DrawPressPage), drawToProc (local of Path, local of showObjectProc, local of EntityProc, local of PageProc, local of DrawPressPage), drawCurveProc (local of Path, local of showObjectProc, local of EntityProc, local of PageProc, local of DrawPressPage), showDotsProc (local of EntityProc, local of PageProc, local of DrawPressPage), SkipFonts (local of DrawPressPage), SpecialShow, Close ส q– "cedar" style˜code– "cedar" stylešฯc™K– "cedar" stylešœ ฯmœ1™K– "cedar" stylešŸœ.˜2JšœŸœ˜Jšœ˜—Jšœ˜—– "cedar" stylešกœ ˜.– "cedar" stylešŸœŸœŸœ˜– "cedar" stylešกœ˜K– "cedar" stylešœ Ÿœ ˜K– "cedar" stylešก œ1˜;K– "cedar" stylešก œ1˜;– "cedar" stylešก œ˜,K– "cedar" stylešœC˜CK– "cedar" stylešœ'˜'K– "cedar" stylešœ)˜)K– "cedar" stylešœ˜K– "cedar" stylešœ˜—K– "cedar" stylešœ@˜@Jšœ˜—K– "cedar" stylešœ˜K– "cedar" stylešœ7Ÿœ˜ -- [samplingProperties: LIST OF PressReader.SamplingProperty]– "cedar" stylešฯb œ+˜6K– "cedar" stylešะck:™:K– "cedar" stylešœ™K– "cedar" stylešœ˜—– "cedar" stylešกœ ˜.K– "cedar" style˜K– "cedar" style˜—K– "cedar" style˜KšŸœŸœŸœ˜K– "cedar" stylešœl˜l– "cedar" style™K– "cedar" style™*K™0Kšœ Ÿœ™K™%šŸœŸœ-Ÿ™EKšŸœ™—K™—šœ˜– "cedar" stylešœ"˜"K– "cedar" stylešœ˜K– "cedar" stylešœ˜K– "cedar" stylešœ˜K– "cedar" stylešœ˜K– "cedar" stylešœ ˜ K– "cedar" stylešœ˜K– "cedar" stylešœ˜K– "cedar" stylešœ˜K– "cedar" stylešœ˜K– "cedar" stylešœ˜K– "cedar" stylešœ ˜ K– "cedar" stylešœ Ÿœ˜)K– "cedar" stylešœ˜—K– "cedar" style˜ K– "cedar" stylešœ*˜*K– "cedar" style˜—– "cedar" stylešŸ˜K– "cedar" stylešœŸœ˜—K– "cedar" stylešœ˜—K– "cedar" stylešœŸœ˜K– "cedar" style˜$K– "cedar" stylešœŸœ˜K– "cedar" stylešœA˜AK– "cedar" stylešœ˜'K– "cedar" style˜– "cedar" style˜K– "cedar" stylešœ'˜'K– "cedar" stylešœ˜K– "cedar" style˜K– "cedar" style˜K– "cedar" style˜K– "cedar" style˜K– "cedar" style˜%K– "cedar" style˜!K– "cedar" stylešœ˜K– "cedar" stylešœ˜K– "cedar" stylešœ˜—K– "cedar" stylešœ ˜—– "cedar" stylešกœ˜+K– "cedar" stylešœŸœ'˜1K– "cedar" stylešœ˜K– "cedar" stylešœ˜—K– "cedar" stylešœ(˜(K– "cedar" stylešœ ˜—K– "cedar" style˜šœ,˜,– "cedar" stylešœ ˜ K– "cedar" stylešŸœŸœŸœ˜DK– "cedar" stylešŸœŸœ˜&—K– "cedar" stylešœ9˜9K– "cedar" style˜—K–[]˜Kšœ)Ÿœ™/K– "cedar" stylešœ9˜9K– "cedar" stylešœ˜K– "cedar" style˜—– "cedar" stylešกœŸœŸ œŸœ˜2K– "cedar" style˜ K– "cedar" style˜—K– "cedar" style˜K– "cedar" stylešŸœ˜K– "cedar" style˜—K– "cedar" styleš ™ K– "cedar" style™K– "cedar" style™3K– "cedar" style™– "cedar" style™+K– "cedar" style™1—K™™+K™—K™šœ,™,K™-Kšœ$™$—K™™.Kšœ ฯrœFค œ5คœ@™๑K™—™5Kšœ ค œ$™=—K™K™™+K™Kš(œ คLœคœ,คœAค œ^ค œsคœ…ค œAคœAค œAค œAค œAคœAคœAคœZค œiค œiคœiคœAค œค™ๅ —K™K™K™—…—/ส^ำ