<> <> <> 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 ANY _ NARROW[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]^; <> 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 { <> pressState: TSOutputPress.PressState _ NARROW[self.outputState]; pressHandle: SirPress.PressHandle _ pressState.pressHandle; pipe: SirPress.Pipe _ pressState.pipe; oldFont: TSFont.Ref _ listReader.currentFont; lastThingWasChar: BOOLEAN _ FALSE; 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: BOOLEAN _ FALSE; 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 => { IF listReader.currentFont # oldFont THEN EXIT; 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, May 26, 1983 3:36 pm. Added underline and strikeout., Michael <> <> <> <> <<>>