<> <> DIRECTORY TSTypes, TSObject, TSFont, TSGlue, TSOps; TSOpsImpl: CEDAR PROGRAM IMPORTS TSTypes, TSFont, TSObject 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 ]; 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]; 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; 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]]] }; END. Michael Plass, September 1, 1982 9:40 pm: Put in call to TSObject.DestroyReader. Michael Plass, November 2, 1982 10:31 am. CEDARized.