1 // TeXFotBuilder.cxx: a Generic TeX backend for Jade
2 // Written by David Megginson <dmeggins@microstar.com>
3 // With changes from Sebastian Rahtz <s.rahtz@elsevier.co.uk>
4 // Last Modification: August 6th, 1998
5 
6 // Table Support: Kathleen Marszalek <kmarszal@watarts.uwaterloo.ca>
7 // Version: 1.0b7
8 // Last Modification: July 7th, 1998
9 
10 #include "config.h"
11 #include "TeXFOTBuilder.h"
12 #include "TeXMessages.h"
13 #include "MessageArg.h"
14 #include "TmpOutputByteStream.h"
15 #include <stdio.h>
16 #include <stdlib.h>
17 
18 #undef TEXDEBUG
19 #undef NDEBUG
20 #include <assert.h>
21 
22 #ifdef DSSSL_NAMESPACE
23 namespace DSSSL_NAMESPACE {
24 #endif
25 
26 // --------- TeXTmpOutputByteStream ------------------------------------------
27 
28 struct TeXTmpOutputByteStream : public TmpOutputByteStream {
TeXTmpOutputByteStreamDSSSL_NAMESPACE::TeXTmpOutputByteStream29   TeXTmpOutputByteStream() : TmpOutputByteStream() {}
30   void commit( OutputByteStream &os ) const;
31 };
32 
33 // ----------------------------------------------------------------------------
34 
35 struct LengthInPoints {
LengthInPointsDSSSL_NAMESPACE::LengthInPoints36   LengthInPoints( long l_ ) : l( l_ ) {}
37   long l;
38 };
39 
commit(OutputByteStream & os) const40 void TeXTmpOutputByteStream::commit( OutputByteStream &os ) const {
41 
42   TmpOutputByteStream::Iter iter( *this );
43   const char *s;
44   size_t n;
45 
46   while( iter.next( s, n ) ) {
47     os.sputn( s, n );
48   }
49 }
50 
51 // --------- TeXFOTBuilder ----------------------------------------------------
52 
53 class TeXFOTBuilder : public SerialFOTBuilder {
54 public:
55 #ifdef TEXDEBUG
curInstance()56   static TeXFOTBuilder &curInstance() { assert( CurInstance != NULL ); return *CurInstance; }
57   // used for testing only: otherwise code is re-entrant
58 #endif
59   struct PageFloatNIC {
60     ~PageFloatNIC();
61     StringC placement;
62   };
63   class TeXExtensionFlowObj : public FOTBuilder::ExtensionFlowObj {
64   public:
65     virtual void atomic(TeXFOTBuilder &, const NodePtr &) const = 0;
66   };
67   class TeXCompoundExtensionFlowObj : public FOTBuilder::CompoundExtensionFlowObj {
68   public:
69     virtual void start(TeXFOTBuilder &, const NodePtr &) const = 0;
70     virtual void end(TeXFOTBuilder &) const = 0;
71   };
72   class PageFloatFlowObj : public TeXCompoundExtensionFlowObj {
start(TeXFOTBuilder & fotb,const NodePtr &) const73     void start(TeXFOTBuilder &fotb, const NodePtr &) const {
74       fotb.startPageFloat(nic_);
75     }
end(TeXFOTBuilder & fotb) const76     void end(TeXFOTBuilder &fotb) const {
77       fotb.endPageFloat();
78     }
hasNIC(const StringC & name) const79     bool hasNIC(const StringC &name) const {
80       return name == "placement" ;
81     }
setNIC(const StringC &,const Value & value)82     void setNIC(const StringC &, const Value &value) {
83       value.convertString(nic_.placement);
84       }
copy() const85     ExtensionFlowObj *copy() const { return new PageFloatFlowObj(*this); }
86   public:
PageFloatFlowObj()87     PageFloatFlowObj() {}
88   private:
89     PageFloatNIC nic_;
90     StringC name_;
91     StringC placement;
92   };
93   class PageFootnoteFlowObj : public TeXCompoundExtensionFlowObj {
start(TeXFOTBuilder & fotb,const NodePtr &) const94     void start(TeXFOTBuilder &fotb, const NodePtr &) const {
95       fotb.startPageFootnote();
96     }
end(TeXFOTBuilder & fotb) const97     void end(TeXFOTBuilder &fotb) const {
98       fotb.endPageFootnote();
99     }
copy() const100     ExtensionFlowObj *copy() const { return new PageFootnoteFlowObj(*this); }
101   public:
PageFootnoteFlowObj()102     PageFootnoteFlowObj() {}
103   private:
104   };
105   //////////////////////////////////////////////////////////////////////
106   // Constructor and destructor.
107   //////////////////////////////////////////////////////////////////////
108 
109   TeXFOTBuilder(OutputByteStream *, Messenger *mgr);
110   ~TeXFOTBuilder();
111 
112   //////////////////////////////////////////////////////////////////////
113   // Atomic flow objects
114   //////////////////////////////////////////////////////////////////////
115   void extension(const ExtensionFlowObj &fo, const NodePtr &);
116   void startExtensionSerial(const CompoundExtensionFlowObj &fo, const NodePtr &nd);
117   void endExtensionSerial(const CompoundExtensionFlowObj &fo);
118   void start();
119   void end();
120   void charactersFromNode(const NodePtr &, const Char *, size_t);
121   void setPreserveSdata(bool);
122   void startPageFloat(const PageFloatNIC &);
123   void endPageFloat();
124   void setPageFloatNIC(const PageFloatNIC &);
125   void startPageFootnote();
126   void endPageFootnote();
127 
128   void characters(const Char *, size_t);
129   void character(const CharacterNIC &);
130   void paragraphBreak(const ParagraphNIC &);
131   void externalGraphic(const ExternalGraphicNIC &);
132   void rule(const RuleNIC &);
133   void alignmentPoint();
134   void pageNumber();
135   void formattingInstruction(const StringC &);
136   void tableColumn(const TableColumnNIC &);
137   void tableCellBeforeRowBorder();
138   void tableCellAfterRowBorder();
139   void tableCellBeforeColumnBorder();
140   void tableCellAfterColumnBorder();
141 
142   void fractionBar();
143   void radicalRadical(const CharacterNIC &);
144   void radicalRadicalDefaulted();
145   void currentNodePageNumber(const NodePtr &);
146 
147   //////////////////////////////////////////////////////////////////////
148   // Non-atomic flow objects
149   //////////////////////////////////////////////////////////////////////
150 
151   void startSequence();
152   void endSequence();
153   void startLineField(const LineFieldNIC &);
154   void endLineField();
155   void startParagraph(const ParagraphNIC &);
156   void endParagraph();
157   void startDisplayGroup(const DisplayGroupNIC &);
158   void endDisplayGroup();
159   void startScroll();
160   void endScroll();
161   void startScore(Char);
162   void startScore(const LengthSpec &);
163   void startScore(Symbol);
164   void endScore();
165   void startLeader(const LeaderNIC &);
166   void endLeader();
167   void startSideline();
168   void endSideline();
169   void startBox(const BoxNIC &);
170   void endBox();
171   // Tables
172   void startTable(const TableNIC &);
173   void endTable();
174   // A call for each border is made immediately
175   // after startTable(), each preceded by any appropriate set*() calls.
176   void tableBeforeRowBorder();
177   void tableAfterRowBorder();
178   void tableBeforeColumnBorder();
179   void tableAfterColumnBorder();
180   void startTablePartSerial(const TablePartNIC &);
181   void endTablePartSerial();
182   void startTableRow();
183   void endTableRow();
184   void startTableCell(const TableCellNIC &);
185   void endTableCell();
186   void startSimplePageSequence();
187   void endSimplePageSequence();
188   // Headers and footers are treated like a separate port.
189   void startSimplePageSequenceHeaderFooter(unsigned);
190   void endSimplePageSequenceHeaderFooter(unsigned);
191   // page-number sosofo
192 
193   void startTablePartHeader();
194   void endTablePartHeader();
195   void startTablePartFooter();
196   void endTablePartFooter();
197   void startMathSequence();
198   void endMathSequence();
199   void startFractionSerial();
200   void endFractionSerial();
201   void startFractionNumerator();
202   void endFractionNumerator();
203   void startFractionDenominator();
204   void endFractionDenominator();
205   void startUnmath();
206   void endUnmath();
207   void startSuperscript();
208   void endSuperscript();
209   void startSubscript();
210   void endSubscript();
211   void startScriptSerial();
212   void endScriptSerial();
213   void startScriptPreSup();
214   void endScriptPreSup();
215   void startScriptPreSub();
216   void endScriptPreSub();
217   void startScriptPostSup();
218   void endScriptPostSup();
219   void startScriptPostSub();
220   void endScriptPostSub();
221   void startScriptMidSup();
222   void endScriptMidSup();
223   void startScriptMidSub();
224   void endScriptMidSub();
225   void startMarkSerial();
226   void endMarkSerial();
227   void startMarkOver();
228   void endMarkOver();
229   void startMarkUnder();
230   void endMarkUnder();
231   void startFenceSerial();
232   void endFenceSerial();
233   void startFenceOpen();
234   void endFenceOpen();
235   void startFenceClose();
236   void endFenceClose();
237   void startRadicalSerial();
238   void endRadicalSerial();
239   void startRadicalDegree();
240   void endRadicalDegree();
241   void startMathOperatorSerial();
242   void endMathOperatorSerial();
243   void startMathOperatorOperator();
244   void endMathOperatorOperator();
245   void startMathOperatorLowerLimit();
246   void endMathOperatorLowerLimit();
247   void startMathOperatorUpperLimit();
248   void endMathOperatorUpperLimit();
249   void startGrid(const GridNIC &);
250   void endGrid();
251   void startGridCell(const GridCellNIC &);
252   void endGridCell();
253   void startNode(const NodePtr &, const StringC &);
254   void endNode();
255   void startLink(const Address &);
256   void endLink();
257 
258 
259   //////////////////////////////////////////////////////////////////////
260   // Inherited characteristics
261   // Set the value of the characteristic for the next flow object.
262   // Inherited characteristics that are not explicitly set have
263   // the same value as the parent flow object.
264   //////////////////////////////////////////////////////////////////////
265 
266   void setFontSize(Length);
267   void setFontFamilyName(const StringC &);
268   void setFontWeight(Symbol);
269   void setFontPosture(Symbol);
270   void setStartIndent(const LengthSpec &);
271   void setEndIndent(const LengthSpec &);
272   void setFirstLineStartIndent(const LengthSpec &);
273   void setLastLineEndIndent(const LengthSpec &);
274   void setLineSpacing(const LengthSpec &);
275   void setFieldWidth(const LengthSpec &);
276   void setMarginaliaSep(const LengthSpec &);
277   void setLines(Symbol);
278   void setQuadding(Symbol);
279   void setDisplayAlignment(Symbol);
280   void setFieldAlign(Symbol);
281   void setColor(const DeviceRGBColor &);
282   void setBackgroundColor(); // background of #f
283   void setBackgroundColor(const DeviceRGBColor &);
284   void setBorderPresent(bool);
285   void setLineThickness(Length);
286   void setCellBeforeRowMargin(Length);
287   void setCellAfterRowMargin(Length);
288   void setCellBeforeColumnMargin(Length);
289   void setCellAfterColumnMargin(Length);
290   void setLineSep(Length);
291   void setBoxSizeBefore(Length);
292   void setBoxSizeAfter(Length);
293   void setPositionPointShift(const LengthSpec &);
294   void setStartMargin(const LengthSpec &);
295   void setEndMargin(const LengthSpec &);
296   void setSidelineSep(const LengthSpec &);
297   void setAsisWrapIndent(const LengthSpec &);
298   void setLineNumberSep(const LengthSpec &);
299   void setLastLineJustifyLimit(const LengthSpec &);
300   void setJustifyGlyphSpaceMaxAdd(const LengthSpec &);
301   void setJustifyGlyphSpaceMaxRemove(const LengthSpec &);
302   void setTableCornerRadius(const LengthSpec &);
303   void setBoxCornerRadius(const LengthSpec &);
304   void setInhibitLineBreaks(bool);
305   void setHyphenate(bool);
306   void setKern(bool);
307   void setLigature(bool);
308   void setScoreSpaces(bool);
309   void setFloatOutMarginalia(bool);
310   void setFloatOutSidelines(bool);
311   void setFloatOutLineNumbers(bool);
312   void setCellBackground(bool);
313   void setSpanWeak(bool);
314   void setIgnoreRecordEnd(bool);
315   void setNumberedLines(bool);
316   void setHangingPunct(bool);
317   void setBoxOpenEnd(bool);
318   void setTruncateLeader(bool);
319   void setAlignLeader(bool);
320   void setTablePartOmitMiddleHeader(bool);
321   void setTablePartOmitMiddleFooter(bool);
322   void setBorderOmitAtBreak(bool);
323   void setPrincipalModeSimultaneous(bool);
324   void setMarginaliaKeepWithPrevious(bool);
325   void setLineJoin(Symbol);
326   void setLineCap(Symbol);
327   void setLineNumberSide(Symbol);
328   void setKernMode(Symbol);
329   void setInputWhitespaceTreatment(Symbol);
330   void setFillingDirection(Symbol);
331   void setWritingMode(Symbol);
332   void setLastLineQuadding(Symbol);
333   void setMathDisplayMode(Symbol);
334   void setBoxType(Symbol);
335   void setGlyphAlignmentMode(Symbol);
336   void setBoxBorderAlignment(Symbol);
337   void setCellRowAlignment(Symbol);
338   void setBorderAlignment(Symbol);
339   void setSidelineSide(Symbol);
340   void setHyphenationKeep(Symbol);
341   void setFontStructure(Symbol);
342   void setFontProportionateWidth(Symbol);
343   void setCellCrossed(Symbol);
344   void setMarginaliaSide(Symbol);
345   void setLayer(long);
346   void setBackgroundLayer(long);
347   void setBorderPriority(long);
348   void setLineRepeat(long);
349   void setSpan(long);
350   void setMinLeaderRepeat(long);
351   void setHyphenationRemainCharCount(long);
352   void setHyphenationPushCharCount(long);
353   void setWidowCount(long);
354   void setOrphanCount(long);
355   // 0 means #f
356   void setExpandTabs(long);
357   void setHyphenationLadderCount(long);
358   // public id or #f
359   void setBackgroundTile(PublicId);
360   void setLineBreakingMethod(PublicId);
361   void setLineCompositionMethod(PublicId);
362   void setImplicitBidiMethod(PublicId);
363   void setGlyphSubstMethod(PublicId);
364   void setGlyphReorderMethod(PublicId);
365   void setHyphenationMethod(PublicId);
366   void setTableAutoWidthMethod(PublicId);
367   void setFontName(PublicId);
368   // Two-letter code
369   void setLanguage(Letter2);
370   void setCountry(Letter2);
371   // For simple page sequence
372   void setPageWidth(Length);
373   void setPageHeight(Length);
374   void setLeftMargin(Length);
375   void setRightMargin(Length);
376   void setTopMargin(Length);
377   void setBottomMargin(Length);
378   void setHeaderMargin(Length);
379   void setFooterMargin(Length);
380 
381   void setPageNumberRestart(bool);
382   void setPageNumberFormat(const StringC &);
383   void setPageNColumns(long);
384   void setPageColumnSep(Length);
385   void setPageBalanceColumns(bool);
386   void setGridRowSep(Length);
387   void setGridColumnSep(Length);
388   void setSubscriptDepth(Length);
389   void setSuperscriptHeight(Length);
390   void setUnderMarkDepth(Length);
391   void setOverMarkHeight(Length);
392   void setHeadingLevel(long);
393 
394   void setMinPreLineSpacing(const OptLengthSpec &);
395   void setMinPostLineSpacing(const OptLengthSpec &);
396   void setMinLeading(const OptLengthSpec &);
397   void setScriptPreAlign(Symbol);
398   void setScriptPostAlign(Symbol);
399   void setScriptMidSupAlign(Symbol);
400   void setScriptMidSubAlign(Symbol);
401   void setNumeratorAlign(Symbol);
402   void setDenominatorAlign(Symbol);
403   void setGridPositionCellType(Symbol);
404   void setGridColumnAlignment(Symbol);
405   void setGridRowAlignment(Symbol);
406   void setGridEquidistantRows(bool);
407   void setGridEquidistantColumns(bool);
408   void setEscapementSpaceBefore(const InlineSpace &);
409   void setEscapementSpaceAfter(const InlineSpace &);
410   void setGlyphSubstTable(const Vector<ConstPtr<GlyphSubstTable> > &tables);
411 
412   void startDisplay( const DisplayNIC & );
413   void endDisplay();
414 
415   enum FotObjectClassType { oc_Unknown, oc_Cell };
416 
417   struct Format {
418 
FormatDSSSL_NAMESPACE::TeXFOTBuilder::Format419     Format() : FotCurDisplaySize( 0 ),
420                FotLineThickness( 1000 ),
421                FotLineCap( symbolButt ),
422                FotBorderPriority( 0 ),
423                FotBorderPresent( true ),
424                FotLineRepeat( 1 ),
425                FotLineSep( 1000 ),
426                FotDisplayAlignment( symbolStart ),
427                FotStartIndentSpec( 0 ),
428                FotEndIndentSpec( 0 ),
429                FotLeftMargin( 1 ),
430                FotRightMargin( 1 ),
431                FotPageWidth( 72000*8 ),
432                FotPageNColumns( 1 ),
433                FotPageColumnSep( 72000/2 ),
434                FotSpan( 1 ),
435                FotCellBeforeColumnMargin( 0 ),
436                FotCellAfterColumnMargin( 0 ),
437                FotObjectClass( oc_Unknown ) {}
438 
439     long                 FotCurDisplaySize;
440     Length               FotLineThickness;
441     Symbol               FotLineCap;
442     long                 FotBorderPriority;
443     bool                 FotBorderPresent;
444     long                 FotLineRepeat;
445     Length               FotLineSep;
446     Symbol               FotDisplayAlignment;
447     LengthSpec           FotStartIndentSpec;
448     LengthSpec           FotEndIndentSpec;
449     Length               FotLeftMargin;
450     Length               FotRightMargin;
451     Length               FotPageWidth;
452     long                 FotPageNColumns;
453     Length               FotPageColumnSep;
454     long                 FotSpan;
455     Length               FotCellBeforeColumnMargin;
456     Length               FotCellAfterColumnMargin;
457     FotObjectClassType   FotObjectClass;
458 
INITIAL_PAGE_SIZEDSSSL_NAMESPACE::TeXFOTBuilder::Format459     static const Length INITIAL_PAGE_SIZE() { return 72000*8; }
460   };
461 
462   struct CompoundFotElement;
463   struct FotElement {
464 
FotElementDSSSL_NAMESPACE::TeXFOTBuilder::FotElement465     FotElement(  CompoundFotElement *parent = NULL )
466      : Parent( parent ), SiblingSeqIdx( -1 ) {}
467     String<char> Characteristics;
468 
outDSSSL_NAMESPACE::TeXFOTBuilder::FotElement469     virtual void out( OutputByteStream &stream ) const
470      { outProlog( stream ); outContent( stream ); outEpilog( stream ); }
471     virtual void open( TeXFOTBuilder &builder );
472     virtual void close( TeXFOTBuilder &builder );
473     virtual bool isAtomic() const = 0;
474     virtual const char *name() const = 0;
parentDSSSL_NAMESPACE::TeXFOTBuilder::FotElement475     CompoundFotElement *parent() const { return Parent; }
nodeInfoEpilogDSSSL_NAMESPACE::TeXFOTBuilder::FotElement476     String<char> &nodeInfoEpilog() { return NodeInfoEpilog; }
setParentDSSSL_NAMESPACE::TeXFOTBuilder::FotElement477     void setParent( CompoundFotElement *parent ) { Parent = parent; }
478     virtual FotElement *lastClosed_() = 0;
479     virtual FotElement *currentlyOpen_() = 0;
setSiblingSeqIdxDSSSL_NAMESPACE::TeXFOTBuilder::FotElement480     void setSiblingSeqIdx( int idx ) { SiblingSeqIdx = idx; }
siblingSeqIdxDSSSL_NAMESPACE::TeXFOTBuilder::FotElement481     int siblingSeqIdx() const { assert( SiblingSeqIdx > -1 ); return SiblingSeqIdx; }
482 
483    protected:
484     int SiblingSeqIdx;
485     CompoundFotElement* Parent;
486     String<char> NodeInfoProlog;
487     String<char> NodeInfoEpilog;
488 
outContentDSSSL_NAMESPACE::TeXFOTBuilder::FotElement489     virtual void outContent( OutputByteStream & ) const {};
490     virtual void outProlog( OutputByteStream &stream ) const = 0;
491     virtual void outEpilog( OutputByteStream &stream ) const = 0;
492   };
493 
494   struct FotElementState {
FotElementStateDSSSL_NAMESPACE::TeXFOTBuilder::FotElementState495     FotElementState() : EnforcingStructure( true ), IsOpen( false ) {}
enforcingStructureDSSSL_NAMESPACE::TeXFOTBuilder::FotElementState496     bool enforcingStructure() { return IsOpen && EnforcingStructure; }
497 
498     bool EnforcingStructure;
499     bool IsOpen;
500     String<char> CurNodeInfoProlog;
501   };
502 
503   struct AtomicFotElement : public FotElement {
504 
AtomicFotElementDSSSL_NAMESPACE::TeXFOTBuilder::AtomicFotElement505     AtomicFotElement( CompoundFotElement *parent = NULL ) : FotElement( parent ) {}
isAtomicDSSSL_NAMESPACE::TeXFOTBuilder::AtomicFotElement506     virtual bool isAtomic() const { return true; }
lastClosed_DSSSL_NAMESPACE::TeXFOTBuilder::AtomicFotElement507     virtual FotElement *lastClosed_() { return NULL; };
currentlyOpen_DSSSL_NAMESPACE::TeXFOTBuilder::AtomicFotElement508     virtual FotElement *currentlyOpen_() { return this; }
509 
510    protected:
outPrologDSSSL_NAMESPACE::TeXFOTBuilder::AtomicFotElement511     virtual void outProlog( OutputByteStream &stream ) const
512      { stream << NodeInfoProlog << "\\insert" << name() << "%\n{" << Characteristics << '}'; }
outEpilogDSSSL_NAMESPACE::TeXFOTBuilder::AtomicFotElement513     virtual void outEpilog( OutputByteStream &stream ) const
514      { stream << '}' << NodeInfoEpilog; }
515   };
516 
517   struct CompoundFotElement : public FotElement {
518 
CompoundFotElementDSSSL_NAMESPACE::TeXFOTBuilder::CompoundFotElement519     CompoundFotElement( CompoundFotElement *parent = NULL )
520      : FotElement( parent ), CurrentlyOpenChildIdx( -1 ), LastClosedChildIdx( -1 ) {}
isAtomicDSSSL_NAMESPACE::TeXFOTBuilder::CompoundFotElement521     virtual bool isAtomic() const { return false; }
openDSSSL_NAMESPACE::TeXFOTBuilder::CompoundFotElement522     virtual void open( TeXFOTBuilder &builder )
523       { FotElement::open( builder ); builder.setCurOs( &PreContent ); };
childJustClosedDSSSL_NAMESPACE::TeXFOTBuilder::CompoundFotElement524     virtual void childJustClosed( FotElement &child )
525      { CurrentlyOpenChildIdx = -1; LastClosedChildIdx = child.siblingSeqIdx(); };
childJustOpenedDSSSL_NAMESPACE::TeXFOTBuilder::CompoundFotElement526     virtual void childJustOpened( FotElement &child )
527      { CurrentlyOpenChildIdx = child.siblingSeqIdx(); };
528     virtual FotElement &child( size_t idx ) = 0;
lastClosedDSSSL_NAMESPACE::TeXFOTBuilder::CompoundFotElement529     static FotElement *lastClosed( CompoundFotElement &treeRoot )
530      { return treeRoot.currentlyOpen( treeRoot )
531         ? treeRoot.currentlyOpen( treeRoot )->lastClosed_() : (FotElement*)NULL; }
currentlyOpenDSSSL_NAMESPACE::TeXFOTBuilder::CompoundFotElement532     static FotElement *currentlyOpen( CompoundFotElement &treeRoot ) {
533       return treeRoot.currentlyOpen_();
534     }
currentlyOpen_DSSSL_NAMESPACE::TeXFOTBuilder::CompoundFotElement535     virtual FotElement *currentlyOpen_()
536      { return CurrentlyOpenChildIdx > -1
537         ? child( (size_t)CurrentlyOpenChildIdx ).currentlyOpen_() : this; }
lastClosed_DSSSL_NAMESPACE::TeXFOTBuilder::CompoundFotElement538     virtual FotElement *lastClosed_()
539      { return LastClosedChildIdx > -1
540         ? &child( (size_t)LastClosedChildIdx )
541         : ( parent() ? parent()->lastClosed_() : (FotElement*)NULL ); }
542 
543    protected:
outPrologDSSSL_NAMESPACE::TeXFOTBuilder::CompoundFotElement544     virtual void outProlog( OutputByteStream &stream ) const {
545       #ifdef TEXDEBUG
546        stream <<  "\nELEMENT\n" << "\nPRO\n" << NodeInfoProlog << "\nEND_PRO\n" << "\\" << name() << "%\n{" << Characteristics << '}';
547       #else
548        stream <<  NodeInfoProlog << "\\" << name() << "%\n{" << Characteristics << '}';
549       #endif
550        PreContent.commit( stream );
551      }
outEpilogDSSSL_NAMESPACE::TeXFOTBuilder::CompoundFotElement552     virtual void outEpilog( OutputByteStream &stream ) const {
553       #ifdef TEXDEBUG
554         stream << "\\end" << name() << "{}" << "\nEPI\n" << NodeInfoEpilog << "\nEND_EPI\nEND_ELEMENT\n" ;
555       #else
556         stream << "\\end" << name() << "{}" << NodeInfoEpilog << "%\n" ;
557       #endif
558     }
559 
560     int CurrentlyOpenChildIdx;
561     int LastClosedChildIdx;
562     TeXTmpOutputByteStream PreContent;
563   };
564 
565   struct Border : public AtomicFotElement {
566 
BorderDSSSL_NAMESPACE::TeXFOTBuilder::Border567     Border( CompoundFotElement *parent = NULL, bool cellBorder_ = true )
568      : AtomicFotElement( parent ), cellBorder( cellBorder_ ), borderPresent( false ) {}
569     long   borderPriority;
570     Length lineThickness;
571     bool   borderPresent;
572     long   lineRepeat;
573     Length lineSep;
574     bool   cellBorder;
575 
576     void resolve( Border &adjacentBorder );
577     void setFromFot( TeXFOTBuilder &builder );
578   };
579 
580   struct CellBeforeRowBorder : public Border {
CellBeforeRowBorderDSSSL_NAMESPACE::TeXFOTBuilder::CellBeforeRowBorder581     CellBeforeRowBorder( CompoundFotElement *parent = NULL ) : Border( parent ) {}
nameDSSSL_NAMESPACE::TeXFOTBuilder::CellBeforeRowBorder582     virtual const char *name() const { return "TableCellBeforeRowBorder"; }
583   };
584   struct CellAfterRowBorder : public Border {
CellAfterRowBorderDSSSL_NAMESPACE::TeXFOTBuilder::CellAfterRowBorder585     CellAfterRowBorder( CompoundFotElement *parent = NULL ) : Border( parent ) {}
nameDSSSL_NAMESPACE::TeXFOTBuilder::CellAfterRowBorder586     virtual const char *name() const { return "TableCellAfterRowBorder"; }
587   };
588   struct CellBeforeColumnBorder : public Border {
CellBeforeColumnBorderDSSSL_NAMESPACE::TeXFOTBuilder::CellBeforeColumnBorder589     CellBeforeColumnBorder( CompoundFotElement *parent = NULL ) : Border( parent ) {}
nameDSSSL_NAMESPACE::TeXFOTBuilder::CellBeforeColumnBorder590     virtual const char *name() const { return "TableCellBeforeColumnBorder"; }
591   };
592   struct CellAfterColumnBorder : public Border {
CellAfterColumnBorderDSSSL_NAMESPACE::TeXFOTBuilder::CellAfterColumnBorder593     CellAfterColumnBorder( CompoundFotElement *parent = NULL ) : Border( parent ) {}
nameDSSSL_NAMESPACE::TeXFOTBuilder::CellAfterColumnBorder594     virtual const char *name() const { return "TableCellAfterColumnBorder"; }
595   };
596   struct TableBeforeRowBorder : public Border {
TableBeforeRowBorderDSSSL_NAMESPACE::TeXFOTBuilder::TableBeforeRowBorder597     TableBeforeRowBorder( CompoundFotElement *parent = NULL ) : Border( parent, false ) {}
nameDSSSL_NAMESPACE::TeXFOTBuilder::TableBeforeRowBorder598     virtual const char *name() const { return "TableBeforeRowBorder"; }
599   };
600   struct TableAfterRowBorder : public Border {
TableAfterRowBorderDSSSL_NAMESPACE::TeXFOTBuilder::TableAfterRowBorder601     TableAfterRowBorder( CompoundFotElement *parent = NULL ) : Border( parent, false ) {}
nameDSSSL_NAMESPACE::TeXFOTBuilder::TableAfterRowBorder602     virtual const char *name() const { return "TableAfterRowBorder"; }
603   };
604   struct TableBeforeColumnBorder : public Border {
TableBeforeColumnBorderDSSSL_NAMESPACE::TeXFOTBuilder::TableBeforeColumnBorder605     TableBeforeColumnBorder( CompoundFotElement *parent = NULL ) : Border( parent, false ) {}
nameDSSSL_NAMESPACE::TeXFOTBuilder::TableBeforeColumnBorder606     virtual const char *name() const { return "TableBeforeColumnBorder"; }
607   };
608   struct TableAfterColumnBorder : public Border {
TableAfterColumnBorderDSSSL_NAMESPACE::TeXFOTBuilder::TableAfterColumnBorder609     TableAfterColumnBorder( CompoundFotElement *parent = NULL ) : Border( parent, false ) {}
nameDSSSL_NAMESPACE::TeXFOTBuilder::TableAfterColumnBorder610     virtual const char *name() const { return "TableAfterColumnBorder"; }
611   };
612 
613   struct Column {
614 
ColumnDSSSL_NAMESPACE::TeXFOTBuilder::Column615     Column() : hasWidth( 0 ), computedWidth( 0 ), defaultTeXLeftBorder( 0 ),
616              defaultTeXRightBorder( 0 ), displayAlignment( symbolStart ),
617              isExplicit( false ) {}
618     bool isExplicit;
619     bool hasWidth;
620     TableLengthSpec width;
621     long computedWidth;
622     Symbol displayAlignment;
623     int defaultTeXLeftBorder; // also used as column border count;
624     int defaultTeXRightBorder; //
625   };
626 
627   struct TablePart;
628   struct Cell : public CompoundFotElement {
629 
CellDSSSL_NAMESPACE::TeXFOTBuilder::Cell630     Cell( CompoundFotElement *parent = NULL )
631      : CompoundFotElement( parent ), missing( false ), OverlappingCell( NULL ),
632        nRowsSpanned( 1 ), nColumnsSpanned( 1 ), displaySize( 0 ),
633        beforeRowBorder(), afterRowBorder(), beforeColumnBorder(),
634        afterColumnBorder(), TeXTableRowIdx( -1 ), TeXTableColumnIdx( -1 ),
635        displayAlignment( symbolStart ), effectiveAlignment( symbolStart ),
636        paragraphChildrenNum( 0 )  {}
637 
638     bool missing;
639     int TeXTableRowIdx;
640     int TeXTableColumnIdx;
641     unsigned nColumnsSpanned;
642     unsigned nRowsSpanned;
643     CellBeforeRowBorder beforeRowBorder;
644     CellAfterRowBorder afterRowBorder;
645     CellBeforeColumnBorder beforeColumnBorder;
646     CellAfterColumnBorder afterColumnBorder;
647     Symbol displayAlignment;
648     Symbol effectiveAlignment;
649     long displaySize;
650     long paragraphChildrenNum;
651 
652     Cell *OverlappingCell;
contentDSSSL_NAMESPACE::TeXFOTBuilder::Cell653     OutputByteStream &content() { return Content; }
openDSSSL_NAMESPACE::TeXFOTBuilder::Cell654     virtual void open( TeXFOTBuilder &builder )
655      { CompoundFotElement::open( builder );
656        builder.setCurOs( &Content );
657        builder.curFotElementState().EnforcingStructure = false; }
closeDSSSL_NAMESPACE::TeXFOTBuilder::Cell658     virtual void close( TeXFOTBuilder &builder )
659      { computeMultiParFlag();
660        CompoundFotElement::close( builder );
661        builder.curFotElementState().EnforcingStructure = true; }
nameDSSSL_NAMESPACE::TeXFOTBuilder::Cell662     virtual const char *name() const { return "TableCell"; }
663     bool singleRowBeforeRowBorderPresent() const;
664     bool singleRowAfterRowBorderPresent() const;
665     bool singleColumnBeforeColumnBorderPresent() const;
666     bool singleColumnAfterColumnBorderPresent() const;
667     void computeOverridingTeXColumnBorders( TablePart &tablePart );
668     void computeOverridingTeXDisplayAlignment( TablePart &tablePart );
669     void computeMultiParFlag();
670 
isOverlappedDSSSL_NAMESPACE::TeXFOTBuilder::Cell671     bool isOverlapped() const { return OverlappingCell == this ? false : true; }
childDSSSL_NAMESPACE::TeXFOTBuilder::Cell672     virtual FotElement &child( size_t ) { assert( false ); return *this; }
673 
674    protected:
675     virtual void outProlog( OutputByteStream &stream ) const;
676     virtual void outEpilog( OutputByteStream &stream ) const;
outContentDSSSL_NAMESPACE::TeXFOTBuilder::Cell677     void outContent( OutputByteStream &stream ) const { Content.commit( stream ); }
678     TeXTmpOutputByteStream Content;
679   };
680 
681   struct Row : public CompoundFotElement {
682 
RowDSSSL_NAMESPACE::TeXFOTBuilder::Row683     Row( CompoundFotElement *parent = NULL ) : CompoundFotElement( parent ) {}
nameDSSSL_NAMESPACE::TeXFOTBuilder::Row684     virtual const char *name() const { return "TableRow"; }
685     Vector<Cell> Cells;
686     static void outVerticalBorders
687       ( const Row *upperRow, const Row *lowerRow, OutputByteStream &stream );
childDSSSL_NAMESPACE::TeXFOTBuilder::Row688     virtual FotElement &child( size_t idx )
689      { assert( idx < Cells.size() ); return Cells[idx]; }
690 
691    protected:
692     void outContent( OutputByteStream &stream ) const;
693   };
694 
695   struct Table;
696   struct TablePart : public CompoundFotElement {
697 
TablePartDSSSL_NAMESPACE::TeXFOTBuilder::TablePart698     TablePart( CompoundFotElement *parent = NULL )
699      : CompoundFotElement( parent ), columnsProcessed( false ),
700        needsColumnReprocessing( false ), isExplicit( true ) {}
701 
702     bool isExplicit;
703 
704     Vector<Column> Columns;
705     String<char> HeaderProlog;
706     Vector<Row> Header;
707     String<char> HeaderEpilog;
708     Vector<Row> Body;
709     String<char> FooterProlog;
710     Vector<Row> Footer;
711     String<char> FooterEpilog;
712 
713     void processColumns( TeXFOTBuilder &builder );
714     void computeTeXColumnBordersAndDisplayAlignment();
715     void normalizeRows();
716     void begin();
717 
parentTableDSSSL_NAMESPACE::TeXFOTBuilder::TablePart718     Table &parentTable() const
719      { assert( Parent != NULL ); return *(Table*)Parent; }
nameDSSSL_NAMESPACE::TeXFOTBuilder::TablePart720     virtual const char *name() const { return "TablePart"; }
721     virtual FotElement &child( size_t idx );
722 
723     bool columnsProcessed;
724     bool needsColumnReprocessing;
725 
726    protected:
outPrologDSSSL_NAMESPACE::TeXFOTBuilder::TablePart727     virtual void outProlog( OutputByteStream &stream ) const
728      { if( isExplicit ) CompoundFotElement::outProlog( stream ); }
outEpilogDSSSL_NAMESPACE::TeXFOTBuilder::TablePart729     virtual void outEpilog( OutputByteStream &stream ) const
730      { if( isExplicit ) CompoundFotElement::outEpilog( stream ); }
731     Row &siblingSeqIdxToRow( int idx ) const;
732     void outContent( OutputByteStream &stream ) const;
733   };
734 
735   struct Table : public CompoundFotElement {
736 
TableDSSSL_NAMESPACE::TeXFOTBuilder::Table737     Table(  CompoundFotElement *parent = NULL )
738      : CompoundFotElement( parent ), beforeRowBorder(), afterRowBorder(),
739        beforeColumnBorder(), afterColumnBorder(), CurCell( NULL ),
740        CurTablePart( NULL ), NoTablePartsSeen( true ) {}
741 
742     Vector<TablePart> TableParts;
743 
744     TableBeforeRowBorder beforeRowBorder;
745     TableAfterRowBorder afterRowBorder;
746     TableBeforeColumnBorder beforeColumnBorder;
747     TableAfterColumnBorder afterColumnBorder;
748     Length tableWidth;
749     Symbol displayAlignment;
750     Length startIndent;
751 
nameDSSSL_NAMESPACE::TeXFOTBuilder::Table752     virtual const char *name() const { return "Table"; }
childDSSSL_NAMESPACE::TeXFOTBuilder::Table753     virtual FotElement &child( size_t idx )
754      { assert( idx < TableParts.size() ); return TableParts[idx]; }
755     void resolveBorders( Vector<Row> *preceedingRows,
756                          Vector<Row> &rows,
757                          Vector<Row> *followingRows,
758                          unsigned startingRowIdx,
759                          bool hasFirstTableRow, bool hasLastTableRow );
760     void begin();
761     void end( TeXFOTBuilder &builder );
762 
curRowsDSSSL_NAMESPACE::TeXFOTBuilder::Table763     Vector<Row> &curRows() { assert( CurRows != NULL ); return *CurRows; }
curTablePartDSSSL_NAMESPACE::TeXFOTBuilder::Table764     TablePart &curTablePart() { assert( CurTablePart != NULL ); return *CurTablePart; }
curCellDSSSL_NAMESPACE::TeXFOTBuilder::Table765     Cell &curCell() { assert( CurCell != NULL ); return *CurCell; }
766 
767     TablePart *CurTablePart;
768     Cell *CurCell;
769     Vector<Row> *CurRows;
770 
771     bool NoTablePartsSeen;
772 
773   protected:
774     void outContent( OutputByteStream &stream ) const;
775   };
776 
777   long computeLengthSpec( const LengthSpec &spec ) const;
curFormat() const778   const Format &curFormat() const { assert( FormatStack.size() > 0 ); return FormatStack.back(); }
curTable()779   Table &curTable() { return CurTable; }
curFotElementState()780   FotElementState &curFotElementState() { return CurFotElementState; }
setCurOs(OutputByteStream * to)781   void setCurOs( OutputByteStream *to ) { CurOs = to; }
782   void elementStart( FotObjectClassType objectClassType );
783 
784   OutputByteStream *fileout_;
785 private:
786 				// Variables.
787   OutputByteStream *CurOs;
788   StrOutputByteStream stringout_;
789   Messenger *mgr_;
790   bool preserveSdata_;
791   int inMath_;
792 
793   Vector<size_t> DisplayBoxLevels;
794   Vector<Format> FormatStack;
795   Format NextFormat;
796   Table CurTable;
797   FotElementState CurFotElementState;
798 
799 				// Functions.
800   OutputByteStream &os();
801   void insertAtomic(const char *name);
802   void insertAtomic(FotElement &fotElement);
803   void startGroup(FotElement &fotElement);
804   void startGroup(const char *name, String<char> *output = NULL );
805   void endGroup(const char *name, String<char> *output = NULL );
806   void closeopenBrace(const char *name, String<char> *output = NULL );
807   void startBrace(const char *name, String<char> *output = NULL );
808   void endBrace(const char *name, String<char> *output = NULL );
809   void startSimpleGroup(const char *name, String<char> *output = NULL );
810   void endSimpleGroup(String<char> *output = NULL);
endGroup()811   void endGroup() {};
812 
813   void setlength(const char *,Length);
814   void set(const char *,const StringC &);
815   void set(const char *,const GroveString &);
816   void set(const char *,Symbol);
817   void set(const char *,const LengthSpec &);
818   void set(const char *,double);
819   void set(const char *,const DeviceRGBColor &);
820   void set(const char *,bool);
821   void set(const char *,long);
822   void set(const char *,long unsigned int);
set(const char * name,unsigned int n)823   void set(const char *name,unsigned int n) {
824     set(name, (unsigned long)n);
825   }
826   void set(const char *,PublicId);
827   void setletter2(const char *,Letter2);
828   void set(const char *,const DisplaySpace &);
829   void set(const char *,const GlyphId &);
830 
831   void set(const char *,const OptLengthSpec &);
832   void set(const char *,const InlineSpace &);
833 
834   // Structures for non-inherited characteristics,
835   // in the order specified in style/FOTBuilder.h.
836 
837   void setDisplayNIC(const DisplayNIC &);
838   void setInlineNIC(const InlineNIC &);
839   void setDisplayGroupNIC(const DisplayGroupNIC &);
840   void setExternalGraphicNIC(const ExternalGraphicNIC &);
841   void setBoxNIC(const BoxNIC &);
842   void setRuleNIC(const RuleNIC &);
843   void setLeaderNIC(const LeaderNIC &);
844   void setParagraphNIC(const ParagraphNIC &);
845   void setCharacterNIC(const CharacterNIC &);
846   void setLineFieldNIC(const LineFieldNIC &);
847   void setTableNIC(const TableNIC &);
848   void setTablePartNIC(const TablePartNIC &);
849   void setTableColumnNIC(const TableColumnNIC &);
850   void setTableCellNIC(const TableCellNIC &);
851   void setGridNIC(const GridNIC &);
852   void setGridCellNIC(const GridCellNIC &);
853 
854   void dumpInherited();
855 
856   void message(const MessageType0 &);
857 };
858 
859 #ifdef TEXDEBUG
860   TeXFOTBuilder *TeXFOTBuilder::CurInstance = NULL;
861 #endif
862 
863 // --------- OutputByteStream operators --------------------------------------
864 
operator <<(OutputByteStream & os,LengthInPoints length)865 OutputByteStream &operator<<( OutputByteStream &os, LengthInPoints length ) {
866 
867   char buf[32];
868   int i;
869   sprintf( buf, "%li.%.3i%n", long(length.l)/1000, abs(long(length.l)%1000), &i );
870   while( buf[--i] == '0' ) {}; if( buf[i] == '.' ) i--;
871     buf[i+1] = '\0';
872   os << buf << "\\p@";
873   return os;
874 }
875 
876 // --------- TeXFOTBuilder::FotElement ---------------------------------------
877 
open(TeXFOTBuilder & builder)878 void TeXFOTBuilder::FotElement::open( TeXFOTBuilder &builder ) {
879 
880   builder.curFotElementState().IsOpen = true;
881   if( parent() )
882     parent()->childJustOpened( *this );
883 
884   if( builder.curFotElementState().CurNodeInfoProlog.size() > 0 ) {
885     NodeInfoProlog = builder.curFotElementState().CurNodeInfoProlog;
886     builder.curFotElementState().CurNodeInfoProlog.resize( 0 );
887   }
888 }
889 
close(TeXFOTBuilder & builder)890 void TeXFOTBuilder::FotElement::close( TeXFOTBuilder &builder ) {
891 
892   if( parent() )
893     parent()->childJustClosed( *this );
894   else {
895     builder.curFotElementState().IsOpen = false;
896     builder.setCurOs( NULL );
897   }
898 }
899 
lastClosed_()900 TeXFOTBuilder::FotElement *TeXFOTBuilder::FotElement::lastClosed_() {
901 
902   return parent() ? parent()->lastClosed_() : (FotElement*)NULL;
903 }
904 
905 // --------- TeXFOTBuilder Standard Display/Element Handling -----------------
906 
elementStart(FotObjectClassType objectClassType)907 void TeXFOTBuilder::elementStart( FotObjectClassType objectClassType ) {
908 
909   NextFormat.FotObjectClass = objectClassType;
910   FormatStack.push_back( NextFormat );
911 }
912 
start()913 void TeXFOTBuilder::start() {
914 
915   NextFormat.FotObjectClass = oc_Unknown;
916   FormatStack.push_back( NextFormat );
917 }
918 
end()919 void TeXFOTBuilder::end() {
920 
921   assert( FormatStack.size() > 0 );
922   FormatStack.resize( FormatStack.size()-1 );
923 
924   assert( FormatStack.size() > 0 );
925   NextFormat = FormatStack.back();
926 }
927 
startDisplay(const DisplayNIC &)928 void TeXFOTBuilder::startDisplay( const DisplayNIC & ) {
929 
930   if( curTable().CurCell != NULL )
931       NextFormat.FotCurDisplaySize = curTable().CurCell->displaySize;
932   else if( NextFormat.FotSpan > 1 )
933       NextFormat.FotCurDisplaySize
934        = NextFormat.FotPageWidth - NextFormat.FotLeftMargin - NextFormat.FotRightMargin;
935   else
936       NextFormat.FotCurDisplaySize
937        = ( NextFormat.FotPageWidth - NextFormat.FotLeftMargin - NextFormat.FotRightMargin
938             - NextFormat.FotPageColumnSep * ( NextFormat.FotPageNColumns - 1 ) )
939           / NextFormat.FotPageNColumns;
940 
941 }
942 
endDisplay()943 void TeXFOTBuilder::endDisplay() {
944 }
945 
946 // --------- TeXFOTBuilder Misc ----------------------------------------------
947 
computeLengthSpec(const LengthSpec & spec) const948 long TeXFOTBuilder::computeLengthSpec( const LengthSpec &spec ) const {
949 
950     if( spec.displaySizeFactor == 0.0 ) {
951         return spec.length;
952     } else {
953         double tem = curFormat().FotCurDisplaySize * spec.displaySizeFactor;
954         return spec.length + long( tem >= 0.0 ? tem +.5 : tem - .5 );
955     }
956 }
957 
958 // --------- TeXFOTBuilder::Table ---------------------------------------------
959 
resolveBorders(Vector<Row> * preceedingRows,Vector<Row> & rows,Vector<Row> *,unsigned startingRowIdx,bool hasFirstTableRow,bool hasLastTableRow)960 void TeXFOTBuilder::Table::resolveBorders
961  ( Vector<Row> *preceedingRows, Vector<Row> &rows,
962    Vector<Row> *, unsigned startingRowIdx, bool hasFirstTableRow,
963    bool hasLastTableRow ) {
964 
965     bool isFirstRow;
966     bool isLastRow;
967     bool isFirstColumn;
968     bool isLastColumn;
969     Cell *cell = NULL;
970     size_t r, c, rr, cc;
971     bool leftEdge, topEdge;
972 
973     #ifdef TEXDEBUG
974       *TeXFOTBuilder::curInstance().fileout_ << "RESOLVING_BORDERS\n";
975     #endif
976 
977     for( r = 0; r < rows.size(); r++ ) {
978       for( c = 0; c < rows[r].Cells.size()-1; c++ ) {
979         cell = &rows[r].Cells[c];
980         if( cell->OverlappingCell == NULL ) {
981           for( rr = r; rr < r + cell->nRowsSpanned; rr++ ) {
982             for( cc = c, leftEdge = true; cc < c + cell->nColumnsSpanned; cc++ ) {
983               rows[rr].Cells[cc].OverlappingCell = cell;
984               rows[rr].Cells[cc].TeXTableRowIdx = rr + startingRowIdx;
985               rows[rr].Cells[cc].TeXTableColumnIdx = cc;
986             }
987           }
988         }
989       }
990     }
991 
992     for( r = 0; r < rows.size(); r++ ) {
993         #ifdef TEXDEBUG
994           *TeXFOTBuilder::curInstance().fileout_ << "ROW " << r << "\n";
995         #endif
996         for( c = 0; c < rows[r].Cells.size() - 1; c++ ) {
997             #ifdef TEXDEBUG
998               *TeXFOTBuilder::curInstance().fileout_ << "    COL " << c << "\n";
999             #endif
1000             cell = &rows[r].Cells[c];
1001             if( cell->OverlappingCell == cell ) {
1002                 for( rr = r, topEdge = true; rr < r + cell->nRowsSpanned; rr++ ) {
1003                     isFirstRow = ( rr == 0 ) ? true : false;
1004                     isLastRow = ( rr == rows.size() - 1 ) ? true : false;
1005                     for( cc = c, leftEdge = true; cc < c + cell->nColumnsSpanned; cc++ ) {
1006                         isFirstColumn = ( cc == 0 ) ? true : false;
1007                         isLastColumn = ( cc == rows[rr].Cells.size() - 2 ) ? true : false;
1008 
1009                         if( leftEdge )
1010                             if( isFirstColumn ) {
1011                                 #ifdef TEXDEBUG
1012                                   *TeXFOTBuilder::curInstance().fileout_
1013                                    << "LEFT_TABLE_BORDER_RES \n";
1014                                 #endif
1015                                 cell->beforeColumnBorder.resolve( beforeColumnBorder );
1016                             } else
1017                                 cell->beforeColumnBorder.resolve
1018                                  ( rows[rr].Cells[cc-1].OverlappingCell->afterColumnBorder );
1019 
1020                         if( topEdge )
1021                             if( isFirstRow && hasFirstTableRow )
1022                                 cell->beforeRowBorder.resolve( beforeRowBorder );
1023                             else
1024                                 if( !isFirstRow )
1025                                     cell->beforeRowBorder.resolve
1026                                      ( rows[rr-1].Cells[cc].OverlappingCell->afterRowBorder );
1027                                 else if( preceedingRows != NULL ) {
1028                                     assert( preceedingRows->size() > 0 );
1029                                     cell->beforeRowBorder.resolve
1030                                      ( (*preceedingRows)[preceedingRows->size()-1].Cells[cc]
1031                                         .OverlappingCell->afterRowBorder );
1032                                 }
1033 
1034                         if( isLastColumn )
1035                             cell->afterColumnBorder.resolve( afterColumnBorder );
1036 
1037                         if( isLastRow && hasLastTableRow )
1038                             cell->afterRowBorder.resolve( afterRowBorder );
1039 
1040                         leftEdge = false;
1041                     }
1042                     topEdge = false;
1043                 }
1044             }
1045         }
1046     }
1047 }
1048 
begin()1049 void TeXFOTBuilder::Table::begin() {
1050 
1051     CurCell = NULL;
1052     NoTablePartsSeen = true;
1053 
1054     TableParts.resize( 0 );
1055     TableParts.resize( 1 );
1056     TableParts.back().setSiblingSeqIdx( 0 );
1057     TableParts.back().setParent( this );
1058     TableParts.back().begin();
1059 }
1060 
end(TeXFOTBuilder & builder)1061 void TeXFOTBuilder::Table::end( TeXFOTBuilder &builder ) {
1062 
1063   bool firstPart, lastPart, hasHeader, hasBody, hasFooter;
1064   for( size_t i = 0; i < TableParts.size(); i++ ) {
1065       firstPart = ( i == 0 ) ? true : false;
1066       lastPart = ( i == TableParts.size() - 1 ) ? true : false;
1067       TablePart &tablePart = TableParts[i];
1068       tablePart.normalizeRows();
1069       hasHeader = tablePart.Header.size() > 0 ? true : false;
1070       hasBody = tablePart.Body.size() > 0 ? true : false;
1071       hasFooter = tablePart.Footer.size() > 0 ? true : false;
1072       if( hasHeader )
1073           resolveBorders( (Vector<Row>*)NULL,
1074                           tablePart.Header,
1075                           hasBody ? &tablePart.Body : (Vector<Row>*)NULL,
1076                           0, firstPart ? true : false, false );
1077       resolveBorders( hasHeader ? &tablePart.Header : (Vector<Row>*)NULL,
1078                       tablePart.Body,
1079                       hasFooter ? &tablePart.Footer : (Vector<Row>*)NULL,
1080                       tablePart.Header.size(), hasHeader ? false : true,
1081                       hasFooter ? false : true );
1082       if( hasFooter )
1083           resolveBorders( hasBody ? &tablePart.Body : (Vector<Row>*)NULL,
1084                           tablePart.Footer,
1085                           (Vector<Row>*)NULL,
1086                           tablePart.Header.size() + tablePart.Body.size(),
1087                           false, lastPart ? true : false );
1088 
1089       if( tablePart.needsColumnReprocessing )
1090         tablePart.processColumns( builder );
1091 
1092       tablePart.computeTeXColumnBordersAndDisplayAlignment();
1093   }
1094 }
1095 
outContent(OutputByteStream & stream) const1096 void TeXFOTBuilder::Table::outContent( OutputByteStream &stream ) const {
1097 
1098   for( size_t i = 0; i < TableParts.size(); i++ )
1099       TableParts[i].out( stream );
1100 };
1101 
1102 // --------- TeXFOTBuilder::TablePart -----------------------------------------
1103 
begin()1104 void TeXFOTBuilder::TablePart::begin() {
1105 
1106     Columns.resize( 0 );
1107     Header.resize( 0 );
1108     Body.resize( 0 );
1109     Footer.resize( 0 );
1110 
1111     columnsProcessed = false;
1112     needsColumnReprocessing = false;
1113 
1114     parentTable().CurRows = &Body;
1115     parentTable().CurTablePart = this;
1116 }
1117 
child(size_t idx)1118 TeXFOTBuilder::FotElement &TeXFOTBuilder::TablePart::child( size_t idx ) {
1119 
1120   if( idx < Header.size() )
1121     return Header[idx];
1122 
1123   idx -= Header.size();
1124   if( idx < Body.size() )
1125     return Body[idx];
1126 
1127   assert( idx < Footer.size() );
1128   idx -= Body.size();
1129   return Footer[idx];
1130 }
1131 
computeTeXColumnBordersAndDisplayAlignment()1132 void TeXFOTBuilder::TablePart::computeTeXColumnBordersAndDisplayAlignment() {
1133 
1134   Vector<Row> *rows;
1135   for( int step = 0; step < 3; step++ ) {
1136     switch( step ) {
1137       case 0: rows = &Header; break;
1138       case 1: rows = &Body; break;
1139       default: rows = &Footer;
1140     }
1141     for( size_t r = 0; r < rows->size(); r++ ) {
1142       if( (*rows)[r].Cells.size()-1 > Columns.size() )
1143         Columns.resize( (*rows)[r].Cells.size()-1 );
1144       for( size_t c = 0; c < (*rows)[r].Cells.size()-1; c++ ) {
1145         if( (*rows)[r].Cells[c].singleColumnBeforeColumnBorderPresent() )
1146           Columns[c].defaultTeXLeftBorder++;
1147         if( (*rows)[r].Cells[c].singleColumnAfterColumnBorderPresent() )
1148           Columns[c].defaultTeXRightBorder++;
1149       }
1150     }
1151   }
1152 
1153   #ifdef TEXDEBUG
1154     for( int step = 0; step < 3; step++ ) {
1155       switch( step ) {
1156         case 0: rows = &Header; break;
1157         case 1: rows = &Body; break;
1158         default: rows = &Footer;
1159       }
1160       for( size_t r = 0; r < rows->size(); r++ ) {
1161         *TeXFOTBuilder::curInstance().fileout_
1162          << "\nROW " << ( step == 0 ? "Header" : ( step == 1 ? "Body" : "Footer" ) ) << "\n";
1163         for( size_t c = 0; c < (*rows)[r].Cells.size()-1; c++ ) {
1164           *TeXFOTBuilder::curInstance().fileout_
1165            << "\n    CELL " << c
1166            << " LB: " << (*rows)[r].Cells[c].beforeColumnBorder.borderPresent
1167            << " RB: " << (*rows)[r].Cells[c].beforeColumnBorder.borderPresent
1168            << " OVERLAPPED: "
1169            << ( (*rows)[r].Cells[c].isOverlapped() ? "YES" : "NO" ) << "\n";
1170         }
1171       }
1172     }
1173   #endif
1174 
1175   size_t TeXTableRowsNum = Header.size() + Body.size() + Footer.size();
1176   for( size_t c = 0; c < Columns.size(); c++ ) {
1177     Columns[c].defaultTeXLeftBorder
1178      = ((size_t)Columns[c].defaultTeXLeftBorder)*2 >= TeXTableRowsNum ? 1 : 0;
1179     Columns[c].defaultTeXRightBorder
1180       = ((size_t)Columns[c].defaultTeXRightBorder)*2 >= TeXTableRowsNum ? 1 : 0;
1181   }
1182 
1183   for( int step = 0; step < 3; step++ ) {
1184     switch( step ) {
1185       case 0: rows = &Header; break;
1186       case 1: rows = &Body; break;
1187       default: rows = &Footer;
1188     }
1189     for( size_t r = 0; r < rows->size(); r++ ) {
1190       for( size_t c = 0; c < (*rows)[r].Cells.size()-1; c++ ) {
1191         if( !(*rows)[r].Cells[c].isOverlapped() ) {
1192           (*rows)[r].Cells[c].computeOverridingTeXColumnBorders( *this );
1193           (*rows)[r].Cells[c].computeOverridingTeXDisplayAlignment( *this );
1194         }
1195       }
1196     }
1197   }
1198 }
1199 
processColumns(TeXFOTBuilder & builder)1200 void TeXFOTBuilder::TablePart::processColumns( TeXFOTBuilder &builder ) {
1201 
1202   long totalNonproportionalWidth = 0L;
1203   double totalProportionalUnits = 0.0;
1204   size_t nonWidthCellsNum = 0;
1205   for( size_t i = 0; i < Columns.size(); i++ ) {
1206     if( Columns[i].hasWidth ) {
1207       if( Columns[i].width.tableUnitFactor ) {
1208         totalProportionalUnits += Columns[i].width.tableUnitFactor;
1209       } else {
1210         Columns[i].computedWidth = builder.computeLengthSpec( Columns[i].width );
1211         totalNonproportionalWidth += Columns[i].computedWidth;
1212       }
1213     } else
1214       nonWidthCellsNum++;
1215   }
1216 
1217   if( totalProportionalUnits > 0 )
1218     totalProportionalUnits += nonWidthCellsNum;
1219   // cannot predict width of some cells, but their width is needed to
1220   // compute widths of proportional cells - force non-with cells to be 1 table-unit
1221 
1222   double proportionalUnit = 0.0;
1223   if( totalProportionalUnits )
1224       proportionalUnit
1225        = ( parentTable().tableWidth - totalNonproportionalWidth ) / totalProportionalUnits;
1226 
1227   for( size_t i = 0; i < Columns.size(); i++ ) {
1228       if( Columns[i].hasWidth ) {
1229           if( Columns[i].width.tableUnitFactor )
1230               Columns[i].computedWidth
1231                = long(proportionalUnit * Columns[i].width.tableUnitFactor);
1232       } else if( totalProportionalUnits > 0 )
1233           Columns[i].computedWidth = long(proportionalUnit);
1234   }
1235 
1236   columnsProcessed = true;
1237 }
1238 
outContent(OutputByteStream & stream) const1239 void TeXFOTBuilder::TablePart::outContent( OutputByteStream &stream ) const {
1240 
1241   stream << "\\TeXTable%\n{" << LengthInPoints( parentTable().tableWidth )
1242          << "}{" << Columns.size() << '}';
1243 
1244   stream << '{';
1245   for( size_t i = 0; i < Columns.size(); i++ ) {
1246     #ifdef TEXDEBUG
1247       stream << "\nCOLUMN " << i << " DEF_LEFT_B: " <<  Columns[i].defaultTeXLeftBorder
1248              << " DEF_RIGHT_B: " <<  Columns[i].defaultTeXRightBorder << "\n";
1249     #endif
1250     if( i == 0 && Columns[i].defaultTeXLeftBorder )
1251       stream << '|';
1252     if( Columns[i].computedWidth > 0 ) {
1253       switch( Columns[i].displayAlignment ) {
1254         case symbolInside:
1255         case symbolStart:
1256           stream << "L{" << LengthInPoints( Columns[i].computedWidth ) << '}';
1257           break;
1258         case symbolOutside:
1259         case symbolEnd:
1260           stream << "R{" << LengthInPoints( Columns[i].computedWidth ) << '}';
1261           break;
1262         case symbolCenter: default:
1263           stream << "C{" << LengthInPoints( Columns[i].computedWidth ) << '}';
1264       }
1265     } else {
1266       switch( Columns[i].displayAlignment ) {
1267         case symbolOutside:
1268         case symbolEnd:     stream << 'r'; break;
1269         case symbolCenter:  stream << 'c'; break;
1270         case symbolInside:
1271         case symbolStart:
1272         default:            stream << 'l'; break;
1273       }
1274     }
1275     if( Columns[i].defaultTeXRightBorder )
1276       stream << '|';
1277   }
1278   stream << "}%\n";
1279 
1280   stream << HeaderProlog;
1281   const Row *recentRow = NULL;
1282   for( size_t i = 0; i < Header.size(); i++ ) {
1283     Row::outVerticalBorders( recentRow, &Header[i], stream );
1284     Header[i].out( stream );
1285     recentRow = &Header[i];
1286   }
1287   stream << HeaderEpilog;
1288 
1289   for( size_t i = 0; i < Body.size(); i++ ) {
1290     Row::outVerticalBorders( recentRow, &Body[i], stream );
1291     Body[i].out( stream );
1292     recentRow = &Body[i];
1293   }
1294 
1295   stream << FooterProlog;
1296   for( size_t i = 0; i < Footer.size(); i++ ) {
1297     Row::outVerticalBorders( recentRow, &Footer[i], stream );
1298     Footer[i].out( stream );
1299     recentRow = &Footer[i];
1300   }
1301   stream << FooterEpilog;
1302 
1303   if( recentRow )
1304     Row::outVerticalBorders( recentRow, NULL, stream );
1305 
1306   stream << "\\endTeXTable" << "{}%\n";
1307 }
1308 
normalizeRows()1309 void TeXFOTBuilder::TablePart::normalizeRows() {
1310 
1311   size_t maxCellsInRow = Columns.size()+1;
1312   Vector<Row> *rows;
1313   for( int step = 0; step < 2; step++ ) {
1314     for( int rowType = 0; rowType < 3; rowType++ ) {
1315       switch( rowType ) {
1316         case 0: rows = &Header; break;
1317         case 1: rows = &Body; break;
1318         default: rows = &Footer;
1319       }
1320       for( size_t r = 0; r < rows->size(); r++ ) {
1321         if( step == 0 ) {
1322           if( (*rows)[r].Cells.size() > 1 ) {
1323             size_t lastCellIdx = (*rows)[r].Cells.size()-2;
1324             Cell &lastCell = (*rows)[r].Cells[lastCellIdx];
1325             if( !lastCell.missing
1326                   &&
1327                 lastCellIdx+lastCell.nColumnsSpanned+1 > maxCellsInRow )
1328               maxCellsInRow = lastCellIdx+lastCell.nColumnsSpanned+1;
1329           }
1330         } else if( (*rows)[r].Cells.size() < maxCellsInRow )
1331           (*rows)[r].Cells.resize( maxCellsInRow );
1332       }
1333     }
1334   }
1335 }
1336 
1337 // --------- TeXFOTBuilder::Row -----------------------------------------------
1338 
outContent(OutputByteStream & stream) const1339 void TeXFOTBuilder::Row::outContent( OutputByteStream &stream ) const {
1340 
1341   bool first = true;
1342   for( size_t i = 0; i + 1 < Cells.size(); i++ ) {
1343     if( !Cells[i].isOverlapped() ) {
1344       if( !first )
1345         stream << "&";
1346       else
1347         first = false;
1348       Cells[i].out( stream );
1349     }
1350   }
1351 }
1352 
outVerticalBorders(const TeXFOTBuilder::Row * upperRow,const TeXFOTBuilder::Row * lowerRow,OutputByteStream & stream)1353 void TeXFOTBuilder::Row::outVerticalBorders
1354  ( const TeXFOTBuilder::Row *upperRow,
1355    const TeXFOTBuilder::Row *lowerRow, OutputByteStream &stream ) {
1356 
1357   assert( upperRow != NULL || lowerRow != NULL );
1358   size_t colNum = upperRow ? upperRow->Cells.size()-1 : lowerRow->Cells.size()-1;
1359   int borderStartIdx = -1;
1360   int borderEndIdx;
1361   for( size_t i = 0; i < colNum; i++ ) {
1362     #ifdef TEXDEBUG
1363       stream << "\nROW: " << "COL " << i << " " <<
1364        ( ( ( upperRow && upperRow->Cells[i].singleRowAfterRowBorderPresent() )
1365            ||
1366           ( lowerRow && lowerRow->Cells[i].singleRowBeforeRowBorderPresent() ) )
1367           ? "Border" : "No Border" );
1368     #endif
1369     if( ( upperRow && upperRow->Cells[i].singleRowAfterRowBorderPresent() )
1370          ||
1371         ( lowerRow && lowerRow->Cells[i].singleRowBeforeRowBorderPresent() ) ) {
1372       if( borderStartIdx < 0 )
1373         borderStartIdx = i;
1374       if( i == colNum-1 ) {
1375         borderEndIdx = i;
1376         goto OUT_BORDER;
1377       }
1378    } else if( borderStartIdx > -1 ) {
1379       borderEndIdx = i-1;
1380       goto OUT_BORDER;
1381    }
1382    continue;
1383 
1384     OUT_BORDER:
1385       if( borderStartIdx == 0 && i == colNum-1 )
1386         stream << "\\Hline%\n";
1387       else
1388         stream << "\\Cline{" << borderStartIdx+1 << '-' << borderEndIdx+1 << "}%\n";
1389       borderStartIdx = -1;
1390   }
1391 }
1392 
1393 // --------- TeXFOTBuilder::Cell ----------------------------------------------
1394 
outProlog(OutputByteStream & stream) const1395 void TeXFOTBuilder::Cell::outProlog( OutputByteStream &stream ) const {
1396 
1397   if( nColumnsSpanned > 1 ) {
1398     stream << "\\multicolumn%\n{" << nColumnsSpanned << "}{";
1399     if( beforeColumnBorder.borderPresent )
1400       stream << '|';
1401     switch( effectiveAlignment ) {
1402       case symbolOutside:
1403       case symbolEnd:     stream << 'r'; break;
1404       case symbolCenter:  stream << 'c'; break;
1405       case symbolInside:
1406       case symbolStart:
1407       default:            stream << 'l'; break;
1408     }
1409     if( afterColumnBorder.borderPresent )
1410       stream << '|';
1411     stream << "}{";
1412   }
1413 
1414   CompoundFotElement::outProlog( stream );
1415 }
1416 
outEpilog(OutputByteStream & stream) const1417 void TeXFOTBuilder::Cell::outEpilog( OutputByteStream &stream ) const {
1418 
1419   CompoundFotElement::outEpilog( stream );
1420   if( nColumnsSpanned > 1 )
1421     stream << "}%\n";
1422 }
1423 
computeMultiParFlag()1424 void TeXFOTBuilder::Cell::computeMultiParFlag() {
1425 
1426   if( paragraphChildrenNum > 1 ) {
1427     StrOutputByteStream str;
1428     str << "\\def\\MultiPar{1}";
1429     String<char> s;
1430     str.extractString( s );
1431     Characteristics += s;
1432   }
1433 }
1434 
computeOverridingTeXColumnBorders(TablePart & tablePart)1435 void TeXFOTBuilder::Cell::computeOverridingTeXColumnBorders( TablePart &tablePart ) {
1436 
1437   StrOutputByteStream str;
1438 
1439   if( tablePart.Columns[TeXTableColumnIdx].defaultTeXLeftBorder
1440        != beforeColumnBorder.borderPresent )
1441     str << "\\def\\TeXTableCellBeforeColumnBorder{"  << beforeColumnBorder.borderPresent << '}';
1442 
1443   if( tablePart.Columns[TeXTableColumnIdx+nColumnsSpanned-1].defaultTeXRightBorder
1444        != afterColumnBorder.borderPresent )
1445     str << "\\def\\TeXTableCellAfterColumnBorder{"  << afterColumnBorder.borderPresent << '}';
1446 
1447   String<char> s;
1448   str.extractString( s );
1449   Characteristics += s;
1450 }
1451 
computeOverridingTeXDisplayAlignment(TablePart & tablePart)1452 void TeXFOTBuilder::Cell::computeOverridingTeXDisplayAlignment( TablePart &tablePart ) {
1453 
1454   effectiveAlignment
1455    = tablePart.Columns[TeXTableColumnIdx].isExplicit
1456       ? tablePart.Columns[TeXTableColumnIdx].displayAlignment : displayAlignment;
1457 
1458   StrOutputByteStream str;
1459   if( effectiveAlignment != tablePart.Columns[TeXTableColumnIdx].displayAlignment ) {
1460     str << "\\def\\TeXTableCellDisplayAlignment{";
1461     switch( effectiveAlignment ) {
1462       case symbolOutside:
1463       case symbolEnd:     str << 'r'; break;
1464       case symbolCenter:  str << 'c'; break;
1465       case symbolInside:
1466       case symbolStart:
1467       default:            str << 'l'; break;
1468     }
1469     str << '}';
1470     String<char> s;
1471     str.extractString( s );
1472     Characteristics += s;
1473   }
1474 }
1475 
singleRowBeforeRowBorderPresent() const1476 bool TeXFOTBuilder::Cell::singleRowBeforeRowBorderPresent() const {
1477 
1478   assert( OverlappingCell != NULL );
1479   if( OverlappingCell->TeXTableRowIdx == TeXTableRowIdx )
1480     return OverlappingCell->beforeRowBorder.borderPresent;
1481   else
1482     return false;
1483 }
1484 
singleRowAfterRowBorderPresent() const1485 bool TeXFOTBuilder::Cell::singleRowAfterRowBorderPresent() const {
1486 
1487   assert( OverlappingCell != NULL );
1488   assert( TeXTableRowIdx > -1 );
1489   if( OverlappingCell->TeXTableRowIdx + OverlappingCell->nRowsSpanned
1490        == ((unsigned)TeXTableRowIdx)+1 )
1491     return OverlappingCell->afterRowBorder.borderPresent;
1492   else
1493     return false;
1494 }
1495 
singleColumnBeforeColumnBorderPresent() const1496 bool TeXFOTBuilder::Cell::singleColumnBeforeColumnBorderPresent() const {
1497 
1498   assert( OverlappingCell != NULL );
1499   assert( TeXTableRowIdx > -1 );
1500   if( OverlappingCell->TeXTableColumnIdx
1501        == TeXTableColumnIdx )
1502     return OverlappingCell->beforeColumnBorder.borderPresent;
1503   else
1504     return false;
1505 }
1506 
singleColumnAfterColumnBorderPresent() const1507 bool TeXFOTBuilder::Cell::singleColumnAfterColumnBorderPresent() const {
1508 
1509   assert( OverlappingCell != NULL );
1510   if( OverlappingCell->TeXTableColumnIdx + (int)OverlappingCell->nColumnsSpanned
1511        == TeXTableColumnIdx+1 )
1512     return OverlappingCell->afterColumnBorder.borderPresent;
1513   else
1514     return false;
1515 }
1516 
1517 // --------- TeXFOTBuilder::Border --------------------------------------------
1518 
setFromFot(TeXFOTBuilder & builder)1519 void TeXFOTBuilder::Border::setFromFot( TeXFOTBuilder &builder ) {
1520 
1521   const TeXFOTBuilder::Format &f = builder.curFormat();
1522   borderPriority = f.FotBorderPriority;
1523   borderPresent = f.FotBorderPresent;
1524   lineThickness = f.FotLineThickness;
1525   lineRepeat = f.FotLineRepeat;
1526   lineSep  = f.FotLineSep;
1527 }
1528 
resolve(Border & adjacentBorder)1529 void TeXFOTBuilder::Border::resolve( Border &adjacentBorder ) {
1530 
1531   if( adjacentBorder.borderPriority > borderPriority
1532      ||
1533     (   adjacentBorder.borderPriority == borderPriority
1534      && !adjacentBorder.cellBorder
1535      && adjacentBorder.borderPresent ) ) {
1536 
1537     lineThickness = adjacentBorder.lineThickness;
1538     borderPresent = adjacentBorder.borderPresent;
1539     lineRepeat = adjacentBorder.lineRepeat;
1540     lineSep = adjacentBorder.lineSep;
1541 
1542     if( adjacentBorder.cellBorder )
1543         adjacentBorder.borderPresent = false;
1544   }
1545 
1546   #ifdef TEXDEBUG
1547     *TeXFOTBuilder::curInstance().fileout_
1548      << "RESOLVE_RESULT: " << borderPresent << "\n";
1549   #endif
1550 }
1551 
1552 // --------- End Tables -------------------------------------------------------
1553 
1554 #define MAYBESET(name,value,default) (value!=default?(set(name,value),0):0)
1555 
1556 //
1557 // Get the current output stream.
1558 //
1559 inline
os()1560 OutputByteStream &TeXFOTBuilder::os()
1561 {
1562   return CurOs == NULL ? *fileout_ : *CurOs;
1563 }
1564 
1565 //
1566 // Define an output operator for StringC
1567 //
1568 // FIXME This won't work for Unicode characters.
1569 
operator <<(OutputByteStream & os,const StringC & s)1570 static OutputByteStream &operator<<(OutputByteStream &os, const StringC &s)
1571 {
1572   for (size_t i = 0; i < s.size(); i++)
1573     os << char(s[i]);
1574   return os;
1575 }
1576 
1577 
1578 //
1579 // Define an output operator for GroveString
1580 //
operator <<(OutputByteStream & os,const GroveString & s)1581 static OutputByteStream &operator<<(OutputByteStream &os, const GroveString &s)
1582 {
1583   for (size_t i = 0; i < s.size(); i++)
1584     os << char(s[i]);
1585   return os;
1586 }
1587 
operator <<(OutputByteStream & os,double d)1588 static OutputByteStream &operator<<(OutputByteStream &os, double d)
1589 {
1590   char buf[64];
1591   sprintf(buf, "%g", d);
1592   return os << buf;
1593 }
1594 
makeTeXFOTBuilder(OutputByteStream * os,Messenger * mgr,const FOTBuilder::Extension * & ext)1595 FOTBuilder *makeTeXFOTBuilder(OutputByteStream *os, Messenger *mgr,
1596 			      const FOTBuilder::Extension *&ext)
1597 {
1598   static const TeXFOTBuilder::PageFloatFlowObj pageFloat;
1599   static const TeXFOTBuilder::PageFootnoteFlowObj pageFootnote;
1600   static const FOTBuilder::Extension extensions[] = {
1601     {
1602       "UNREGISTERED::Sebastian Rahtz//Flow Object Class::page-float",
1603       0,
1604       0,
1605       0,
1606       0,
1607       &pageFloat
1608     },
1609     {
1610       "UNREGISTERED::Sebastian Rahtz//Flow Object Class::page-footnote",
1611       0,
1612       0,
1613       0,
1614       0,
1615       &pageFootnote
1616     },
1617     {
1618       "UNREGISTERED::James Clark//Characteristic::page-number-format",
1619       0,
1620       (void (FOTBuilder::*)(const StringC &))&TeXFOTBuilder::setPageNumberFormat,
1621       0,
1622       0
1623     },
1624     {
1625       "UNREGISTERED::James Clark//Characteristic::page-number-restart?",
1626       (void (FOTBuilder::*)(bool))&TeXFOTBuilder::setPageNumberRestart,
1627       0,
1628       0
1629     },
1630     {
1631       "UNREGISTERED::James Clark//Characteristic::page-n-columns",
1632       0,
1633       0,
1634       (void (FOTBuilder::*)(long))&TeXFOTBuilder::setPageNColumns,
1635       0
1636     },
1637     {
1638       "UNREGISTERED::James Clark//Characteristic::page-column-sep",
1639       0,
1640       0,
1641       0,
1642       (void (FOTBuilder::*)(FOTBuilder::Length))&TeXFOTBuilder::setPageColumnSep,
1643     },
1644     {
1645       "UNREGISTERED::James Clark//Characteristic::page-balance-columns?",
1646       (void (FOTBuilder::*)(bool))&TeXFOTBuilder::setPageBalanceColumns,
1647       0,
1648       0
1649     },
1650     {
1651       "UNREGISTERED::James Clark//Characteristic::subscript-depth",
1652       0,
1653       0,
1654       0,
1655       (void (FOTBuilder::*)(FOTBuilder::Length))&TeXFOTBuilder::setSubscriptDepth,
1656     },
1657     {
1658       "UNREGISTERED::James Clark//Characteristic::over-mark-height",
1659       0,
1660       0,
1661       0,
1662       (void (FOTBuilder::*)(FOTBuilder::Length))&TeXFOTBuilder::setOverMarkHeight,
1663     },
1664     {
1665       "UNREGISTERED::James Clark//Characteristic::under-mark-depth",
1666       0,
1667       0,
1668       0,
1669       (void (FOTBuilder::*)(FOTBuilder::Length))&TeXFOTBuilder::setUnderMarkDepth,
1670     },
1671     {
1672       "UNREGISTERED::James Clark//Characteristic::superscript-height",
1673       0,
1674       0,
1675       0,
1676       (void (FOTBuilder::*)(FOTBuilder::Length))&TeXFOTBuilder::setSuperscriptHeight,
1677     },
1678     {
1679       "UNREGISTERED::James Clark//Characteristic::grid-row-sep",
1680       0,
1681       0,
1682       0,
1683       (void (FOTBuilder::*)(FOTBuilder::Length))&TeXFOTBuilder::setGridRowSep,
1684     },
1685     {
1686       "UNREGISTERED::James Clark//Characteristic::grid-column-sep",
1687       0,
1688       0,
1689       0,
1690       (void (FOTBuilder::*)(FOTBuilder::Length))&TeXFOTBuilder::setGridColumnSep,
1691     },
1692     {
1693       "UNREGISTERED::James Clark//Characteristic::heading-level",
1694       0,
1695       0,
1696       (void (FOTBuilder::*)(long))&TeXFOTBuilder::setHeadingLevel,
1697       0
1698     },
1699     {
1700       "UNREGISTERED::James Clark//Characteristic::preserve-sdata?",
1701       (void (FOTBuilder::*)(bool))&TeXFOTBuilder::setPreserveSdata,
1702       0,
1703       0,
1704       0,
1705       0
1706     },
1707 
1708     { 0, 0, 0}
1709   };
1710   ext = extensions;
1711   return new TeXFOTBuilder(os, mgr);
1712 }
1713 
1714 ////////////////////////////////////////////////////////////////////////
1715 // Constructor and Destructor
1716 ////////////////////////////////////////////////////////////////////////
1717 
TeXFOTBuilder(OutputByteStream * o,Messenger * mgr)1718 TeXFOTBuilder::TeXFOTBuilder(OutputByteStream *o, Messenger *mgr)
1719 : fileout_(o), mgr_(mgr), CurOs( NULL ), preserveSdata_(1), inMath_(0)
1720 {
1721   #ifdef TEXDEBUG
1722     CurInstance = this;
1723   #endif
1724   NextFormat.FotCurDisplaySize = Format::INITIAL_PAGE_SIZE();
1725   FormatStack.push_back( NextFormat );
1726   os() << "\\FOT{2}";
1727 }
1728 
~TeXFOTBuilder()1729 TeXFOTBuilder::~TeXFOTBuilder()
1730 {
1731   os() << "\\endFOT{}";
1732 }
1733 
1734 //////////////////////////////////////////////////////////////////////
1735 // Atomic flow objects
1736 //////////////////////////////////////////////////////////////////////
1737 
characters(const Char * s,size_t n)1738 void TeXFOTBuilder::characters(const Char *s, size_t n)
1739 {
1740   for (; n > 0; n--, s++) {
1741 				// Since TeX has only 256 characters
1742 				// by default, two-byte characters
1743 				// will need special treatment.
1744     if (*s > 255) {
1745       //      set("Ch",(unsigned long)(*s));
1746       // insertAtomic("Character");
1747       //
1748       // Don't complicate matters, just give the character!
1749        os() << "\\Character{" << (unsigned long)(*s) << "}";
1750     } else {
1751 				// Otherwise, check for special
1752 				// TeX escapes.
1753       switch(*s) {
1754       default:
1755 	os() << char(*s);
1756 	break;
1757       case '\\':
1758       case '^':
1759       case '_':
1760       case '~':
1761 	os() << "\\char" << int(*s) << "{}";
1762 	break;
1763       case '{':
1764       case '}':
1765       case '$':
1766       case '&':
1767       case '#':
1768       case '%':
1769 	os() << "\\" << char(*s);
1770 	break;
1771       case '\r':
1772 	os() << '\n';
1773 	break;
1774       case '\n':
1775 	break;
1776       case '-':
1777       case '<':
1778       case '>':
1779         os() << char(*s);
1780 	if (!inMath_)
1781           os() << "\\/"; // break ligatures
1782         break;
1783 
1784       }
1785     }
1786   }
1787 }
1788 
character(const CharacterNIC & nic)1789 void TeXFOTBuilder::character(const CharacterNIC &nic)
1790 {
1791   setCharacterNIC(nic);
1792   //  insertAtomic("Character");
1793   dumpInherited();
1794   os() << "\\Character{" << (unsigned long)(nic.ch) << "}";
1795 }
1796 
paragraphBreak(const ParagraphNIC & nic)1797 void TeXFOTBuilder::paragraphBreak(const ParagraphNIC &nic)
1798 {
1799   setParagraphNIC(nic);
1800   insertAtomic("ParagraphBreak");
1801 }
1802 
externalGraphic(const ExternalGraphicNIC & nic)1803 void TeXFOTBuilder::externalGraphic(const ExternalGraphicNIC &nic)
1804 {
1805   setExternalGraphicNIC(nic);
1806   insertAtomic("ExternalGraphic");
1807 }
1808 
rule(const RuleNIC & nic)1809 void TeXFOTBuilder::rule(const RuleNIC &nic)
1810 {
1811   setRuleNIC(nic);
1812   insertAtomic("Rule");
1813 }
1814 
alignmentPoint()1815 void TeXFOTBuilder::alignmentPoint()
1816 {
1817   insertAtomic("AlignmentPoint");
1818 }
1819 
1820 // page-number sosofo
pageNumber()1821 void TeXFOTBuilder::pageNumber()
1822 {
1823   insertAtomic("PageNumber");
1824 }
1825 
formattingInstruction(const StringC & instr)1826 void TeXFOTBuilder::formattingInstruction (const StringC &instr)
1827 {
1828   os() << instr;
1829 }
1830 
tableColumn(const TableColumnNIC & nic)1831 void TeXFOTBuilder::tableColumn(const TableColumnNIC &nic)
1832 {
1833   setTableColumnNIC(nic);
1834 
1835   if( nic.columnIndex >= curTable().curTablePart().Columns.size() )
1836       curTable().curTablePart().Columns.resize( nic.columnIndex + 1 );
1837 
1838   Column &col = curTable().curTablePart().Columns[nic.columnIndex];
1839 
1840   col.isExplicit = true;
1841   col.hasWidth = nic.hasWidth;
1842   if( nic.hasWidth )
1843       col.width = nic.width;
1844 
1845   col.displayAlignment = curFormat().FotDisplayAlignment;
1846 
1847   insertAtomic("TableColumn");
1848 }
1849 
tableCellBeforeRowBorder()1850 void TeXFOTBuilder::tableCellBeforeRowBorder()
1851 {
1852   start();
1853   curTable().curCell().beforeRowBorder.setFromFot( *this );
1854   insertAtomic( curTable().curCell().beforeRowBorder );
1855   end();
1856 }
1857 
tableCellAfterRowBorder()1858 void TeXFOTBuilder::tableCellAfterRowBorder()
1859 {
1860   start();
1861   curTable().curCell().afterRowBorder.setFromFot( *this );
1862   insertAtomic( curTable().curCell().afterRowBorder );
1863   end();
1864 }
1865 
tableCellBeforeColumnBorder()1866 void TeXFOTBuilder::tableCellBeforeColumnBorder()
1867 {
1868   start();
1869   curTable().curCell().beforeColumnBorder.setFromFot( *this );
1870   insertAtomic( curTable().curCell().beforeColumnBorder );
1871   end();
1872 }
1873 
tableCellAfterColumnBorder()1874 void TeXFOTBuilder::tableCellAfterColumnBorder()
1875 {
1876   start();
1877   curTable().curCell().afterColumnBorder.setFromFot( *this );
1878   insertAtomic( curTable().curCell().afterColumnBorder );
1879   end();
1880 }
1881 
fractionBar()1882 void TeXFOTBuilder::fractionBar()
1883 {
1884   insertAtomic("FractionBar");
1885 }
1886 
radicalRadical(const CharacterNIC & c)1887 void TeXFOTBuilder::radicalRadical(const CharacterNIC &c)
1888 {
1889   setCharacterNIC(c);
1890   insertAtomic("RadicalRadical");
1891 }
1892 
radicalRadicalDefaulted()1893 void TeXFOTBuilder::radicalRadicalDefaulted()
1894 {
1895   insertAtomic("RadicalRadicalDefaulted");
1896 }
1897 
currentNodePageNumber(const NodePtr & node)1898 void TeXFOTBuilder::currentNodePageNumber(const NodePtr &node)
1899 {
1900   GroveString id;
1901   unsigned long ei;
1902 
1903   // FIX ME!
1904   // Only PARTIALLY supported -- I currently allow cross-references
1905   // only to elements.
1906   if (node->getId(id) == accessOK) {
1907     set("Label",id);
1908   } else if (node->elementIndex(ei) == accessOK) {
1909     set("Element",ei);
1910   } else {
1911     message(TeXMessages::unsupportedPageNumberNonElement);
1912     return;
1913   }
1914   unsigned long g = node->groveIndex();
1915   if (g) {
1916     set("GroveIndex",g);
1917   }
1918   insertAtomic("CurrentNodePageNumber");
1919 }
1920 
1921 
1922 //////////////////////////////////////////////////////////////////////
1923 // Non-atomic flow objects
1924 //////////////////////////////////////////////////////////////////////
1925 
startSequence()1926 void TeXFOTBuilder::startSequence()
1927 {
1928   start();
1929   if( !curFotElementState().enforcingStructure() )
1930     startGroup("Seq");
1931 }
1932 
endSequence()1933 void TeXFOTBuilder::endSequence()
1934 {
1935   if( !curFotElementState().enforcingStructure() )
1936     endGroup("Seq");
1937   end();
1938 }
1939 
startLineField(const LineFieldNIC & nic)1940 void TeXFOTBuilder::startLineField(const LineFieldNIC &nic)
1941 {
1942   start();
1943   setLineFieldNIC(nic);
1944   startGroup("LineField");
1945 }
1946 
endLineField()1947 void TeXFOTBuilder::endLineField()
1948 {
1949   endGroup("LineField");
1950   end();
1951 }
1952 
startParagraph(const ParagraphNIC & nic)1953 void TeXFOTBuilder::startParagraph(const ParagraphNIC &nic)
1954 {
1955   startDisplay( nic );
1956   if( curFormat().FotObjectClass == oc_Cell )
1957     curTable().curCell().paragraphChildrenNum++;
1958   start();
1959   setParagraphNIC(nic);
1960   startGroup("Par");
1961 }
1962 
endParagraph()1963 void TeXFOTBuilder::endParagraph()
1964 {
1965   endGroup("Par");
1966   end();
1967   endDisplay();
1968 }
1969 
startDisplayGroup(const DisplayGroupNIC & nic)1970 void TeXFOTBuilder::startDisplayGroup(const DisplayGroupNIC &nic)
1971 {
1972   startDisplay( nic );
1973   start();
1974   setDisplayGroupNIC(nic);
1975   startGroup("DisplayGroup");
1976 }
1977 
endDisplayGroup()1978 void TeXFOTBuilder::endDisplayGroup()
1979 {
1980   endGroup("DisplayGroup");
1981   end();
1982   endDisplay();
1983 }
1984 
startScroll()1985 void TeXFOTBuilder::startScroll()
1986 {
1987   start();
1988   startGroup("Scroll");
1989 }
1990 
endScroll()1991 void TeXFOTBuilder::endScroll()
1992 {
1993   endGroup("Scroll");
1994   end();
1995 }
1996 
startScore(Char ch)1997 void TeXFOTBuilder::startScore(Char ch)
1998 {
1999   start();
2000   set("ScoreCharacter",(unsigned long)ch);
2001   startGroup("Score");
2002 }
2003 
startScore(const LengthSpec & len)2004 void TeXFOTBuilder::startScore(const LengthSpec &len)
2005 {
2006   start();
2007   set("ScoreLength",len);
2008   startGroup("Score");
2009 }
2010 
startScore(Symbol type)2011 void TeXFOTBuilder::startScore(Symbol type)
2012 {
2013   start();
2014   set("ScoreType",type);
2015   startGroup("Score");
2016 }
2017 
endScore()2018 void TeXFOTBuilder::endScore()
2019 {
2020   endGroup("Score");
2021   end();
2022 }
2023 
startLeader(const LeaderNIC & nic)2024 void TeXFOTBuilder::startLeader(const LeaderNIC &nic)
2025 {
2026   start();
2027   setLeaderNIC(nic);
2028   startGroup("Leader");
2029 }
2030 
endLeader()2031 void TeXFOTBuilder::endLeader()
2032 {
2033   endGroup("Leader");
2034   end();
2035 }
2036 
startSideline()2037 void TeXFOTBuilder::startSideline()
2038 {
2039   start();
2040   startGroup("SideLine");
2041 }
2042 
endSideline()2043 void TeXFOTBuilder::endSideline()
2044 {
2045   endGroup("SideLine");
2046   end();
2047 }
2048 
startBox(const BoxNIC & nic)2049 void TeXFOTBuilder::startBox(const BoxNIC &nic)
2050 {
2051   if( nic.isDisplay ) {
2052     DisplayBoxLevels.push_back( FormatStack.size() );
2053     startDisplay(nic);
2054   }
2055   start();
2056   setBoxNIC(nic);
2057   startGroup("BOX");
2058 }
2059 
endBox()2060 void TeXFOTBuilder::endBox()
2061 {
2062   endGroup("BOX");
2063   end();
2064   if( DisplayBoxLevels.size() > 0 && DisplayBoxLevels.back() == FormatStack.size() ) {
2065     DisplayBoxLevels.resize( DisplayBoxLevels.size() - 1 );
2066     endDisplay();
2067   }
2068 }
2069 
2070 // Tables
startTable(const TableNIC & nic)2071 void TeXFOTBuilder::startTable(const TableNIC &nic)
2072 {
2073   #ifdef TEXDEBUG
2074     *fileout_ << "\nTABLE_START\n";
2075   #endif
2076   startDisplay( nic );
2077   start();
2078 
2079   setTableNIC(nic);
2080 
2081   Length curStartIndent = computeLengthSpec( curFormat().FotStartIndentSpec );
2082   curTable().startIndent = curStartIndent;
2083 
2084   curTable().begin();
2085   curTable().displayAlignment = curFormat().FotDisplayAlignment;
2086 
2087   if( nic.widthType == TableNIC::widthExplicit )
2088       curTable().tableWidth = computeLengthSpec( nic.width );
2089   else
2090       curTable().tableWidth
2091        = curFormat().FotCurDisplaySize - curStartIndent
2092           - computeLengthSpec( curFormat().FotEndIndentSpec );
2093 
2094   startGroup( curTable() );
2095   curTable().curTablePart().open( *this );
2096 }
2097 
endTable()2098 void TeXFOTBuilder::endTable()
2099 {
2100   #ifdef TEXDEBUG
2101     *fileout_ << "\nTABLE_END\n";
2102   #endif
2103 
2104   if( curTable().NoTablePartsSeen ) {
2105     curTable().curTablePart().close( *this );
2106     curTable().curTablePart().isExplicit = false;
2107   }
2108 
2109   curTable().end( *this );
2110   curTable().close( *this );
2111   curTable().out( os() );
2112 
2113   endGroup();
2114   end();
2115   endDisplay();
2116 }
2117 
2118 // A call for each border is made immediately
2119 // after startTable(), each preceded by any appropriate set*() calls.
tableBeforeRowBorder()2120 void TeXFOTBuilder::tableBeforeRowBorder()
2121 {
2122   start();
2123   curTable().beforeRowBorder.setFromFot( *this );
2124   insertAtomic( curTable().beforeRowBorder );
2125   end();
2126 }
2127 
tableAfterRowBorder()2128 void TeXFOTBuilder::tableAfterRowBorder()
2129 {
2130   start();
2131   curTable().afterRowBorder.setFromFot( *this );
2132   insertAtomic( curTable().afterRowBorder );
2133   end();
2134 }
2135 
tableBeforeColumnBorder()2136 void TeXFOTBuilder::tableBeforeColumnBorder()
2137 {
2138   start();
2139   curTable().beforeColumnBorder.setFromFot( *this );
2140   insertAtomic( curTable().beforeColumnBorder );
2141   end();
2142 }
2143 
tableAfterColumnBorder()2144 void TeXFOTBuilder::tableAfterColumnBorder()
2145 {
2146   start();
2147   curTable().afterColumnBorder.setFromFot( *this );
2148   insertAtomic( curTable().afterColumnBorder );
2149   end();
2150 }
2151 
startTablePartSerial(const TablePartNIC & nic)2152 void TeXFOTBuilder::startTablePartSerial(const TablePartNIC &nic)
2153 {
2154   #ifdef TEXDEBUG
2155     *fileout_ << "\nTABLE_PART_START\n";
2156   #endif
2157 
2158   startDisplay( nic );
2159   start();
2160 
2161   setTablePartNIC(nic);
2162 
2163   if( curTable().NoTablePartsSeen )
2164       curTable().NoTablePartsSeen = false;
2165   else {
2166       curTable().TableParts.resize( curTable().TableParts.size()+1 );
2167       curTable().TableParts.back().setSiblingSeqIdx( curTable().TableParts.size()-1 );
2168       curTable().TableParts.back().setParent( &curTable() );
2169   }
2170 
2171   curTable().TableParts.back().begin();
2172   curTable().TableParts.back().open( *this );
2173 
2174   startGroup( curTable().curTablePart() );
2175 }
2176 
endTablePartSerial()2177 void TeXFOTBuilder::endTablePartSerial()
2178 {
2179   curTable().curTablePart().close( *this );
2180   curTable().CurTablePart = NULL;
2181   endGroup();
2182   end();
2183   endDisplay();
2184 
2185   #ifdef TEXDEBUG
2186     *fileout_ << "\nTABLE_PART_END\n";
2187   #endif
2188 }
2189 
startTableRow()2190 void TeXFOTBuilder::startTableRow()
2191 {
2192   #ifdef TEXDEBUG
2193     *fileout_ << "\nTABLE_ROW_START\n";
2194   #endif
2195 
2196   curTable().curRows().resize( curTable().curRows().size() + 1 );
2197   curTable().curRows().back().setSiblingSeqIdx( curTable().curRows().size()-1 );
2198   curTable().curRows().back().setParent( &curTable().curTablePart() );
2199   startGroup( curTable().curRows().back() );
2200   curTable().curRows().back().open( *this );
2201 }
2202 
endTableRow()2203 void TeXFOTBuilder::endTableRow()
2204 {
2205   curTable().curRows().back().close( *this );
2206   endGroup();
2207 
2208   #ifdef TEXDEBUG
2209     *fileout_ << "\nTABLE_ROW_END\n";
2210   #endif
2211 }
2212 
startTableCell(const TableCellNIC & nic)2213 void TeXFOTBuilder::startTableCell(const TableCellNIC &nic)
2214 {
2215   #ifdef TEXDEBUG
2216     *fileout_ << "\nTABLE_CELL_START index: " << nic.columnIndex
2217               << " missing: " << nic.missing << "\n";
2218   #endif
2219 
2220   setTableCellNIC(nic);
2221 
2222   TablePart &tp = curTable().curTablePart();
2223   if( !tp.columnsProcessed )
2224       tp.processColumns( *this );
2225 
2226   Vector<Cell> &Cells = curTable().curRows().back().Cells;
2227   { size_t curSize = Cells.size();
2228     if( nic.columnIndex >= curSize ) {
2229         Cells.resize( nic.columnIndex + 1 );
2230         for( size_t i = curSize; i < Cells.size(); i++ )
2231           Cells[i].setSiblingSeqIdx( i );
2232     }
2233   }
2234 
2235   Cell &cell = Cells[nic.columnIndex];
2236   curTable().CurCell = &cell;
2237   cell.missing = nic.missing;
2238   cell.setParent( &curTable().curRows().back() );
2239 
2240   if( nic.nColumnsSpanned != 1 )
2241       cell.nColumnsSpanned = nic.nColumnsSpanned;
2242 
2243   if( nic.nRowsSpanned != 1 )
2244       cell.nRowsSpanned = nic.nRowsSpanned;
2245 
2246   long newDisplaySize = 0;
2247   for( size_t i = nic.columnIndex; i < nic.columnIndex + nic.nColumnsSpanned; i++ )
2248       if( i < tp.Columns.size() ) {
2249           if( tp.Columns[i].hasWidth )
2250               newDisplaySize
2251                += computeLengthSpec( tp.Columns[i].width );
2252       } else
2253       if( !nic.missing ) {
2254           tp.Columns.resize( tp.Columns.size() + 1 );
2255           tp.Columns.back().hasWidth = false;
2256       }
2257 
2258   if( newDisplaySize > 0 ) {
2259       newDisplaySize -= NextFormat.FotCellBeforeColumnMargin
2260                          + NextFormat.FotCellAfterColumnMargin;
2261       NextFormat.FotCurDisplaySize = newDisplaySize;
2262   }
2263 
2264   cell.displaySize = NextFormat.FotCurDisplaySize;
2265   cell.displayAlignment = NextFormat.FotDisplayAlignment;
2266 
2267   elementStart( oc_Cell );
2268   startGroup( cell );
2269   cell.open( *this );
2270 }
2271 
endTableCell()2272 void TeXFOTBuilder::endTableCell()
2273 {
2274   curTable().curCell().close( *this );
2275   curTable().CurCell = NULL;
2276   endGroup();
2277   end();
2278 
2279   #ifdef TEXDEBUG
2280     *fileout_ << "\nTABLE_CELL_END\n";
2281   #endif
2282 }
2283 
startSimplePageSequence()2284 void TeXFOTBuilder::startSimplePageSequence()
2285 {
2286   NextFormat.FotCurDisplaySize
2287    = ( NextFormat.FotPageWidth - NextFormat.FotLeftMargin - NextFormat.FotRightMargin
2288         - NextFormat.FotPageColumnSep * ( NextFormat.FotPageNColumns - 1 ) )
2289       / NextFormat.FotPageNColumns;
2290 
2291   start();
2292   startGroup("SpS");
2293 }
2294 
endSimplePageSequence()2295 void TeXFOTBuilder::endSimplePageSequence()
2296 {
2297   endGroup("SpS");
2298   end();
2299 }
2300 
2301 // These aren't real flow objects, so handle them a little
2302 // differently.
startSimplePageSequenceHeaderFooter(unsigned flags)2303 void TeXFOTBuilder::startSimplePageSequenceHeaderFooter(unsigned flags)
2304 {
2305   os() << "\n\\SpS";
2306   if ((flags & (firstHF|otherHF)) == firstHF)
2307     os() << "First";
2308   else
2309     os() << "Other";
2310   if ((flags & (frontHF|backHF)) == frontHF)
2311     os() << "Front";
2312   else
2313     os() << "Back";
2314   switch (flags & (leftHF|centerHF|rightHF)) {
2315   case leftHF:
2316     os() << "Left";
2317     break;
2318   case centerHF:
2319     os() << "Center";
2320     break;
2321   case rightHF:
2322     os() << "Right";
2323     break;
2324   }
2325   if ((flags & (headerHF|footerHF)) == headerHF)
2326     os() << "Header";
2327   else
2328     os() << "Footer";
2329   os() << "%\n{";
2330 }
2331 
endSimplePageSequenceHeaderFooter(unsigned)2332 void TeXFOTBuilder::endSimplePageSequenceHeaderFooter(unsigned)
2333 {
2334   endSimpleGroup();
2335 }
2336 
startTablePartHeader()2337 void TeXFOTBuilder::startTablePartHeader()
2338 {
2339   curTable().CurRows = &curTable().curTablePart().Header;
2340   startGroup( "TablePartHeader", &curTable().curTablePart().HeaderProlog );
2341 }
2342 
endTablePartHeader()2343 void TeXFOTBuilder::endTablePartHeader()
2344 {
2345   curTable().CurRows = &curTable().curTablePart().Body;
2346   endGroup( "TablePartHeader", &curTable().curTablePart().HeaderEpilog );
2347 }
2348 
startTablePartFooter()2349 void TeXFOTBuilder::startTablePartFooter()
2350 {
2351   curTable().CurRows = &curTable().curTablePart().Footer;
2352   startGroup( "TablePartFooter", &curTable().curTablePart().FooterProlog );
2353 }
2354 
endTablePartFooter()2355 void TeXFOTBuilder::endTablePartFooter()
2356 {
2357   curTable().CurRows = &curTable().curTablePart().Body;
2358   endGroup( "TablePartFooter", &curTable().curTablePart().FooterEpilog );
2359 }
2360 
startMathSequence()2361 void TeXFOTBuilder::startMathSequence()
2362 {
2363   inMath_++;
2364   startGroup("MathSeq");
2365 }
2366 
endMathSequence()2367 void TeXFOTBuilder::endMathSequence()
2368 {
2369   endGroup("MathSeq");
2370   inMath_++;
2371 }
2372 
startFractionSerial()2373 void TeXFOTBuilder::startFractionSerial()
2374 {
2375   startGroup("FractionSerial");
2376 }
2377 
endFractionSerial()2378 void TeXFOTBuilder::endFractionSerial()
2379 {
2380   endGroup("FractionSerial");
2381 }
2382 
startFractionNumerator()2383 void TeXFOTBuilder::startFractionNumerator()
2384 {
2385   startGroup("FractionNumerator");
2386 }
2387 
endFractionNumerator()2388 void TeXFOTBuilder::endFractionNumerator()
2389 {
2390   endGroup("FractionNumerator");
2391 }
2392 
startFractionDenominator()2393 void TeXFOTBuilder::startFractionDenominator()
2394 {
2395   startGroup("FractionDenominator");
2396 }
2397 
endFractionDenominator()2398 void TeXFOTBuilder::endFractionDenominator()
2399 {
2400   endGroup("FractionDenominator");
2401 }
2402 
startUnmath()2403 void TeXFOTBuilder::startUnmath()
2404 {
2405   startBrace("Unmath");
2406 }
2407 
endUnmath()2408 void TeXFOTBuilder::endUnmath()
2409 {
2410   endBrace("Unmath");
2411 }
2412 
startSuperscript()2413 void TeXFOTBuilder::startSuperscript()
2414 {
2415    startBrace("Superscript");
2416 }
2417 
endSuperscript()2418 void TeXFOTBuilder::endSuperscript()
2419 {
2420   endBrace("Superscript");
2421 }
2422 
startSubscript()2423 void TeXFOTBuilder::startSubscript()
2424 {
2425   startBrace("Subscript");
2426 }
2427 
endSubscript()2428 void TeXFOTBuilder::endSubscript()
2429 {
2430   endBrace("Subscript");
2431 }
startScriptSerial()2432 void TeXFOTBuilder::startScriptSerial()
2433 {
2434   startBrace("ScriptSerial");
2435 }
2436 
endScriptSerial()2437 void TeXFOTBuilder::endScriptSerial()
2438 {
2439 }
2440 
startScriptPreSup()2441 void TeXFOTBuilder::startScriptPreSup()
2442 {
2443   closeopenBrace("ScriptPreSup"); // ends brace started in startScript Serial
2444 }
2445 
endScriptPreSup()2446 void TeXFOTBuilder::endScriptPreSup()
2447 {
2448   endSimpleGroup();
2449 }
2450 
startScriptPreSub()2451 void TeXFOTBuilder::startScriptPreSub()
2452 {
2453   startSimpleGroup("ScriptPreSub");
2454 }
2455 
endScriptPreSub()2456 void TeXFOTBuilder::endScriptPreSub()
2457 {
2458   endSimpleGroup();
2459 }
2460 
startScriptPostSup()2461 void TeXFOTBuilder::startScriptPostSup()
2462 {
2463   startSimpleGroup("ScriptPostSup");
2464 }
2465 
endScriptPostSup()2466 void TeXFOTBuilder::endScriptPostSup()
2467 {
2468   endSimpleGroup();
2469 }
2470 
startScriptPostSub()2471 void TeXFOTBuilder::startScriptPostSub()
2472 {
2473   startSimpleGroup("ScriptPostSub");
2474 }
2475 
endScriptPostSub()2476 void TeXFOTBuilder::endScriptPostSub()
2477 {
2478   endSimpleGroup();
2479 }
2480 
startScriptMidSup()2481 void TeXFOTBuilder::startScriptMidSup()
2482 {
2483   startSimpleGroup("ScriptMidSup");
2484 }
2485 
endScriptMidSup()2486 void TeXFOTBuilder::endScriptMidSup()
2487 {
2488   endSimpleGroup();
2489 }
2490 
startScriptMidSub()2491 void TeXFOTBuilder::startScriptMidSub()
2492 {
2493   startSimpleGroup("ScriptMidSub");
2494 }
2495 
endScriptMidSub()2496 void TeXFOTBuilder::endScriptMidSub()
2497 {
2498   endSimpleGroup();
2499 }
2500 
startMarkSerial()2501 void TeXFOTBuilder::startMarkSerial()
2502 {
2503   startGroup("MarkSerial");
2504 }
2505 
endMarkSerial()2506 void TeXFOTBuilder::endMarkSerial()
2507 {
2508   endGroup("MarkSerial");
2509 }
2510 
startMarkOver()2511 void TeXFOTBuilder::startMarkOver()
2512 {
2513   startGroup("MarkOver");
2514 }
2515 
endMarkOver()2516 void TeXFOTBuilder::endMarkOver()
2517 {
2518   endGroup("MarkOver");
2519 }
2520 
startMarkUnder()2521 void TeXFOTBuilder::startMarkUnder()
2522 {
2523   startGroup("MarkUnder");
2524 }
2525 
endMarkUnder()2526 void TeXFOTBuilder::endMarkUnder()
2527 {
2528   endGroup("MarkUnder");
2529 }
2530 
startFenceSerial()2531 void TeXFOTBuilder::startFenceSerial()
2532 {
2533   startBrace("FenceSerial");
2534 }
2535 
endFenceSerial()2536 void TeXFOTBuilder::endFenceSerial()
2537 {
2538     //  endGroup("FenceSerial");
2539 }
2540 
startFenceOpen()2541 void TeXFOTBuilder::startFenceOpen()
2542 {
2543   // Extra closing brace for end of fence body
2544   closeopenBrace("FenceOpen");
2545 }
2546 
endFenceOpen()2547 void TeXFOTBuilder::endFenceOpen()
2548 {
2549   endSimpleGroup();
2550 }
2551 
startFenceClose()2552 void TeXFOTBuilder::startFenceClose()
2553 {
2554   startSimpleGroup("FenceClose");
2555 }
2556 
endFenceClose()2557 void TeXFOTBuilder::endFenceClose()
2558 {
2559   endSimpleGroup();
2560 }
2561 
startRadicalSerial()2562 void TeXFOTBuilder::startRadicalSerial()
2563 {
2564   startGroup("RadicalSerial");
2565 }
2566 
endRadicalSerial()2567 void TeXFOTBuilder::endRadicalSerial()
2568 {
2569   endGroup("RadicalSerial");
2570 }
2571 
startRadicalDegree()2572 void TeXFOTBuilder::startRadicalDegree()
2573 {
2574   startGroup("RadicalDegree");
2575 }
2576 
endRadicalDegree()2577 void TeXFOTBuilder::endRadicalDegree()
2578 {
2579   endGroup("RadicalDegree");
2580 }
2581 
startMathOperatorSerial()2582 void TeXFOTBuilder::startMathOperatorSerial()
2583 {
2584   startGroup("MathOperatorSerial");
2585 }
2586 
endMathOperatorSerial()2587 void TeXFOTBuilder::endMathOperatorSerial()
2588 {
2589   endGroup("MathOperatorSerial");
2590 }
2591 
startMathOperatorOperator()2592 void TeXFOTBuilder::startMathOperatorOperator()
2593 {
2594   startGroup("MathOperatorOperator");
2595 }
2596 
endMathOperatorOperator()2597 void TeXFOTBuilder::endMathOperatorOperator()
2598 {
2599   endGroup("MathOperatorOperator");
2600 }
2601 
startMathOperatorLowerLimit()2602 void TeXFOTBuilder::startMathOperatorLowerLimit()
2603 {
2604   startGroup("MathOperatorLowerLimit");
2605 }
2606 
endMathOperatorLowerLimit()2607 void TeXFOTBuilder::endMathOperatorLowerLimit()
2608 {
2609   endGroup("MathOperatorLowerLimit");
2610 }
2611 
startMathOperatorUpperLimit()2612 void TeXFOTBuilder::startMathOperatorUpperLimit()
2613 {
2614   startGroup("MathOperatorUpperLimit");
2615 }
2616 
endMathOperatorUpperLimit()2617 void TeXFOTBuilder::endMathOperatorUpperLimit()
2618 {
2619   endGroup("MathOperatorUpperLimit");
2620 }
2621 
startGrid(const GridNIC & nic)2622 void TeXFOTBuilder::startGrid(const GridNIC &nic)
2623 {
2624   setGridNIC(nic);
2625   startGroup("Grid");
2626 }
2627 
endGrid()2628 void TeXFOTBuilder::endGrid()
2629 {
2630   endGroup("Grid");
2631 }
2632 
startGridCell(const GridCellNIC & nic)2633 void TeXFOTBuilder::startGridCell(const GridCellNIC &nic)
2634 {
2635   setGridCellNIC(nic);
2636   startGroup("GridCell");
2637 }
2638 
endGridCell()2639 void TeXFOTBuilder::endGridCell()
2640 {
2641   endGroup("GridCell");
2642 }
2643 
startNode(const NodePtr & node,const StringC & processingMode)2644 void TeXFOTBuilder::startNode(const NodePtr &node,
2645 			      const StringC &processingMode)
2646 {
2647   GroveString id;
2648   unsigned long ei;
2649 
2650   if (node->getId(id) == accessOK) {
2651     set("Label",id);
2652   }
2653   else if (node->elementIndex(ei) == accessOK) {
2654     set("Element", ei);
2655   }
2656   unsigned long g = node->groveIndex();
2657   if (g) {
2658     set("GroveIndex", g);
2659   }
2660   if (processingMode.size()) {
2661     set("ProcessingMode", processingMode);
2662   }
2663 
2664   if( curFotElementState().enforcingStructure() ) {
2665     startGroup( "Node", &(curFotElementState().CurNodeInfoProlog) );
2666     #ifdef TEXDEBUG
2667       *fileout_ << "\nSTART_NODE " << ei << "\n";
2668     #endif
2669   } else
2670     startGroup("Node");
2671 }
2672 
endNode()2673 void TeXFOTBuilder::endNode()
2674 {
2675   if( curFotElementState().enforcingStructure() ) {
2676     curFotElementState().CurNodeInfoProlog.resize( 0 );
2677     FotElement *lastClosed = CompoundFotElement::lastClosed( curTable() );
2678     if( lastClosed != NULL )
2679       endGroup( "Node", &lastClosed->nodeInfoEpilog() );
2680     #ifdef TEXDEBUG
2681       *fileout_ << "\nEND_NODE\n";
2682     #endif
2683   } else
2684     endGroup("Node");
2685 }
2686 
startLink(const Address & addr)2687 void TeXFOTBuilder::startLink(const Address &addr)
2688 {
2689   GroveString id;
2690   unsigned long ei;
2691 
2692   // FIX ME!
2693   // This needs a lot of work -- for now, it supports only links to
2694   // elements.
2695 
2696   switch (addr.type) {
2697   case Address::none:
2698     break;
2699   case Address::resolvedNode:
2700     if (addr.node->getId(id) == accessOK) {
2701       set("Label",id);
2702     } else if (addr.node->elementIndex(ei) == accessOK) {
2703       set("Element", ei);
2704     }
2705     else {
2706       message(TeXMessages::unsupportedLinkNonElement);
2707     }
2708     break;
2709   case Address::idref:
2710 				// just the first IDREF for now
2711     set("Label",addr.params[0]);
2712     break;
2713   case Address::entity:
2714     message(TeXMessages::unsupportedLinkEntity);
2715     break;
2716   case Address::sgmlDocument:
2717     message(TeXMessages::unsupportedLinkSgmlDoc);
2718     break;
2719   case Address::hytimeLinkend:
2720     message(TeXMessages::unsupportedLinkHyTime);
2721     break;
2722   case Address::tei:
2723     message(TeXMessages::unsupportedLinkTei);
2724     break;
2725   case Address::html:
2726     message(TeXMessages::unsupportedLinkHtml);
2727     break;
2728   }
2729   if (addr.node) {
2730     unsigned long g = addr.node->groveIndex();
2731     if (g) {
2732       set("GroveIndex",g);
2733     }
2734   }
2735   startGroup("Link");
2736 }
2737 
endLink()2738 void TeXFOTBuilder::endLink()
2739 {
2740   endGroup("Link");
2741 }
2742 
2743 /////////////////////////////////////////////////////////////////////
2744 // Inherited characteristics
2745 // Set the value of the characteristic for the next flow object.
2746 // Inherited characteristics that are not explicitly set have
2747 // the same value as the parent flow object.
2748 //////////////////////////////////////////////////////////////////////
2749 
setFontSize(Length size)2750 void TeXFOTBuilder::setFontSize(Length size)
2751 {
2752   setlength("fSize",size);
2753 }
2754 
setFontFamilyName(const StringC & name)2755 void TeXFOTBuilder::setFontFamilyName(const StringC &name)
2756 {
2757   stringout_ << "\\def\\fFamName{";
2758   for (size_t i = 0; i < name.size(); i++)
2759     {
2760       switch(name[i]) {
2761       case ' ':
2762 	stringout_ << '-';
2763         break;
2764       default:
2765 	stringout_ << char(name[i]);
2766 	break;
2767        }
2768       }
2769       stringout_ << "}";
2770 }
2771 
setFontWeight(Symbol weight)2772 void TeXFOTBuilder::setFontWeight(Symbol weight)
2773 {
2774   set("fWeight",weight);
2775 }
2776 
setFontPosture(Symbol posture)2777 void TeXFOTBuilder::setFontPosture(Symbol posture)
2778 {
2779   set("fPosture",posture);
2780 }
2781 
setStartIndent(const LengthSpec & indent)2782 void TeXFOTBuilder::setStartIndent(const LengthSpec &indent)
2783 {
2784   NextFormat.FotStartIndentSpec = indent;
2785   set("StartIndent",indent);
2786 }
2787 
setEndIndent(const LengthSpec & indent)2788 void TeXFOTBuilder::setEndIndent(const LengthSpec &indent)
2789 {
2790   NextFormat.FotEndIndentSpec = indent;
2791   set("EndIndent",indent);
2792 }
2793 
setFirstLineStartIndent(const LengthSpec & indent)2794 void TeXFOTBuilder::setFirstLineStartIndent(const LengthSpec &indent)
2795 {
2796   set("FirstLineStartIndent",indent);
2797 }
2798 
setLastLineEndIndent(const LengthSpec & indent)2799 void TeXFOTBuilder::setLastLineEndIndent(const LengthSpec &indent)
2800 {
2801   set("LastLineEndIndent",indent);
2802 }
2803 
setLineSpacing(const LengthSpec & spacing)2804 void TeXFOTBuilder::setLineSpacing(const LengthSpec &spacing)
2805 {
2806   set("LineSpacing",spacing);
2807 }
2808 
setFieldWidth(const LengthSpec & width)2809 void TeXFOTBuilder::setFieldWidth(const LengthSpec &width)
2810 {
2811   set("FieldWidth",width);
2812 }
2813 
setMarginaliaSep(const LengthSpec & sep)2814 void TeXFOTBuilder::setMarginaliaSep(const LengthSpec &sep)
2815 {
2816   set("MarginaliaSep",sep);
2817 }
2818 
setLines(Symbol lines)2819 void TeXFOTBuilder::setLines(Symbol lines)
2820 {
2821   set("Lines",lines);
2822 }
2823 
setQuadding(Symbol quadding)2824 void TeXFOTBuilder::setQuadding(Symbol quadding)
2825 {
2826   set("Quadding",quadding);
2827 }
2828 
setDisplayAlignment(Symbol align)2829 void TeXFOTBuilder::setDisplayAlignment(Symbol align)
2830 {
2831   NextFormat.FotDisplayAlignment = align;
2832   set("DisplayAlignment",align);
2833 }
2834 
setFieldAlign(Symbol align)2835 void TeXFOTBuilder::setFieldAlign(Symbol align)
2836 {
2837   set("FieldAlign",align);
2838 }
2839 
setColor(const DeviceRGBColor & color)2840 void TeXFOTBuilder::setColor(const DeviceRGBColor &color)
2841 {
2842   set("Color",color);
2843 }
2844 
setBackgroundColor()2845 void TeXFOTBuilder::setBackgroundColor()
2846 {
2847   set("BackgroundColor",symbolFalse);
2848 }
2849 
setBackgroundColor(const DeviceRGBColor & color)2850 void TeXFOTBuilder::setBackgroundColor(const DeviceRGBColor &color)
2851 {
2852   set("BackgroundColor",color);
2853 }
2854 
setBorderPresent(bool flag)2855 void TeXFOTBuilder::setBorderPresent(bool flag)
2856 {
2857   NextFormat.FotBorderPresent = flag;
2858   set("BorderPresent",flag);
2859 }
2860 
setLineThickness(Length thickness)2861 void TeXFOTBuilder::setLineThickness(Length thickness)
2862 {
2863   NextFormat.FotLineThickness = thickness;
2864   setlength("LineThickness",thickness);
2865 }
2866 
setCellBeforeRowMargin(Length margin)2867 void TeXFOTBuilder::setCellBeforeRowMargin(Length margin)
2868 {
2869   setlength("CellBeforeRowMargin",margin);
2870 }
2871 
setCellAfterRowMargin(Length margin)2872 void TeXFOTBuilder::setCellAfterRowMargin(Length margin)
2873 {
2874   setlength("CellAfterRowMargin",margin);
2875 }
2876 
setCellBeforeColumnMargin(Length margin)2877 void TeXFOTBuilder::setCellBeforeColumnMargin(Length margin)
2878 {
2879   NextFormat.FotCellBeforeColumnMargin = margin;
2880   setlength("CellBeforeColumnMargin",margin);
2881 }
2882 
setCellAfterColumnMargin(Length margin)2883 void TeXFOTBuilder::setCellAfterColumnMargin(Length margin)
2884 {
2885   NextFormat.FotCellAfterColumnMargin = margin;
2886   setlength("CellAfterColumnMargin",margin);
2887 }
2888 
setLineSep(Length sep)2889 void TeXFOTBuilder::setLineSep(Length sep)
2890 {
2891   NextFormat.FotLineSep = sep;
2892   setlength("LineSep",sep);
2893 }
2894 
setBoxSizeBefore(Length size)2895 void TeXFOTBuilder::setBoxSizeBefore(Length size)
2896 {
2897   setlength("BoxSizeBefore",size);
2898 }
2899 
setBoxSizeAfter(Length size)2900 void TeXFOTBuilder::setBoxSizeAfter(Length size)
2901 {
2902   setlength("BoxSizeAfter",size);
2903 }
2904 
setPositionPointShift(const LengthSpec & shift)2905 void TeXFOTBuilder::setPositionPointShift(const LengthSpec &shift)
2906 {
2907   set("PositionPointShift",shift);
2908 }
2909 
setStartMargin(const LengthSpec & margin)2910 void TeXFOTBuilder::setStartMargin(const LengthSpec &margin)
2911 {
2912   set("StartMargin",margin);
2913 }
2914 
setEndMargin(const LengthSpec & margin)2915 void TeXFOTBuilder::setEndMargin(const LengthSpec &margin)
2916 {
2917   set("EndMargin",margin);
2918 }
2919 
setSidelineSep(const LengthSpec & sep)2920 void TeXFOTBuilder::setSidelineSep(const LengthSpec &sep)
2921 {
2922   set("SidelineSep",sep);
2923 }
2924 
setAsisWrapIndent(const LengthSpec & indent)2925 void TeXFOTBuilder::setAsisWrapIndent(const LengthSpec &indent)
2926 {
2927   set("AsisWrapIndent",indent);
2928 }
2929 
setLineNumberSep(const LengthSpec & sep)2930 void TeXFOTBuilder::setLineNumberSep(const LengthSpec &sep)
2931 {
2932   set("LineNumberSep",sep);
2933 }
2934 
setLastLineJustifyLimit(const LengthSpec & limit)2935 void TeXFOTBuilder::setLastLineJustifyLimit(const LengthSpec &limit)
2936 {
2937   set("LastLineJustifyLimit",limit);
2938 }
2939 
setJustifyGlyphSpaceMaxAdd(const LengthSpec & max)2940 void TeXFOTBuilder::setJustifyGlyphSpaceMaxAdd(const LengthSpec &max)
2941 {
2942   set("JustifyGlyphSpaceMaxAdd",max);
2943 }
2944 
setJustifyGlyphSpaceMaxRemove(const LengthSpec & max)2945 void TeXFOTBuilder::setJustifyGlyphSpaceMaxRemove(const LengthSpec &max)
2946 {
2947   set("JustifyGlyphSpaceMaxRemove",max);
2948 }
2949 
setTableCornerRadius(const LengthSpec & radius)2950 void TeXFOTBuilder::setTableCornerRadius(const LengthSpec &radius)
2951 {
2952   set("TableCornerRadius",radius);
2953 }
2954 
setBoxCornerRadius(const LengthSpec & radius)2955 void TeXFOTBuilder::setBoxCornerRadius(const LengthSpec &radius)
2956 {
2957   set("BoxCornerRadius",radius);
2958 }
2959 
setInhibitLineBreaks(bool flag)2960 void TeXFOTBuilder::setInhibitLineBreaks(bool flag)
2961 {
2962   set("InhibitLineBreaks",flag);
2963 }
2964 
setHyphenate(bool flag)2965 void TeXFOTBuilder::setHyphenate(bool flag)
2966 {
2967   set("Hyphenate",flag);
2968 }
2969 
setKern(bool flag)2970 void TeXFOTBuilder::setKern(bool flag)
2971 {
2972   set("Kern",flag);
2973 }
2974 
setLigature(bool flag)2975 void TeXFOTBuilder::setLigature(bool flag)
2976 {
2977   set("Ligature",flag);
2978 }
2979 
setScoreSpaces(bool flag)2980 void TeXFOTBuilder::setScoreSpaces(bool flag)
2981 {
2982   set("ScoreSpaces",flag);
2983 }
2984 
setFloatOutMarginalia(bool flag)2985 void TeXFOTBuilder::setFloatOutMarginalia(bool flag)
2986 {
2987   set("FloatOutMarginalia",flag);
2988 }
2989 
setFloatOutSidelines(bool flag)2990 void TeXFOTBuilder::setFloatOutSidelines(bool flag)
2991 {
2992   set("FloatOutSidelines",flag);
2993 }
2994 
setFloatOutLineNumbers(bool flag)2995 void TeXFOTBuilder::setFloatOutLineNumbers(bool flag)
2996 {
2997   set("FloatOutLineNumbers",flag);
2998 }
2999 
setCellBackground(bool flag)3000 void TeXFOTBuilder::setCellBackground(bool flag)
3001 {
3002   set("CellBackground",flag);
3003 }
3004 
setSpanWeak(bool flag)3005 void TeXFOTBuilder::setSpanWeak(bool flag)
3006 {
3007   set("SpanWeak",flag);
3008 }
3009 
setIgnoreRecordEnd(bool flag)3010 void TeXFOTBuilder::setIgnoreRecordEnd(bool flag)
3011 {
3012   set("IgnoreRecordEnd",flag);
3013 }
3014 
setNumberedLines(bool flag)3015 void TeXFOTBuilder::setNumberedLines(bool flag)
3016 {
3017   set("NumberedLines",flag);
3018 }
3019 
setHangingPunct(bool flag)3020 void TeXFOTBuilder::setHangingPunct(bool flag)
3021 {
3022   set("HangingPunct",flag);
3023 }
3024 
setBoxOpenEnd(bool flag)3025 void TeXFOTBuilder::setBoxOpenEnd(bool flag)
3026 {
3027   set("BoxOpenEnd",flag);
3028 }
3029 
setTruncateLeader(bool flag)3030 void TeXFOTBuilder::setTruncateLeader(bool flag)
3031 {
3032   set("TruncateLeader",flag);
3033 }
3034 
setAlignLeader(bool flag)3035 void TeXFOTBuilder::setAlignLeader(bool flag)
3036 {
3037   set("AlignLeader",flag);
3038 }
3039 
setTablePartOmitMiddleHeader(bool flag)3040 void TeXFOTBuilder::setTablePartOmitMiddleHeader(bool flag)
3041 {
3042   set("TablePartOmitMiddleHeader",flag);
3043 }
3044 
setTablePartOmitMiddleFooter(bool flag)3045 void TeXFOTBuilder::setTablePartOmitMiddleFooter(bool flag)
3046 {
3047   set("TablePartOmitMiddleFooter",flag);
3048 }
3049 
setBorderOmitAtBreak(bool flag)3050 void TeXFOTBuilder::setBorderOmitAtBreak(bool flag)
3051 {
3052   set("BorderOmitAtBreak",flag);
3053 }
3054 
setPrincipalModeSimultaneous(bool flag)3055 void TeXFOTBuilder::setPrincipalModeSimultaneous(bool flag)
3056 {
3057   set("PrincipalModeSimultaneous",flag);
3058 }
3059 
setMarginaliaKeepWithPrevious(bool flag)3060 void TeXFOTBuilder::setMarginaliaKeepWithPrevious(bool flag)
3061 {
3062   set("MarginaliaKeepWithPrevious",flag);
3063 }
3064 
setLineJoin(Symbol join)3065 void TeXFOTBuilder::setLineJoin(Symbol join)
3066 {
3067   set("LineJoin",join);
3068 }
3069 
setLineCap(Symbol cap)3070 void TeXFOTBuilder::setLineCap(Symbol cap)
3071 {
3072   NextFormat.FotLineCap = cap;
3073   set("LineCap",cap);
3074 }
3075 
setLineNumberSide(Symbol side)3076 void TeXFOTBuilder::setLineNumberSide(Symbol side)
3077 {
3078   set("LineNumberSide",side);
3079 }
3080 
setKernMode(Symbol mode)3081 void TeXFOTBuilder::setKernMode(Symbol mode)
3082 {
3083   set("KernMode",mode);
3084 }
3085 
setInputWhitespaceTreatment(Symbol treatment)3086 void TeXFOTBuilder::setInputWhitespaceTreatment(Symbol treatment)
3087 {
3088   set("InputWhitespaceTreatment",treatment);
3089 }
3090 
setFillingDirection(Symbol direction)3091 void TeXFOTBuilder::setFillingDirection(Symbol direction)
3092 {
3093   set("FillingDirection",direction);
3094 }
3095 
setWritingMode(Symbol mode)3096 void TeXFOTBuilder::setWritingMode(Symbol mode)
3097 {
3098   set("WritingMode",mode);
3099 }
3100 
setLastLineQuadding(Symbol quadding)3101 void TeXFOTBuilder::setLastLineQuadding(Symbol quadding)
3102 {
3103   set("LastLineQuadding",quadding);
3104 }
3105 
setMathDisplayMode(Symbol mode)3106 void TeXFOTBuilder::setMathDisplayMode(Symbol mode)
3107 {
3108   set("MathDisplayMode",mode);
3109 }
3110 
setBoxType(Symbol type)3111 void TeXFOTBuilder::setBoxType(Symbol type)
3112 {
3113   set("BoxType",type);
3114 }
3115 
setGlyphAlignmentMode(Symbol mode)3116 void TeXFOTBuilder::setGlyphAlignmentMode(Symbol mode)
3117 {
3118   set("GlyphAlignmentMode",mode);
3119 }
3120 
setBoxBorderAlignment(Symbol align)3121 void TeXFOTBuilder::setBoxBorderAlignment(Symbol align)
3122 {
3123   set("BoxBorderAlignment",align);
3124 }
3125 
setCellRowAlignment(Symbol align)3126 void TeXFOTBuilder::setCellRowAlignment(Symbol align)
3127 {
3128   set("CellRowAlignment",align);
3129 }
3130 
setBorderAlignment(Symbol align)3131 void TeXFOTBuilder::setBorderAlignment(Symbol align)
3132 {
3133   set("BorderAlignment",align);
3134 }
3135 
setSidelineSide(Symbol side)3136 void TeXFOTBuilder::setSidelineSide(Symbol side)
3137 {
3138   set("SidelineSide",side);
3139 }
3140 
setHyphenationKeep(Symbol keep)3141 void TeXFOTBuilder::setHyphenationKeep(Symbol keep)
3142 {
3143   set("HyphenationKeep",keep);
3144 }
3145 
setFontStructure(Symbol structure)3146 void TeXFOTBuilder::setFontStructure(Symbol structure)
3147 {
3148   set("fStructure",structure);
3149 }
3150 
setFontProportionateWidth(Symbol width)3151 void TeXFOTBuilder::setFontProportionateWidth(Symbol width)
3152 {
3153   set("fProportionateWidth",width);
3154 }
3155 
setCellCrossed(Symbol crossed)3156 void TeXFOTBuilder::setCellCrossed(Symbol crossed)
3157 {
3158   set("CellCrossed",crossed);
3159 }
3160 
setMarginaliaSide(Symbol side)3161 void TeXFOTBuilder::setMarginaliaSide(Symbol side)
3162 {
3163   set("MarginaliaSide",side);
3164 }
3165 
setLayer(long n)3166 void TeXFOTBuilder::setLayer(long n)
3167 {
3168   set("Layer",n);
3169 }
3170 
setBackgroundLayer(long n)3171 void TeXFOTBuilder::setBackgroundLayer(long n)
3172 {
3173   set("BackgroundLayer",n);
3174 }
3175 
setBorderPriority(long n)3176 void TeXFOTBuilder::setBorderPriority(long n)
3177 {
3178   NextFormat.FotBorderPriority = n;
3179   set("BorderPriority",n);
3180 }
3181 
setLineRepeat(long n)3182 void TeXFOTBuilder::setLineRepeat(long n)
3183 {
3184   NextFormat.FotLineRepeat = n;
3185   set("LineRepeat",n);
3186 }
3187 
setSpan(long n)3188 void TeXFOTBuilder::setSpan(long n)
3189 {
3190   NextFormat.FotSpan = n;
3191   set("Span",n);
3192 }
3193 
setMinLeaderRepeat(long n)3194 void TeXFOTBuilder::setMinLeaderRepeat(long n)
3195 {
3196   set("MinLeaderRepeat",n);
3197 }
3198 
setHyphenationRemainCharCount(long n)3199 void TeXFOTBuilder::setHyphenationRemainCharCount(long n)
3200 {
3201   set("HyphenationRemainCharCount",n);
3202 }
3203 
setHyphenationPushCharCount(long n)3204 void TeXFOTBuilder::setHyphenationPushCharCount(long n)
3205 {
3206   set("HyphenationPushCharCount",n);
3207 }
3208 
setWidowCount(long n)3209 void TeXFOTBuilder::setWidowCount(long n)
3210 {
3211   set("WidowCount",n);
3212 }
3213 
setOrphanCount(long n)3214 void TeXFOTBuilder::setOrphanCount(long n)
3215 {
3216   set("OrphanCount",n);
3217 }
3218 
3219 // 0 means #f
setExpandTabs(long n)3220 void TeXFOTBuilder::setExpandTabs(long n)
3221 {
3222   set("ExpandTabs",n);
3223 }
3224 
setHyphenationLadderCount(long n)3225 void TeXFOTBuilder::setHyphenationLadderCount(long n)
3226 {
3227   set("HyphenationLadderCount",n);
3228 }
3229 
3230 // public id or #f
setBackgroundTile(PublicId id)3231 void TeXFOTBuilder::setBackgroundTile(PublicId id)
3232 {
3233   set("BackgroundTile",id);
3234 }
3235 
setLineBreakingMethod(PublicId id)3236 void TeXFOTBuilder::setLineBreakingMethod(PublicId id)
3237 {
3238   set("LineBreakingMethod",id);
3239 }
3240 
setLineCompositionMethod(PublicId id)3241 void TeXFOTBuilder::setLineCompositionMethod(PublicId id)
3242 {
3243   set("LineCompositionMethod",id);
3244 }
3245 
setImplicitBidiMethod(PublicId id)3246 void TeXFOTBuilder::setImplicitBidiMethod(PublicId id)
3247 {
3248   set("ImplicitBidiMethod",id);
3249 }
3250 
setGlyphSubstMethod(PublicId id)3251 void TeXFOTBuilder::setGlyphSubstMethod(PublicId id)
3252 {
3253   set("GlyphSubstMethod",id);
3254 }
3255 
setGlyphReorderMethod(PublicId id)3256 void TeXFOTBuilder::setGlyphReorderMethod(PublicId id)
3257 {
3258   set("GlyphReorderMethod",id);
3259 }
3260 
setHyphenationMethod(PublicId id)3261 void TeXFOTBuilder::setHyphenationMethod(PublicId id)
3262 {
3263   set("HyphenationMethod",id);
3264 }
3265 
setTableAutoWidthMethod(PublicId id)3266 void TeXFOTBuilder::setTableAutoWidthMethod(PublicId id)
3267 {
3268   set("TableAutoWidthMethod",id);
3269 }
3270 
setFontName(PublicId id)3271 void TeXFOTBuilder::setFontName(PublicId id)
3272 {
3273   set("fName",id);
3274 }
3275 
3276 // Two-letter code
setLanguage(Letter2 language)3277 void TeXFOTBuilder::setLanguage(Letter2 language)
3278 {
3279   setletter2("Language",language);
3280 }
3281 
setCountry(Letter2 country)3282 void TeXFOTBuilder::setCountry(Letter2 country)
3283 {
3284   setletter2("Country",country);
3285 }
3286 
3287 // For simple page sequence
setPageWidth(Length width)3288 void TeXFOTBuilder::setPageWidth(Length width)
3289 {
3290   NextFormat.FotPageWidth = width;
3291   setlength("PageWidth",width);
3292 }
3293 
setPageHeight(Length height)3294 void TeXFOTBuilder::setPageHeight(Length height)
3295 {
3296   setlength("PageHeight",height);
3297 }
3298 
setLeftMargin(Length margin)3299 void TeXFOTBuilder::setLeftMargin(Length margin)
3300 {
3301   NextFormat.FotLeftMargin = margin;
3302   setlength("LeftMargin",margin);
3303 }
3304 
setRightMargin(Length margin)3305 void TeXFOTBuilder::setRightMargin(Length margin)
3306 {
3307   NextFormat.FotRightMargin = margin;
3308   setlength("RightMargin",margin);
3309 }
3310 
setTopMargin(Length margin)3311 void TeXFOTBuilder::setTopMargin(Length margin)
3312 {
3313   setlength("TopMargin",margin);
3314 }
3315 
setBottomMargin(Length margin)3316 void TeXFOTBuilder::setBottomMargin(Length margin)
3317 {
3318   setlength("BottomMargin",margin);
3319 }
3320 
setHeaderMargin(Length margin)3321 void TeXFOTBuilder::setHeaderMargin(Length margin)
3322 {
3323   setlength("HeaderMargin",margin);
3324 }
3325 
setFooterMargin(Length margin)3326 void TeXFOTBuilder::setFooterMargin(Length margin)
3327 {
3328   setlength("FooterMargin",margin);
3329 }
3330 
3331 				// New inherited characteristics
3332 				// added 1 March/97 with math support.
setMinPreLineSpacing(const OptLengthSpec & len)3333 void TeXFOTBuilder::setMinPreLineSpacing(const OptLengthSpec &len)
3334 {
3335   set("MinPreLineSpacing",len);
3336 }
3337 
3338 
setMinPostLineSpacing(const OptLengthSpec & len)3339 void TeXFOTBuilder::setMinPostLineSpacing(const OptLengthSpec &len)
3340 {
3341   set("MinPostLineSpacing",len);
3342 }
3343 
3344 
setMinLeading(const OptLengthSpec & len)3345 void TeXFOTBuilder::setMinLeading(const OptLengthSpec &len)
3346 {
3347   set("MinLeading",len);
3348 }
3349 
3350 
setScriptPreAlign(Symbol sym)3351 void TeXFOTBuilder::setScriptPreAlign(Symbol sym)
3352 {
3353   set("ScriptPreAlign",sym);
3354 }
3355 
3356 
setScriptPostAlign(Symbol sym)3357 void TeXFOTBuilder::setScriptPostAlign(Symbol sym)
3358 {
3359   set("ScriptPostAlign",sym);
3360 }
3361 
3362 
setScriptMidSupAlign(Symbol sym)3363 void TeXFOTBuilder::setScriptMidSupAlign(Symbol sym)
3364 {
3365   set("ScriptMidSupAlign",sym);
3366 }
3367 
3368 
setScriptMidSubAlign(Symbol sym)3369 void TeXFOTBuilder::setScriptMidSubAlign(Symbol sym)
3370 {
3371   set("ScriptMidSubAlign",sym);
3372 }
3373 
3374 
setNumeratorAlign(Symbol sym)3375 void TeXFOTBuilder::setNumeratorAlign(Symbol sym)
3376 {
3377   set("NumeratorAlign",sym);
3378 }
3379 
3380 
setDenominatorAlign(Symbol sym)3381 void TeXFOTBuilder::setDenominatorAlign(Symbol sym)
3382 {
3383   set("DenominatorAlign",sym);
3384 }
3385 
3386 
setGridPositionCellType(Symbol sym)3387 void TeXFOTBuilder::setGridPositionCellType(Symbol sym)
3388 {
3389   set("GridPositionCellType",sym);
3390 }
3391 
3392 
setGridColumnAlignment(Symbol sym)3393 void TeXFOTBuilder::setGridColumnAlignment(Symbol sym)
3394 {
3395   set("GridColumnAlignment",sym);
3396 }
3397 
3398 
setGridRowAlignment(Symbol sym)3399 void TeXFOTBuilder::setGridRowAlignment(Symbol sym)
3400 {
3401   set("GridRowAlignment",sym);
3402 }
3403 
3404 
setGridEquidistantRows(bool flag)3405 void TeXFOTBuilder::setGridEquidistantRows(bool flag)
3406 {
3407   set("GridEquidistantRows",flag);
3408 }
3409 
3410 
setGridEquidistantColumns(bool flag)3411 void TeXFOTBuilder::setGridEquidistantColumns(bool flag)
3412 {
3413   set("GridEquidistantColumns",flag);
3414 }
3415 
3416 
setEscapementSpaceBefore(const InlineSpace & space)3417 void TeXFOTBuilder::setEscapementSpaceBefore(const InlineSpace &space)
3418 {
3419   set("EscapementSpaceBefore",space);
3420 }
3421 
3422 
setEscapementSpaceAfter(const InlineSpace & space)3423 void TeXFOTBuilder::setEscapementSpaceAfter(const InlineSpace &space)
3424 {
3425   set("EscapementSpaceAfter",space);
3426 }
3427 
3428 
setGlyphSubstTable(const Vector<ConstPtr<GlyphSubstTable>> &)3429 void TeXFOTBuilder::setGlyphSubstTable(const Vector<ConstPtr<GlyphSubstTable> > &)
3430 {
3431   // FIX ME!
3432   message(TeXMessages::unsupportedGlyphSubstTable);
3433   // set("GlyphSubstTable",tables);
3434 }
3435 
3436 ////////////////////////////////////////////////////////////////////////
3437 // Private member functions.
3438 ////////////////////////////////////////////////////////////////////////
3439 
3440 //
3441 // Insert an atomic flow object.
3442 //
insertAtomic(const char * name)3443 void TeXFOTBuilder::insertAtomic(const char *name)
3444 {
3445   os() << "\\insert" << name << "%\n{";
3446   dumpInherited();
3447   os() << '}';
3448 }
3449 
insertAtomic(TeXFOTBuilder::FotElement & fotElement)3450 void TeXFOTBuilder::insertAtomic( TeXFOTBuilder::FotElement &fotElement )
3451 {
3452   stringout_.extractString( fotElement.Characteristics );
3453 }
3454 
3455 //
3456 // Start a non-atomic flow object.
3457 //
startGroup(const char * name,String<char> * output)3458 void TeXFOTBuilder::startGroup(const char *name, String<char> *output )
3459 {
3460   if( output ) {
3461     String<char> s;
3462     stringout_.extractString( s );
3463     StrOutputByteStream out;
3464     out << "\\" << name << "%\n{" << s << '}';
3465     out.extractString( s );
3466     *output += s;
3467   } else {
3468     os() << "\\" << name << "%\n{";
3469     dumpInherited();
3470     os() << '}';
3471   }
3472 }
3473 
startGroup(TeXFOTBuilder::FotElement & fotElement)3474 void TeXFOTBuilder::startGroup( TeXFOTBuilder::FotElement &fotElement ) {
3475 
3476   stringout_.extractString( fotElement.Characteristics );
3477 }
3478 
3479 //
3480 // Start a non-atomic flow object, with the content delimited by braces,
3481 // but no macro name at all; we just emit all the characteristics in
3482 // the stream after the brace.
3483 //
startSimpleGroup(const char * name,String<char> * output)3484 void TeXFOTBuilder::startSimpleGroup(const char *name, String<char> *output )
3485 {
3486   if( output ) {
3487     String<char> s;
3488     stringout_.extractString( s );
3489     StrOutputByteStream out;
3490     out << "%\n{" << s ;
3491     out.extractString( s );
3492     *output += s;
3493   } else {
3494     os() << "%\n{";
3495     dumpInherited();
3496   }
3497 }
3498 
3499 //
3500 // End with just a closing brace
3501 //
endSimpleGroup(String<char> * output)3502 void TeXFOTBuilder::endSimpleGroup(String<char> *output )
3503 {
3504   if( output ) {
3505     StrOutputByteStream out;
3506     out << "}";
3507     String<char> s;
3508     out.extractString( s );
3509     *output += s;
3510   }
3511   else
3512     os() << "}";
3513 }
3514 //
3515 // Stop and start a brace, but note characteristics
3516 //
closeopenBrace(const char * name,String<char> * output)3517 void TeXFOTBuilder::closeopenBrace(const char *name, String<char> *output )
3518 {
3519   if( output ) {
3520     String<char> s;
3521     stringout_.extractString( s );
3522     StrOutputByteStream out;
3523     out << "}{" << s ;
3524     out.extractString( s );
3525     *output += s;
3526   } else {
3527     os() << "}{";
3528     dumpInherited();
3529   }
3530 }
3531 //
3532 // Start a non-atomic flow object, with the content delimited by braces
3533 //
startBrace(const char * name,String<char> * output)3534 void TeXFOTBuilder::startBrace(const char *name, String<char> *output )
3535 {
3536   if( output ) {
3537     String<char> s;
3538     stringout_.extractString( s );
3539     StrOutputByteStream out;
3540     out << "\\" << name << "%\n{" << s << "}{";
3541     out.extractString( s );
3542     *output += s;
3543   } else {
3544     os() << "\\" << name << "%\n{";
3545     dumpInherited();
3546     os() << "}{";
3547   }
3548 }
3549 
3550 //
3551 // End a non-atomic flow object with just a closing brace
3552 //
endBrace(const char * name,String<char> * output)3553 void TeXFOTBuilder::endBrace(const char *name, String<char> *output )
3554 {
3555   if( output ) {
3556     StrOutputByteStream out;
3557     out << "}";
3558     String<char> s;
3559     out.extractString( s );
3560     *output += s;
3561   }
3562   else
3563     os() << "}";
3564 }
3565 
3566 //
3567 // End a non-atomic flow object.
3568 //
endGroup(const char * name,String<char> * output)3569 void TeXFOTBuilder::endGroup(const char *name, String<char> *output )
3570 {
3571   if( output ) {
3572     StrOutputByteStream out;
3573     out << "\\end" << name << "{}";
3574     String<char> s;
3575     out.extractString( s );
3576     *output += s;
3577   }
3578   else
3579     os() << "\\end" << name << "{}";
3580 }
3581 
3582 //
3583 // Set a Length (needs a different name to avoid conflict
3584 // with long.
3585 //
setlength(const char * name,Length size)3586 void TeXFOTBuilder::setlength(const char *name,Length size)
3587 {
3588   stringout_ << "\\def\\" << name << "%\n{"
3589 	      << float(size/1000.0)
3590 	      << "\\p@}";
3591 }
3592 
3593 //
3594 // Set a StringC.
3595 //
set(const char * name,const StringC & value)3596 void TeXFOTBuilder::set(const char *name,const StringC &value)
3597 {
3598   stringout_ << "\\def\\" << name << "%\n{"
3599 	      << value
3600 	      << '}';
3601 }
3602 
3603 //
3604 // Set a GroveString
3605 //
set(const char * name,const GroveString & value)3606 void TeXFOTBuilder::set(const char *name,const GroveString &value)
3607 {
3608   stringout_ << "\\def\\" << name << "%\n{"
3609 	      << value
3610 	      << '}';
3611 }
3612 
3613 //
3614 // Set a Symbol.
3615 //
set(const char * name,Symbol sym)3616 void TeXFOTBuilder::set(const char *name,Symbol sym)
3617 {
3618   const char * symbolName = "";
3619 
3620   switch (sym) {
3621   case symbolFalse:
3622     symbolName = "false";
3623     break;
3624   case symbolTrue:
3625     symbolName = "true";
3626     break;
3627   case symbolNotApplicable:
3628     symbolName = "notapplicable";
3629     break;
3630   case symbolUltraCondensed:
3631     symbolName = "ultracondensed";
3632     break;
3633   case symbolExtraCondensed:
3634     symbolName = "extracondensed";
3635     break;
3636   case symbolCondensed:
3637     symbolName = "condensed";
3638     break;
3639   case symbolSemiCondensed:
3640     symbolName = "semicondensed";
3641     break;
3642   case symbolUltraLight:
3643     symbolName = "ultralight";
3644     break;
3645   case symbolExtraLight:
3646     symbolName = "extralight";
3647     break;
3648   case symbolLight:
3649     symbolName = "light";
3650     break;
3651   case symbolSemiLight:
3652     symbolName = "semilight";
3653     break;
3654   case symbolMedium:
3655     symbolName = "medium";
3656     break;
3657   case symbolSemiExpanded:
3658     symbolName = "semiexpanded";
3659     break;
3660   case symbolExpanded:
3661     symbolName = "expanded";
3662     break;
3663   case symbolExtraExpanded:
3664     symbolName = "extraexpanded";
3665     break;
3666   case symbolUltraExpanded:
3667     symbolName = "ultraexpanded";
3668     break;
3669   case symbolSemiBold:
3670     symbolName = "semibold";
3671     break;
3672   case symbolBold:
3673     symbolName = "bold";
3674     break;
3675   case symbolExtraBold:
3676     symbolName = "extrabold";
3677     break;
3678   case symbolUltraBold:
3679     symbolName = "ultrabold";
3680     break;
3681   case symbolUpright:
3682     symbolName = "upright";
3683     break;
3684   case symbolOblique:
3685     symbolName = "oblique";
3686     break;
3687   case symbolBackSlantedOblique:
3688     symbolName = "backslantedoblique";
3689     break;
3690   case symbolItalic:
3691     symbolName = "italic";
3692     break;
3693   case symbolBackSlantedItalic:
3694     symbolName = "backslanteditalic";
3695     break;
3696   case symbolStart:
3697     symbolName = "start";
3698     break;
3699   case symbolEnd:
3700     symbolName = "end";
3701     break;
3702   case symbolCenter:
3703     symbolName = "center";
3704     break;
3705   case symbolJustify:
3706     symbolName = "justify";
3707     break;
3708   case symbolSpreadInside:
3709     symbolName = "spreadinside";
3710     break;
3711   case symbolSpreadOutside:
3712     symbolName = "spreadoutside";
3713     break;
3714   case symbolPageInside:
3715     symbolName = "pageinside";
3716     break;
3717   case symbolPageOutside:
3718     symbolName = "pageoutside";
3719     break;
3720   case symbolWrap:
3721     symbolName = "wrap";
3722     break;
3723   case symbolAsis:
3724     symbolName = "asis";
3725     break;
3726   case symbolAsisWrap:
3727     symbolName = "asiswrap";
3728     break;
3729   case symbolAsisTruncate:
3730     symbolName = "asistruncate";
3731     break;
3732   case symbolNone:
3733     symbolName = "none";
3734     break;
3735   case symbolBefore:
3736     symbolName = "before";
3737     break;
3738   case symbolThrough:
3739     symbolName = "through";
3740     break;
3741   case symbolAfter:
3742     symbolName = "after";
3743     break;
3744   case symbolTopToBottom:
3745     symbolName = "toptobottom";
3746     break;
3747   case symbolLeftToRight:
3748     symbolName = "lefttoright";
3749     break;
3750   case symbolBottomToTop:
3751     symbolName = "bottomtotop";
3752     break;
3753   case symbolRightToLeft:
3754     symbolName = "righttoleft";
3755     break;
3756   case symbolInside:
3757     symbolName = "inside";
3758     break;
3759   case symbolOutside:
3760     symbolName = "outside";
3761     break;
3762   case symbolHorizontal:
3763     symbolName = "horizontal";
3764     break;
3765   case symbolVertical:
3766     symbolName = "vertical";
3767     break;
3768   case symbolEscapement:
3769     symbolName = "escapement";
3770     break;
3771   case symbolLineProgression:
3772     symbolName = "lineprogression";
3773     break;
3774   case symbolMath:
3775     symbolName = "math";
3776     break;
3777   case symbolOrdinary:
3778     symbolName = "ordinary";
3779     break;
3780   case symbolOperator:
3781     symbolName = "operator";
3782     break;
3783   case symbolBinary:
3784     symbolName = "binary";
3785     break;
3786   case symbolRelation:
3787     symbolName = "relation";
3788     break;
3789   case symbolOpening:
3790     symbolName = "opening";
3791     break;
3792   case symbolClosing:
3793     symbolName = "closing";
3794     break;
3795   case symbolPunctuation:
3796     symbolName = "punctuation";
3797     break;
3798   case symbolInner:
3799     symbolName = "inner";
3800     break;
3801   case symbolSpace:
3802     symbolName = "space";
3803     break;
3804   case symbolPage:
3805     symbolName = "page";
3806     break;
3807   case symbolPageRegion:
3808     symbolName = "pageregion";
3809     break;
3810   case symbolColumnSet:
3811     symbolName = "columnset";
3812     break;
3813   case symbolColumn:
3814     symbolName = "column";
3815     break;
3816   case symbolMax:
3817     symbolName = "max";
3818     break;
3819   case symbolMaxUniform:
3820     symbolName = "maxuniform";
3821     break;
3822   case symbolMiter:
3823     symbolName = "miter";
3824     break;
3825   case symbolRound:
3826     symbolName = "round";
3827     break;
3828   case symbolBevel:
3829     symbolName = "bevel";
3830     break;
3831   case symbolButt:
3832     symbolName = "butt";
3833     break;
3834   case symbolSquare:
3835     symbolName = "square";
3836     break;
3837   case symbolLoose:
3838     symbolName = "loose";
3839     break;
3840   case symbolNormal:
3841     symbolName = "normal";
3842     break;
3843   case symbolKern:
3844     symbolName = "kern";
3845     break;
3846   case symbolTight:
3847     symbolName = "tight";
3848     break;
3849   case symbolTouch:
3850     symbolName = "touch";
3851     break;
3852   case symbolPreserve:
3853     symbolName = "preserve";
3854     break;
3855   case symbolCollapse:
3856     symbolName = "collapse";
3857     break;
3858   case symbolIgnore:
3859     symbolName = "ignore";
3860     break;
3861   case symbolRelative:
3862     symbolName = "relative";
3863     break;
3864   case symbolDisplay:
3865     symbolName = "display";
3866     break;
3867   case symbolInline:
3868     symbolName = "inline";
3869     break;
3870   case symbolBorder:
3871     symbolName = "border";
3872     break;
3873   case symbolBackground:
3874     symbolName = "background";
3875     break;
3876   case symbolBoth:
3877     symbolName = "both";
3878     break;
3879   case symbolBase:
3880     symbolName = "base";
3881     break;
3882   case symbolFont:
3883     symbolName = "font";
3884     break;
3885   case symbolTop:
3886     symbolName = "top";
3887     break;
3888   case symbolBottom:
3889     symbolName = "bottom";
3890     break;
3891   case symbolSpread:
3892     symbolName = "spread";
3893     break;
3894   case symbolSolid:
3895     symbolName = "solid";
3896     break;
3897   case symbolOutline:
3898     symbolName = "outline";
3899     break;
3900   case symbolWith:
3901     symbolName = "with";
3902     break;
3903   case symbolAgainst:
3904     symbolName = "against";
3905     break;
3906   case symbolForce:
3907     symbolName = "force";
3908     break;
3909   case symbolIndependent:
3910     symbolName = "independent";
3911     break;
3912   case symbolPile:
3913     symbolName = "pile";
3914     break;
3915   case symbolSupOut:
3916     symbolName = "supout";
3917     break;
3918   case symbolSubOut:
3919     symbolName = "subout";
3920     break;
3921   case symbolLeadEdge:
3922     symbolName = "leadedge";
3923     break;
3924   case symbolTrailEdge:
3925     symbolName = "trailedge";
3926     break;
3927   case symbolExplicit:
3928     symbolName = "explicit";
3929     break;
3930   case symbolRowMajor:
3931     symbolName = "rowmajor";
3932     break;
3933   case symbolColumnMajor:
3934     symbolName = "columnmajor";
3935     break;
3936   }
3937 
3938   stringout_ << "\\def\\" << name << "%\n{" << symbolName << '}';
3939 }
3940 
3941 //
3942 // Set a LengthSpec.
3943 //
set(const char * name,const LengthSpec & spec)3944 void TeXFOTBuilder::set(const char *name,const LengthSpec &spec)
3945 {
3946   stringout_ << "\\def\\" << name << "%\n{"
3947 	      << float(spec.length/1000.0)
3948 	      << "\\p@}";
3949   stringout_ << "\\def\\" << name << "Factor%\n{"
3950 	      << spec.displaySizeFactor
3951 	      << '}';
3952 }
3953 
3954 //
3955 // Set a double.
3956 //
set(const char * name,double n)3957 void TeXFOTBuilder::set(const char *name,double n)
3958 {
3959   stringout_ << "\\def\\" << name << "%\n{" << n << '}';
3960 }
3961 
3962 //
3963 // Set a DeviceRGBColor.
3964 //
set(const char * name,const DeviceRGBColor & color)3965 void TeXFOTBuilder::set(const char *name, const DeviceRGBColor &color)
3966 {
3967   stringout_ << "\\def\\" << name << "Red%\n{" << int(color.red) << '}';
3968   stringout_ << "\\def\\" << name << "Green%\n{" << int(color.green) << '}';
3969   stringout_ << "\\def\\" << name << "Blue%\n{" << int(color.blue) << '}';
3970 }
3971 
3972 //
3973 // Set a bool.
3974 //
set(const char * name,bool flag)3975 void TeXFOTBuilder::set(const char *name,bool flag)
3976 {
3977   stringout_ << "\\def\\" << name << "%\n{"
3978 	      << (flag ? 1 : 0)
3979 	      << '}';
3980 }
3981 
3982 //
3983 // Set a long.
3984 //
set(const char * name,long n)3985 void TeXFOTBuilder::set(const char *name,long n)
3986 {
3987   stringout_ << "\\def\\" << name << "%\n{" << n << '}';
3988 }
3989 
3990 //
3991 // Set an unsigned long.
3992 //
set(const char * name,long unsigned int n)3993 void TeXFOTBuilder::set(const char *name,long unsigned int n)
3994 {
3995   stringout_ << "\\def\\" << name << "%\n{" << n << '}';
3996 }
3997 
3998 //
3999 // Set a PublicId.
4000 //
set(const char * name,PublicId id)4001 void TeXFOTBuilder::set(const char *name,PublicId id)
4002 {
4003   stringout_ << "\\def\\" << name << "%\n{" << id << '}';
4004 }
4005 
4006 //
4007 // Set a Letter2.
4008 //
setletter2(const char * name,Letter2 code)4009 void TeXFOTBuilder::setletter2(const char *name,Letter2 code)
4010 {
4011   char letter1 = (code & 0xff00) >> 8;
4012   char letter2 = (code & 0xff);
4013   stringout_ << "\\def\\" << name << "%\n{" << letter1 << letter2 << '}';
4014 }
4015 
4016 //
4017 // This one is a problem because it duplications functionality from
4018 // above.
4019 //
set(const char * name,const DisplaySpace & space)4020 void TeXFOTBuilder::set(const char *name,const DisplaySpace &space)
4021 {
4022   if (space.nominal.length != 0 || space.min.length != 0
4023       || space.max.length != 0) {
4024     stringout_ << "\\def\\" << name << "Nom%\n{"
4025 		<< (space.nominal.length/1000.0) << "\\p@}";
4026     if (space.nominal.displaySizeFactor != 0)
4027       stringout_ << "\\def\\" << name << "NomFactor%\n{"
4028 		  << space.nominal.displaySizeFactor << '}';
4029     if (space.min.length != 0)
4030       stringout_ << "\\def\\" << name << "Min%\n{"
4031 		  << (space.min.length/1000.0) << "\\p@}";
4032     if (space.min.displaySizeFactor != 0)
4033       stringout_ << "\\def\\" << name << "MinFactor%\n{"
4034 		  << space.min.displaySizeFactor << '}';
4035     if (space.max.length != 0)
4036       stringout_ << "\\def\\" << name << "Max%\n{"
4037 		  << (space.max.length/1000.0) << "\\p@}";
4038     if (space.max.displaySizeFactor != 0)
4039       stringout_ << "\\def\\" << name << "MaxFactor%\n{"
4040 		  << space.max.displaySizeFactor << '}';
4041     if (space.priority != 0)
4042       stringout_ << "\\def\\" << name << "Priority%\n{"
4043 		  << space.priority << '}';
4044     if (space.conditional)
4045       stringout_ << "\\def\\" << name << "Conditional%\n{"
4046 		  << (space.conditional ? 1 : 0) << '}';
4047     if (space.force)
4048       stringout_ << "\\def\\" << name << "Force%\n{"
4049 		  << (space.force ? 1 : 0) << '}';
4050   }
4051 }
4052 
set(const char * name,const GlyphId & glyphId)4053 void TeXFOTBuilder::set(const char *name,const GlyphId &glyphId)
4054 {
4055   stringout_ << "\\def\\" << name << "%\n{";
4056   if (glyphId.publicId) {
4057     stringout_ << glyphId.publicId;
4058     if (glyphId.suffix)
4059       stringout_ << "::" << glyphId.suffix;
4060   }
4061   stringout_ << '}';
4062 }
4063 
set(const char * name,const OptLengthSpec & spec)4064 void TeXFOTBuilder::set(const char *name,const OptLengthSpec &spec)
4065 {
4066   if (spec.hasLength) {
4067     set(name,spec.length);
4068   }
4069 }
4070 
4071 // This one is also a problem because it duplicates functionality.
set(const char * name,const InlineSpace & space)4072 void TeXFOTBuilder::set(const char *name,const InlineSpace &space)
4073 {
4074   if (space.nominal.length != 0 || space.min.length != 0
4075       || space.max.length != 0) {
4076     stringout_ << "\\def\\" << name << "Nom%\n{"
4077 		<< (space.nominal.length/1000.0) << "\\p@}";
4078     if (space.nominal.displaySizeFactor != 0)
4079       stringout_ << "\\def\\" << name << "NomFactor%\n{"
4080 		  << space.nominal.displaySizeFactor << '}';
4081     if (space.min.length != 0)
4082       stringout_ << "\\def\\" << name << "Min%\n{"
4083 		  << (space.min.length/1000.0) << "\\p@}";
4084     if (space.min.displaySizeFactor != 0)
4085       stringout_ << "\\def\\" << name << "MinFactor%\n{"
4086 		  << space.min.displaySizeFactor << '}';
4087     if (space.max.length != 0)
4088       stringout_ << "\\def\\" << name << "Max%\n{"
4089 		  << (space.max.length/1000.0) << "\\p@}";
4090     if (space.max.displaySizeFactor != 0)
4091       stringout_ << "\\def\\" << name << "MaxFactor%\n{"
4092 		  << space.max.displaySizeFactor << '}';
4093   }
4094 }
4095 
4096 //
4097 // Structures for non-inherited characters, in the order specified
4098 // in /style/FOTBuilder.h.
4099 //
4100 
setDisplayNIC(const DisplayNIC & nic)4101 void TeXFOTBuilder::setDisplayNIC(const DisplayNIC &nic)
4102 {
4103   set("sb",nic.spaceBefore);
4104   set("sa",nic.spaceAfter);
4105   MAYBESET("PositionPreference",nic.positionPreference,symbolFalse);
4106   MAYBESET("Keep",nic.keep,symbolFalse);
4107   MAYBESET("BreakBefore",nic.breakBefore,symbolFalse);
4108   MAYBESET("BreakAfter",nic.breakAfter,symbolFalse);
4109   MAYBESET("KeepWithPrevious",nic.keepWithPrevious,symbolFalse);
4110   MAYBESET("KeepWithNext",nic.keepWithNext,symbolFalse);
4111   MAYBESET("MayViolateKeepBefore",nic.mayViolateKeepBefore,symbolFalse);
4112   MAYBESET("MayViolateKeepAfter",nic.mayViolateKeepAfter,symbolFalse);
4113 }
4114 
setInlineNIC(const InlineNIC & nic)4115 void TeXFOTBuilder::setInlineNIC(const InlineNIC &nic)
4116 {
4117   MAYBESET("BreakBeforePriority",nic.breakBeforePriority,0);
4118   MAYBESET("BreakAfterPriority",nic.breakAfterPriority,0);
4119 }
4120 
setDisplayGroupNIC(const DisplayGroupNIC & nic)4121 void TeXFOTBuilder::setDisplayGroupNIC(const DisplayGroupNIC &nic)
4122 {
4123   setDisplayNIC(nic);
4124   if (nic.hasCoalesceId)
4125     set("CoalesceId",nic.coalesceId);
4126 }
4127 
setExternalGraphicNIC(const ExternalGraphicNIC & nic)4128 void TeXFOTBuilder::setExternalGraphicNIC(const ExternalGraphicNIC &nic)
4129 {
4130   setDisplayNIC(nic);
4131   setInlineNIC(nic);
4132 
4133   MAYBESET("IsDisplay",nic.isDisplay,symbolFalse);
4134   MAYBESET("ScaleType",nic.scaleType,symbolMaxUniform);
4135   if (nic.scaleType == symbolFalse) {
4136     set("ScaleX",nic.scale[0]);
4137     set("ScaleY",nic.scale[1]);
4138   }
4139   set("EntitySystemId",nic.entitySystemId);
4140   set("NotationSystemId",nic.notationSystemId);
4141   if(nic.hasMaxWidth)
4142     set("MaxWidth",nic.maxWidth);
4143   if (nic.hasMaxHeight)
4144     set("MaxHeight",nic.maxHeight);
4145   if (!nic.isDisplay) {
4146     set("EscapementDirection",nic.escapementDirection);
4147     set("PositionPointX",nic.positionPointX);
4148     set("PositionPointY",nic.positionPointY);
4149   }
4150 }
4151 
setBoxNIC(const BoxNIC & nic)4152 void TeXFOTBuilder::setBoxNIC(const BoxNIC &nic)
4153 {
4154   setDisplayNIC(nic);
4155   setInlineNIC(nic);
4156 				// BoxNIC
4157   MAYBESET("IsDisplay",nic.isDisplay,symbolFalse);
4158 }
4159 
setRuleNIC(const RuleNIC & nic)4160 void TeXFOTBuilder::setRuleNIC(const RuleNIC &nic)
4161 {
4162   setDisplayNIC(nic);
4163   setInlineNIC(nic);
4164 				// Rule NIC
4165   set("Orientation",nic.orientation);
4166   if (nic.hasLength)
4167     set("Length",nic.length);
4168 }
4169 
setLeaderNIC(const LeaderNIC & nic)4170 void TeXFOTBuilder::setLeaderNIC(const LeaderNIC &nic)
4171 {
4172   setInlineNIC(nic);
4173   if (nic.hasLength)
4174     set("Length",nic.length);
4175 }
4176 
setParagraphNIC(const ParagraphNIC & nic)4177 void TeXFOTBuilder::setParagraphNIC(const ParagraphNIC &nic)
4178 {
4179   setDisplayNIC(nic);
4180 }
4181 
setCharacterNIC(const CharacterNIC & nic)4182 void TeXFOTBuilder::setCharacterNIC(const CharacterNIC &nic)
4183 {
4184   if (nic.specifiedC & (1 << CharacterNIC::cChar))
4185     set("Ch",(unsigned long)nic.ch);
4186   if (nic.specifiedC & (1 << CharacterNIC::cGlyphId))
4187     set("GlyphId",nic.glyphId);
4188   if (nic.specifiedC & (1 << CharacterNIC::cBreakBeforePriority))
4189     set("BreakBeforePriority",nic.breakBeforePriority);
4190   if (nic.specifiedC & (1 << CharacterNIC::cBreakAfterPriority))
4191     set("BreakAfterPriority",nic.breakAfterPriority);
4192   if (nic.specifiedC & (1 << CharacterNIC::cMathClass))
4193     set("MathClass",nic.mathClass);
4194   if (nic.specifiedC & (1 << CharacterNIC::cMathFontPosture))
4195     set("MathFontPosture",nic.mathFontPosture);
4196   if (nic.specifiedC & (1 << CharacterNIC::cScript))
4197     set("Script",(long unsigned int)nic.script);
4198   if (nic.specifiedC & (1 << CharacterNIC::cIsDropAfterLineBreak))
4199     set("IsDropAfterLineBreak",nic.isDropAfterLineBreak);
4200   if (nic.specifiedC & (1 << CharacterNIC::cIsDropUnlessBeforeLineBreak))
4201     set("IsDropUnlessBeforeLineBreak",nic.isDropUnlessBeforeLineBreak);
4202   if (nic.specifiedC & (1 << CharacterNIC::cIsPunct))
4203     set("IsPunct",nic.isPunct);
4204   if (nic.specifiedC & (1 << CharacterNIC::cIsInputWhitespace))
4205     set("IsInputWhiteSpace",nic.isInputWhitespace);
4206   if (nic.specifiedC & (1 << CharacterNIC::cIsInputTab))
4207     set("IsInputTab",nic.isInputTab);
4208   if (nic.specifiedC & (1 << CharacterNIC::cIsRecordEnd))
4209     set("IsRecordEnd",nic.isRecordEnd);
4210   if (nic.specifiedC & (1 << CharacterNIC::cIsSpace))
4211     set("IsSpace",nic.isSpace);
4212   MAYBESET("StretchFactor",nic.stretchFactor,1.0);
4213 }
4214 
setLineFieldNIC(const LineFieldNIC & nic)4215 void TeXFOTBuilder::setLineFieldNIC(const LineFieldNIC &nic)
4216 {
4217   setInlineNIC(nic);
4218 }
4219 
setTableNIC(const TableNIC & nic)4220 void TeXFOTBuilder::setTableNIC(const TableNIC &nic)
4221 {
4222   setDisplayNIC(nic);
4223 				// TableNIC
4224   switch (nic.widthType) {
4225   case TableNIC::widthFull:
4226     set("TableWidth","full");
4227     break;
4228   case TableNIC::widthMinimum:
4229     set("TableWidth","minimum");
4230     break;
4231   case TableNIC::widthExplicit:
4232     set("TableWidth",nic.width);
4233     break;
4234   }
4235 }
4236 
setTablePartNIC(const TablePartNIC & nic)4237 void TeXFOTBuilder::setTablePartNIC(const TablePartNIC &nic)
4238 {
4239   setDisplayNIC(nic);
4240 }
4241 
setTableColumnNIC(const TableColumnNIC & nic)4242 void TeXFOTBuilder::setTableColumnNIC(const TableColumnNIC &nic)
4243 {
4244   MAYBESET("ColumnIndex",long(nic.columnIndex),0);
4245   MAYBESET("NColumnsSpanned",long(nic.nColumnsSpanned),1);
4246   if (nic.hasWidth)
4247     set("Width",nic.width);
4248 }
4249 
setTableCellNIC(const TableCellNIC & nic)4250 void TeXFOTBuilder::setTableCellNIC(const TableCellNIC &nic)
4251 {
4252   // FIX ME!
4253   // does not deal with "missing" bool yet.
4254   MAYBESET("ColumnIndex",long(nic.columnIndex),0);
4255   MAYBESET("NColumnsSpanned",long(nic.nColumnsSpanned),1);
4256   MAYBESET("NRowsSpanned",long(nic.nRowsSpanned),1);
4257 }
4258 
setGridNIC(const GridNIC & nic)4259 void TeXFOTBuilder::setGridNIC(const GridNIC &nic)
4260 {
4261   set("NColumns",nic.nColumns);
4262   set("NRows",nic.nRows);
4263 }
4264 
setGridCellNIC(const GridCellNIC & nic)4265 void TeXFOTBuilder::setGridCellNIC(const GridCellNIC &nic)
4266 {
4267   set("ColumnNumber",nic.columnNumber);
4268   set("RowNumber",nic.rowNumber);
4269 }
4270 
4271 
4272 // Dump all accumulated inherited characteristics.
4273 
dumpInherited()4274 void TeXFOTBuilder::dumpInherited()
4275 {
4276   String<char> tem;
4277   stringout_.extractString(tem);
4278   os() << tem;
4279 }
4280 
message(const MessageType0 & msg)4281 void TeXFOTBuilder::message(const MessageType0 &msg)
4282 {
4283   mgr_->message(msg);
4284 }
4285 
setPageNumberFormat(const StringC & name)4286 void TeXFOTBuilder::setPageNumberFormat(const StringC &name)
4287 {
4288   set("PageNumberFormat",name);
4289 }
4290 
setPageNColumns(long n)4291 void TeXFOTBuilder::setPageNColumns(long n)
4292 {
4293   NextFormat.FotPageNColumns = n;
4294   set("PageNColumns",n);
4295 }
4296 
setPageColumnSep(Length w)4297 void TeXFOTBuilder::setPageColumnSep(Length w)
4298 {
4299   NextFormat.FotPageColumnSep = w;
4300   setlength("PageColumnSep",w);
4301 }
4302 
setPageBalanceColumns(bool flag)4303 void TeXFOTBuilder::setPageBalanceColumns(bool flag)
4304 {
4305  set("PageBalanceColumns",flag);
4306 }
4307 
setSubscriptDepth(Length w)4308 void TeXFOTBuilder::setSubscriptDepth(Length w)
4309 {
4310  setlength("SubScriptDepth",w);
4311 }
4312 
setOverMarkHeight(Length w)4313 void TeXFOTBuilder::setOverMarkHeight(Length w)
4314 {
4315  setlength("OverMarkHeight",w);
4316 }
4317 
setUnderMarkDepth(Length w)4318 void TeXFOTBuilder::setUnderMarkDepth(Length w)
4319 {
4320  setlength("UnderMarkDepth",w);
4321 }
4322 
setSuperscriptHeight(Length w)4323 void TeXFOTBuilder::setSuperscriptHeight(Length w)
4324 {
4325  setlength("SuperscriptHeight",w);
4326 }
4327 
setGridRowSep(Length w)4328 void TeXFOTBuilder::setGridRowSep(Length  w)
4329 {
4330  setlength("GridRowsep",w);
4331 }
4332 
setGridColumnSep(Length w)4333 void TeXFOTBuilder::setGridColumnSep(Length w)
4334 {
4335  setlength("GridColumnSep",w);
4336 }
4337 
setHeadingLevel(long n)4338 void TeXFOTBuilder::setHeadingLevel(long n)
4339 {
4340  set("HeadingLevel",n);
4341 }
4342 
setPageNumberRestart(bool flag)4343 void TeXFOTBuilder::setPageNumberRestart(bool flag)
4344 {
4345  set("PageNumberRestart",flag);
4346 }
4347 
startPageFloat(const PageFloatNIC & nic)4348 void TeXFOTBuilder::startPageFloat(const PageFloatNIC &nic)
4349 {
4350   setPageFloatNIC(nic);
4351   startGroup("PageFloat");
4352 }
4353 
endPageFloat()4354 void TeXFOTBuilder::endPageFloat()
4355 {
4356   endGroup("PageFloat");
4357 }
4358 
startPageFootnote()4359 void TeXFOTBuilder::startPageFootnote()
4360 {
4361   startBrace("PageFootnote");
4362 }
4363 
endPageFootnote()4364 void TeXFOTBuilder::endPageFootnote()
4365 {
4366   endBrace("PageFootnote");
4367 }
4368 
setPageFloatNIC(const PageFloatNIC & nic)4369 void TeXFOTBuilder::setPageFloatNIC(const PageFloatNIC &nic)
4370 {
4371   set("placement",nic.placement);
4372 }
4373 
~PageFloatNIC()4374 TeXFOTBuilder::PageFloatNIC::~PageFloatNIC()
4375 {
4376 }
4377 
extension(const ExtensionFlowObj & fo,const NodePtr & nd)4378 void TeXFOTBuilder::extension(const ExtensionFlowObj &fo, const NodePtr &nd)
4379 {
4380   ((const TeXExtensionFlowObj &)fo).atomic(*this, nd);
4381 }
4382 
startExtensionSerial(const CompoundExtensionFlowObj & fo,const NodePtr & nd)4383 void TeXFOTBuilder::startExtensionSerial(const CompoundExtensionFlowObj &fo, const NodePtr &nd)
4384 {
4385   ((const TeXCompoundExtensionFlowObj &)fo).start(*this, nd);
4386 }
4387 
endExtensionSerial(const CompoundExtensionFlowObj & fo)4388 void TeXFOTBuilder::endExtensionSerial(const CompoundExtensionFlowObj &fo)
4389 {
4390   ((const TeXCompoundExtensionFlowObj &)fo).end(*this);
4391 }
4392 
setPreserveSdata(bool b)4393 void TeXFOTBuilder::setPreserveSdata(bool b)
4394 {
4395   preserveSdata_ = b;
4396 }
4397 
charactersFromNode(const NodePtr & nd,const Char * s,size_t n)4398 void TeXFOTBuilder::charactersFromNode(const NodePtr &nd, const Char *s, size_t n)
4399 {
4400   GroveString name;
4401   if (preserveSdata_ && n == 1 && nd->getEntityName(name) == accessOK)
4402     os() << "\\Entity{" << name << '}';
4403   else
4404     TeXFOTBuilder::characters(s, n);
4405 }
4406 
4407 #ifdef DSSSL_NAMESPACE
4408 }
4409 #endif
4410 
4411 #include "TeXFOTBuilder_inst.cxx"
4412