/* * Copyright (c) 1987 University of Maryland Department of Computer Science. * All rights reserved. Permission to copy for any purpose is hereby granted * so long as this copyright notice remains intact. */ /* Box structures */ /* Magic constants. Note that these are stored into `scaled' types. */ #define RunningRule (-(1 << 30)) #define MFracDefaultThickness (1 << 31) /* => default rule thickness */ /* Magic penalty values */ #define InfPenalty 10000 /* infinity---no break at all */ #define EjectPenalty (-10000) /* negative infinity---forced break */ /* Ordinary list types */ #define CharNode 0 /* character; also math char */ #define HListNode 1 /* a horizontal list */ #define VListNode 2 /* a vertical list */ #define RuleNode 3 /* a rule */ #define InsertNode 4 /* an insertion */ #define MarkNode 5 /* a mark */ #define AdjustNode 6 /* a \vadjust */ #define LigatureNode 7 /* a ligature */ #define DiscretionaryNode 8 /* a discretionary break */ #define WhatsitNode 9 /* a "whatsit" */ #define BeginMathNode 10 /* a begin-math */ #define EndMathNode 11 /* an end-math */ #define GlueNode 12 /* link to glue */ #define KernNode 13 /* kerning */ #define PenaltyNode 14 /* penalty */ #define UnsetAlignNode 15 /* \halign or \valign that is incomplete */ /* Types arising only in math lists */ #define MathAtom 16 /* math atom */ #define MathStyle 17 /* math style change */ #define MathFraction 18 /* math fraction */ #define MathLeft 19 /* math left delimiter \left */ #define MathRight 20 /* math right delimiter \right */ #define MathChoice 21 /* math 4-way choice */ #define MathSubList 22 /* math list, possibly empty */ #define MathSubBox 23 /* math box (\hlist or \vlist) */ /* Kinds of math atoms */ enum MKind { MKindOrd, MKindOp, MKindOpLimits, MKindOpNoLimits, MKindBin, MKindRel, MKindOpen, MKindClose, MKindPunct, MKindInner, MKindOver, MKindUnder, MKindAcc, MKindRad, MKindVCent }; /* Math text styles */ #define MStyleCramped 1 /* added to others to get cramped style */ #define MStyleDisplay 0 /* display style */ #define MStyleText 2 /* text style */ #define MStyleScript 4 /* script style */ #define MStyleSScript 6 /* scriptscript style */ /* * A font and character. Note that these limit the number of fonts and * characters/font to 256. */ struct fontchar { char fc_font; /* font index */ char fc_char; /* character index within the font */ }; /* a box */ struct box { scaled bx_width; /* width of the box */ scaled bx_depth; /* depth of the box */ scaled bx_height; /* height of the box */ scaled bx_offset; /* offset (lower if h, right if v) */ struct node *bx_contents; /* contents of the box */ int bx_glueorder; /* -3=>minus hfilll; 3=>plus hfilll */ float bx_glueset; /* glue setting ratio */ }; /* a rule */ struct rule { scaled ru_width; /* width of the rule */ scaled ru_depth; /* depth of the rule */ scaled ru_height; /* height of the rule */ }; /* an insert */ struct insert { int ins_number; /* 0..254 (I hope) */ i32 ins_floatingpenalty; /* \floatingpenalty for this insert */ scaled ins_naturalheightplusdepth; /* what more can I say? */ scaled ins_splitmaxdepth; /* \splitmaxdepth for this insert */ struct node *ins_splittopskip; /* \splittopskip for this insert */ struct node *ins_contents; /* insertion contents */ }; /* a ligature */ struct ligature { struct fontchar lig_fc; /* the ligature character */ struct node *lig_orig; /* the original set of characters */ }; /* a discretionary break */ struct discret { struct node *disc_prebrk; /* characters to precede break */ struct node *disc_postbrk; /* characters to follow break */ int disc_replaces; /* replaces this many nodes */ }; /* a whatsit */ struct whatsit { int wh_type; /* type of whatsit */ char *wh_other; /* other stuff */ }; /* * A glue specification. There may be multiple pointers to this glue spec, * so we have a reference count attached. */ struct gluespec { int gl_refcount; /* # pointers to here */ scaled gl_width; /* normal width */ scaled gl_stretch; /* strechability */ scaled gl_shrink; /* shrinkability */ short gl_stretchorder; /* 0..3 for <>, fil, fill, filll */ short gl_shrinkorder; /* same */ }; /* a link-to-glue node */ #define GlueIsNormal 0 /* ordinary glue */ #define GlueIsSkip 1 /* \hskip or \vskip */ #define GlueIsNonScript 2 /* \nonscript */ #define GlueIsMuGlue 3 /* mu glue */ #define GlueIsALeaders 4 /* aligned leaders */ #define GlueIsCLeaders 5 /* centered leaders */ #define GlueIsXLeaders 6 /* expanded leaders */ struct gluenode { int gn_type; /* special glue types */ struct node *gn_glue; /* the glue itself */ struct BoundName *gn_skip; /* skip parameter that generated it */ struct box *gn_leaderbox; /* leader box if leaders */ }; /* a kern */ #define ImplicitKern 0 /* kerning for things like "AV" */ #define ExplicitKern 1 /* \kern or italic correction */ #define MKern 2 /* \mkern */ struct kern { int kern_type; /* type of kern */ scaled kern_width; /* width of kern */ }; /* * An unset (incomplete) alignment (\halign or \valign). * This looks to be the largest node type, so I am using 'char' and 'short' * to try to keep it small... */ struct unsetalign { scaled unset_width; /* width of the unset box */ scaled unset_depth; /* depth of the unset box */ scaled unset_height; /* height of the unset box */ struct node *unset_contents; /* contents of the unset box */ scaled unset_glueshrink; /* total glue shrink */ scaled unset_gluestretch; /* total glue stretch */ char unset_shrinkorder; /* glue shrink order */ char unset_stretchorder; /* glue stretch order */ short unset_spancount; /* the number of spanned columns */ }; /* a token list */ struct toklist { int tok_refcount; /* the number of references */ struct node *tok_list; /* the tokens or the macro def'n */ }; /* Math delimiter */ struct delim { char smallfam; /* family number for small char */ char smallchar; /* character in small family */ char largefam; /* family number for large char */ char largechar; /* character in large family */ }; /* Math atoms, radicals, \left s, \right s, accents */ struct matom { enum MKind kind; /* atom kind (if not \left, \right) */ struct node *nucleus; /* nucleus */ struct node *supscr; /* superscript (optional) */ struct node *subscr; /* subscript (optional) */ struct delim delimiter; /* delimiter(s) (optional) */ /* accents are stored in the small delim */ }; /* Math fraction */ struct mfrac { struct node *numerator; /* numerator */ struct node *denominator; /* denominator */ scaled thickness; /* dividing rule thickness */ struct delim leftdelim; /* left delimiter (optional) */ struct delim rightdelim; /* right delimiter (optional) */ }; /* Math choice */ struct mchoice { struct node *ifdisplay; struct node *iftext; struct node *ifscript; struct node *ifsscript; }; /* * This structure exists mainly for `sizeof'. Character nodes are by far the * most common nodes, so to save memory space, nodes of type CharNode are kept * in a separate free list and do not get a full size node. This means that * node lists must be handled carefully, but that is already necessary, so it * is no loss. */ struct charnode { struct node *next; short type; struct fontchar fc; }; /* * A node in a list. Note that the first part of this structure is shared * with the struct charnode. */ struct node { struct node *next; /* next in linked list */ short type; /* type of this node */ struct fontchar fc; /* value iff char */ union { struct box un_box; /* value iff box */ struct rule un_rule; /* value iff rule */ struct insert un_ins; /* value iff insert */ struct toklist *un_mark; /* value iff mark */ struct ligature un_lig; /* value iff ligature */ struct discret un_disc; /* value iff discret. brk */ struct whatsit un_whatsit; /* value iff whatsit */ struct gluespec un_gluespec; /* value iff glue */ struct gluenode un_gluenode; /* value iff link to glue */ struct kern un_kern; /* value iff kern */ i32 un_integer; /* value if integer */ struct unsetalign un_unset; /* value iff unset alignment */ struct matom un_matom; /* value if math atom */ struct mfrac un_mfrac; /* value iff math fraction */ struct mchoice un_mchoice; /* value iff math choice */ struct node *un_node; /* value if node list */ } node_un; }; /* Shorthand */ #define FC fc #define Font fc.fc_font #define Char fc.fc_char #define BoxWidth node_un.un_box.bx_width #define BoxDepth node_un.un_box.bx_depth #define BoxHeight node_un.un_box.bx_height #define BoxOffset node_un.un_box.bx_offset #define BoxContents node_un.un_box.bx_contents #define BoxGlueOrder node_un.un_box.bx_glueorder #define BoxGlueSet node_un.un_box.bx_glueset #define RuleWidth node_un.un_rule.ru_width #define RuleDepth node_un.un_rule.ru_depth #define RuleHeight node_un.un_rule.ru_height #define InsertNumber node_un.un_ins.ins_number #define InsertFloatingPenalty node_un.un_ins.ins_floatingpenalty #define InsertNaturalHeightPlusDepth node_un.un_ins.ins_naturalheightplusdepth #define InsertSplitMaxDepth node_un.un_ins.ins_splitmaxdepth #define InsertSplitTopSkip node_un.un_ins.ins_splittopskip #define InsertContents node_un.un_ins.ins_contents #define Mark node_un.un_mark #define LigatureFC node_un.un_lig.lig_fc #define LigatureOrig node_un.un_lig.lig_orig #define DiscretPreBreak node_un.un_disc.disc_prebrk #define DiscretPostBreak node_un.un_disc.disc_postbrk #define DiscretReplaces node_un.un_disc.disc_replaces #define WhatsitType node_un.un_whatsit.wh_type #define WhatsitOther node_un.un_whatsit.wh_other #define GlueRefCount node_un.un_gluespec.gl_refcount #define GlueWidth node_un.un_gluespec.gl_width #define GlueStretch node_un.un_gluespec.gl_stretch #define GlueShrink node_un.un_gluespec.gl_shrink #define GlueStretchOrder node_un.un_gluespec.gl_stretchorder #define GlueShrinkOrder node_un.un_gluespec.gl_shrinkorder #define Glue node_un.un_gluenode.gn_glue #define GlueSkip node_un.un_gluenode.gn_skip #define GlueType node_un.un_gluenode.gn_type #define GlueLeaderBox node_un.un_gluenode.gn_leaderbox #define KernWidth node_un.un_kern.kern_width #define KernType node_un.un_kern.kern_type #define Penalty node_un.un_integer #define UnsetWidth node_un.un_unset.unset_width #define UnsetDepth node_un.un_unset.unset_depth #define UnsetHeight node_un.un_unset.unset_height #define UnsetContents node_un.un_unset.unset_contents #define UnsetGlueShrink node_un.un_unset.unset_glueshrink #define UnsetGlueStretch node_un.un_unset.unset_gluestretch #define UnsetShrinkOrder node_un.un_unset.unset_shrinkorder #define UnsetStretchOrder node_un.un_unset.unset_stretchorder #define UnsetSpanCount node_un.un_unset.unset_spancount #define MAtomKind node_un.un_matom.kind #define MAtomNucleus node_un.un_matom.nucleus #define MAtomSupscr node_un.un_matom.supscr #define MAtomSubscr node_un.un_matom.subscr #define MAtomDelimiter node_un.un_matom.delimiter #define MAtomAccFam node_un.un_matom.delimiter.smallfam #define MAtomAccChar node_un.un_matom.delimiter.smallchar #define MFracNumerator node_un.un_mfrac.numerator #define MFracDenominator node_un.un_mfrac.denominator #define MFracThickness node_un.un_mfrac.thickness #define MFracLeftDelim node_un.un_mfrac.leftdelim #define MFracRightDelim node_un.un_mfrac.rightdelim #define MChoiceDisplay node_un.un_mchoice.ifdisplay #define MChoiceText node_un.un_mchoice.iftext #define MChoiceScript node_un.un_mchoice.ifscript #define MChoiceSScript node_un.un_mchoice.ifsscript #define MStyle node_un.un_integer #define MSub node_un.un_node struct node *FreeNodes; struct node *FreeChars; struct node *MoreNodes(); struct node *MoreChars(); /* * These macros quickly allocate and dispose of nodes. Watch out; the * arguments to NewNode and NewCharNode should be pointers that are to * be filled in. Moreover, the argument is accessed twice, so beware * side effects! */ #define NewNode(n) \ if (((n) = FreeNodes) == NULL) \ (n) = MoreNodes(); \ else \ FreeNodes = (n)->next #define NewCharNode(n) \ if (((n) = FreeChars) == NULL) \ (n) = MoreChars(); \ else \ FreeChars = (n)->next #define FreeNode(n) ((n)->next = FreeNodes, FreeNodes = (n)) #define FreeChar(n) ((n)->next = FreeChars, FreeChars = (n)) /* To free either a CharNode or a Node, use FreeEither! */ #define FreeEither(n) ((n)->type ? FreeNode(n) : FreeChar(n)) #define DelTokRef(p) (--(p)->tok_refcount < 0 ? FlushList(p) : NULL) #define DelGlueRef(p) (--(p)->GlueRefCount < 0 ? FreeNode(p) : NULL) /* These determine the granularity of node allocation */ #define NodeAllocSize 300 /* Nodes per MoreNodes() */ #define CharAllocSize 2500 /* CharNodes per MoreChars() */ struct node *CopyGlueSpec(); struct node *LinkToSkipParam(); struct node *LinkToGlueSpec(); struct node *LinkToCopyOfSkipParam(); #define NodeListDisplay(p) (s_addc('.'), ShowNodeList(p), s_delc()) /* * The ordering of the types is important here, because it allows simple * decisions for common operations. */ #define CanBreakAtGlue(n) ((n)->type < BeginMathNode) #define CanDiscardAfterBreak(n) ((n)->type >= BeginMathNode) struct node ZeroGlue; /* the zero-amount glue (0pt) */ struct node FilGlue; /* 0pt plus1fil minus0pt */ struct node FillGlue; /* 0pt plus1fill minus0pt */ struct node SSGlue; /* 0pt plus1fil minus1fil */ struct node FilNegGlue; /* 0pt plus-1fil minus0pt */ i32 ShowBoxMaxDepth; /* max nesting depth in box displays */ i32 ShowBoxMaxBreadth; /* max number of items per list level */ int FontInShortDisplay; /* the "current font" during a ShortDisplay */