TSTranslateImpl.mesa
Translates from Tioga tree representation to box & glue representation.
Michael Plass, December 8, 1982 3:38 pm
Rick Beach, May 18, 1983 3:15 pm
DIRECTORY
Ascii, Atom, LooksReader, NodeProps, NodeStyle, Rope, RopeReader, TextLooks, TextNode, TSTranslate, TSTranslatePrivate, TSArtwork, TSFont, TSGraphic, TSGlue, TSObject, TSOps, TSTypes;
TSTranslateImpl: PROGRAM
IMPORTS Atom, LooksReader, NodeProps, NodeStyle, Rope, RopeReader, TextNode, TSTranslatePrivate, TSArtwork, TSFont, TSGraphic, TSObject, TSOps, TSTypes
EXPORTS TSTranslate =
BEGIN OPEN TSTypes, TSTranslatePrivate;
FontNotFound: PUBLIC SIGNAL [fontName: Rope.ROPE, location: INT] RETURNS [substitute: Rope.ROPE] = CODE;
ROPE: TYPE = Rope.ROPE;
underAndStrikeThickess: REAL ← 0.4;
underlineDrop: REAL ← -3.0;
strikeoutRise: REAL ← 3.0;
TreeToVlist: PUBLIC PROCEDURE [t: TextNode.Ref, progressProc: TSTranslate.ProgressProc ← NIL] RETURNS [galley: TSObject.ItemList, style: NodeStyle.Ref] =
BEGIN
state: State ← NewState[];
state.level ← 0;
state.currentNode ← t;
state.remainingLength ← 0;
state.progressProc ← progressProc;
state.totalChars ← state.charsToGo ←
TextNode.LocNumber[TextNode.LastLocWithin[t], 0];
galley ← TSObject.CreateItemList[ProduceFromBranch, state];
style ← state.nodeStyle;
style.ApplyAll[t, print];
IF NodeProps.GetProp[t, $Yum] # NIL THEN state.totalChars ← state.charsToGo ← 1;
END;
ProduceFromBranch: TSObject.ProducerProc = TRUSTED {
state: State ← NARROW[listWriter.writerData];
deltaLevel: INTEGER ← 0;
mark, artworkClass: ROPE;
SkipOverBranch: PROCEDURE = {
continuationNode: TextNode.Ref ← TextNode.LastWithin[state.currentNode];
state.charsToGo ← state.totalChars-
TextNode.LocNumber[TextNode.LastLocWithin[state.currentNode], 0];
state.remainingLength ← 0;
state.level ← state.level +
TextNode.Level[continuationNode] - TextNode.Level[state.currentNode];
state.currentNode ← continuationNode;
};
ProduceMarkBranch: PROCEDURE = {
contents: TSObject.ItemList;
box: TSObject.Box;
newMark: TSObject.MarkList ← NEW[TSObject.MarkListItem];
Inhibit infinite recursion. (remove mark prop)
NodeProps.RemProp[state.currentNode, $Mark];
contents ← TreeToVlist[state.currentNode].galley;
InitializeStateForNewNode[contents.listWriter, NARROW[contents.listWriter.writerData]];
box ← TSOps.GetSlimBoxFrom[contents];
newMark.link ← NIL;
newMark.markKind ← Atom.MakeAtom[mark];
newMark.markValue ← box;
listWriter.ProduceItem[newMark];
Reinstate Mark property now that branch has been packaged.
NodeProps.PutProp[state.currentNode, $Mark, mark];
};
ProduceArtworkBranch: PROCEDURE = {
object: TSGraphic.Object;
extent: Dimensions;
box: TSObject.Box;
objectFromBranch: TSArtwork.ObjectFromBranchProc ← TSArtwork.Lookup[artworkClass];
object ← objectFromBranch[state.currentNode];
extent ← object.Layout[
maxX: state.galleyWidth,
maxY: RealDimn[6, in],
suggestedX: state.galleyWidth
];
box ← NEW[graphic TSObject.BoxRec ← [extent, graphic [object]]];
listWriter.ProduceItem[box];
};
IF state.remainingLength = 0 THEN {
DO -- move forward in the branch producing marks before initializing a text node
[state.currentNode, deltaLevel] ← TextNode.Forward[state.currentNode];
state.level ← state.level + deltaLevel;
IF state.progressProc # NIL THEN
state.progressProc[100*(state.totalChars-state.charsToGo)/(state.totalChars+0.01)];
IF state.level <= 0 THEN {
listWriter.ProduceItem[TSObject.fillGlue];
listWriter.ProduceEnd[];
IF state.progressProc # NIL THEN
state.progressProc[100];
RETURN
};
mark ← NARROW[NodeProps.GetProp[state.currentNode, $Mark]];
IF mark.Length = 0 THEN EXIT;
ProduceMarkBranch[];
SkipOverBranch[];
IF state.level <= 0 THEN {
listWriter.ProduceItem[TSObject.fillGlue];
listWriter.ProduceEnd[];
IF state.progressProc # NIL THEN
state.progressProc[100];
RETURN
};
ENDLOOP;
InitializeStateForNewNode[listWriter, state];
};
artworkClass ← NARROW[NodeProps.GetProp[state.currentNode, $ArtworkClass]];
IF artworkClass.Length = 0 OR state.level=0 THEN ProduceFromTextNode[listWriter, state]
ELSE {
ProduceArtworkBranch[];
SkipOverBranch[];
IF state.level <= 0 THEN {
listWriter.ProduceItem[TSObject.fillGlue];
listWriter.ProduceEnd[];
IF state.progressProc # NIL THEN
state.progressProc[100];
RETURN
};
};
};
ProduceFromTextNode: PROCEDURE [listWriter: TSObject.ListWriter, state: State] = {
OPEN state^;
r: TSObject.ListReader;
hlist: TSObject.ItemList ← TSObject.CreateItemList[producer: NIL];
hlistWriter: TSObject.ListWriter ← hlist.listWriter;
hlist.listWriter ← NIL;
IF leftFillParameter # NIL THEN hlistWriter.ProduceItem[leftFillParameter];
IF rightFillParameter # NIL THEN hlistWriter.ProduceItem[rightFillParameter];
IF leftFillParameter # NIL THEN
FOR p: LIST OF REF ANY ← leftFillParameter.listParameter, p.rest UNTIL p=NIL DO
hlistWriter.ProduceItem[p.first];
ENDLOOP;
IF firstIndentItem # NIL THEN {hlistWriter.ProduceItem[firstIndentItem]; firstIndentItem ← NIL};
oldLooks ← TextLooks.allLooks; -- to force apply on first char
UNTIL remainingLength = 0 DO
ropeIndex: INT ← ropeReader.GetIndex[];
char: CHAR ← RopeReader.Get[ropeReader];
looks: TextLooks.Looks ← LooksReader.Get[looksReader];
charsToGo ← charsToGo-1;
remainingLength ← remainingLength - 1;
IF looks # oldLooks OR underlining#None OR strikeout#None THEN {
under, strike: Dimn ← zeroDimn;
GetNewLooks[hlistWriter, state, looks ! TSFont.FontNotFound => TRUSTED {substituteName ← SIGNAL FontNotFound[name, state.totalChars-state.charsToGo]}];
SELECT underlining FROM
None => {};
LettersAndDigits => IF char IN ['A..'Z] OR char IN ['a..'z] OR char IN ['0..'9] THEN under ← Pt[underAndStrikeThickess];
Visible => IF char IN (' ..'~] THEN under ← Pt[underAndStrikeThickess];
All => under ← Pt[underAndStrikeThickess];
ENDCASE => ERROR;
SELECT strikeout FROM
None => {};
LettersAndDigits => IF char IN ['A..'Z] OR char IN ['a..'z] OR char IN ['0..'9] THEN strike ← Pt[underAndStrikeThickess];
Visible => IF char IN (' ..'~] THEN strike ← Pt[underAndStrikeThickess];
All => strike ← Pt[underAndStrikeThickess];
ENDCASE => ERROR;
hlistWriter.ProduceParameter[underlineThickness, under];
hlistWriter.ProduceParameter[strikeoutThickness, strike];
IF under#zeroDimn THEN hlistWriter.ProduceParameter[underlineBottom, Pt[underlineDrop]];
IF strike#zeroDimn THEN hlistWriter.ProduceParameter[strikeoutBottom, Pt[strikeoutRise]];
};
SELECT char FROM
Ascii.CR => EXIT;
Ascii.TAB => {
hlistWriter.ProduceEnd[];
hlist ← Tabify[hlist, state];
hlistWriter ← hlist.listWriter;
hlist.listWriter ← NIL;
};
Ascii.SP => hlistWriter.ProduceFromRope[curfont, rope, ropeIndex, space];
ENDCASE => hlistWriter.ProduceFromRope[curfont, rope, ropeIndex, char];
ENDLOOP;
IF progressProc#NIL THEN progressProc[100*(totalChars-charsToGo)/(totalChars+0.01)];
FOR p: LIST OF REF ANY ← endFill, p.rest UNTIL p=NIL DO
hlistWriter.ProduceItem[p.first];
ENDLOOP;
hlistWriter.ProduceEnd[];
r ← TSOps.BreakUp[hlist, right, galleyWidth].CreateReader[];
UNTIL r.End[] DO
IF r.CurrentTag[] = exception THEN listWriter.ProduceItem[r.CurrentItem[]]
ELSE ERROR;
r.Next[];
ENDLOOP;
r.DestroyReader[];
ProduceBottomLeadingStretchAndShrink[listWriter, state];
};
END.
Michael Plass, June 28, 1982 8:56 am. Renamed from TPTranslateImpl.
Michael Plass, July 15, 1982 11:20 am. Fixed it so CRs do not cause firstIndent on the next line.
Michael Plass, September 15, 1982 10:54 am. Changed Rope.SP, etc, to refer to Ascii.
Michael Plass, November 12, 1982 10:53 am. Added underline and strikeout.
Michael Plass, November 17, 1982 9:13 am. Changed TreeToVlist to return style.
Michael Plass, November 17, 1982 12:09 pm. Added FontNotFound.
Michael Plass, December 8, 1982 3:38 pm. Took account of layout proc change.
Rick Beach, May 18, 1983 8:26 am. Added marks to ProduceFromBranch., Rick
Edited on May 18, 1983 8:24 am, by Beach
Move production of Mark branch inside test for initialize new branch.
Create: ProduceMarkBranch (local of ProduceFromBranch), ProduceArtworkBranch (local of ProduceFromBranch)