DIRECTORY Atom, TSTypes, TSObject, TSOps, TSDumper, TSFont, TSGlue, TSOutput, NodeStyle, NodeStyleWorks, TJaM, Rope, TSJaMPageBuilder ; TSJaMPageBuilderImpl: CEDAR PROGRAM IMPORTS Atom, TSTypes, TSObject, TSOps, TSDumper, TSFont, TSOutput, NodeStyle, NodeStyleWorks, TJaM EXPORTS TSJaMPageBuilder = BEGIN OPEN TSTypes; ROPE: TYPE = Rope.ROPE; Frame: TYPE = TJaM.Frame; Handle: TYPE = REF TPStateRec; TPStateRec: TYPE = RECORD [ pageReader: TSObject.ListReader, currentMarks: TSObject.MarkList, topMargin, leftMargin, pageHeight, paperHeight, paperWidth: Dimn, columns: NAT, output: TSOutput.Handle, curFont: TSFont.Ref, styleName: ATOM, documentName: ROPE, aborted: BOOLEAN _ FALSE ]; AbortCheck: SIGNAL RETURNS [stop: BOOL] ~ CODE; RunPageBuilder: PUBLIC PROCEDURE [ galley: TSObject.ItemList, style: NodeStyle.Ref, output: TSOutput.Handle, abortCheckProc: TSJaMPageBuilder.AbortCheckProc _ NIL, documentName: Rope.ROPE _ NIL -- only a hint ] RETURNS [aborted: BOOLEAN] = { styleName: ATOM ~ style.GetStyleName[]; frame: Frame _ NodeStyleWorks.GetFrame[style: style, styleName: styleName, kind: print]; handle: Handle _ NEW[TPStateRec]; leadedGalley: TSObject.ItemList _ TSOps.InsertLeading[galley]; handle.styleName _ styleName; RegisterJaMProcs[frame]; handle.paperHeight _ Pt[style.GetPageLength[]]; handle.paperWidth _ Pt[style.GetPageWidth[]]; handle.pageHeight _ Pt[style.GetPageLength[]-style.GetTopMargin[]-style.GetHeaderMargin[]-style.GetFooterMargin[]-style.GetBottomMargin[]]; handle.topMargin _ Pt[style.GetTopMargin[]]; handle.leftMargin _ Pt[style.GetLeftMargin[]]; handle.columns _ style.GetColumns[]; handle.documentName _ documentName; handle.pageReader _ TSOps.BreakUp[ list: TSOps.InsertLeading[galley], direction: down, size: handle.pageHeight ].CreateReader[]; handle.output _ output; frame.propList _ Atom.PutPropOnList[frame.propList, $PageBuilderHandle, handle]; TJaM.Execute[frame, TJaM.CvX[pageBuilderName] ! AbortCheck => {RESUME[abortCheckProc[]]}]; frame.propList _ Atom.RemPropFromList[frame.propList, $PageBuilderHandle]; NodeStyleWorks.FreeFrame[frame: frame, styleName: styleName, kind: print]; aborted _ handle.aborted; }; HandleFromFrame: PROC [f: Frame] RETURNS [Handle] ~ { RETURN [NARROW[Atom.GetPropFromList[f.propList, $PageBuilderHandle]]] }; pageBuilderName: ATOM = Atom.MakeAtom["PageBuilder"]; PopList: PROCEDURE [f: Frame] RETURNS [itemList: TSObject.ItemList] = BEGIN list: LIST OF REF ANY _ NIL; count: INT _ TJaM.PopInt[f]; THROUGH [0..count) DO item: REF ANY _ TJaM.Pop[f]; IF item # NIL THEN list _ CONS[item, list]; ENDLOOP; itemList _ TSObject.ItemListFromExplicitList[list]; END; Page: PROCEDURE [f: Frame] = BEGIN -- Pushes the next page box onto the stack handle: Handle _ HandleFromFrame[f]; handle.aborted _ SIGNAL AbortCheck[]; DO -- until we find a page box or empty the page list IF handle.aborted OR handle.pageReader = NIL OR handle.pageReader.End[] THEN { TJaM.PushBool[f, FALSE]; IF handle.pageReader # NIL THEN handle.pageReader.DestroyReader[]; handle.pageReader _ NIL; EXIT } ELSE { IF ISTYPE[handle.pageReader.CurrentItem[], TSObject.MarkList] THEN { thisPageMarks: TSObject.MarkList _ NARROW[handle.pageReader.CurrentItem[], TSObject.MarkList]; handle.currentMarks _ MergeMarkLists[thisPageMarks, handle.currentMarks]; handle.pageReader.Next[]; LOOP; }; TJaM.Push[f, handle.pageReader.CurrentItem[]]; handle.pageReader.Next[]; TJaM.PushBool[f, TRUE]; EXIT }; ENDLOOP; END; ShipOut: PROCEDURE [f: Frame] = BEGIN -- Sends a constructed page to the outside world handle: Handle _ HandleFromFrame[f]; item: REF ANY _ TJaM.Pop[f]; handle.output.newPageProc[handle.output]; WITH item SELECT FROM box: TSObject.Box => { IF handle.output.pageSizeProc # NIL THEN handle.output.pageSizeProc[ handle.output, handle.paperHeight, handle.paperWidth ]; handle.output.BoxOut[ xRef: handle.leftMargin, yRef: SubDimn[handle.paperHeight, handle.topMargin], box: box^ ]; }; ENDCASE => NULL; END; BoxFromHList: PROCEDURE [list: TSObject.ItemList] RETURNS [box: TSObject.Box] = { source: TSObject.ListReader _ list.CreateReader[]; box _ TSOps.Package[source: source, direction: right, desired: [zeroDimn,nilDimn,nilDimn,nilDimn]].box; source.DestroyReader[]; }; Columns: PROCEDURE [f: Frame] = BEGIN handle: Handle _ HandleFromFrame[f]; TJaM.PushInt[f, handle.columns]; END; DocumentName: PROCEDURE [f: Frame] = BEGIN handle: Handle _ HandleFromFrame[f]; TJaM.PushRope[f, handle.documentName]; END; TextBox: PROCEDURE [f: Frame] = BEGIN handle: Handle _ HandleFromFrame[f]; rope: ROPE _ TJaM.PopRope[f]; IF handle.curFont = NIL THEN handle.curFont _ TSFont.Lookup["Helvetica"]; TJaM.Push[f, BoxFromHList[TSOps.ItemListFromRope[handle.curFont, rope]]]; END; TextFont: PROCEDURE [f: Frame] = BEGIN handle: Handle _ HandleFromFrame[f]; fontSize: Dimn _ RealDimn[TJaM.PopReal[f], pt]; fontName: ROPE _ TJaM.PopRope[f]; handle.curFont _ TSFont.Lookup[fontName, fontSize]; END; Vbox: PROCEDURE [f: Frame] = BEGIN source: TSObject.ListReader _ PopList[f].CreateReader[]; box: TSObject.Box _ TSOps.Package[ source: source, direction: down, desired: [nilDimn, nilDimn, zeroDimn, nilDimn] ].box; TJaM.Push[f, box]; source.DestroyReader[]; END; Hbox: PROCEDURE [f: Frame] = BEGIN TJaM.Push[f, BoxFromHList[PopList[f]]]; END; VboxTo: PROCEDURE [f: Frame] = BEGIN size: Dimn _ RealDimn[TJaM.PopReal[f], pt]; source: TSObject.ListReader _ PopList[f].CreateReader[]; TJaM.Push[f, TSOps.Package[ source: source, direction: down, desired: [nilDimn, nilDimn, zeroDimn, size] ].box]; source.DestroyReader[]; END; HboxTo: PROCEDURE [f: Frame] = BEGIN size: Dimn _ RealDimn[TJaM.PopReal[f], pt]; source: TSObject.ListReader _ PopList[f].CreateReader[]; TJaM.Push[f, TSOps.Package[ source: source, direction: right, desired: [zeroDimn, size, nilDimn, nilDimn] ].box]; source.DestroyReader[]; END; fillGlue: TSObject.Glue = NEW[TSGlue.Glue _ [zeroDimn, TSGlue.fill, zeroDimn]]; Fill: PROCEDURE [f: Frame] = BEGIN TJaM.Push[f, fillGlue]; END; DumpBox: PROCEDURE [f: Frame] = BEGIN TSDumper.DumpList[TSObject.SingletonList[TJaM.Pop[f]]]; END; emptyBox: TSObject.Box = NEW[TSObject.BoxRec _ [[zeroDimn, zeroDimn, zeroDimn, zeroDimn], empty[]]]; GetMark: PROCEDURE [f: Frame] = { handle: Handle _ HandleFromFrame[f]; markKind: ROPE _ TJaM.PopRope[f]; IF handle.currentMarks # NIL THEN { markAtom: ATOM _ Atom.MakeAtom[markKind]; l: REF TSObject.MarkListItem _ handle.currentMarks; UNTIL l = NIL OR l.markKind = markAtom DO l _ l.link; ENDLOOP; IF l = NIL THEN TJaM.Push[f, emptyBox] ELSE TJaM.Push[f, l.markValue]; } ELSE TJaM.Push[f, emptyBox]; }; GetFirstMark: PROCEDURE [f: Frame] = { handle: Handle _ HandleFromFrame[f]; markKind: ROPE _ TJaM.PopRope[f]; IF handle.currentMarks # NIL THEN { markAtom: ATOM _ Atom.MakeAtom[markKind]; l: REF TSObject.MarkListItem _ handle.currentMarks; last: REF TSObject.MarkListItem _ NIL; UNTIL l = NIL DO IF l.markKind = markAtom THEN last _ l; l _ l.link; ENDLOOP; IF last = NIL THEN TJaM.Push[f, emptyBox] ELSE TJaM.Push[f, last.markValue]; } ELSE TJaM.Push[f, emptyBox]; }; MergeMarkLists: PROCEDURE [new, old: TSObject.MarkList] RETURNS [TSObject.MarkList] = { p, q, r: TSObject.MarkList; p _ old; UNTIL p = NIL DO r _ p; q _ p.link; UNTIL q = NIL DO IF p.markKind = q.markKind THEN r.link _ q.link ELSE r _ q; q _ q.link; ENDLOOP; p _ p.link; ENDLOOP; p _ new; UNTIL p = NIL OR p.link = NIL DO p _ p.link; ENDLOOP; IF p = NIL THEN new _ old ELSE p.link _ old; RETURN [new]; }; ExchBox: PROCEDURE [f: Frame] = { item1: REF ANY _ TJaM.Pop[f]; item2: REF ANY _ TJaM.Pop[f]; TJaM.Push[f, item1]; TJaM.Push[f, item2]; }; RegisterJaMProcs: PROCEDURE [f: Frame] = BEGIN OPEN NodeStyleWorks; RegisterStyleCommand[f, Atom.MakeAtom[".page"], Page]; -- -> .true . OR -> .false RegisterStyleCommand[f, Atom.MakeAtom[".getmark"], GetMark]; -- -> (markkind) -> RegisterStyleCommand[f, Atom.MakeAtom[".getfirstmark"], GetFirstMark]; -- -> (markkind) -> RegisterStyleCommand[f, Atom.MakeAtom[".columns"], Columns]; -- -> .true . OR -> .false RegisterStyleCommand[f, Atom.MakeAtom[".shipout"], ShipOut]; -- -> . The box is sent out RegisterStyleCommand[f, Atom.MakeAtom[".documentname"], DocumentName]; -- -> string . RegisterStyleCommand[f, Atom.MakeAtom[".textbox"], TextBox]; -- string -> . uses current font RegisterStyleCommand[f, Atom.MakeAtom[".textfont"], TextFont]; -- fontnamestring fontpointsize -> . sets current font RegisterStyleCommand[f, Atom.MakeAtom[".vbox"], Vbox]; -- ... n -> . RegisterStyleCommand[f, Atom.MakeAtom[".hbox"], Hbox]; -- ... n -> . RegisterStyleCommand[f, Atom.MakeAtom[".vboxto"], VboxTo]; -- ... n height -> . RegisterStyleCommand[f, Atom.MakeAtom[".hboxto"], HboxTo]; -- ... n height -> . RegisterStyleCommand[f, Atom.MakeAtom[".fill"], Fill]; -- -> . RegisterStyleCommand[f, Atom.MakeAtom[".dumpbox"], DumpBox]; -- -> . RegisterStyleCommand[f, Atom.MakeAtom[".exchbox"], ExchBox]; -- -> END; END. :TSJaMPageBuilderImpl.mesa Edited by: Maxwell, January 25, 1983 2:39 pm Michael Plass, April 2, 1985 2:13:04 pm PST Last Edited by: Beach, May 7, 1984 4:13:18 pm PDT This proc can dump boxes, for use in debugging Merge the new and old lists of marks into one list with old duplicates eliminated, preserving order. Using a niave n**2 search, eliminate duplicates from the old list. Find the end of the new list to concatenate the old one. Michael Plass, September 1, 1982 9:21 pm: Put in calls to TSObject.DestroyReader. Michael Plass, November 2, 1982 2:39 pm. Tioga formatted. Michael Plass, November 12, 1982 10:11 am. pZone. Michael Plass, November 16, 1982 2:36 pm. Changed to use some of the page layout parameters. Michael Plass, November 17, 1982 9:34 am. Fixed frame and style stuff. Michael Plass, November 17, 1982 11:13 am. Fixed bug that prevented .page from working after the end marker was sent. Michael Plass, February 15, 1983 1:04 pm. Removed dependency on JaMTypeScript. Rick Beach, May 17, 1983 10:17 am. Added .getmark routines., Rick Edited on May 17, 1983 10:16 am, by Beach Added .exchbox to permit a layout style to get a page, then get headers which must precede the page. Edited on May 24, 1983 8:52 am, by Beach Added MergeMarkLists to properly maintain a page history of marks., MergeMarkLists Edited on January 10, 1984 9:33 am, by Plass Added calls to TSWrecker. Michael Plass, March 12, 1985 2:22:10 pm PST JaM --> TJaM changes to: DIRECTORY, TSJaMPageBuilderImpl, RunPageBuilder, PopRope, PushRope, Page, Columns, TextFont, Vbox, Hbox, VboxTo, HboxTo Κ Μ– "cedar" style˜Jšœ™J™,Jšœ,™,J™1šΟk ˜ J˜J˜J˜ J˜J˜ J˜J˜J˜ J˜ J˜J˜J˜J˜J˜J˜—šœ ˜#Jš˜J˜[Jšœ˜—Jšœœ ˜J˜Jšœœœ˜Jšœœ˜J˜Jšœœœ ˜šœ œœ˜J˜ J˜ J˜AJšœ œ˜ J˜J˜Jšœ˜Jšœœ˜Jšœ œ˜J˜J˜—š œ œœœœ˜/J˜—šΟnœœ œ˜"J˜J˜J˜Jšœ2œ˜6JšœœœΟc˜,J˜Jšœ œ˜Jšœ œ˜'J•StartOfExpansionI[style: NodeStyle.Ref, styleName: ATOM, kind: NodeStyleOps.OfStyle]šœX˜XJšœœ ˜!J˜>Jšœ˜J˜Jšœ/˜/Jšœ-˜-Jšœ‹˜‹Jšœ,˜,Jšœ.˜.Jšœ$˜$J˜#˜"J˜"J˜J˜J˜—J˜JšœP˜PJšœ?œ˜ZJšœJ˜JJ–F[frame: TJaM.Frame, styleName: ATOM, kind: NodeStyleOps.OfStyle]šœJ˜JJ˜J˜J˜—šžœœ œ ˜5Jšœœ7˜EJšœ˜J˜—Jšœ5˜5J˜šžœ œ œ ˜EJš˜Jš œœœœœœ˜Jšœœ˜šœ ˜Jšœœœ˜Jšœœœœ ˜+Jšœ˜—J˜3Jšœ˜J˜—šžœ œ ˜JšœŸ*˜0Jšœ$˜$Jšœœ˜%šœŸ2˜5šœœœœ˜NJšœœ˜Jšœœ#˜BJšœœ˜Jš˜J˜—šœ˜šœœ5œ˜DJšœ#œ5˜^JšœI˜IJšœ˜Jšœ˜J˜—Jšœ.˜.J˜Jšœœ˜Jš˜J˜—Jšœ˜—Jšœ˜J˜—šžœ œ ˜JšœŸ0˜6Jšœ$˜$Jšœœœ˜J˜)šœœ˜šœ˜šœœ˜(šœ˜Jšœ4˜4Jšœ˜——˜J˜J˜4Jšœ ˜ J˜—Jšœ˜—Jšœœ˜—Jšœ˜J˜—šž œ œœ˜QJ˜2J˜gJ˜J˜J˜—šžœ œ ˜Jš˜Jšœ$˜$Jšœ ˜ Jšœ˜J˜—šž œ œ ˜$Jš˜Jšœ$˜$J˜&Jšœ˜J˜—šžœ œ ˜Jš˜Jšœ$˜$Jšœœ˜Jšœœœ-˜IJšœI˜IJšœ˜J˜—šžœ œ ˜ Jš˜Jšœ$˜$J˜/Jšœ œ˜!J˜3Jšœ˜J˜—šžœ œ ˜Jš˜J˜8˜"J˜J˜J˜.J˜—Jšœ˜J˜Jšœ˜J˜—šžœ œ ˜Jš˜Jšœ'˜'Jšœ˜J˜—šžœ œ ˜Jš˜J˜+J˜8šœ˜J˜J˜J˜,J˜—J˜Jšœ˜J˜—šžœ œ ˜Jš˜J˜+J˜8šœ˜J˜J˜J˜,J˜—J˜Jšœ˜J˜—Jšœœ2˜OJ˜šžœ œ ˜Jš˜Jšœ˜Jšœ˜J˜—JšŸ.™.šžœ œ ˜Jš˜J˜7Jšœ˜J˜—JšœœH˜dšΟbœ œ˜!Jšœ$˜$Jšœ œ˜!šœœœ˜#Jšœ œ˜)J˜3šœœœ˜)J˜ Jš˜—Jšœœœ˜&Jšœ˜J˜—Jšœ˜J˜J˜—š  œ œ˜&Jšœ$˜$Jšœ œ˜!šœœœ˜#Jšœ œ˜)Jšœœ-˜3Jšœœœ˜&šœœ˜Jšœœ ˜'J˜ Jš˜—Jšœœœ˜)Jšœ˜"J˜—Jšœ˜J˜J˜—šžœ œœ˜WJ™dJšœ˜J™BJ˜šœœ˜J˜J˜ šœœ˜Jšœœœ˜;J˜ Jšœ˜—J˜ Jšœ˜—J™8J˜š œœœ œ˜ J˜ Jšœ˜—Jšœœœ œ˜,Jšœ˜ Jšœ˜J˜—šžœ œ˜!Jšœœœ˜Jšœœœ˜Jšœ˜Jšœ˜J˜J˜—šžœ œ ˜(Jšœœ˜Jšœ7Ÿ%˜\Jšœ=Ÿ2˜oJšœGŸ2˜yJšœ=Ÿ%˜bJšœ=Ÿ!˜^JšœGŸ˜VJšœ=Ÿ&˜cJšœ?Ÿ7˜vJšœ7Ÿ+˜bJšœ7Ÿ+˜bJšœ;Ÿ2˜mJšœ;Ÿ2˜mJšœ7Ÿ˜JJšœ=Ÿ ˜JJšœ=Ÿ!˜^Jšœ˜J˜—Jšœ˜J˜J™RJšœ9™9Jšœ1™1Jšœ\™\JšœF™FJšœu™uJšœN™NJšœ;Οr™A™)Jšœ‘œV™d—™(Jšœ‘œ.‘™R—™,Jšœ™—codešœ,™,K™ Kšœ ‘w™ƒ—Kšž™—…—#ΰ4ζ