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