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 {
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 {
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]];
{
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];
}; -- 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