1
4
5
23
24# include "luametatex.h"
25
26dir_state_info lmt_dir_state = {
27 .text_dir_ptr = null,
28 .padding = 0,
29};
30
31
32
33inline static halfword tex_aux_push_dir_node(halfword p, halfword d)
34{
35 halfword n = tex_copy_node(d);
36 node_next(n) = p;
37 return n;
38}
39
40inline static halfword tex_aux_pop_dir_node(halfword p)
41{
42 halfword n = node_next(p);
43 tex_flush_node(p);
44 return n;
45}
46
47halfword tex_update_dir_state(halfword p, halfword initial)
48{
49 if (node_subtype(p) == normal_dir_subtype) {
50 lmt_linebreak_state.dir_ptr = tex_aux_push_dir_node(lmt_linebreak_state.dir_ptr, p);
51 return dir_direction(p);
52 } else {
53 lmt_linebreak_state.dir_ptr = tex_aux_pop_dir_node(lmt_linebreak_state.dir_ptr);
54 if (lmt_linebreak_state.dir_ptr) {
55 return dir_direction(lmt_linebreak_state.dir_ptr);
56 } else {
57 return initial;
58 }
59 }
60}
61
62
66
67halfword tex_sanitize_dir_state(halfword first, halfword last, halfword initial)
68{
69 for (halfword e = first; e && e != last; e = node_next(e)) {
70 if (node_type(e) == dir_node) {
71 if (node_subtype(e) == normal_dir_subtype) {
72 lmt_linebreak_state.dir_ptr = tex_aux_push_dir_node(lmt_linebreak_state.dir_ptr, e);
73 } else if (lmt_linebreak_state.dir_ptr && dir_direction(lmt_linebreak_state.dir_ptr) == dir_direction(e)) {
74
75 lmt_linebreak_state.dir_ptr = tex_aux_pop_dir_node(lmt_linebreak_state.dir_ptr);
76 }
77 }
78 }
79 if (lmt_linebreak_state.dir_ptr) {
80 return dir_direction(lmt_linebreak_state.dir_ptr);
81 } else {
82 return initial;
83 }
84}
85
86
90
91void tex_append_dir_state(void)
92{
93 halfword dir = lmt_dir_state.text_dir_ptr;
94 halfword tail = cur_list.tail;
95 halfword first = null;
96 halfword last = null;
97 if (tracing_paragraph_lists) {
98 tex_begin_diagnostic();
99 tex_print_format("[paragraph: dirstate]");
100 tex_show_box(dir);
101 tex_end_diagnostic();
102 }
103 while (dir) {
104 if ((node_next(dir)) || (dir_direction(dir) != par_direction_par)) {
105 halfword tmp = tex_new_dir(normal_dir_subtype, dir_direction(dir));
106 tex_attach_attribute_list_copy(tmp, tail);
107 tex_try_couple_nodes(tmp, first);
108 first = tmp;
109 if (! last) {
110 last = tmp;
111 }
112 }
113 dir = node_next(dir);
114 }
115 if (first) {
116 if (tracing_paragraph_lists) {
117 tex_begin_diagnostic();
118 tex_print_format("[paragraph: injected dirs]");
119 tex_show_box(first);
120 tex_end_diagnostic();
121 }
122 tex_couple_nodes(cur_list.tail, first);
123 cur_list.tail = last;
124 }
125}
126
127halfword tex_complement_dir_state(halfword tail)
128{
129 halfword aftertail = node_next(tail);
130 for (halfword topdir = lmt_linebreak_state.dir_ptr; topdir ; topdir = node_next(topdir)) {
131 halfword dir = tex_new_dir(cancel_dir_subtype, dir_direction(topdir));
132 tex_attach_attribute_list_copy(dir, tail);
133 tex_couple_nodes(tail, dir);
134 tex_try_couple_nodes(dir, aftertail);
135 tail = dir;
136 }
137 return tail;
138}
139
140void tex_initialize_directions(void)
141{
142 lmt_dir_state.text_dir_ptr = tex_new_dir(normal_dir_subtype, direction_def_value);
143}
144
145void tex_cleanup_directions(void)
146{
147 tex_flush_node(lmt_dir_state.text_dir_ptr);
148}
149
150halfword tex_new_dir(quarterword subtype, halfword direction)
151{
152 halfword p = tex_new_node(dir_node, subtype);
153 dir_direction(p) = direction;
154 dir_level(p) = cur_level;
155 return p;
156}
157
158void tex_push_text_dir_ptr(halfword val)
159{
160 if (tracing_direction_lists) {
161 tex_begin_diagnostic();
162 tex_print_format("[direction: push text, level %i, before]", cur_level);
163 tex_show_box(lmt_dir_state.text_dir_ptr);
164 tex_end_diagnostic();
165 }
166 if (dir_level(lmt_dir_state.text_dir_ptr) == cur_level) {
167
168 dir_direction(lmt_dir_state.text_dir_ptr) = val;
169 } else {
170
171 halfword text_dir_tmp = tex_new_dir(normal_dir_subtype, val);
172 node_next(text_dir_tmp) = lmt_dir_state.text_dir_ptr;
173 lmt_dir_state.text_dir_ptr = text_dir_tmp;
174 }
175 if (tracing_direction_lists) {
176 tex_begin_diagnostic();
177 tex_print_format("[direction: push text, level %i, after]", cur_level);
178 tex_show_box(lmt_dir_state.text_dir_ptr);
179 tex_end_diagnostic();
180 }
181}
182
183void tex_pop_text_dir_ptr(void)
184{
185 halfword text_dir_ptr = lmt_dir_state.text_dir_ptr;
186 if (tracing_direction_lists) {
187 tex_begin_diagnostic();
188 tex_print_format("[direction: pop text, level %i, before]", cur_level);
189 tex_show_box(lmt_dir_state.text_dir_ptr);
190 tex_end_diagnostic();
191 }
192 if (dir_level(text_dir_ptr) == cur_level) {
193
194 halfword text_dir_tmp = node_next(text_dir_ptr);
195 tex_flush_node(text_dir_ptr);
196 lmt_dir_state.text_dir_ptr = text_dir_tmp;
197 }
198 if (tracing_direction_lists) {
199 tex_begin_diagnostic();
200 tex_print_format("[direction: pop text, level %i, after]", cur_level);
201 tex_show_box(lmt_dir_state.text_dir_ptr);
202 tex_end_diagnostic();
203 }
204}
205
206void tex_set_math_dir(halfword d)
207{
208 if (valid_direction(d)) {
209 update_tex_math_direction(d);
210 }
211}
212
213void tex_set_par_dir(halfword d)
214{
215 if (valid_direction(d)) {
216 update_tex_par_direction(d);
217 }
218}
219
220void tex_set_text_dir(halfword d)
221{
222 if (valid_direction(d)) {
223 tex_inject_text_or_line_dir(d, 0);
224 update_tex_text_direction(d);
225 update_tex_internal_dir_state(internal_dir_state_par + 1);
226 }
227}
228
229void tex_set_line_dir(halfword d)
230{
231 if (valid_direction(d)) {
232 tex_inject_text_or_line_dir(d, 1);
233 update_tex_text_direction(d);
234 update_tex_internal_dir_state(internal_dir_state_par + 1);
235 }
236}
237
238void tex_set_box_dir(halfword b, singleword d)
239{
240 if (valid_direction(d)) {
241 box_dir(box_register(b)) = (singleword) d;
242 }
243}
244 |