TSBoxerImpl.mesa
Making boxes from lists
Michael Plass, November 2, 1982 10:33 am
Last Edited by: Beach, May 24, 1983 9:10 am
DIRECTORY TSTypes, TSObject, TSFont, TSGlue, TSOps;
TSBoxerImpl: CEDAR PROGRAM IMPORTS TSObject, TSTypes, TSGlue, TSFont EXPORTS TSOps =
BEGIN OPEN TSTypes;
Package: PUBLIC PROCEDURE [
source: TSObject.ListReader,
direction: Direction,
desired: Dimensions,
itemCount: INTLAST[INT],
front, rear: LIST OF REF ANYNIL
] RETURNS [box: TSObject.Box, markList: TSObject.MarkList] = {
pretend we are doing a horizontal list
rex: Direction ← direction;
lex: Direction ← SELECT direction FROM
right => left, down => up, left => right, up => down, ENDCASE => ERROR;
uex: Direction ← SELECT direction FROM
right => up, down => right, left => down, up => left, ENDCASE => ERROR;
dex: Direction ← SELECT direction FROM
right => down, down => left, left => up, up => right, ENDCASE => ERROR;
totGlue: TSGlue.GlueSum ← TSGlue.zeroGlueSum;
AddGlue: PROC [glue: TSGlue.Glue] = INLINE {OPEN TSGlue;
totGlue.space.texPts ← totGlue.space.texPts + glue.space.texPts;
SELECT ABS[glue.stretch.texPts] FROM
< fil.texPts => totGlue.stretch[0].texPts ← totGlue.stretch[0].texPts + glue.stretch.texPts;
< fill.texPts => totGlue.stretch[1].texPts ← totGlue.stretch[1].texPts + glue.stretch.texPts;
< filll.texPts => totGlue.stretch[2].texPts ← totGlue.stretch[2].texPts + glue.stretch.texPts;
ENDCASE => totGlue.stretch[3].texPts ← totGlue.stretch[3].texPts + glue.stretch.texPts;
SELECT ABS[glue.shrink.texPts] FROM
< fil.texPts => totGlue.shrink[0].texPts ← totGlue.shrink[0].texPts + glue.shrink.texPts;
< fill.texPts => totGlue.shrink[1].texPts ← totGlue.shrink[1].texPts + glue.shrink.texPts;
< filll.texPts => totGlue.shrink[2].texPts ← totGlue.shrink[2].texPts + glue.shrink.texPts;
ENDCASE => totGlue.shrink[3].texPts ← totGlue.shrink[3].texPts + glue.shrink.texPts;
};
maxHeight: Dimn ← desired[uex];
maxDepth: Dimn ← desired[dex];
shiftAmt: Dimn ← source.parameter[shift];
newList: TSObject.ItemList ← TSObject.CreateItemList[producer: NIL];
AppendMarks: PROC [new: TSObject.MarkList] = {
IF new # NIL THEN {
copy: TSObject.MarkList ← NEW[TSObject.MarkListItem ← new^];
AppendMarks[new.link];
copy.link ← markList;
markList ← copy;
};
};
AddException: PROC[x: REF ANY] = {
SELECT TRUE FROM
ISTYPE[x, TSObject.Glue] => {
g: TSObject.Glue ← NARROW[x];
AddGlue[g^];
newList.listWriter.ProduceItem[g];
};
ISTYPE[x, TSObject.Box] => {
b: TSObject.Box ← NARROW[x];
totGlue.space ← AddDimn[totGlue.space, AddDimn[b.extent[lex], b.extent[rex]]];
maxHeight ← MaxDimn[maxHeight, b.extent[uex].AddDimn[shiftAmt]];
maxDepth ← MaxDimn[maxDepth, b.extent[dex].SubDimn[shiftAmt]];
newList.listWriter.ProduceItem[b];
};
ISTYPE[x, TSObject.Kerf] => {
p: LIST OF REF ANYNARROW[x, TSObject.Kerf].join;
WHILE p # NIL DO
AddException[p.first];
p ← p.rest;
ENDLOOP;
};
ISTYPE[x, TSObject.Kern] => {
totGlue.space ← AddDimn[totGlue.space, NARROW[x, TSObject.Kern]^];
newList.listWriter.ProduceItem[x];
};
ISTYPE[x, TSObject.Parameter] => {
newList.listWriter.ProduceItem[x];
shiftAmt ← source.parameter[shift];
};
ISTYPE[x, TSObject.MarkList] => {
AppendMarks[NARROW[x, TSObject.MarkList]];
};
ENDCASE => {};
};
FOR ty: TSObject.ParameterType IN TSObject.ParameterType DO
newList.listWriter.ProduceParameter[ty, source.parameter[ty]];
ENDLOOP;
WHILE front # NIL DO
AddException[front.first];
front ← front.rest;
ENDLOOP;
FOR count: INT ← 0, count+1 UNTIL count = itemCount OR source.End[] DO
SELECT source.CurrentTag[] FROM
char => {
extent: Dimensions ← source.currentFont.CharDimensions[source.CurrentChar[]];
totGlue.space ← AddDimn[totGlue.space, AddDimn[extent[lex], extent[rex]]];
maxHeight ← MaxDimn[maxHeight, extent[uex].AddDimn[shiftAmt]];
maxDepth ← MaxDimn[maxDepth, extent[dex].SubDimn[shiftAmt]];
newList.listWriter.ProduceFromRope[source.currentFont, source.baseRope, source.ropeOffset, char];
};
space => {
AddGlue[source.currentFont.SpaceGlue[]];
newList.listWriter.ProduceFromRope[source.currentFont, source.baseRope, source.ropeOffset, space];
};
hyphen => {};
end => EXIT;
exception => {AddException[source.CurrentItem[]]};
ENDCASE => ERROR;
source.Next[];
ENDLOOP;
WHILE rear # NIL DO
AddException[rear.first];
rear ← rear.rest;
ENDLOOP;
newList.listWriter.ProduceEnd[];
newList.listWriter ← NIL;
IF maxHeight = nilDimn THEN maxHeight ← zeroDimn;
IF maxDepth = nilDimn THEN maxDepth ← zeroDimn;
IF desired[lex] = nilDimn THEN {
IF desired[rex] = nilDimn THEN
desired[lex] ← desired[rex] ← RealDimn[0.5, totGlue.space]
ELSE desired[lex] ← SubDimn[totGlue.space, desired[rex]]
}
ELSE IF desired[rex] = nilDimn THEN
desired[rex] ← SubDimn[totGlue.space, desired[lex]];
desired[uex] ← maxHeight; desired[dex]←maxDepth;
box ← NEW[TSObject.BoxRec ← [
extent: desired,
body: list [
direction: direction,
items: newList,
glueset: TSGlue.SetGlue[
AddDimn[desired[lex],desired[rex]],
TSGlue.GlueFromSum[totGlue]
]
]
]];
};
END.
Michael Plass, September 7, 1982 1:55 pm. newList.listWriter ← NIL;
Michael Plass, November 2, 1982 10:33 am. CEDARized.
Rick Beach, May 13, 1983 1:56 pm. Package now produces marks.