beta-0.89.2
[luatex.git] / source / texk / web2c / luatexdir / dvi / dvigen.h
blob49552f1d9c2372f69782175bdd76e479d7f06801
1 /* dvigen.h
3 Copyright 2009-2013 Taco Hoekwater <taco@luatex.org>
5 This file is part of LuaTeX.
7 LuaTeX is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2 of the License, or (at your
10 option) any later version.
12 LuaTeX is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License along
18 with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
21 #ifndef DVIGEN_H
22 # define DVIGEN_H
24 extern int total_pages;
25 extern scaled max_v;
26 extern scaled max_h;
27 extern int max_push;
28 extern int last_bop;
29 extern int dead_cycles;
30 extern boolean doing_leaders;
31 extern int oval, ocmd;
32 extern int lq, lr;
33 extern int cur_s;
35 typedef int dvi_index; /* an index into the output buffer */
37 extern int dvi_buf_size;
38 extern eight_bits *dvi_buf; /* 0 is unused */
39 extern dvi_index half_buf;
40 extern dvi_index dvi_limit;
41 extern dvi_index dvi_ptr;
42 extern int dvi_offset;
43 extern int dvi_gone;
46 To put a byte in the buffer without paying the cost of invoking a procedure
47 each time, we use the macro |dvi_out|.
50 # define dvi_out(A) do { \
51 dvi_buf[dvi_ptr++]=(eight_bits)(A); \
52 if (dvi_ptr==dvi_limit) dvi_swap(); \
53 } while (0)
55 extern void dvi_swap(void);
56 extern void dvi_four(int x);
57 extern void dvi_push(void);
58 extern void dvi_pop(int l);
59 extern void out_cmd(void);
60 extern void dvi_font_def(internal_font_number f);
62 # define dvi_set(A,B) do { \
63 oval=A; ocmd=set1; out_cmd(); dvi.h += (B); \
64 } while (0)
66 # define dvi_put(A) do { \
67 oval=A; ocmd=put1; out_cmd(); \
68 } while (0)
70 # define location(A) varmem[(A)+1].cint
72 extern halfword down_ptr, right_ptr; /* heads of the down and right stacks */
75 The |vinfo| fields in the entries of the down stack or the right stack
76 have six possible settings: |y_here| or |z_here| mean that the \.{DVI}
77 command refers to |y| or |z|, respectively (or to |w| or |x|, in the
78 case of horizontal motion); |yz_OK| means that the \.{DVI} command is
79 \\{down} (or \\{right}) but can be changed to either |y| or |z| (or
80 to either |w| or |x|); |y_OK| means that it is \\{down} and can be changed
81 to |y| but not |z|; |z_OK| is similar; and |d_fixed| means it must stay
82 \\{down}.
84 The four settings |yz_OK|, |y_OK|, |z_OK|, |d_fixed| would not need to
85 be distinguished from each other if we were simply solving the
86 digit-subscripting problem mentioned above. But in \TeX's case there is
87 a complication because of the nested structure of |push| and |pop|
88 commands. Suppose we add parentheses to the digit-subscripting problem,
89 redefining hits so that $\delta_y\ldots \delta_y$ is a hit if all $y$'s between
90 the $\delta$'s are enclosed in properly nested parentheses, and if the
91 parenthesis level of the right-hand $\delta_y$ is deeper than or equal to
92 that of the left-hand one. Thus, `(' and `)' correspond to `|push|'
93 and `|pop|'. Now if we want to assign a subscript to the final 1 in the
94 sequence
95 $$2_y\,7_d\,1_d\,(\,8_z\,2_y\,8_z\,)\,1$$
96 we cannot change the previous $1_d$ to $1_y$, since that would invalidate
97 the $2_y\ldots2_y$ hit. But we can change it to $1_z$, scoring a hit
98 since the intervening $8_z$'s are enclosed in parentheses.
101 typedef enum {
102 y_here = 1, /* |vinfo| when the movement entry points to a |y| command */
103 z_here = 2, /* |vinfo| when the movement entry points to a |z| command */
104 yz_OK = 3, /* |vinfo| corresponding to an unconstrained \\{down} command */
105 y_OK = 4, /* |vinfo| corresponding to a \\{down} that can't become a |z| */
106 z_OK = 5, /* |vinfo| corresponding to a \\{down} that can't become a |y| */
107 d_fixed = 6, /* |vinfo| corresponding to a \\{down} that can't change */
108 } movement_codes;
110 /* As we search through the stack, we are in one of three states,
111 |y_seen|, |z_seen|, or |none_seen|, depending on whether we have
112 encountered |y_here| or |z_here| nodes. These states are encoded as
113 multiples of 6, so that they can be added to the |info| fields for quick
114 decision-making. */
116 # define none_seen 0 /* no |y_here| or |z_here| nodes have been encountered yet */
117 # define y_seen 6 /* we have seen |y_here| but not |z_here| */
118 # define z_seen 12 /* we have seen |z_here| but not |y_here| */
120 extern void movement(scaled w, eight_bits o);
121 extern void prune_movements(int l);
124 The actual distances by which we want to move might be computed as the
125 sum of several separate movements. For example, there might be several
126 glue nodes in succession, or we might want to move right by the width of
127 some box plus some amount of glue. More importantly, the baselineskip
128 distances are computed in terms of glue together with the depth and
129 height of adjacent boxes, and we want the \.{DVI} file to lump these
130 three quantities together into a single motion.
132 Therefore, \TeX\ maintains two pairs of global variables: |dvi.h| and |dvi.v|
133 are the |h| and |v| coordinates corresponding to the commands actually
134 output to the \.{DVI} file, while |cur.h| and |cur.v| are the coordinates
135 corresponding to the current state of the output routines. Coordinate
136 changes will accumulate in |cur.h| and |cur.v| without being reflected
137 in the output, until such a change becomes necessary or desirable; we
138 can call the |movement| procedure whenever we want to make |dvi.h=pos.h|
139 or |dvi.v=pos.v|.
141 The current font reflected in the \.{DVI} output is called |dvi_f|;
142 there is no need for a `\\{cur\_f}' variable.
144 The depth of nesting of |hlist_out| and |vlist_out| is called |cur_s|;
145 this is essentially the depth of |push| commands in the \.{DVI} output.
148 # define synch_h(p) do { \
149 if (p.h != dvi.h) { \
150 movement(p.h - dvi.h, right1); \
151 dvi.h = p.h; \
153 } while (0)
155 # define synch_v(p) do { \
156 if (p.v != dvi.v) { \
157 movement(dvi.v - p.v, down1); \
158 dvi.v = p.v; \
160 } while (0)
162 # define synch_dvi_with_pos(p) do {synch_h(p); synch_v(p); } while (0)
164 # define billion 1000000000.0
166 # define vet_glue(A) do { glue_temp=A; \
167 if (glue_temp>billion) \
168 glue_temp=billion; \
169 else if (glue_temp<-billion) \
170 glue_temp=-billion; \
171 } while (0)
173 extern scaledpos dvi;
175 extern void dvi_special(PDF pdf, halfword p);
177 extern void ensure_dvi_header_written(PDF pdf);
178 extern void finish_dvi_file(PDF pdf, int version, int revision);
180 extern void dvi_place_glyph(PDF pdf, internal_font_number f, int c, int ex);
181 extern void dvi_place_rule(PDF pdf, halfword q, scaledpos size);
183 extern void dvi_begin_page(PDF pdf);
184 extern void dvi_end_page(PDF pdf);
186 #endif