TSOutputImpl.mesa
Last changed by Michael Plass, November 2, 1982 10:40 am
DIRECTORY
Rope,
SirPress,
TSTypes,
TSFont,
TSGlue,
TSGraphic,
TSObject,
TSOutput,
TSOutputPress;
TSOutputImpl: CEDAR PROGRAM
IMPORTS SirPress, TSTypes, TSFont, TSGlue, TSObject, TSGraphic, TSOutputPress
EXPORTS TSOutput =
BEGIN OPEN TSTypes, TSOutput;
Close: PUBLIC PROCEDURE [self: Handle] = {self.finishProc[self]; self.outputState ← NIL};
ShipOut: PUBLIC PROCEDURE[self: Handle, page: TSObject.BoxRec] = {
self.newPageProc[self];
BoxOut[self, page.extent[left], page.extent[down], page];
};
BoxOut: PUBLIC PROCEDURE [
self: Handle,
xRef, yRef: Dimn,
box: TSObject.BoxRec
] = TRUSTED {
x: Dimn ← xRef;
y: Dimn ← yRef;
Move: SAFE PROCEDURE [dir: Direction, d: Dimn] = CHECKED INLINE {
SELECT dir FROM
left => x ← SubDimn[x, d];
right => x ← AddDimn[x, d];
up => y ← AddDimn[y, d];
down => y ← SubDimn[y, d];
ENDCASE;
};
WITH b: box SELECT FROM
char => self.charProc[self, x, y, b.c, b.font];
rule => self.ruleProc[
self,
SubDimn[x, box.extent[left]],
SubDimn[y, box.extent[down]],
AddDimn[box.extent[left], box.extent[right]],
AddDimn[box.extent[up], box.extent[down]]
];
graphic => b.graphicObject.Paint[self, x, y, box.extent];
list => {
opposite: Direction ← SELECT b.direction FROM
up => down, down => up, left => right, right => left,
ENDCASE => ERROR;
shiftDirection: Direction ← SELECT b.direction FROM
up => left, down => right, left => down, right => up,
ENDCASE => ERROR;
listReader: TSObject.ListReader ← b.items.CreateReader[];
DoUnderlineAndStrikeout: SAFE PROCEDURE [width: Dimn] = CHECKED {
IF width.texPts <= 0 THEN RETURN;
IF listReader.parameter[underlineThickness] # zeroDimn THEN self.ruleProc[self, x, y.AddDimn[listReader.parameter[underlineBottom]], width, listReader.parameter[underlineThickness]];
IF listReader.parameter[strikeoutThickness] # zeroDimn THEN self.ruleProc[self, x, y.AddDimn[listReader.parameter[strikeoutBottom]], width, listReader.parameter[strikeoutThickness]];
};
ExceptionOut: SAFE PROC[t: REF ANY] = CHECKED {
SELECT TRUE FROM
ISTYPE[t, TSObject.Glue] => {
g: TSObject.Glue ← NARROW[t];
glueSize: Dimn ← TSGlue.FixGlue[g^, b.glueset];
IF b.direction = right THEN DoUnderlineAndStrikeout[glueSize];
Move[b.direction, glueSize];
};
ISTYPE[t, TSObject.Box] => {
innerBox: TSObject.Box ← NARROW[t];
Move[b.direction, innerBox.extent[opposite]];
IF b.direction = right THEN DoUnderlineAndStrikeout [innerBox.extent[opposite].AddDimn[innerBox.extent[b.direction]]];
Move[shiftDirection, listReader.parameter[shift]];
BoxOut[self, x, y, innerBox^];
Move[shiftDirection, [-listReader.parameter[shift].texPts]];
Move[b.direction, innerBox.extent[b.direction]];
};
ISTYPE[t, TSObject.Kerf] => {
p: LIST OF REF ANYNARROW[t, TSObject.Kerf].join;
WHILE p # NIL DO
ExceptionOut[p.first];
p ← p.rest;
ENDLOOP;
};
ISTYPE[t, TSObject.Kern] => {
kernSize: Dimn ← NARROW[t, TSObject.Kern]^;
IF b.direction = right THEN DoUnderlineAndStrikeout[kernSize];
Move[b.direction, kernSize];
};
ENDCASE => {};
};
Move[opposite, b.extent[opposite]];
UNTIL listReader.End[] DO
IF b.direction = right
AND self.outputState # NIL
AND ISTYPE[self.outputState, TSOutputPress.PressState]
AND listReader.parameter[strikeoutThickness] = zeroDimn
AND listReader.parameter[underlineThickness] = zeroDimn
AND listReader.currentFont # NIL THEN {
accelerator for lines of text
pressState: TSOutputPress.PressState ← NARROW[self.outputState];
pressHandle: SirPress.PressHandle ← pressState.pressHandle;
pipe: SirPress.Pipe ← pressState.pipe;
oldFont: TSFont.Ref ← listReader.currentFont;
lastThingWasChar: BOOLEANFALSE;
shiftAmt: Dimn ← listReader.parameter[shift];
self.colorProc[
self: self,
hue: listReader.parameter[hue].texPts,
saturation: listReader.parameter[saturation].texPts,
brightness: listReader.parameter[brightness].texPts
];
pressState.SetFont[oldFont];
pressHandle.OpenPipe[pipe];
DO newLastThingWasChar: BOOLEANFALSE;
SELECT listReader.CurrentTag[] FROM
char => {
c: CHAR ← listReader.CurrentChar[];
IF listReader.currentFont # oldFont THEN EXIT;
IF NOT lastThingWasChar THEN pipe.PipePosition[x.DimnInt[mica]];
pipe.PipeChar[c];
Move[right, oldFont.Width[c]];
newLastThingWasChar ← TRUE;
};
space => {
Move[right, TSGlue.FixGlue[oldFont.SpaceGlue[], b.glueset]];
};
exception => {
t: REF ANY ← listReader.CurrentItem[];
SELECT TRUE FROM
ISTYPE[t, TSObject.Glue] => {
g: TSObject.Glue ← NARROW[t];
Move[b.direction, TSGlue.FixGlue[g^, b.glueset]];
};
ISTYPE[t, TSObject.Kern] => {
Move[b.direction, NARROW[t, TSObject.Kern]^];
};
ENDCASE => EXIT;
};
ENDCASE => EXIT;
lastThingWasChar ← newLastThingWasChar;
listReader.Next[];
ENDLOOP;
pressHandle.ClosePipe[pipe, y.AddDimn[shiftAmt].DimnInt[mica]];
}; -- end of accelerator
IF NOT listReader.End[] THEN {
self.colorProc[
self: self,
hue: listReader.parameter[hue].texPts,
saturation: listReader.parameter[saturation].texPts,
brightness: listReader.parameter[brightness].texPts
];
SELECT listReader.CurrentTag[] FROM
char => {
c: CHAR ← listReader.CurrentChar[];
extent: Dimensions ← listReader.currentFont.CharDimensions[c];
Move[b.direction, extent[opposite]];
DoUnderlineAndStrikeout[extent[left].AddDimn[extent[right]]];
Move[shiftDirection, listReader.parameter[shift]];
self.charProc[self, x, y, c, listReader.currentFont];
Move[shiftDirection, [-listReader.parameter[shift].texPts]];
Move[b.direction, extent[b.direction]];
};
space => {
spaceSize: Dimn ← TSGlue.FixGlue[listReader.currentFont.SpaceGlue[], b.glueset];
DoUnderlineAndStrikeout[spaceSize];
Move[b.direction, spaceSize]
};
hyphen => {};
exception => ExceptionOut[listReader.CurrentItem[]];
ENDCASE => ERROR;
listReader.Next[];
}
ENDLOOP;
listReader.DestroyReader[];
};
ENDCASE => {};
};
END.
Michael Plass, September 1, 1982 9:30 pm: Put in calls to TSObject.DestroyReader.
Michael Plass, September 15, 1982 11:22 am: Put in call to TSFont.Width instead of TSFont.CharDimensions.
Michael Plass, November 2, 1982 10:40 am. CEDARized.
Michael Plass, November 12, 1982 9:59 am. Added underline and strikeout.