summaryrefslogtreecommitdiff
path: root/dviware/umddvi/h/box.h
blob: 05314900acc5b066a7ea415bf72d25fb5ea9e70f (plain)
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 */