ShowPressImpl.mesa
Copyright © 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
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]; };
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!!!
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 ];
! VFonts.Error => SELECT code FROM
VFonts.ErrorCode[fontNotFound] => ERROR ShowPressError[CantFindFonts, viewer];
ENDCASE => 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: BOOLFALSE] = {
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: BOOLFALSE;
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 {
Cull unrotated characters obviously outside the context
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]];
{
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;
};
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.
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