TSOpsImpl.mesa
Michael Plass, November 2, 1982 10:30 am
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 ANYNIL, 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.