TSIncludePressImpl.mesa
Michael Plass, August 2, 1985 9:27:42 am PDT
DIRECTORY
PressReader,
Real,
Rope,
SirPress,
TSArtwork,
TSOutputPress,
TextNode,
TSGraphic,
IO,
TSOutput,
TSTypes USING [Dimn, zeroDimn, RealDimn, DimnRatio, bp, Dimensions];
TSIncludePressImpl: CEDAR PROGRAM
IMPORTS PressReader, Real, Rope, SirPress, TSArtwork, TextNode, IO, TSTypes
= BEGIN OPEN TSTypes;
bytesPerPage: NAT ~ 512; -- as per press file format.
micasPerPoint: REAL = 2540.0/72.0;
pointsPerMica: REAL = 72.0/2540.0;
ObjectFromBranchProc: TYPE = TSArtwork.ObjectFromBranchProc;
ROPE: TYPE = Rope.ROPE;
IncludePressRec: TYPE = RECORD [pressFileName: ROPE, topMargin, leftMargin, height, width: REAL];
Break: PROC [char: CHAR] RETURNS [IO.CharClass] = {
IF char = ': THEN RETURN [break];
IF char = ' OR char = '  OR char = ', OR char = '; OR char = '\n THEN RETURN [sepr];
RETURN [other];
};
GetName: PROC [stream: IO.STREAM] RETURNS [name: ROPE] ~ {
name ← NIL;
name ← IO.GetTokenRope[stream, Break ! IO.EndOfStream => CONTINUE].token;
};
GetBP: PROC [stream: IO.STREAM] RETURNS [REAL] = {
r: REALIO.GetReal[stream];
unit: ROPE ← GetName[stream];
multipler: REALSELECT TRUE FROM
unit.Equal["in"] => 72.0,
unit.Equal["pt"] => 72.0/72.27,
unit.Equal["cm"] => 72.0/2.54,
unit.Equal["mm"] => 72.0/25.4,
unit.Equal["bp"] => 1.0,
ENDCASE => 0.0;
IF multipler = 0.0 THEN ERROR;
RETURN [r*multipler];
};
IncludePressFromBranch: ObjectFromBranchProc = {
data: REF IncludePressRec ← NEW[IncludePressRec];
textNode: TextNode.RefTextNode ← TextNode.NarrowToTextNode[node];
nodeContents: ROPE ← textNode.rope;
stream: IO.STREAMIO.RIS[nodeContents];
data.pressFileName ← GetName[stream];
FOR i: NAT IN [0..4) DO
keyword: ROPE ← GetName[stream];
colon: ROPE ← GetName[stream];
IF colon.Equal[":"] THEN NULL ELSE ERROR;
SELECT TRUE FROM
keyword.Equal["TopMargin", FALSE] => data.topMargin ← GetBP[stream];
keyword.Equal["LeftMargin", FALSE] => data.leftMargin ← GetBP[stream];
keyword.Equal["Height", FALSE] => data.height ← GetBP[stream];
keyword.Equal["Width", FALSE] => data.width ← GetBP[stream];
ENDCASE => ERROR;
ENDLOOP;
object ← NEW[TSGraphic.ObjectRec];
object.paintProc ← IncludePressPaint;
object.layoutProc ← IncludePressLayout;
object.data ← data;
};
IncludePressLayout: TSGraphic.LayoutProc = {
data: REF IncludePressRec ← NARROW[self.data];
extent ← [zeroDimn, RealDimn[data.width, bp], zeroDimn, RealDimn[data.height, bp]];
};
IncludePressPaint: TSGraphic.PaintProc = {
data: REF IncludePressRec ← NARROW[self.data];
handle: TSOutput.Handle ← NARROW[context];
pressState: TSOutputPress.PressState ← NARROW[handle.outputState];
pressHandle: SirPress.PressHandle ← pressState.pressHandle;
pressFile: PressReader.Handle ← PressReader.OpenPressFile[data.pressFileName];
fontTable: REF ARRAY [0..6*16) OF PressReader.FontDirectoryEntry ← NEW[ARRAY [0..6*16) OF PressReader.FontDirectoryEntry];
xTranslate: INT ← Real.RoundLI[(DimnRatio[originX, bp] - data.leftMargin)*micasPerPoint];
yTranslate: INT ← Real.RoundLI[(DimnRatio[originY, bp] - (11*72-data.topMargin))*micasPerPoint];
FontInitProc: PressReader.FontEntryProc = { -- build a list of needed fonts
fontTable[fontDirectoryEntry.fontSet*16 + fontDirectoryEntry.font] ← fontDirectoryEntry;
}; -- FontInitProc
PageProc: PressReader.PageProc = {
EntityProc: PressReader.EntityProc = { -- Xe, Ye, fontSet
xe: INT ← entityTrailer.Xe + xTranslate;
ye: INT ← entityTrailer.Ye + yTranslate;
x: INT ← xe;
y: INT ← ye;
currentFont: PressReader.FontDirectoryEntry; -- will be established by setFont
currentSpaceX, currentSpaceY: INT; -- will be established by setFont
hue: REAL ← 0.0;
saturation: REAL ← 1.0;
brightness: REAL ← 0.0;
skipAlternative, inAlternative: BOOLFALSE;
reposition: BOOLEANFALSE;
showCharactersProc: PressReader.ShowCharactersProc = {
IF skipAlternative THEN RETURN;
IF reposition THEN {pressHandle.PutText[text, x, y]; reposition ← FALSE}
ELSE pressHandle.PutTextHere[text];
}; -- showCharactersProc
fontProc: PressReader.FontProc = {
IF skipAlternative THEN RETURN;
currentFont ← fontTable[entityTrailer.fontSet*16+font];
IF currentFont.family.Length # 0 THEN
pressHandle.SetFont[currentFont.family, currentFont.size, currentFont.face.encoding, currentFont.rotation];
};
positionProc: PressReader.PositionProc = {
IF skipAlternative THEN RETURN;
IF opCode = setX THEN x ← xe + value
ELSE y ← ye + value;
reposition ← TRUE;
};
spacingProc: PressReader.SpacingProc = {
IF skipAlternative THEN RETURN;
SELECT opCode FROM
setSpaceX, setSpaceXShort => currentSpaceX ← value;
setSpaceY, setSpaceYShort => currentSpaceY ← value;
resetSpace => {
currentSpaceX ← 200;
currentSpaceY ← 0;
};
ENDCASE => ERROR;
IF opCode = resetSpace THEN pressHandle.ResetSpace ELSE pressHandle.SetSpace[currentSpaceX, currentSpaceY];
};
spaceProc: PressReader.SpaceProc = {
showCharactersProc[showCharacterImmediate, 1, " "];
};
colorProc: PressReader.ColorProc = {
IF skipAlternative THEN RETURN;
SELECT opCode FROM
setHue => pressHandle.SetHue[value];
setSaturation => pressHandle.SetSaturation[value];
setBrightness => pressHandle.SetBrightness[value];
ENDCASE => ERROR;
};
showRectangleProc: PressReader.ShowRectangleProc = {
IF skipAlternative THEN RETURN;
pressHandle.PutRectangle[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;
};
showObjectProc: PressReader.ShowObjectProc = {
moveToProc: PressReader.MoveToProc = {pressHandle.PutMoveTo[x: x+xe, y: y+ye]};
drawToProc: PressReader.DrawToProc = {pressHandle.PutDrawTo[x: x+xe, y: y+ye]};
drawCurveProc: PressReader.DrawCurveProc = {
pressHandle.PutCubic[cX, cY, bX, bY, aX, aY];
};
IF skipAlternative THEN RETURN;
pressHandle.StartOutline;
pressFile.GetObject[moveToProc, drawToProc, drawCurveProc];
pressHandle.EndOutline;
}; -- showObjectProc
showDotsProc: PressReader.ShowDotsProc = {
codingType, dotsPerLine, scanLines, passDots, displayDots, passLines, displayLines: INT ← 0;
scanMode: CARDINAL ← 0;
windowWidth, windowHeight: INT ← 0;
dotInfo: PressReader.Dots;
samplingInfo: LIST OF PressReader.SamplingProperty ← NIL;
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 ← width;
windowHeight ← height;
};
setSamplingPropertiesProc: PressReader.SetSamplingPropertiesProc = {
samplingInfo ← samplingProperties;
};
dotsFollowProc: PressReader.DotsFollowProc = {
dotInfo ← dots;
};
ScratchRec: TYPE ~ RECORD [SEQUENCE length: NAT OF WORD];
scratch: REF ScratchRec;
bytesPerLine: INT ← 0;
IF skipAlternative THEN RETURN;
pressFile.GetDots[setCodingProc, setModeProc, setWindowProc, setSizeProc, setSamplingPropertiesProc, dotsFollowProc];
scratch ← NEW[ScratchRec[(dotsPerLine+3)/2]];
pressHandle.BeginScannedRectangle[
x: x, y: y,
dotsPerLine: dotsPerLine,
numberOfLines: scanLines,
width: windowWidth,
height: windowHeight,
nextLineDirection: LOOPHOLE[scanMode MOD 4],
nextDotDirection: LOOPHOLE[scanMode / 4],
coding: SELECT codingType FROM
0 => bitMap,
1 => bitSampled,
2 => bitBitSampled,
4 => nybbleSampled,
8 => byteSampled,
ENDCASE => ERROR
];
bytesPerLine ← (MAX[codingType, 1] * dotsPerLine + 7)/8;
scratch[bytesPerLine/2] ← 0; -- make sure array is big enough
dotInfo.file.SetIndex[INT[dotInfo.pageNumber]*bytesPerPage+dotInfo.byteOffset];
FOR i: INT IN [0..scanLines) DO
TRUSTED {[] ← dotInfo.file.UnsafeGetBlock[[base: (LOOPHOLE[@scratch[0]]), startIndex: 0, count: bytesPerLine]]};
TRUSTED {pressHandle.UnsafeShowLine[@scratch[0]]};
ENDLOOP;
pressHandle.EndScannedRectangle;
}; -- showDotsProc
fontProc[0];
pressHandle.SetColor[0, 0, 0];
pressFile.GetCommands[
showCharactersProc: showCharactersProc,
fontProc: fontProc,
positionProc: positionProc,
spacingProc: spacingProc,
spaceProc: spaceProc,
colorProc: colorProc,
showRectangleProc: showRectangleProc,
alternativeProc: alternativeProc,
showObjectProc: showObjectProc,
showDotsProc: showDotsProc
];
}; -- EntityProc
pressFile.GetPage[EntityProc];
}; -- PageProc
SkipFonts: PressReader.FontDirectoryProc = {
};
pressFile.GetFonts[FontInitProc];
pressFile.GetParts[pageNumber, PageProc, SkipFonts];
pressFile.ClosePressFile[];
};
pageNumber: INT ← 1;
TSArtwork.Register["IncludePress", IncludePressFromBranch];
END.