1 /* directions.h
2 
3    Copyright 2009 Taco Hoekwater <taco@luatex.org>
4 
5    This file is part of LuaTeX.
6 
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.
11 
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.
16 
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/>. */
19 
20 
21 #ifndef DIRECTIONS_H
22 #  define DIRECTIONS_H
23 
24 #  define dir_T 0
25 #  define dir_L 1
26 #  define dir_B 2
27 #  define dir_R 3
28 
29 #  define dir_TLT  0
30 #  define dir_TRT  4
31 #  define dir_LTL  9
32 #  define dir_RTT  24
33 
34 extern const char *dir_strings[128];
35 
36                                    /* #  define dir_array_size  25 *//* |dir_RTT + 1| */
37 
38 /* inv(primary) == tertiary */
39 /*
40 boolean _is_mirrored[dir_array_size];
41 _is_mirrored[dir_TLT] = 0;
42 _is_mirrored[dir_TRT] = 0;
43 _is_mirrored[dir_LTL] = 0;
44 _is_mirrored[dir_RTT] = 0;
45 */
46 
47 #  define is_mirrored(a) 0
48 
49 /* secondary == tertiary */
50 /*
51 boolean _is_rotated[dir_array_size];
52 _is_rotated[dir_TLT] = 0;
53 _is_rotated[dir_TRT] = 0;
54 _is_rotated[dir_LTL] = 0;
55 _is_rotated[dir_RTT] = 1;
56 */
57 
58 #  define is_rotated(a) (a == dir_RTT)
59 
60 /* secondary == secondary */
61 /*
62 boolean _textdir_parallel[dir_array_size][dir_array_size];
63 _textdir_parallel[dir_TLT][dir_TLT] = 1;
64 _textdir_parallel[dir_TLT][dir_TRT] = 1;
65 _textdir_parallel[dir_TLT][dir_LTL] = 0;
66 _textdir_parallel[dir_TLT][dir_RTT] = 0;
67 _textdir_parallel[dir_TRT][dir_TLT] = 1;
68 _textdir_parallel[dir_TRT][dir_TRT] = 1;
69 _textdir_parallel[dir_TRT][dir_LTL] = 0;
70 _textdir_parallel[dir_TRT][dir_RTT] = 0;
71 _textdir_parallel[dir_LTL][dir_TLT] = 0;
72 _textdir_parallel[dir_LTL][dir_TRT] = 0;
73 _textdir_parallel[dir_LTL][dir_LTL] = 1;
74 _textdir_parallel[dir_LTL][dir_RTT] = 1;
75 _textdir_parallel[dir_RTT][dir_TLT] = 0;
76 _textdir_parallel[dir_RTT][dir_TRT] = 0;
77 _textdir_parallel[dir_RTT][dir_LTL] = 1;
78 _textdir_parallel[dir_RTT][dir_RTT] = 1;
79 */
80 
81 #  define textdir_parallel(a,b)  (((a == dir_TLT || a == dir_TRT)&&(b == dir_TLT || b == dir_TRT)) || \
82 				((a == dir_LTL || a == dir_RTT)&&(b == dir_LTL || b == dir_RTT)))
83 
84 
85 /* primary == primary */
86 /*
87 boolean _pardir_parallel[dir_array_size][dir_array_size];
88 _pardir_parallel[dir_TLT][dir_TLT] = 1;
89 _pardir_parallel[dir_TLT][dir_TRT] = 1;
90 _pardir_parallel[dir_TLT][dir_LTL] = 0;
91 _pardir_parallel[dir_TLT][dir_RTT] = 0;
92 _pardir_parallel[dir_TRT][dir_TLT] = 1;
93 _pardir_parallel[dir_TRT][dir_TRT] = 1;
94 _pardir_parallel[dir_TRT][dir_LTL] = 0;
95 _pardir_parallel[dir_TRT][dir_RTT] = 0;
96 _pardir_parallel[dir_LTL][dir_TLT] = 0;
97 _pardir_parallel[dir_LTL][dir_TRT] = 0;
98 _pardir_parallel[dir_LTL][dir_LTL] = 1;
99 _pardir_parallel[dir_LTL][dir_RTT] = 1;
100 _pardir_parallel[dir_RTT][dir_TLT] = 0;
101 _pardir_parallel[dir_RTT][dir_TRT] = 0;
102 _pardir_parallel[dir_RTT][dir_LTL] = 1;
103 _pardir_parallel[dir_RTT][dir_RTT] = 1;
104 */
105 
106 
107 #  define pardir_parallel(a,b) (((a == dir_TLT || a == dir_TRT)&&(b == dir_TLT || b == dir_TRT)) || \
108 			      ((a == dir_LTL || a == dir_RTT)&&(b == dir_LTL || b == dir_RTT)))
109 
110 
111 /* inv(primary) == primary */
112 /*
113 boolean _pardir_opposite[dir_array_size][dir_array_size];
114 _pardir_opposite[dir_TLT][dir_TLT] = 0;
115 _pardir_opposite[dir_TLT][dir_TRT] = 0;
116 _pardir_opposite[dir_TLT][dir_LTL] = 0;
117 _pardir_opposite[dir_TLT][dir_RTT] = 0;
118 _pardir_opposite[dir_TRT][dir_TLT] = 0;
119 _pardir_opposite[dir_TRT][dir_TRT] = 0;
120 _pardir_opposite[dir_TRT][dir_LTL] = 0;
121 _pardir_opposite[dir_TRT][dir_RTT] = 0;
122 _pardir_opposite[dir_LTL][dir_TLT] = 0;
123 _pardir_opposite[dir_LTL][dir_TRT] = 0;
124 _pardir_opposite[dir_LTL][dir_LTL] = 0;
125 _pardir_opposite[dir_LTL][dir_RTT] = 1;
126 _pardir_opposite[dir_RTT][dir_TLT] = 0;
127 _pardir_opposite[dir_RTT][dir_TRT] = 0;
128 _pardir_opposite[dir_RTT][dir_LTL] = 1;
129 _pardir_opposite[dir_RTT][dir_RTT] = 0;
130 */
131 
132 #  define pardir_opposite(a,b) ((a == dir_LTL && b == dir_RTT)||(a == dir_RTT && b == dir_LTL))
133 
134 
135 /* inv(secondary) == secondary */
136 /*
137 boolean _textdir_opposite[dir_array_size][dir_array_size];
138 _textdir_opposite[dir_TLT][dir_TLT] = 0;
139 _textdir_opposite[dir_TLT][dir_TRT] = 1;
140 _textdir_opposite[dir_TLT][dir_LTL] = 0;
141 _textdir_opposite[dir_TLT][dir_RTT] = 0;
142 _textdir_opposite[dir_TRT][dir_TLT] = 1;
143 _textdir_opposite[dir_TRT][dir_TRT] = 0;
144 _textdir_opposite[dir_TRT][dir_LTL] = 0;
145 _textdir_opposite[dir_TRT][dir_RTT] = 0;
146 _textdir_opposite[dir_LTL][dir_TLT] = 0;
147 _textdir_opposite[dir_LTL][dir_TRT] = 0;
148 _textdir_opposite[dir_LTL][dir_LTL] = 0;
149 _textdir_opposite[dir_LTL][dir_RTT] = 0;
150 _textdir_opposite[dir_RTT][dir_TLT] = 0;
151 _textdir_opposite[dir_RTT][dir_TRT] = 0;
152 _textdir_opposite[dir_RTT][dir_LTL] = 0;
153 _textdir_opposite[dir_RTT][dir_RTT] = 0;
154 */
155 
156 #  define textdir_opposite(a,b) ((a == dir_TLT && b == dir_TRT)||(a == dir_TRT && b == dir_TLT))
157 
158 
159 /* inv(tertiary) == tertiary */
160 /*
161 boolean _glyphdir_opposite[dir_array_size][dir_array_size];
162 _glyphdir_opposite[dir_TLT][dir_TLT] = 0;
163 _glyphdir_opposite[dir_TLT][dir_TRT] = 0;
164 _glyphdir_opposite[dir_TLT][dir_LTL] = 0;
165 _glyphdir_opposite[dir_TLT][dir_RTT] = 0;
166 _glyphdir_opposite[dir_TRT][dir_TLT] = 0;
167 _glyphdir_opposite[dir_TRT][dir_TRT] = 0;
168 _glyphdir_opposite[dir_TRT][dir_LTL] = 0;
169 _glyphdir_opposite[dir_TRT][dir_RTT] = 0;
170 _glyphdir_opposite[dir_LTL][dir_TLT] = 0;
171 _glyphdir_opposite[dir_LTL][dir_TRT] = 0;
172 _glyphdir_opposite[dir_LTL][dir_LTL] = 0;
173 _glyphdir_opposite[dir_LTL][dir_RTT] = 0;
174 _glyphdir_opposite[dir_RTT][dir_TLT] = 0;
175 _glyphdir_opposite[dir_RTT][dir_TRT] = 0;
176 _glyphdir_opposite[dir_RTT][dir_LTL] = 0;
177 _glyphdir_opposite[dir_RTT][dir_RTT] = 0;
178 */
179 
180 #  define glyphdir_opposite(a,b) 0
181 
182 
183 /* primary == primary */
184 /*
185 boolean _pardir_eq[dir_array_size][dir_array_size];
186 _pardir_eq[dir_TLT][dir_TLT] = 1;
187 _pardir_eq[dir_TLT][dir_TRT] = 1;
188 _pardir_eq[dir_TLT][dir_LTL] = 0;
189 _pardir_eq[dir_TLT][dir_RTT] = 0;
190 _pardir_eq[dir_TRT][dir_TLT] = 1;
191 _pardir_eq[dir_TRT][dir_TRT] = 1;
192 _pardir_eq[dir_TRT][dir_LTL] = 0;
193 _pardir_eq[dir_TRT][dir_RTT] = 0;
194 _pardir_eq[dir_LTL][dir_TLT] = 0;
195 _pardir_eq[dir_LTL][dir_TRT] = 0;
196 _pardir_eq[dir_LTL][dir_LTL] = 1;
197 _pardir_eq[dir_LTL][dir_RTT] = 0;
198 _pardir_eq[dir_RTT][dir_TLT] = 0;
199 _pardir_eq[dir_RTT][dir_TRT] = 0;
200 _pardir_eq[dir_RTT][dir_LTL] = 0;
201 _pardir_eq[dir_RTT][dir_RTT] = 1;
202 */
203 
204 #  define pardir_eq(a,b) (((a == dir_TLT || a == dir_TRT)&&(b == dir_TLT || b == dir_TRT))|| \
205 			(a == dir_LTL && b == dir_LTL) ||		\
206 			(a == dir_RTT && b == dir_RTT))
207 
208 /* secondary == secondary */
209 /*
210 boolean _textdir_eq[dir_array_size][dir_array_size];
211 _textdir_eq[dir_TLT][dir_TLT] = 1;
212 _textdir_eq[dir_TLT][dir_TRT] = 0;
213 _textdir_eq[dir_TLT][dir_LTL] = 0;
214 _textdir_eq[dir_TLT][dir_RTT] = 0;
215 _textdir_eq[dir_TRT][dir_TLT] = 0;
216 _textdir_eq[dir_TRT][dir_TRT] = 1;
217 _textdir_eq[dir_TRT][dir_LTL] = 0;
218 _textdir_eq[dir_TRT][dir_RTT] = 0;
219 _textdir_eq[dir_LTL][dir_TLT] = 0;
220 _textdir_eq[dir_LTL][dir_TRT] = 0;
221 _textdir_eq[dir_LTL][dir_LTL] = 1;
222 _textdir_eq[dir_LTL][dir_RTT] = 1;
223 _textdir_eq[dir_RTT][dir_TLT] = 0;
224 _textdir_eq[dir_RTT][dir_TRT] = 0;
225 _textdir_eq[dir_RTT][dir_LTL] = 1;
226 _textdir_eq[dir_RTT][dir_RTT] = 1;
227 */
228 
229 #  define textdir_eq(a,b) ((a == dir_TLT && b == dir_TLT) || \
230 			 (a == dir_TRT && b == dir_TRT) || \
231 			 (a == dir_LTL && (b == dir_LTL || b == dir_RTT)) || \
232 			 (a == dir_RTT && (b == dir_LTL || b == dir_RTT))
233 
234 
235 /* tertiary == tertiary */
236 /*
237 boolean _glyphdir_eq[dir_array_size][dir_array_size];
238 _glyphdir_eq[dir_TLT][dir_TLT] = 1;
239 _glyphdir_eq[dir_TLT][dir_TRT] = 1;
240 _glyphdir_eq[dir_TLT][dir_LTL] = 0;
241 _glyphdir_eq[dir_TLT][dir_RTT] = 1;
242 _glyphdir_eq[dir_TRT][dir_TLT] = 1;
243 _glyphdir_eq[dir_TRT][dir_TRT] = 1;
244 _glyphdir_eq[dir_TRT][dir_LTL] = 0;
245 _glyphdir_eq[dir_TRT][dir_RTT] = 1;
246 _glyphdir_eq[dir_LTL][dir_TLT] = 0;
247 _glyphdir_eq[dir_LTL][dir_TRT] = 0;
248 _glyphdir_eq[dir_LTL][dir_LTL] = 1;
249 _glyphdir_eq[dir_LTL][dir_RTT] = 0;
250 _glyphdir_eq[dir_RTT][dir_TLT] = 1;
251 _glyphdir_eq[dir_RTT][dir_TRT] = 1;
252 _glyphdir_eq[dir_RTT][dir_LTL] = 0;
253 _glyphdir_eq[dir_RTT][dir_RTT] = 1;
254 */
255 
256 #  define glyphdir_eq(a,b) ((a != dir_LTL && b != dir_LTL) || \
257 			  (a == dir_LTL && b == dir_LTL))
258 
259 
260 /* primary == secondary */
261 /*
262 boolean _partextdir_eq[dir_array_size][dir_array_size];
263 _partextdir_eq[dir_TLT][dir_TLT] = 0;
264 _partextdir_eq[dir_TLT][dir_TRT] = 0;
265 _partextdir_eq[dir_TLT][dir_LTL] = 1;
266 _partextdir_eq[dir_TLT][dir_RTT] = 1;
267 _partextdir_eq[dir_TRT][dir_TLT] = 0;
268 _partextdir_eq[dir_TRT][dir_TRT] = 0;
269 _partextdir_eq[dir_TRT][dir_LTL] = 1;
270 _partextdir_eq[dir_TRT][dir_RTT] = 1;
271 _partextdir_eq[dir_LTL][dir_TLT] = 1;
272 _partextdir_eq[dir_LTL][dir_TRT] = 0;
273 _partextdir_eq[dir_LTL][dir_LTL] = 0;
274 _partextdir_eq[dir_LTL][dir_RTT] = 0;
275 _partextdir_eq[dir_RTT][dir_TLT] = 0;
276 _partextdir_eq[dir_RTT][dir_TRT] = 1;
277 _partextdir_eq[dir_RTT][dir_LTL] = 0;
278 _partextdir_eq[dir_RTT][dir_RTT] = 0;
279 */
280 
281 #  define partextdir_eq(a,b) (((a == dir_TLT || a == dir_TRT)&&(b == dir_LTL || b == dir_RTT)) || \
282 			    (a == dir_LTL && b == dir_TLT) ||		\
283 			    (a == dir_RTT && b == dir_TRT))
284 
285 
286 /* secondary != tertiary */
287 /*
288 boolean _textglyphdir_orthogonal[dir_array_size]
289 _textglyphdir_orthogonal[dir_TLT] = 1;
290 _textglyphdir_orthogonal[dir_TRT] = 1;
291 _textglyphdir_orthogonal[dir_LTL] = 1;
292 _textglyphdir_orthogonal[dir_RTT] = 0;
293 */
294 
295 #  define textglyphdir_orthogonal(a) (a != dir_RTT)
296 
297 /* secondary == L */
298 /*
299 boolean _textdir_is[dir_array_size];
300 _textdir_is[dir_TLT] = 1;
301 _textdir_is[dir_TRT] = 1;
302 _textdir_is[dir_LTL] = 1;
303 _textdir_is[dir_RTT] = 0;
304 */
305 
306 #  define textdir_is_L(a) (a == dir_TLT)
307 
308 #  define push_dir(a,b)				\
309    { halfword dir_tmp=new_dir((a));             \
310        vlink(dir_tmp)=b;                        \
311        b=dir_tmp;                               \
312    }
313 
314 #  define push_dir_node(a,b)		    \
315    { halfword dir_tmp=copy_node((a));	    \
316        vlink(dir_tmp)=b;                    \
317        b=dir_tmp;                           \
318    }
319 
320 #  define pop_dir_node(b)                 \
321    { halfword dir_tmp=b;                  \
322        b=vlink(dir_tmp);                  \
323        flush_node(dir_tmp);               \
324    }
325 
326 extern halfword dir_ptr;
327 
328 extern halfword text_dir_ptr;
329 
330 extern void initialize_directions(void);
331 extern halfword new_dir(int s);
332 
333 extern const char *string_dir(int d);
334 extern void print_dir(int d);
335 
336 extern void scan_direction(void);
337 
338 extern halfword do_push_dir_node(halfword p, halfword a);
339 extern halfword do_pop_dir_node(halfword p);
340 
341 scaled pack_width(int curdir, int pdir, halfword p, boolean isglyph);
342 scaled_whd pack_width_height_depth(int curdir, int pdir, halfword p,
343                                    boolean isglyph);
344 
345 void update_text_dir_ptr(int val);
346 
347 #endif
348