<> <> <> DIRECTORY TSTypes, TSObject, TSFont, TSGlue, TSOps; TSOpsImpl: CEDAR PROGRAM IMPORTS TSTypes, TSFont, TSObject, TSOps EXPORTS TSOps = BEGIN OPEN TSTypes; InsertLeading: PUBLIC PROCEDURE [self: TSObject.ItemList] RETURNS [new: TSObject.ItemList] = { new _ TSObject.CreateItemList[ ProduceLeading, NEW[InterlineDataRec _ [reader: self.CreateReader[]]] ]; }; InterlineDataRec: TYPE = RECORD [ reader: TSObject.ListReader, prevDepth: Dimn _ nilDimn ]; fillBottomSkip: LIST OF REF ANY = LIST[TSObject.filGlue]; pageBottomSkip: LIST OF REF ANY _ fillBottomSkip; ProduceLeading: TSObject.ProducerProc = { r: REF InterlineDataRec _ NARROW[listWriter.writerData]; joinList, leading: LIST OF REF ANY; penalty: Penalty; box: TSObject.Box; item: REF ANY; baselineDistance: Dimn; kerf: TSObject.Kerf _ NEW[TSObject.KerfRec]; Finish: PROC = { listWriter.ProduceEnd[]; r.reader.DestroyReader[]; r.reader _ NIL; }; IF r.reader.End[] THEN {Finish[]; RETURN}; [joinList, penalty] _ AccumulateKerf[r.reader]; UNTIL r.reader.CurrentTag[] # exception OR NOT ISTYPE[r.reader.CurrentItem[], TSObject.MarkList] DO afterJoinList: LIST OF REF ANY; afterPenalty: Penalty; item _ r.reader.CurrentItem[]; r.reader.Next[]; [afterJoinList, afterPenalty] _ AccumulateKerf[r.reader]; joinList _ CONS[joinList, afterJoinList]; penalty _ penalty + afterPenalty; listWriter.ProduceItem[item]; ENDLOOP; IF r.reader.CurrentTag[] = exception THEN { item _ r.reader.CurrentItem[]; IF ISTYPE[item, TSObject.Box] THEN box _ NARROW[item] } ELSE IF r.reader.CurrentTag[] = char THEN item _ box _ NEW[TSObject.BoxRec _ [ r.reader.currentFont.CharDimensions[r.reader.CurrentChar[]], char [r.reader.currentFont, r.reader.CurrentChar[]] ]]; baselineDistance _ IF box = NIL OR r.prevDepth = nilDimn THEN zeroDimn ELSE AddDimn[r.prevDepth, box.extent[up]]; IF baselineDistance.texPts > r.reader.parameter[minbaseline].texPts + r.reader.parameter[mingaps].texPts THEN leading _ r.reader.listParameter[lineskip] ELSE leading _ LIST[NEW[Dimn _ SubDimn[r.reader.parameter[minbaseline], baselineDistance] ]]; kerf.join _ Concatenate[joinList, leading]; kerf.penalty _ penalty; kerf.prebreak _ pageBottomSkip; IF r.prevDepth # nilDimn THEN listWriter.ProduceItem[kerf]; IF item # NIL THEN listWriter.ProduceItem[item]; IF box # NIL THEN r.prevDepth _ box.extent[down] ELSE r.prevDepth _ zeroDimn; IF r.reader.End[] THEN Finish[] ELSE r.reader.Next[]; }; AccumulateKerf: PROCEDURE [self: TSObject.ListReader] RETURNS [explicitList: LIST OF REF ANY _ NIL, penalty: Penalty _ 0] = { SELECT self.CurrentTag[] FROM exception => { p: REF ANY _ self.CurrentItem[]; SELECT TRUE FROM ISTYPE[p, TSObject.Glue] OR ISTYPE[p, TSObject.Kern] => { self.Next[]; [explicitList, penalty] _ AccumulateKerf[self]; explicitList _ CONS[p, explicitList]; }; ISTYPE[p, TSObject.Penalty] => { self.Next[]; [explicitList, penalty] _ AccumulateKerf[self]; penalty _ penalty + NARROW[p, TSObject.Penalty]^.penalty; }; ISTYPE[p, TSObject.Parameter] OR ISTYPE[p, TSObject.ListParameter] => { self.Next[]; [explicitList, penalty] _ AccumulateKerf[self]; }; ENDCASE; }; ENDCASE; }; Concatenate: PROC[a,b: LIST OF REF ANY] RETURNS [LIST OF REF ANY] = { RETURN[IF a=NIL THEN b ELSE CONS[a.first, Concatenate[a.rest, b]]] }; NumberOfBoxesIn: PUBLIC PROCEDURE [list: TSObject.ItemList] RETURNS [numberOfBoxes: INT _ 0] = { listReader: TSObject.ListReader _ list.CreateReader[]; UNTIL listReader.End[] DO IF listReader.CurrentTag[] = exception AND ISTYPE[listReader.CurrentItem[], TSObject.Box] THEN numberOfBoxes _ numberOfBoxes + 1; listReader.Next[]; ENDLOOP; listReader.DestroyReader[]; }; FirstBoxOf: PUBLIC PROCEDURE [list: TSObject.ItemList] RETURNS [box: TSObject.Box _ NIL] = { listReader: TSObject.ListReader _ list.CreateReader[]; UNTIL listReader.End[] OR box#NIL DO IF listReader.CurrentTag[] = exception AND ISTYPE[listReader.CurrentItem[], TSObject.Box] THEN box _ NARROW[listReader.CurrentItem[]]; listReader.Next[]; ENDLOOP; listReader.DestroyReader[]; }; GetSlimBoxFrom: PUBLIC PROCEDURE [list: TSObject.ItemList] RETURNS [box: TSObject.Box] = { IF NumberOfBoxesIn[list] = 1 THEN { box _ FirstBoxOf[list]; TRUSTED { WITH b: box SELECT FROM list => box _ TSOps.Package[b.items.CreateReader[], right, [zeroDimn, nilDimn, nilDimn, nilDimn]].box; ENDCASE; }; } ELSE { list _ TSOps.InsertLeading[list]; box _ TSOps.Package[list.CreateReader[], down, [zeroDimn, nilDimn, zeroDimn, nilDimn]].box; }; }; END. Michael Plass, September 1, 1982 9:40 pm: Put in call to TSObject.DestroyReader. Michael Plass, November 2, 1982 10:31 am. CEDARized. Rick Beach, May 23, 1983 2:56 pm. Moved NumberOfBoxes and FirstBoxOf from TSArtworkImpl to TSOps., AccumulateKerf, Rick <> <> <> <> <> <<>> <<>> <> <> <<>>