1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
|
/*
* 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 */
|