Retrospective commit from 2009-08-15.
[bpt/emacs.git] / src / bidi.c
1 /* Low-level bidirectional buffer-scanning functions for GNU Emacs.
2 Copyright (C) 2000, 2001, 2004, 2005 Free Software Foundation, Inc.
3
4 This file is part of GNU Emacs.
5
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
21
22 /* A sequential implementation of the Unicode Bidirectional algorithm,
23 as per UAX#9, a part of the Unicode Standard.
24
25 Unlike the reference and most other implementations, this one is
26 designed to be called once for every character in the buffer.
27
28 The main entry point is bidi_get_next_char_visually. Each time it
29 is called, it finds the next character in the visual order, and
30 returns its information in a special structure. The caller is then
31 expected to process this character for display or any other
32 purposes, and call bidi_get_next_char_visually for the next
33 character. See the comments in bidi_get_next_char_visually for
34 more details about its algorithm that finds the next visual-order
35 character by resolving their levels on the fly.
36
37 A note about references to UAX#9 rules: if the reference says
38 something like "X9/Retaining", it means that you need to refer to
39 rule X9 and to its modifications decribed in the "Implementation
40 Notes" section of UAX#9, under "Retaining Format Codes". */
41
42 #ifdef HAVE_CONFIG_H
43 #include <config.h>
44 #endif
45
46 #include <stdio.h>
47
48 #ifdef HAVE_STRING_H
49 #include <string.h>
50 #endif
51
52 #include "lisp.h"
53 #include "buffer.h"
54 #include "character.h"
55 #include "dispextern.h"
56
57 static int bidi_initialized = 0;
58
59 static Lisp_Object bidi_type_table;
60
61 #define LRM_CHAR 0x200E
62 #define RLM_CHAR 0x200F
63 #define LRE_CHAR 0x202A
64 #define RLE_CHAR 0x202B
65 #define PDF_CHAR 0x202C
66 #define LRO_CHAR 0x202D
67 #define RLO_CHAR 0x202E
68
69 #define CHARSET_HEBREW 0x88
70 #define CHARSET_ARABIC 0x87
71 #define CHARSET_SYRIAC -1 /* these are undefined yet, -1 is invalid */
72 #define CHARSET_THAANA -1
73
74 /* FIXME: need to define wrappers for FETCH_CHAR etc. that return
75 BIDI_EOB when they hit ZV. */
76 #define BIDI_EOB -1
77 #define BIDI_BOB -2
78
79 #ifdef TEST_STANDALONE
80 /* Testing. */
81
82 static unsigned char *input_buf;
83 static size_t input_buf_size;
84
85 int _fetch_multibyte_char_len, _c_c_;
86
87 #undef FETCH_CHAR_ADVANCE
88 #define FETCH_CHAR_ADVANCE(ch, cp, bp) \
89 do { \
90 ch = input_buf[cp]; \
91 (cp)++; \
92 (bp)++; \
93 if (ch == '\0') \
94 ch = BIDI_EOB; \
95 } while (0)
96
97 #undef FETCH_CHAR
98 #define FETCH_CHAR(n) ((_c_c_ = input_buf[n]) ? _c_c_ : BIDI_EOB)
99
100 #undef CHAR_CHARSET
101 #define CHAR_CHARSET(c) \
102 (((c) >= 128 || ((c) < 8 && (c)) || ((c) >= 'A' && (c) < 'X')) \
103 ? CHARSET_HEBREW \
104 : ((((c) >= 'X' && (c) <= 'Z') || ((c) >= '6' && (c) <= '9')) \
105 ? CHARSET_ARABIC \
106 : CHARSET_ASCII))
107
108 #undef CHAR_TO_BYTE
109 #define CHAR_TO_BYTE(pos) (pos)
110
111 #define char_bytes(ch) 1
112
113 #undef LRE_CHAR
114 #undef LRO_CHAR
115 #undef RLE_CHAR
116 #undef RLO_CHAR
117 #undef PDF_CHAR
118 #undef RLM_CHAR
119 #undef LRM_CHAR
120
121 #define LRE_CHAR 1
122 #define LRO_CHAR 2
123 #define RLE_CHAR 3
124 #define RLO_CHAR 4
125 #define PDF_CHAR 5
126 #define RLM_CHAR 6
127 #define LRM_CHAR 7
128
129 static const char *bidi_name[] =
130 {
131 "[???]", "[LRE]", "[LRO]", "[RLE]", "[RLO]", "[PDF]", "[RLM]", "[LRM]"
132 };
133
134 #endif /* TEST_STANDALONE */
135
136 /* Local data structures. (Look in dispextern.h for the rest.) */
137
138 /* What we need to know about the current paragraph. */
139 struct bidi_paragraph_info {
140 int start_bytepos; /* byte position where it begins */
141 int end_bytepos; /* byte position where it ends */
142 int embedding_level; /* its basic embedding level */
143 bidi_dir_t base_dir; /* its base direction */
144 };
145
146 /* Data type for describing the bidirectional character categories. */
147 typedef enum {
148 UNKNOWN_BC,
149 NEUTRAL,
150 WEAK,
151 STRONG
152 } bidi_category_t;
153
154 int bidi_ignore_explicit_marks_for_paragraph_level = 1;
155
156 bidi_dir_t bidi_overriding_paragraph_direction = NEUTRAL_DIR;
157
158 /* FIXME: Unused? */
159 #define ASCII_BIDI_TYPE_SET(STR, TYPE) \
160 do { \
161 unsigned char *p; \
162 for (p = (STR); *p; p++) \
163 CHAR_TABLE_SET (bidi_type_table, *p, (TYPE)); \
164 } while (0)
165
166 static void
167 bidi_initialize ()
168 {
169 /* FIXME: This should come from the Unicode Database. */
170 struct {
171 int from, to;
172 bidi_type_t type;
173 } bidi_type[] =
174 { { 0x0000, 0x0008, WEAK_BN },
175 { 0x0009, 0x0000, NEUTRAL_S },
176 { 0x000A, 0x0000, NEUTRAL_B },
177 { 0x000B, 0x0000, NEUTRAL_S },
178 { 0x000C, 0x0000, NEUTRAL_WS },
179 { 0x000D, 0x0000, NEUTRAL_B },
180 { 0x000E, 0x001B, WEAK_BN },
181 { 0x001C, 0x001E, NEUTRAL_B },
182 { 0x001F, 0x0000, NEUTRAL_S },
183 { 0x0020, 0x0000, NEUTRAL_WS },
184 { 0x0021, 0x0022, NEUTRAL_ON },
185 { 0x0023, 0x0025, WEAK_ET },
186 { 0x0026, 0x002A, NEUTRAL_ON },
187 { 0x002B, 0x0000, WEAK_ET },
188 { 0x002C, 0x0000, WEAK_CS },
189 { 0x002D, 0x0000, WEAK_ET },
190 { 0x002E, 0x0000, WEAK_CS },
191 { 0x002F, 0x0000, WEAK_ES },
192 { 0x0030, 0x0039, WEAK_EN },
193 { 0x003A, 0x0000, WEAK_CS },
194 { 0x003B, 0x0040, NEUTRAL_ON },
195 { 0x005B, 0x0060, NEUTRAL_ON },
196 { 0x007B, 0x007E, NEUTRAL_ON },
197 { 0x007F, 0x0084, WEAK_BN },
198 { 0x0085, 0x0000, NEUTRAL_B },
199 { 0x0086, 0x009F, WEAK_BN },
200 { 0x00A0, 0x0000, WEAK_CS },
201 { 0x00A1, 0x0000, NEUTRAL_ON },
202 { 0x00A2, 0x00A5, WEAK_ET },
203 { 0x00A6, 0x00A9, NEUTRAL_ON },
204 { 0x00AB, 0x00AF, NEUTRAL_ON },
205 { 0x00B0, 0x00B1, WEAK_ET },
206 { 0x00B2, 0x00B3, WEAK_EN },
207 { 0x00B4, 0x0000, NEUTRAL_ON },
208 { 0x00B6, 0x00B8, NEUTRAL_ON },
209 { 0x00B9, 0x0000, WEAK_EN },
210 { 0x00BB, 0x00BF, NEUTRAL_ON },
211 { 0x00D7, 0x0000, NEUTRAL_ON },
212 { 0x00F7, 0x0000, NEUTRAL_ON },
213 { 0x02B9, 0x02BA, NEUTRAL_ON },
214 { 0x02C2, 0x02CF, NEUTRAL_ON },
215 { 0x02D2, 0x02DF, NEUTRAL_ON },
216 { 0x02E5, 0x02ED, NEUTRAL_ON },
217 { 0x0300, 0x036F, WEAK_NSM },
218 { 0x0374, 0x0375, NEUTRAL_ON },
219 { 0x037E, 0x0385, NEUTRAL_ON },
220 { 0x0387, 0x0000, NEUTRAL_ON },
221 { 0x03F6, 0x0000, NEUTRAL_ON },
222 { 0x0483, 0x0489, WEAK_NSM },
223 { 0x058A, 0x0000, NEUTRAL_ON },
224 { 0x0591, 0x05BD, WEAK_NSM },
225 { 0x05BE, 0x0000, STRONG_R },
226 { 0x05BF, 0x0000, WEAK_NSM },
227 { 0x05C0, 0x0000, STRONG_R },
228 { 0x05C1, 0x05C2, WEAK_NSM },
229 { 0x05C3, 0x0000, STRONG_R },
230 { 0x05C4, 0x0000, WEAK_NSM },
231 { 0x05D0, 0x05F4, STRONG_R },
232 { 0x060C, 0x0000, WEAK_CS },
233 { 0x061B, 0x064A, STRONG_AL },
234 { 0x064B, 0x0655, WEAK_NSM },
235 { 0x0660, 0x0669, WEAK_AN },
236 { 0x066A, 0x0000, WEAK_ET },
237 { 0x066B, 0x066C, WEAK_AN },
238 { 0x066D, 0x066F, STRONG_AL },
239 { 0x0670, 0x0000, WEAK_NSM },
240 { 0x0671, 0x06D5, STRONG_AL },
241 { 0x06D6, 0x06DC, WEAK_NSM },
242 { 0x06DD, 0x0000, STRONG_AL },
243 { 0x06DE, 0x06E4, WEAK_NSM },
244 { 0x06E5, 0x06E6, STRONG_AL },
245 { 0x06E7, 0x06E8, WEAK_NSM },
246 { 0x06E9, 0x0000, NEUTRAL_ON },
247 { 0x06EA, 0x06ED, WEAK_NSM },
248 { 0x06F0, 0x06F9, WEAK_EN },
249 { 0x06FA, 0x070D, STRONG_AL },
250 { 0x070F, 0x0000, WEAK_BN },
251 { 0x0710, 0x0000, STRONG_AL },
252 { 0x0711, 0x0000, WEAK_NSM },
253 { 0x0712, 0x072C, STRONG_AL },
254 { 0x0730, 0x074A, WEAK_NSM },
255 { 0x0780, 0x07A5, STRONG_AL },
256 { 0x07A6, 0x07B0, WEAK_NSM },
257 { 0x07B1, 0x0000, STRONG_AL },
258 { 0x0901, 0x0902, WEAK_NSM },
259 { 0x093C, 0x0000, WEAK_NSM },
260 { 0x0941, 0x0948, WEAK_NSM },
261 { 0x094D, 0x0000, WEAK_NSM },
262 { 0x0951, 0x0954, WEAK_NSM },
263 { 0x0962, 0x0963, WEAK_NSM },
264 { 0x0981, 0x0000, WEAK_NSM },
265 { 0x09BC, 0x0000, WEAK_NSM },
266 { 0x09C1, 0x09C4, WEAK_NSM },
267 { 0x09CD, 0x0000, WEAK_NSM },
268 { 0x09E2, 0x09E3, WEAK_NSM },
269 { 0x09F2, 0x09F3, WEAK_ET },
270 { 0x0A02, 0x0000, WEAK_NSM },
271 { 0x0A3C, 0x0000, WEAK_NSM },
272 { 0x0A41, 0x0A4D, WEAK_NSM },
273 { 0x0A70, 0x0A71, WEAK_NSM },
274 { 0x0A81, 0x0A82, WEAK_NSM },
275 { 0x0ABC, 0x0000, WEAK_NSM },
276 { 0x0AC1, 0x0AC8, WEAK_NSM },
277 { 0x0ACD, 0x0000, WEAK_NSM },
278 { 0x0B01, 0x0000, WEAK_NSM },
279 { 0x0B3C, 0x0000, WEAK_NSM },
280 { 0x0B3F, 0x0000, WEAK_NSM },
281 { 0x0B41, 0x0B43, WEAK_NSM },
282 { 0x0B4D, 0x0B56, WEAK_NSM },
283 { 0x0B82, 0x0000, WEAK_NSM },
284 { 0x0BC0, 0x0000, WEAK_NSM },
285 { 0x0BCD, 0x0000, WEAK_NSM },
286 { 0x0C3E, 0x0C40, WEAK_NSM },
287 { 0x0C46, 0x0C56, WEAK_NSM },
288 { 0x0CBF, 0x0000, WEAK_NSM },
289 { 0x0CC6, 0x0000, WEAK_NSM },
290 { 0x0CCC, 0x0CCD, WEAK_NSM },
291 { 0x0D41, 0x0D43, WEAK_NSM },
292 { 0x0D4D, 0x0000, WEAK_NSM },
293 { 0x0DCA, 0x0000, WEAK_NSM },
294 { 0x0DD2, 0x0DD6, WEAK_NSM },
295 { 0x0E31, 0x0000, WEAK_NSM },
296 { 0x0E34, 0x0E3A, WEAK_NSM },
297 { 0x0E3F, 0x0000, WEAK_ET },
298 { 0x0E47, 0x0E4E, WEAK_NSM },
299 { 0x0EB1, 0x0000, WEAK_NSM },
300 { 0x0EB4, 0x0EBC, WEAK_NSM },
301 { 0x0EC8, 0x0ECD, WEAK_NSM },
302 { 0x0F18, 0x0F19, WEAK_NSM },
303 { 0x0F35, 0x0000, WEAK_NSM },
304 { 0x0F37, 0x0000, WEAK_NSM },
305 { 0x0F39, 0x0000, WEAK_NSM },
306 { 0x0F3A, 0x0F3D, NEUTRAL_ON },
307 { 0x0F71, 0x0F7E, WEAK_NSM },
308 { 0x0F80, 0x0F84, WEAK_NSM },
309 { 0x0F86, 0x0F87, WEAK_NSM },
310 { 0x0F90, 0x0FBC, WEAK_NSM },
311 { 0x0FC6, 0x0000, WEAK_NSM },
312 { 0x102D, 0x1030, WEAK_NSM },
313 { 0x1032, 0x1037, WEAK_NSM },
314 { 0x1039, 0x0000, WEAK_NSM },
315 { 0x1058, 0x1059, WEAK_NSM },
316 { 0x1680, 0x0000, NEUTRAL_WS },
317 { 0x169B, 0x169C, NEUTRAL_ON },
318 { 0x1712, 0x1714, WEAK_NSM },
319 { 0x1732, 0x1734, WEAK_NSM },
320 { 0x1752, 0x1753, WEAK_NSM },
321 { 0x1772, 0x1773, WEAK_NSM },
322 { 0x17B7, 0x17BD, WEAK_NSM },
323 { 0x17C6, 0x0000, WEAK_NSM },
324 { 0x17C9, 0x17D3, WEAK_NSM },
325 { 0x17DB, 0x0000, WEAK_ET },
326 { 0x1800, 0x180A, NEUTRAL_ON },
327 { 0x180B, 0x180D, WEAK_NSM },
328 { 0x180E, 0x0000, WEAK_BN },
329 { 0x18A9, 0x0000, WEAK_NSM },
330 { 0x1FBD, 0x0000, NEUTRAL_ON },
331 { 0x1FBF, 0x1FC1, NEUTRAL_ON },
332 { 0x1FCD, 0x1FCF, NEUTRAL_ON },
333 { 0x1FDD, 0x1FDF, NEUTRAL_ON },
334 { 0x1FED, 0x1FEF, NEUTRAL_ON },
335 { 0x1FFD, 0x1FFE, NEUTRAL_ON },
336 { 0x2000, 0x200A, NEUTRAL_WS },
337 { 0x200B, 0x200D, WEAK_BN },
338 { 0x200F, 0x0000, STRONG_R },
339 { 0x2010, 0x2027, NEUTRAL_ON },
340 { 0x2028, 0x0000, NEUTRAL_WS },
341 { 0x2029, 0x0000, NEUTRAL_B },
342 { 0x202A, 0x0000, LRE },
343 { 0x202B, 0x0000, RLE },
344 { 0x202C, 0x0000, PDF },
345 { 0x202D, 0x0000, LRO },
346 { 0x202E, 0x0000, RLO },
347 { 0x202F, 0x0000, NEUTRAL_WS },
348 { 0x2030, 0x2034, WEAK_ET },
349 { 0x2035, 0x2057, NEUTRAL_ON },
350 { 0x205F, 0x0000, NEUTRAL_WS },
351 { 0x2060, 0x206F, WEAK_BN },
352 { 0x2070, 0x0000, WEAK_EN },
353 { 0x2074, 0x2079, WEAK_EN },
354 { 0x207A, 0x207B, WEAK_ET },
355 { 0x207C, 0x207E, NEUTRAL_ON },
356 { 0x2080, 0x2089, WEAK_EN },
357 { 0x208A, 0x208B, WEAK_ET },
358 { 0x208C, 0x208E, NEUTRAL_ON },
359 { 0x20A0, 0x20B1, WEAK_ET },
360 { 0x20D0, 0x20EA, WEAK_NSM },
361 { 0x2100, 0x2101, NEUTRAL_ON },
362 { 0x2103, 0x2106, NEUTRAL_ON },
363 { 0x2108, 0x2109, NEUTRAL_ON },
364 { 0x2114, 0x0000, NEUTRAL_ON },
365 { 0x2116, 0x2118, NEUTRAL_ON },
366 { 0x211E, 0x2123, NEUTRAL_ON },
367 { 0x2125, 0x0000, NEUTRAL_ON },
368 { 0x2127, 0x0000, NEUTRAL_ON },
369 { 0x2129, 0x0000, NEUTRAL_ON },
370 { 0x212E, 0x0000, WEAK_ET },
371 { 0x2132, 0x0000, NEUTRAL_ON },
372 { 0x213A, 0x0000, NEUTRAL_ON },
373 { 0x2140, 0x2144, NEUTRAL_ON },
374 { 0x214A, 0x215F, NEUTRAL_ON },
375 { 0x2190, 0x2211, NEUTRAL_ON },
376 { 0x2212, 0x2213, WEAK_ET },
377 { 0x2214, 0x2335, NEUTRAL_ON },
378 { 0x237B, 0x2394, NEUTRAL_ON },
379 { 0x2396, 0x244A, NEUTRAL_ON },
380 { 0x2460, 0x249B, WEAK_EN },
381 { 0x24EA, 0x0000, WEAK_EN },
382 { 0x24EB, 0x2FFB, NEUTRAL_ON },
383 { 0x3000, 0x0000, NEUTRAL_WS },
384 { 0x3001, 0x3004, NEUTRAL_ON },
385 { 0x3008, 0x3020, NEUTRAL_ON },
386 { 0x302A, 0x302F, WEAK_NSM },
387 { 0x3030, 0x0000, NEUTRAL_ON },
388 { 0x3036, 0x3037, NEUTRAL_ON },
389 { 0x303D, 0x303F, NEUTRAL_ON },
390 { 0x3099, 0x309A, WEAK_NSM },
391 { 0x309B, 0x309C, NEUTRAL_ON },
392 { 0x30A0, 0x0000, NEUTRAL_ON },
393 { 0x30FB, 0x0000, NEUTRAL_ON },
394 { 0x3251, 0x325F, NEUTRAL_ON },
395 { 0x32B1, 0x32BF, NEUTRAL_ON },
396 { 0xA490, 0xA4C6, NEUTRAL_ON },
397 { 0xFB1D, 0x0000, STRONG_R },
398 { 0xFB1E, 0x0000, WEAK_NSM },
399 { 0xFB1F, 0xFB28, STRONG_R },
400 { 0xFB29, 0x0000, WEAK_ET },
401 { 0xFB2A, 0xFB4F, STRONG_R },
402 { 0xFB50, 0xFD3D, STRONG_AL },
403 { 0xFD3E, 0xFD3F, NEUTRAL_ON },
404 { 0xFD50, 0xFDFC, STRONG_AL },
405 { 0xFE00, 0xFE23, WEAK_NSM },
406 { 0xFE30, 0xFE4F, NEUTRAL_ON },
407 { 0xFE50, 0x0000, WEAK_CS },
408 { 0xFE51, 0x0000, NEUTRAL_ON },
409 { 0xFE52, 0x0000, WEAK_CS },
410 { 0xFE54, 0x0000, NEUTRAL_ON },
411 { 0xFE55, 0x0000, WEAK_CS },
412 { 0xFE56, 0xFE5E, NEUTRAL_ON },
413 { 0xFE5F, 0x0000, WEAK_ET },
414 { 0xFE60, 0xFE61, NEUTRAL_ON },
415 { 0xFE62, 0xFE63, WEAK_ET },
416 { 0xFE64, 0xFE68, NEUTRAL_ON },
417 { 0xFE69, 0xFE6A, WEAK_ET },
418 { 0xFE6B, 0x0000, NEUTRAL_ON },
419 { 0xFE70, 0xFEFC, STRONG_AL },
420 { 0xFEFF, 0x0000, WEAK_BN },
421 { 0xFF01, 0xFF02, NEUTRAL_ON },
422 { 0xFF03, 0xFF05, WEAK_ET },
423 { 0xFF06, 0xFF0A, NEUTRAL_ON },
424 { 0xFF0B, 0x0000, WEAK_ET },
425 { 0xFF0C, 0x0000, WEAK_CS },
426 { 0xFF0D, 0x0000, WEAK_ET },
427 { 0xFF0E, 0x0000, WEAK_CS },
428 { 0xFF0F, 0x0000, WEAK_ES },
429 { 0xFF10, 0xFF19, WEAK_EN },
430 { 0xFF1A, 0x0000, WEAK_CS },
431 { 0xFF1B, 0xFF20, NEUTRAL_ON },
432 { 0xFF3B, 0xFF40, NEUTRAL_ON },
433 { 0xFF5B, 0xFF65, NEUTRAL_ON },
434 { 0xFFE0, 0xFFE1, WEAK_ET },
435 { 0xFFE2, 0xFFE4, NEUTRAL_ON },
436 { 0xFFE5, 0xFFE6, WEAK_ET },
437 { 0xFFE8, 0xFFEE, NEUTRAL_ON },
438 { 0xFFF9, 0xFFFB, WEAK_BN },
439 { 0xFFFC, 0xFFFD, NEUTRAL_ON },
440 { 0x1D167, 0x1D169, WEAK_NSM },
441 { 0x1D173, 0x1D17A, WEAK_BN },
442 { 0x1D17B, 0x1D182, WEAK_NSM },
443 { 0x1D185, 0x1D18B, WEAK_NSM },
444 { 0x1D1AA, 0x1D1AD, WEAK_NSM },
445 { 0x1D7CE, 0x1D7FF, WEAK_EN },
446 { 0xE0001, 0xE007F, WEAK_BN } };
447 int i;
448
449 bidi_type_table = Fmake_char_table (Qnil, make_number (STRONG_L));
450
451 for (i = 0; i < sizeof bidi_type / sizeof bidi_type[0]; i++)
452 char_table_set_range (bidi_type_table, bidi_type[i].from,
453 bidi_type[i].to ? bidi_type[i].to : bidi_type[i].from,
454 make_number (bidi_type[i].type));
455 bidi_initialized = 1;
456 }
457
458 static int
459 bidi_is_arabic_number (int ch)
460 {
461 #ifdef TEST_STANDALONE
462 return ch >= '6' && ch <= '9';
463 #else
464 return 0; /* FIXME! */
465 #endif
466 }
467
468 /* Return the bidi type of a character CH. */
469 bidi_type_t
470 bidi_get_type (int ch)
471 {
472 return (bidi_type_t) XINT (CHAR_TABLE_REF (bidi_type_table, ch));
473 }
474
475 /* Given a bidi TYPE of a character, return its category. */
476 bidi_category_t
477 bidi_get_category (bidi_type_t type)
478 {
479 switch (type)
480 {
481 case UNKNOWN_BT:
482 return UNKNOWN_BC;
483 case STRONG_L:
484 case STRONG_R:
485 case STRONG_AL:
486 case LRE:
487 case LRO:
488 case RLE:
489 case RLO:
490 return STRONG;
491 case PDF: /* ??? really?? */
492 case WEAK_EN:
493 case WEAK_ES:
494 case WEAK_ET:
495 case WEAK_AN:
496 case WEAK_CS:
497 case WEAK_NSM:
498 case WEAK_BN:
499 return WEAK;
500 case NEUTRAL_B:
501 case NEUTRAL_S:
502 case NEUTRAL_WS:
503 case NEUTRAL_ON:
504 return NEUTRAL;
505 default:
506 abort ();
507 }
508 }
509
510 /* FIXME: exceedingly temporary! Should consult the Unicode database
511 of character properties. */
512 int
513 bidi_mirror_char (int c)
514 {
515 static const char mirrored_pairs[] = "()<>[]{}";
516 const char *p = strchr (mirrored_pairs, c);
517
518 if (p)
519 {
520 size_t i = p - mirrored_pairs;
521
522 if ((i & 1) == 0)
523 return mirrored_pairs[i + 1];
524 else
525 return mirrored_pairs[i - 1];
526 }
527 return c;
528 }
529
530 /* Copy the bidi iterator from FROM to TO. To save cycles, this only
531 copies the part of the level stack that is actually in use. */
532 static inline void
533 bidi_copy_it (struct bidi_it *to, struct bidi_it *from)
534 {
535 int i;
536
537 /* Copy everything except the level stack. */
538 memcpy (to, from, ((int)&((struct bidi_it *)0)->level_stack[0]));
539
540 /* Copy the active part of the level stack. */
541 to->level_stack[0] = from->level_stack[0]; /* level zero is always in use */
542 for (i = 1; i <= from->stack_idx; i++)
543 to->level_stack[i] = from->level_stack[i];
544 }
545
546 /* Caching the bidi iterator states. */
547
548 static struct bidi_it bidi_cache[1000]; /* FIXME: make this dynamically allocated! */
549 static int bidi_cache_idx;
550 static int bidi_cache_last_idx;
551
552 static inline void
553 bidi_cache_reset (void)
554 {
555 bidi_cache_idx = 0;
556 bidi_cache_last_idx = -1;
557 }
558
559 static inline void
560 bidi_cache_fetch_state (int idx, struct bidi_it *bidi_it)
561 {
562 int current_scan_dir = bidi_it->scan_dir;
563
564 if (idx < 0 || idx >= bidi_cache_idx)
565 abort ();
566
567 bidi_copy_it (bidi_it, &bidi_cache[idx]);
568 bidi_it->scan_dir = current_scan_dir;
569 bidi_cache_last_idx = idx;
570 }
571
572 /* Find a cached state with a given CHARPOS and resolved embedding
573 level less or equal to LEVEL. if LEVEL is -1, disregard the
574 resolved levels in cached states. DIR, if non-zero, means search
575 in that direction from the last cache hit. */
576 static inline int
577 bidi_cache_search (int charpos, int level, int dir)
578 {
579 int i, i_start;
580
581 if (bidi_cache_idx)
582 {
583 if (charpos < bidi_cache[bidi_cache_last_idx].charpos)
584 dir = -1;
585 else if (charpos > bidi_cache[bidi_cache_last_idx].charpos)
586 dir = 1;
587 if (dir)
588 i_start = bidi_cache_last_idx;
589 else
590 {
591 dir = -1;
592 i_start = bidi_cache_idx - 1;
593 }
594
595 if (dir < 0)
596 {
597 /* Linear search for now; FIXME! */
598 for (i = i_start; i >= 0; i--)
599 if (bidi_cache[i].charpos == charpos
600 && (level == -1 || bidi_cache[i].resolved_level <= level))
601 return i;
602 }
603 else
604 {
605 for (i = i_start; i < bidi_cache_idx; i++)
606 if (bidi_cache[i].charpos == charpos
607 && (level == -1 || bidi_cache[i].resolved_level <= level))
608 return i;
609 }
610 }
611
612 return -1;
613 }
614
615 /* Find a cached state where the resolved level changes to a value
616 that is lower than LEVEL, and return its cache slot index. DIR is
617 the direction to search, starting with the last used cache slot.
618 BEFORE, if non-zero, means return the index of the slot that is
619 ``before'' the level change in the search direction. That is,
620 given the cached levels like this:
621
622 1122333442211
623 AB C
624
625 and assuming we are at the position cached at the slot marked with
626 C, searching backwards (DIR = -1) for LEVEL = 2 will return the
627 index of slot B or A, depending whether BEFORE is, respectively,
628 non-zero or zero. */
629 static int
630 bidi_cache_find_level_change (int level, int dir, int before)
631 {
632 if (bidi_cache_idx)
633 {
634 int i = dir ? bidi_cache_last_idx : bidi_cache_idx - 1;
635 int incr = before ? 1 : 0;
636
637 if (!dir)
638 dir = -1;
639 else if (!incr)
640 i += dir;
641
642 if (dir < 0)
643 {
644 while (i >= incr)
645 {
646 if (bidi_cache[i - incr].resolved_level >= 0
647 && bidi_cache[i - incr].resolved_level < level)
648 return i;
649 i--;
650 }
651 }
652 else
653 {
654 while (i < bidi_cache_idx - incr)
655 {
656 if (bidi_cache[i + incr].resolved_level >= 0
657 && bidi_cache[i + incr].resolved_level < level)
658 return i;
659 i++;
660 }
661 }
662 }
663
664 return -1;
665 }
666
667 static inline void
668 bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved)
669 {
670 int idx;
671
672 /* We should never cache on backward scans. */
673 if (bidi_it->scan_dir == -1)
674 abort ();
675 idx = bidi_cache_search (bidi_it->charpos, -1, 1);
676
677 if (idx < 0)
678 {
679 idx = bidi_cache_idx;
680 if (idx > sizeof (bidi_cache) / sizeof (bidi_cache[0]) - 1)
681 abort ();
682 bidi_copy_it (&bidi_cache[idx], bidi_it);
683 if (!resolved)
684 bidi_cache[idx].resolved_level = -1;
685 }
686 else
687 {
688 /* Copy only the members which could have changed, to avoid
689 costly copying of the entire struct. */
690 bidi_cache[idx].type = bidi_it->type;
691 bidi_cache[idx].orig_type = bidi_it->orig_type;
692 if (resolved)
693 bidi_cache[idx].resolved_level = bidi_it->resolved_level;
694 else
695 bidi_cache[idx].resolved_level = -1;
696 bidi_cache[idx].invalid_levels = bidi_it->invalid_levels;
697 bidi_cache[idx].invalid_rl_levels = bidi_it->invalid_rl_levels;
698 bidi_cache[idx].next_for_neutral = bidi_it->next_for_neutral;
699 bidi_cache[idx].next_for_ws = bidi_it->next_for_ws;
700 bidi_cache[idx].ignore_bn_limit = bidi_it->ignore_bn_limit;
701 }
702
703 bidi_cache_last_idx = idx;
704 if (idx >= bidi_cache_idx)
705 bidi_cache_idx = idx + 1;
706 }
707
708 static inline bidi_type_t
709 bidi_cache_find (int charpos, int level, struct bidi_it *bidi_it)
710 {
711 int i = bidi_cache_search (charpos, level, bidi_it->scan_dir);
712
713 if (i >= 0)
714 {
715 bidi_dir_t current_scan_dir = bidi_it->scan_dir;
716
717 *bidi_it = bidi_cache[i];
718 bidi_cache_last_idx = i;
719 /* Don't let scan direction from from the cached state override
720 the current scan direction. */
721 bidi_it->scan_dir = current_scan_dir;
722 return bidi_it->type;
723 }
724
725 return UNKNOWN_BT;
726 }
727
728 static inline int
729 bidi_peek_at_next_level (struct bidi_it *bidi_it)
730 {
731 if (bidi_cache_idx == 0 || bidi_cache_last_idx == -1)
732 abort ();
733 return bidi_cache[bidi_cache_last_idx + bidi_it->scan_dir].resolved_level;
734 }
735
736 /* Return non-zero if buffer's byte position POS is the last character
737 of a paragraph. THIS_CH is the character preceding the one at POS in
738 the buffer. */
739 int
740 bidi_at_paragraph_end (int this_ch, int pos)
741 {
742 int next_ch = FETCH_CHAR (pos);
743
744 /* FIXME: This should support all Unicode characters that can end a
745 paragraph. */
746 return (this_ch == '\n' && next_ch == '\n') || this_ch == BIDI_EOB;
747 }
748
749 /* Determine the start-of-run (sor) directional type given the two
750 embedding levels on either side of the run boundary. Also, update
751 the saved info about previously seen characters, since that info is
752 generally valid for a single level run. */
753 static inline void
754 bidi_set_sor_type (struct bidi_it *bidi_it, int level_before, int level_after)
755 {
756 int higher_level = level_before > level_after ? level_before : level_after;
757
758 /* The prev_was_pdf gork is required for when we have several PDFs
759 in a row. In that case, we want to compute the sor type for the
760 next level run only once: when we see the first PDF. That's
761 because the sor type depends only on the higher of the two levels
762 that we find on the two sides of the level boundary (see UAX#9,
763 clause X10), and so we don't need to know the final embedding
764 level to which we descend after processing all the PDFs. */
765 if (level_before < level_after || !bidi_it->prev_was_pdf)
766 /* FIXME: should the default sor direction be user selectable? */
767 bidi_it->sor = (higher_level & 1) != 0 ? R2L : L2R;
768 if (level_before > level_after)
769 bidi_it->prev_was_pdf = 1;
770
771 bidi_it->prev.type = UNKNOWN_BT;
772 bidi_it->last_strong.type = bidi_it->last_strong.orig_type =
773 bidi_it->last_strong.pristine_type = UNKNOWN_BT;
774 bidi_it->prev_for_neutral.type = bidi_it->sor == R2L ? STRONG_R : STRONG_L;
775 bidi_it->prev_for_neutral.charpos = bidi_it->charpos;
776 bidi_it->prev_for_neutral.bytepos = bidi_it->bytepos;
777 bidi_it->next_for_neutral.type = bidi_it->next_for_neutral.orig_type =
778 bidi_it->next_for_neutral.pristine_type = UNKNOWN_BT;
779 bidi_it->ignore_bn_limit = 0; /* meaning it's unknown */
780 }
781
782 void
783 bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it)
784 {
785 bidi_it->level_stack[0].level = 0;
786 if (dir == R2L)
787 bidi_it->level_stack[0].level = 1;
788 else if (dir == NEUTRAL_DIR) /* P2 */
789 {
790 bidi_type_t type;
791 int pos = bidi_it->charpos, bytepos = bidi_it->bytepos;
792 int ch;
793
794 if (pos < 0)
795 pos = bytepos = 0;
796 else if (bidi_it->ch != BIDI_EOB)
797 {
798 pos++;
799 bytepos += bidi_it->ch_len;
800 }
801
802 ch = FETCH_CHAR (bytepos);
803 pos++;
804 bytepos += CHAR_BYTES (ch);
805
806 /* FIXME: should actually go to where the paragraph begins and
807 start the loop below from there, since UAX#9 says to find the
808 first strong directional character in the paragraph. */
809
810 for (type = bidi_get_type (ch);
811 /* NOTE: UAX#9 says to search only for L, AL, or R types of
812 characters, and ignore RLE, RLO, LRE, and LRO. However,
813 I'm not sure it makes sense to omit those 4; should try
814 with and without that to see the effect. */
815 (bidi_get_category (type) != STRONG)
816 || (bidi_ignore_explicit_marks_for_paragraph_level
817 && (type == RLE || type == RLO
818 || type == LRE || type == LRO));
819 type = bidi_get_type (ch))
820 {
821 if (type == NEUTRAL_B || bidi_at_paragraph_end (ch, bytepos))
822 break;
823 FETCH_CHAR_ADVANCE (ch, pos, bytepos);
824 }
825 if (type == STRONG_R || type == STRONG_AL) /* P3 */
826 bidi_it->level_stack[0].level = 1;
827 }
828 bidi_it->scan_dir = 1; /* FIXME: do we need to have control on this? */
829 bidi_it->resolved_level = bidi_it->level_stack[0].level;
830 bidi_it->level_stack[0].override = NEUTRAL_DIR; /* X1 */
831 bidi_it->invalid_levels = 0;
832 bidi_it->invalid_rl_levels = -1;
833 bidi_it->new_paragraph = 0;
834 bidi_it->next_en_pos = -1;
835 bidi_it->next_for_ws.type = UNKNOWN_BT;
836 bidi_set_sor_type (bidi_it, bidi_it->level_stack[0].level, 0); /* X10 */
837
838 bidi_cache_reset ();
839 }
840
841 /* Do whatever UAX#9 clause X8 says should be done at paragraph's end,
842 and set the new paragraph flag in the iterator. */
843 static inline void
844 bidi_set_paragraph_end (struct bidi_it *bidi_it)
845 {
846 bidi_it->invalid_levels = 0;
847 bidi_it->invalid_rl_levels = -1;
848 bidi_it->stack_idx = 0;
849 bidi_it->resolved_level = bidi_it->level_stack[0].level;
850 bidi_it->new_paragraph = 1;
851 }
852
853 /* Initialize the bidi iterator from buffer position POS for paragraph
854 direction DIR. Return the embedding level at POS. */
855 void
856 bidi_init_it (int pos, bidi_dir_t dir, struct bidi_it *bidi_it)
857 {
858 if (! bidi_initialized)
859 bidi_initialize ();
860 bidi_set_paragraph_end (bidi_it);
861 bidi_it->charpos = pos;
862 if (pos <= 0)
863 {
864 bidi_it->bytepos = bidi_it->charpos;
865 bidi_it->ch_len = 1; /* so that incrementing bytepos works */
866 }
867 else
868 {
869 bidi_it->bytepos = CHAR_TO_BYTE (pos);
870 bidi_it->ch_len
871 = MULTIBYTE_FORM_LENGTH (BYTE_POS_ADDR (bidi_it->bytepos),
872 MAX_MULTIBYTE_LENGTH);
873 }
874 bidi_it->ch = '\x1d'; /* FIXME: should be U+2029 */
875 bidi_it->type = NEUTRAL_B;
876 bidi_it->orig_type = UNKNOWN_BT;
877 bidi_it->pristine_type = UNKNOWN_BT;
878 bidi_it->prev_was_pdf = 0;
879 bidi_it->prev.type = bidi_it->prev.orig_type = UNKNOWN_BT;
880 bidi_it->last_strong.type = bidi_it->last_strong.orig_type =
881 bidi_it->last_strong.pristine_type = UNKNOWN_BT;
882 bidi_it->next_for_neutral.charpos = -1;
883 bidi_it->next_for_neutral.type =
884 bidi_it->next_for_neutral.orig_type =
885 bidi_it->next_for_neutral.pristine_type = UNKNOWN_BT;
886 bidi_it->prev_for_neutral.charpos = -1;
887 bidi_it->prev_for_neutral.type =
888 bidi_it->prev_for_neutral.orig_type =
889 bidi_it->prev_for_neutral.pristine_type = UNKNOWN_BT;
890 bidi_it->sor = L2R; /* FIXME: should it be user-selectable? */
891 bidi_paragraph_init (dir, bidi_it);
892 }
893
894 /* Push the current embedding level and override status; reset the
895 current level to LEVEL and the current override status to OVERRIDE. */
896 static inline void
897 bidi_push_embedding_level (struct bidi_it *bidi_it,
898 int level, bidi_dir_t override)
899 {
900 bidi_it->stack_idx++;
901 if (bidi_it->stack_idx >= BIDI_MAXLEVEL)
902 abort ();
903 bidi_it->level_stack[bidi_it->stack_idx].level = level;
904 bidi_it->level_stack[bidi_it->stack_idx].override = override;
905 }
906
907 /* Pop the embedding level and directional override status from the
908 stack, and return the new level. */
909 static inline int
910 bidi_pop_embedding_level (struct bidi_it *bidi_it)
911 {
912 /* UAX#9 says to ignore invalid PDFs. */
913 if (bidi_it->stack_idx > 0)
914 bidi_it->stack_idx--;
915 return bidi_it->level_stack[bidi_it->stack_idx].level;
916 }
917
918 /* Record in SAVED_INFO the information about the current character. */
919 static inline void
920 bidi_remember_char (struct bidi_saved_info *saved_info,
921 struct bidi_it *bidi_it)
922 {
923 saved_info->charpos = bidi_it->charpos;
924 saved_info->bytepos = bidi_it->bytepos;
925 saved_info->type = bidi_it->type;
926 saved_info->orig_type = bidi_it->orig_type;
927 saved_info->pristine_type = bidi_it->pristine_type;
928 }
929
930 /* Resolve the type of a neutral character according to the type of
931 surrounding strong text and the current embedding level. */
932 static inline bidi_type_t
933 bidi_resolve_neutral_1 (bidi_type_t prev_type, bidi_type_t next_type, int lev)
934 {
935 /* N1: European and Arabic numbers are treated as though they were R. */
936 if (next_type == WEAK_EN || next_type == WEAK_AN)
937 next_type = STRONG_R;
938 if (prev_type == WEAK_EN || prev_type == WEAK_AN)
939 prev_type = STRONG_R;
940
941 if (next_type == prev_type) /* N1 */
942 return next_type;
943 else if ((lev & 1) == 0) /* N2 */
944 return STRONG_L;
945 else
946 return STRONG_R;
947 }
948
949 static inline int
950 bidi_explicit_dir_char (int c)
951 {
952 /* FIXME: this should be replaced with a lookup table with suitable
953 bits set, like standard C ctype macros do. */
954 return (c == LRE_CHAR || c == LRO_CHAR
955 || c == RLE_CHAR || c == RLO_CHAR || c == PDF_CHAR);
956 }
957
958 /* A helper function for bidi_resolve_explicit. It advances to the
959 next character in logical order and determines the new embedding
960 level and directional override, but does not take into account
961 empty embeddings. */
962 static int
963 bidi_resolve_explicit_1 (struct bidi_it *bidi_it)
964 {
965 int curchar;
966 bidi_type_t type;
967 int current_level;
968 int new_level;
969 bidi_dir_t override;
970
971 if (bidi_it->charpos < 0)
972 bidi_it->charpos = bidi_it->bytepos = 0;
973 else
974 {
975 bidi_it->charpos++;
976 bidi_it->bytepos += bidi_it->ch_len;
977 }
978
979 current_level = bidi_it->level_stack[bidi_it->stack_idx].level; /* X1 */
980 override = bidi_it->level_stack[bidi_it->stack_idx].override;
981 new_level = current_level;
982
983 /* in case it is a unibyte character (not yet implemented) */
984 /* _fetch_multibyte_char_len = 1; */
985 curchar = FETCH_CHAR (bidi_it->bytepos);
986 bidi_it->ch = curchar;
987 bidi_it->ch_len = CHAR_BYTES (curchar);
988
989 type = bidi_get_type (curchar);
990 bidi_it->pristine_type = type;
991
992 if (type != PDF)
993 bidi_it->prev_was_pdf = 0;
994
995 bidi_it->orig_type = UNKNOWN_BT;
996
997 switch (type)
998 {
999 case RLE: /* X2 */
1000 case RLO: /* X4 */
1001 bidi_it->orig_type = type;
1002 type = WEAK_BN; /* X9/Retaining */
1003 if (bidi_it->ignore_bn_limit <= 0)
1004 {
1005 if (current_level <= BIDI_MAXLEVEL - 4)
1006 {
1007 /* Compute the least odd embedding level greater than
1008 the current level. */
1009 new_level = ((current_level + 1) & ~1) + 1;
1010 if (bidi_it->orig_type == RLE)
1011 override = NEUTRAL_DIR;
1012 else
1013 override = R2L;
1014 if (current_level == BIDI_MAXLEVEL - 4)
1015 bidi_it->invalid_rl_levels = 0;
1016 bidi_push_embedding_level (bidi_it, new_level, override);
1017 }
1018 else
1019 {
1020 bidi_it->invalid_levels++;
1021 /* See the commentary about invalid_rl_levels below. */
1022 if (bidi_it->invalid_rl_levels < 0)
1023 bidi_it->invalid_rl_levels = 0;
1024 bidi_it->invalid_rl_levels++;
1025 }
1026 }
1027 else if (bidi_it->prev.orig_type == WEAK_EN /* W5/Retaining */
1028 || bidi_it->next_en_pos > bidi_it->charpos)
1029 type = WEAK_EN;
1030 break;
1031 case LRE: /* X3 */
1032 case LRO: /* X5 */
1033 bidi_it->orig_type = type;
1034 type = WEAK_BN; /* X9/Retaining */
1035 if (bidi_it->ignore_bn_limit <= 0)
1036 {
1037 if (current_level <= BIDI_MAXLEVEL - 5)
1038 {
1039 /* Compute the least even embedding level greater than
1040 the current level. */
1041 new_level = ((current_level + 2) & ~1);
1042 if (bidi_it->orig_type == LRE)
1043 override = NEUTRAL_DIR;
1044 else
1045 override = L2R;
1046 bidi_push_embedding_level (bidi_it, new_level, override);
1047 }
1048 else
1049 {
1050 bidi_it->invalid_levels++;
1051 /* invalid_rl_levels counts invalid levels encountered
1052 while the embedding level was already too high for
1053 LRE/LRO, but not for RLE/RLO. That is because
1054 there may be exactly one PDF which we should not
1055 ignore even though invalid_levels is non-zero.
1056 invalid_rl_levels helps to know what PDF is
1057 that. */
1058 if (bidi_it->invalid_rl_levels >= 0)
1059 bidi_it->invalid_rl_levels++;
1060 }
1061 }
1062 else if (bidi_it->prev.orig_type == WEAK_EN /* W5/Retaining */
1063 || bidi_it->next_en_pos > bidi_it->charpos)
1064 type = WEAK_EN;
1065 break;
1066 case PDF: /* X7 */
1067 bidi_it->orig_type = type;
1068 type = WEAK_BN; /* X9/Retaining */
1069 if (bidi_it->ignore_bn_limit <= 0)
1070 {
1071 if (!bidi_it->invalid_rl_levels)
1072 {
1073 new_level = bidi_pop_embedding_level (bidi_it);
1074 bidi_it->invalid_rl_levels = -1;
1075 if (bidi_it->invalid_levels)
1076 bidi_it->invalid_levels--;
1077 /* else nothing: UAX#9 says to ignore invalid PDFs */
1078 }
1079 if (!bidi_it->invalid_levels)
1080 new_level = bidi_pop_embedding_level (bidi_it);
1081 else
1082 {
1083 bidi_it->invalid_levels--;
1084 bidi_it->invalid_rl_levels--;
1085 }
1086 }
1087 else if (bidi_it->prev.orig_type == WEAK_EN /* W5/Retaining */
1088 || bidi_it->next_en_pos > bidi_it->charpos)
1089 type = WEAK_EN;
1090 break;
1091 default:
1092 /* Nothing. */
1093 break;
1094 }
1095
1096 bidi_it->type = type;
1097
1098 return new_level;
1099 }
1100
1101 /* Given an iterator state in BIDI_IT, advance one character position
1102 in the buffer to the next character (in the logical order), resolve
1103 any explicit embeddings and directional overrides, and return the
1104 embedding level of the character after resolving explicit
1105 directives and ignoring empty embeddings. */
1106 static int
1107 bidi_resolve_explicit (struct bidi_it *bidi_it)
1108 {
1109 int prev_level = bidi_it->level_stack[bidi_it->stack_idx].level;
1110 int new_level = bidi_resolve_explicit_1 (bidi_it);
1111
1112 if (prev_level < new_level
1113 && bidi_it->type == WEAK_BN
1114 && bidi_it->ignore_bn_limit == 0 /* only if not already known */
1115 && bidi_explicit_dir_char (FETCH_CHAR (bidi_it->bytepos
1116 + bidi_it->ch_len)))
1117 {
1118 /* Avoid pushing and popping embedding levels if the level run
1119 is empty, as this breaks level runs where it shouldn't.
1120 UAX#9 removes all the explicit embedding and override codes,
1121 so empty embeddings disappear without a trace. We need to
1122 behave as if we did the same. */
1123 struct bidi_it saved_it;
1124 int level = prev_level;
1125
1126 bidi_copy_it (&saved_it, bidi_it);
1127
1128 while (bidi_explicit_dir_char (FETCH_CHAR (bidi_it->bytepos
1129 + bidi_it->ch_len)))
1130 {
1131 level = bidi_resolve_explicit_1 (bidi_it);
1132 }
1133
1134 if (level == prev_level) /* empty embedding */
1135 saved_it.ignore_bn_limit = bidi_it->charpos + 1;
1136 else /* this embedding is non-empty */
1137 saved_it.ignore_bn_limit = -1;
1138
1139 bidi_copy_it (bidi_it, &saved_it);
1140 if (bidi_it->ignore_bn_limit > 0)
1141 {
1142 /* We pushed a level, but we shouldn't have. Undo that. */
1143 if (!bidi_it->invalid_rl_levels)
1144 {
1145 new_level = bidi_pop_embedding_level (bidi_it);
1146 bidi_it->invalid_rl_levels = -1;
1147 if (bidi_it->invalid_levels)
1148 bidi_it->invalid_levels--;
1149 }
1150 if (!bidi_it->invalid_levels)
1151 new_level = bidi_pop_embedding_level (bidi_it);
1152 else
1153 {
1154 bidi_it->invalid_levels--;
1155 bidi_it->invalid_rl_levels--;
1156 }
1157 }
1158 }
1159
1160 /* For when the paragraph end is defined by anything other than a
1161 special Unicode character (a.k.a. ``higher protocols''). */
1162 if (bidi_it->type != NEUTRAL_B)
1163 if (bidi_at_paragraph_end (bidi_it->ch,
1164 bidi_it->bytepos + bidi_it->ch_len))
1165 bidi_it->type = NEUTRAL_B;
1166
1167 if (bidi_it->type == NEUTRAL_B) /* X8 */
1168 {
1169 bidi_set_paragraph_end (bidi_it);
1170 bidi_it->orig_type = bidi_it->type; /* needed below and in L1 */
1171 }
1172
1173 return new_level;
1174 }
1175
1176 /* Advance in the buffer, resolve weak types and return the type of
1177 the next character after weak type resolution. */
1178 bidi_type_t
1179 bidi_resolve_weak (struct bidi_it *bidi_it)
1180 {
1181 bidi_type_t type;
1182 bidi_dir_t override;
1183 int prev_level = bidi_it->level_stack[bidi_it->stack_idx].level;
1184 int new_level = bidi_resolve_explicit (bidi_it);
1185 int next_char;
1186 bidi_type_t type_of_next;
1187 struct bidi_it saved_it;
1188
1189 type = bidi_it->type;
1190 override = bidi_it->level_stack[bidi_it->stack_idx].override;
1191
1192 if (type == UNKNOWN_BT
1193 || type == LRE
1194 || type == LRO
1195 || type == RLE
1196 || type == RLO
1197 || type == PDF)
1198 abort ();
1199
1200 if (new_level != prev_level
1201 || bidi_it->type == NEUTRAL_B)
1202 {
1203 /* We've got a new embedding level run, compute the directional
1204 type of sor and initialize per-run variables (UAX#9, clause
1205 X10). */
1206 bidi_set_sor_type (bidi_it, prev_level, new_level);
1207 }
1208 else if (type == NEUTRAL_S || type == NEUTRAL_WS
1209 || type == WEAK_BN || type == STRONG_AL)
1210 bidi_it->orig_type = type; /* needed in L1 */
1211
1212 /* Level and directional override status are already recorded in
1213 bidi_it, and do not need any change; see X6. */
1214 if (override == R2L) /* X6 */
1215 type = STRONG_R;
1216 else if (override == L2R)
1217 type = STRONG_L;
1218 else if (type == STRONG_AL)
1219 type = STRONG_R; /* W3 */
1220 else if (type == WEAK_NSM) /* W1 */
1221 {
1222 /* Note that we don't need to consider the case where the prev
1223 character has its type overridden by an RLO or LRO: such
1224 characters are outside the current level run, and thus not
1225 relevant to this NSM. Thus, NSM gets the pristine_type of
1226 the previous character. */
1227 if (bidi_it->prev.type != UNKNOWN_BT)
1228 type = bidi_it->prev.pristine_type;
1229 else if (bidi_it->sor == R2L)
1230 type = STRONG_R;
1231 else if (bidi_it->sor == L2R)
1232 type = STRONG_L;
1233 else /* shouldn't happen! */
1234 abort ();
1235 if (type == WEAK_EN /* W2 after W1 */
1236 && bidi_it->last_strong.orig_type == STRONG_AL)
1237 type = WEAK_AN;
1238 }
1239 else if (type == WEAK_EN /* W2 */
1240 && bidi_it->last_strong.orig_type == STRONG_AL)
1241 type = WEAK_AN;
1242 else if ((type == WEAK_ES
1243 && (bidi_it->prev.orig_type == WEAK_EN /* W4 */
1244 && (bidi_it->prev.pristine_type == WEAK_EN
1245 || bidi_it->prev.pristine_type == WEAK_NSM))) /* aft W1 */
1246 || (type == WEAK_CS
1247 && ((bidi_it->prev.orig_type == WEAK_EN
1248 && (bidi_it->prev.pristine_type == WEAK_EN /* W4 */
1249 || bidi_it->prev.pristine_type == WEAK_NSM)) /* a/W1 */
1250 || bidi_it->prev.orig_type == WEAK_AN))) /* W4 */
1251 {
1252 next_char = FETCH_CHAR (bidi_it->bytepos + bidi_it->ch_len);
1253 type_of_next = bidi_get_type (next_char);
1254
1255 if (type_of_next == WEAK_BN
1256 || bidi_explicit_dir_char (next_char))
1257 {
1258 bidi_copy_it (&saved_it, bidi_it);
1259 while (bidi_resolve_explicit (bidi_it) == new_level
1260 && bidi_it->type == WEAK_BN)
1261 ;
1262 type_of_next = bidi_it->type;
1263 bidi_copy_it (bidi_it, &saved_it);
1264 }
1265
1266 /* If the next character is EN, but the last strong-type
1267 character is AL, that next EN will be changed to AN when we
1268 process it in W2 above. So in that case, this ES should not
1269 be changed into EN. */
1270 if (type == WEAK_ES
1271 && type_of_next == WEAK_EN
1272 && bidi_it->last_strong.orig_type != STRONG_AL)
1273 type = WEAK_EN;
1274 else if (type == WEAK_CS)
1275 {
1276 if (bidi_it->prev.orig_type == WEAK_AN
1277 && (type_of_next == WEAK_AN
1278 /* If the next character is EN, but the last
1279 strong-type character is AL, EN will be later
1280 changed to AN when we process it in W2 above. So
1281 in that case, this ES should not be changed into
1282 EN. */
1283 || (type_of_next == WEAK_EN
1284 && bidi_it->last_strong.orig_type == STRONG_AL)))
1285 type = WEAK_AN;
1286 else if (bidi_it->prev.orig_type == WEAK_EN
1287 && type_of_next == WEAK_EN
1288 && bidi_it->last_strong.orig_type != STRONG_AL)
1289 type = WEAK_EN;
1290 }
1291 }
1292 else if (type == WEAK_ET /* W5: ET with EN before or after it */
1293 || type == WEAK_BN) /* W5/Retaining */
1294 {
1295 if (bidi_it->prev.orig_type == WEAK_EN /* ET/BN with EN before it */
1296 || bidi_it->next_en_pos > bidi_it->charpos)
1297 type = WEAK_EN;
1298 /* W5: ET with EN after it. */
1299 else
1300 {
1301 int en_pos = bidi_it->charpos + 1;
1302
1303 next_char = FETCH_CHAR (bidi_it->bytepos + bidi_it->ch_len);
1304 type_of_next = bidi_get_type (next_char);
1305
1306 if (type_of_next == WEAK_ET
1307 || type_of_next == WEAK_BN
1308 || bidi_explicit_dir_char (next_char))
1309 {
1310 bidi_copy_it (&saved_it, bidi_it);
1311 while (bidi_resolve_explicit (bidi_it) == new_level
1312 && (bidi_it->type == WEAK_BN || bidi_it->type == WEAK_ET))
1313 ;
1314 type_of_next = bidi_it->type;
1315 en_pos = bidi_it->charpos;
1316 bidi_copy_it (bidi_it, &saved_it);
1317 }
1318 if (type_of_next == WEAK_EN)
1319 {
1320 /* If the last strong character is AL, the EN we've
1321 found will become AN when we get to it (W2). */
1322 if (bidi_it->last_strong.orig_type != STRONG_AL)
1323 {
1324 type = WEAK_EN;
1325 /* Remember this EN position, to speed up processing
1326 of the next ETs. */
1327 bidi_it->next_en_pos = en_pos;
1328 }
1329 else if (type == WEAK_BN)
1330 type = NEUTRAL_ON; /* W6/Retaining */
1331 }
1332 }
1333 }
1334
1335 if (type == WEAK_ES || type == WEAK_ET || type == WEAK_CS /* W6 */
1336 || (type == WEAK_BN && (bidi_it->prev.orig_type == WEAK_CS /* W6/Ret. */
1337 || bidi_it->prev.orig_type == WEAK_ES
1338 || bidi_it->prev.orig_type == WEAK_ET)))
1339 type = NEUTRAL_ON;
1340
1341 /* Store the type we've got so far, before we clobber it with strong
1342 types in W7 and while resolving neutral types. But leave alone
1343 the original types that were recorded above, because we will need
1344 them for the L1 clause. */
1345 if (bidi_it->orig_type == UNKNOWN_BT)
1346 bidi_it->orig_type = type;
1347
1348 if (type == WEAK_EN) /* W7 */
1349 {
1350 if ((bidi_it->last_strong.orig_type == STRONG_L)
1351 || (bidi_it->last_strong.type == UNKNOWN_BT && bidi_it->sor == L2R))
1352 type = STRONG_L;
1353 }
1354
1355 bidi_it->type = type;
1356 return type;
1357 }
1358
1359 bidi_type_t
1360 bidi_resolve_neutral (struct bidi_it *bidi_it)
1361 {
1362 int prev_level = bidi_it->level_stack[bidi_it->stack_idx].level;
1363 bidi_type_t type = bidi_resolve_weak (bidi_it);
1364 int current_level = bidi_it->level_stack[bidi_it->stack_idx].level;
1365
1366 if (!(type == STRONG_R
1367 || type == STRONG_L
1368 || type == WEAK_BN
1369 || type == WEAK_EN
1370 || type == WEAK_AN
1371 || type == NEUTRAL_B
1372 || type == NEUTRAL_S
1373 || type == NEUTRAL_WS
1374 || type == NEUTRAL_ON))
1375 abort ();
1376
1377 if (bidi_get_category (type) == NEUTRAL
1378 || (type == WEAK_BN && prev_level == current_level))
1379 {
1380 if (bidi_it->next_for_neutral.type != UNKNOWN_BT)
1381 type = bidi_resolve_neutral_1 (bidi_it->prev_for_neutral.type,
1382 bidi_it->next_for_neutral.type,
1383 current_level);
1384 else
1385 {
1386 /* Arrrgh!! The UAX#9 algorithm is too deeply entrenched in
1387 the assumption of batch-style processing; see clauses W4,
1388 W5, and especially N1, which require to look far forward
1389 (as well as back) in the buffer. May the fleas of a
1390 thousand camels infest the armpits of those who design
1391 supposedly general-purpose algorithms by looking at their
1392 own implementations, and fail to consider other possible
1393 implementations! */
1394 struct bidi_it saved_it;
1395 bidi_type_t next_type;
1396
1397 if (bidi_it->scan_dir == -1)
1398 abort ();
1399
1400 bidi_copy_it (&saved_it, bidi_it);
1401 /* Scan the text forward until we find the first non-neutral
1402 character, and then use that to resolve the neutral we
1403 are dealing with now. We also cache the scanned iterator
1404 states, to salvage some of the effort later. */
1405 bidi_cache_iterator_state (bidi_it, 0);
1406 do {
1407 /* Record the info about the previous character, so that
1408 it will be cached below with this state. */
1409 if (bidi_it->orig_type != WEAK_BN /* W1/Retaining */
1410 && bidi_it->type != WEAK_BN)
1411 bidi_remember_char (&bidi_it->prev, bidi_it);
1412 type = bidi_resolve_weak (bidi_it);
1413 /* Paragraph separators have their levels fully resolved
1414 at this point, so cache them as resolved. */
1415 bidi_cache_iterator_state (bidi_it, type == NEUTRAL_B);
1416 /* FIXME: implement L1 here, by testing for a newline and
1417 resetting the level for any sequence of whitespace
1418 characters adjacent to it. */
1419 } while (!(type == NEUTRAL_B
1420 || (type != WEAK_BN
1421 && bidi_get_category (type) != NEUTRAL)
1422 /* This is all per level run, so stop when we
1423 reach the end of this level run. */
1424 || bidi_it->level_stack[bidi_it->stack_idx].level !=
1425 current_level));
1426
1427 bidi_remember_char (&saved_it.next_for_neutral, bidi_it);
1428
1429 switch (type)
1430 {
1431 case STRONG_L:
1432 case STRONG_R:
1433 case STRONG_AL:
1434 next_type = type;
1435 break;
1436 case WEAK_EN:
1437 case WEAK_AN:
1438 /* N1: ``European and Arabic numbers are treated as
1439 though they were R.'' */
1440 next_type = STRONG_R;
1441 saved_it.next_for_neutral.type = STRONG_R;
1442 break;
1443 case WEAK_BN:
1444 if (!bidi_explicit_dir_char (bidi_it->ch))
1445 abort (); /* can't happen: BNs are skipped */
1446 /* FALLTHROUGH */
1447 case NEUTRAL_B:
1448 /* Marched all the way to the end of this level run.
1449 We need to use the eor type, whose information is
1450 stored by bidi_set_sor_type in the prev_for_neutral
1451 member. */
1452 if (saved_it.type != WEAK_BN
1453 || bidi_get_category (bidi_it->prev.orig_type) == NEUTRAL)
1454 {
1455 next_type = bidi_it->prev_for_neutral.type;
1456 saved_it.next_for_neutral.type = next_type;
1457 }
1458 else
1459 {
1460 /* This is a BN which does not adjoin neutrals.
1461 Leave its type alone. */
1462 bidi_copy_it (bidi_it, &saved_it);
1463 return bidi_it->type;
1464 }
1465 break;
1466 default:
1467 abort ();
1468 }
1469 type = bidi_resolve_neutral_1 (saved_it.prev_for_neutral.type,
1470 next_type, current_level);
1471 saved_it.type = type;
1472 bidi_copy_it (bidi_it, &saved_it);
1473 }
1474 }
1475 return type;
1476 }
1477
1478 /* Given an iterator state in BIDI_IT, advance one character position
1479 in the buffer to the next character (in the logical order), resolve
1480 the bidi type of that next character, and return that type. */
1481 bidi_type_t
1482 bidi_type_of_next_char (struct bidi_it *bidi_it)
1483 {
1484 bidi_type_t type;
1485
1486 /* This should always be called during a forward scan. */
1487 if (bidi_it->scan_dir != 1)
1488 abort ();
1489
1490 /* Reset the limit until which to ignore BNs if we step out of the
1491 area where we found only empty levels. */
1492 if ((bidi_it->ignore_bn_limit > 0
1493 && bidi_it->ignore_bn_limit <= bidi_it->charpos)
1494 || (bidi_it->ignore_bn_limit == -1
1495 && !bidi_explicit_dir_char (bidi_it->ch)))
1496 bidi_it->ignore_bn_limit = 0;
1497
1498 type = bidi_resolve_neutral (bidi_it);
1499
1500 return type;
1501 }
1502
1503 /* Given an iterator state BIDI_IT, advance one character position in
1504 the buffer to the next character (in the logical order), resolve
1505 the embedding and implicit levels of that next character, and
1506 return the resulting level. */
1507 int
1508 bidi_level_of_next_char (struct bidi_it *bidi_it)
1509 {
1510 bidi_type_t type;
1511 int level, prev_level = -1;
1512 struct bidi_saved_info next_for_neutral;
1513
1514 if (bidi_it->scan_dir == 1)
1515 {
1516 /* There's no sense in trying to advance if we hit end of text. */
1517 if (bidi_it->ch == BIDI_EOB)
1518 return bidi_it->resolved_level;
1519
1520 /* Record the info about the previous character. */
1521 if (bidi_it->orig_type != WEAK_BN /* W1/Retaining */
1522 && bidi_it->type != WEAK_BN)
1523 bidi_remember_char (&bidi_it->prev, bidi_it);
1524 if (bidi_it->orig_type == STRONG_R || bidi_it->orig_type == STRONG_L
1525 || bidi_it->orig_type == STRONG_AL)
1526 bidi_remember_char (&bidi_it->last_strong, bidi_it);
1527 /* FIXME: it sounds like we don't need both prev and
1528 prev_for_neutral members, but I'm leaving them both for now. */
1529 if (bidi_it->type == STRONG_R || bidi_it->type == STRONG_L
1530 || bidi_it->type == WEAK_EN || bidi_it->type == WEAK_AN)
1531 bidi_remember_char (&bidi_it->prev_for_neutral, bidi_it);
1532
1533 /* If we overstepped the characters used for resolving neutrals
1534 and whitespace, invalidate their info in the iterator. */
1535 if (bidi_it->charpos >= bidi_it->next_for_neutral.charpos)
1536 bidi_it->next_for_neutral.type = UNKNOWN_BT;
1537 if (bidi_it->next_en_pos >= 0
1538 && bidi_it->charpos >= bidi_it->next_en_pos)
1539 bidi_it->next_en_pos = -1;
1540 if (bidi_it->next_for_ws.type != UNKNOWN_BT
1541 && bidi_it->charpos >= bidi_it->next_for_ws.charpos)
1542 bidi_it->next_for_ws.type = UNKNOWN_BT;
1543
1544 /* This must be taken before we fill the iterator with the info
1545 about the next char. If we scan backwards, the iterator
1546 state must be already cached, so there's no need to know the
1547 embedding level of the previous character, since we will be
1548 returning to our caller shortly. */
1549 prev_level = bidi_it->level_stack[bidi_it->stack_idx].level;
1550 }
1551 next_for_neutral = bidi_it->next_for_neutral;
1552
1553 /* Perhaps it is already cached. */
1554 type = bidi_cache_find (bidi_it->charpos + bidi_it->scan_dir, -1, bidi_it);
1555 if (type != UNKNOWN_BT)
1556 {
1557 /* Don't lose the information for resolving neutrals! The
1558 cached states could have been cached before their
1559 next_for_neutral member was computed. If we are on our way
1560 forward, we can simply take the info from the previous
1561 state. */
1562 if (bidi_it->scan_dir == 1
1563 && bidi_it->next_for_neutral.type == UNKNOWN_BT)
1564 bidi_it->next_for_neutral = next_for_neutral;
1565
1566 /* If resolved_level is -1, it means this state was cached
1567 before it was completely resolved, so we cannot return
1568 it. */
1569 if (bidi_it->resolved_level != -1)
1570 return bidi_it->resolved_level;
1571 }
1572 if (bidi_it->scan_dir == -1)
1573 /* If we are going backwards, the iterator state is already cached
1574 from previous scans, and should be fully resolved. */
1575 abort ();
1576
1577 if (type == UNKNOWN_BT)
1578 type = bidi_type_of_next_char (bidi_it);
1579
1580 if (type == NEUTRAL_B)
1581 return bidi_it->resolved_level;
1582
1583 level = bidi_it->level_stack[bidi_it->stack_idx].level;
1584 if ((bidi_get_category (type) == NEUTRAL /* && type != NEUTRAL_B */)
1585 || (type == WEAK_BN && prev_level == level))
1586 {
1587 if (bidi_it->next_for_neutral.type == UNKNOWN_BT)
1588 abort ();
1589
1590 /* If the cached state shows a neutral character, it was not
1591 resolved by bidi_resolve_neutral, so do it now. */
1592 type = bidi_resolve_neutral_1 (bidi_it->prev_for_neutral.type,
1593 bidi_it->next_for_neutral.type,
1594 level);
1595 }
1596
1597 if (!(type == STRONG_R
1598 || type == STRONG_L
1599 || type == WEAK_BN
1600 || type == WEAK_EN
1601 || type == WEAK_AN))
1602 abort ();
1603 bidi_it->type = type;
1604
1605 /* For L1 below, we need to know, for each WS character, whether
1606 it belongs to a sequence of WS characters preceeding a newline
1607 or a TAB or a paragraph separator. */
1608 if (bidi_it->pristine_type == NEUTRAL_WS
1609 && bidi_it->next_for_ws.type == UNKNOWN_BT)
1610 {
1611 int ch;
1612 int clen = bidi_it->ch_len;
1613 int bpos = bidi_it->bytepos;
1614 int cpos = bidi_it->charpos;
1615 bidi_type_t chtype;
1616
1617 do {
1618 /*_fetch_multibyte_char_len = 1;*/
1619 ch = FETCH_CHAR (bpos + clen);
1620 bpos += clen;
1621 cpos++;
1622 clen = CHAR_BYTES (ch);
1623 if (ch == '\n' /* || ch == LINESEP_CHAR */)
1624 chtype = NEUTRAL_B;
1625 else
1626 chtype = bidi_get_type (ch);
1627 } while (chtype == NEUTRAL_WS || chtype == WEAK_BN
1628 || bidi_explicit_dir_char (ch)); /* L1/Retaining */
1629 bidi_it->next_for_ws.type = chtype;
1630 bidi_it->next_for_ws.charpos = cpos;
1631 bidi_it->next_for_ws.bytepos = bpos;
1632 }
1633
1634 /* Resolve implicit levels, with a twist: PDFs get the embedding
1635 level of the enbedding they terminate. See below for the
1636 reason. */
1637 if (bidi_it->pristine_type == PDF
1638 /* Don't do this if this formatting code didn't change the
1639 embedding level due to invalid or empty embeddings. */
1640 && prev_level != level)
1641 {
1642 /* Don't look in UAX#9 for the reason for this: it's our own
1643 private quirk. The reason is that we want the formatting
1644 codes to be delivered so that they bracket the text of their
1645 embedding. For example, given the text
1646
1647 {RLO}teST{PDF}
1648
1649 we want it to be displayed as
1650
1651 {RLO}STet{PDF}
1652
1653 not as
1654
1655 STet{RLO}{PDF}
1656
1657 which will result because we bump up the embedding level as
1658 soon as we see the RLO and pop it as soon as we see the PDF,
1659 so RLO itself has the same embedding level as "teST", and
1660 thus would be normally delivered last, just before the PDF.
1661 The switch below fiddles with the level of PDF so that this
1662 ugly side effect does not happen.
1663
1664 (This is, of course, only important if the formatting codes
1665 are actually displayed, but Emacs does display them if the
1666 user wants to.) */
1667 level = prev_level;
1668 }
1669 else if (bidi_it->pristine_type == NEUTRAL_B /* L1 */
1670 || bidi_it->pristine_type == NEUTRAL_S
1671 || bidi_it->ch == '\n' /* || bidi_it->ch == LINESEP_CHAR */
1672 || (bidi_it->pristine_type == NEUTRAL_WS
1673 && (bidi_it->next_for_ws.type == NEUTRAL_B
1674 || bidi_it->next_for_ws.type == NEUTRAL_S)))
1675 level = bidi_it->level_stack[0].level;
1676 else if ((level & 1) == 0) /* I1 */
1677 {
1678 if (type == STRONG_R)
1679 level++;
1680 else if (type == WEAK_EN || type == WEAK_AN)
1681 level += 2;
1682 }
1683 else /* I2 */
1684 {
1685 if (type == STRONG_L || type == WEAK_EN || type == WEAK_AN)
1686 level++;
1687 }
1688
1689 bidi_it->resolved_level = level;
1690 return level;
1691 }
1692
1693 /* Move to the other edge of a level given by LEVEL. If END_FLAG is
1694 non-zero, we are at the end of a level, and we need to prepare to
1695 resume the scan of the lower level.
1696
1697 If this level's other edge is cached, we simply jump to it, filling
1698 the iterator structure with the iterator state on the other edge.
1699 Otherwise, we walk the buffer until we come back to the same level
1700 as LEVEL.
1701
1702 Note: we are not talking here about a ``level run'' in the UAX#9
1703 sense of the term, but rather about a ``level'' which includes
1704 all the levels higher than it. In other words, given the levels
1705 like this:
1706
1707 11111112222222333333334443343222222111111112223322111
1708 A B C
1709
1710 and assuming we are at point A scanning left to right, this
1711 function moves to point C, whereas the UAX#9 ``level 2 run'' ends
1712 at point B. */
1713 static void
1714 bidi_find_other_level_edge (struct bidi_it *bidi_it, int level, int end_flag)
1715 {
1716 int dir = end_flag ? -bidi_it->scan_dir : bidi_it->scan_dir;
1717 int idx;
1718
1719 /* Try the cache first. */
1720 if ((idx = bidi_cache_find_level_change (level, dir, end_flag)) >= 0)
1721 bidi_cache_fetch_state (idx, bidi_it);
1722 else
1723 {
1724 int new_level;
1725
1726 if (end_flag)
1727 abort (); /* if we are at end of level, its edges must be cached */
1728
1729 bidi_cache_iterator_state (bidi_it, 1);
1730 do {
1731 new_level = bidi_level_of_next_char (bidi_it);
1732 bidi_cache_iterator_state (bidi_it, 1);
1733 } while (new_level >= level);
1734 }
1735 }
1736
1737 void
1738 bidi_get_next_char_visually (struct bidi_it *bidi_it)
1739 {
1740 int old_level, new_level, next_level;
1741 struct bidi_it prev_bidi_it;
1742
1743 if (bidi_it->scan_dir == 0)
1744 {
1745 bidi_it->scan_dir = 1; /* default to logical order */
1746 }
1747
1748 if (bidi_it->new_paragraph)
1749 bidi_paragraph_init (bidi_overriding_paragraph_direction, bidi_it);
1750 if (bidi_cache_idx == 0)
1751 bidi_copy_it (&prev_bidi_it, bidi_it);
1752
1753 old_level = bidi_it->resolved_level;
1754 new_level = bidi_level_of_next_char (bidi_it);
1755 if (bidi_it->ch == BIDI_EOB)
1756 return;
1757
1758 /* Reordering of resolved levels (clause L2) is implemented by
1759 jumping to the other edge of the level and flipping direction of
1760 scanning the buffer whenever we find a level change. */
1761 if (new_level != old_level)
1762 {
1763 int ascending = new_level > old_level;
1764 int level_to_search = ascending ? old_level + 1 : old_level;
1765 int incr = ascending ? 1 : -1;
1766 int expected_next_level = old_level + incr;
1767
1768 /* If we don't have anything cached yet, we need to cache the
1769 previous character we've seen, since we'll need it to record
1770 where to jump when the last non-base level is exhausted. */
1771 if (bidi_cache_idx == 0)
1772 bidi_cache_iterator_state (&prev_bidi_it, 1);
1773 /* Jump (or walk) to the other edge of this level. */
1774 bidi_find_other_level_edge (bidi_it, level_to_search, !ascending);
1775 /* Switch scan direction and peek at the next character in the
1776 new direction. */
1777 bidi_it->scan_dir = -bidi_it->scan_dir;
1778
1779 /* The following loop handles the case where the resolved level
1780 jumps by more than one. This is typical for numbers inside a
1781 run of text with left-to-right embedding direction, but can
1782 also happen in other situations. In those cases the decision
1783 where to continue after a level change, and in what direction,
1784 is tricky. For example, given a text like below:
1785
1786 abcdefgh
1787 11336622
1788
1789 (where the numbers below the text show the resolved levels),
1790 the result of reordering according to UAX#9 should be this:
1791
1792 efdcghba
1793
1794 This is implemented by the loop below which flips direction
1795 and jumps to the other edge of the level each time it finds
1796 the new level not to be the expected one. The expected level
1797 is always one more or one less than the previous one. */
1798 next_level = bidi_peek_at_next_level (bidi_it);
1799 while (next_level != expected_next_level)
1800 {
1801 expected_next_level += incr;
1802 level_to_search += incr;
1803 bidi_find_other_level_edge (bidi_it, level_to_search, !ascending);
1804 bidi_it->scan_dir = -bidi_it->scan_dir;
1805 next_level = bidi_peek_at_next_level (bidi_it);
1806 }
1807
1808 /* Finally, deliver the next character in the new direction. */
1809 next_level = bidi_level_of_next_char (bidi_it);
1810 }
1811
1812 if (bidi_it->scan_dir == 1 && bidi_cache_idx)
1813 {
1814 /* If we are at paragraph's base embedding level and beyond the
1815 last cached position, the cache's job is done and we can
1816 discard it. */
1817 if (bidi_it->resolved_level == bidi_it->level_stack[0].level
1818 && bidi_it->charpos > bidi_cache[bidi_cache_idx - 1].charpos)
1819 bidi_cache_reset ();
1820 /* But as long as we are caching during forward scan, we must
1821 cache each state, or else the cache integrity will be
1822 compromised: it assumes cached states correspond to buffer
1823 positions 1:1. */
1824 else
1825 bidi_cache_iterator_state (bidi_it, 1);
1826 }
1827 }
1828
1829 /* This is meant to be called from within the debugger, whenever you
1830 wish to examine the cache contents. */
1831 void
1832 bidi_dump_cached_states (void)
1833 {
1834 int i;
1835 int ndigits = 1;
1836
1837 if (bidi_cache_idx == 0)
1838 {
1839 fprintf (stderr, "The cache is empty.\n");
1840 return;
1841 }
1842 fprintf (stderr, "Total of %d state%s in cache:\n",
1843 bidi_cache_idx, bidi_cache_idx == 1 ? "" : "s");
1844
1845 for (i = bidi_cache[bidi_cache_idx - 1].charpos; i > 0; i /= 10)
1846 ndigits++;
1847 fputs ("ch ", stderr);
1848 for (i = 0; i < bidi_cache_idx; i++)
1849 fprintf (stderr, "%*c", ndigits, bidi_cache[i].ch);
1850 fputs ("\n", stderr);
1851 fputs ("lvl ", stderr);
1852 for (i = 0; i < bidi_cache_idx; i++)
1853 fprintf (stderr, "%*d", ndigits, bidi_cache[i].resolved_level);
1854 fputs ("\n", stderr);
1855 fputs ("pos ", stderr);
1856 for (i = 0; i < bidi_cache_idx; i++)
1857 fprintf (stderr, "%*d", ndigits, bidi_cache[i].charpos);
1858 fputs ("\n", stderr);
1859 }
1860
1861 #ifdef TEST_STANDALONE
1862
1863 #include <sys/stat.h>
1864 #include <signal.h>
1865
1866 static char display_line[80];
1867 static int simulate_display;
1868 static int incr = 1;
1869
1870 void
1871 signal_catcher (int sig)
1872 {
1873 if (simulate_display)
1874 puts (display_line);
1875 else
1876 {
1877 puts ("<");
1878 fflush (stdout);
1879 }
1880 signal (sig, SIG_DFL);
1881 raise (sig);
1882 }
1883
1884 void
1885 put_line (char *p)
1886 {
1887 if (simulate_display)
1888 {
1889 if (incr == -1)
1890 {
1891 if (p >= display_line)
1892 memset (display_line, ' ', p - display_line + 1);
1893 }
1894 else
1895 *p = '\0';
1896 fputs (display_line, stdout);
1897 }
1898 fflush (stdout);
1899 }
1900
1901 char *
1902 init_display_direction (bidi_dir_t default_dir, int base_level)
1903 {
1904 char *p;
1905
1906 /* To which display margin should we flush the lines? */
1907 switch (default_dir)
1908 {
1909 case NEUTRAL_DIR:
1910 if ((base_level & 1) == 0)
1911 {
1912 p = display_line;
1913 incr = 1;
1914 }
1915 else
1916 {
1917 p = display_line + sizeof (display_line) - 1;
1918 *p-- = '\0';
1919 incr = -1;
1920 }
1921 break;
1922 case L2R:
1923 p = display_line;
1924 incr = 1;
1925 break;
1926 case R2L:
1927 p = display_line + sizeof (display_line) - 1;
1928 *p-- = '\0';
1929 incr = -1;
1930 break;
1931 default:
1932 abort ();
1933 }
1934
1935 return p;
1936 }
1937
1938 static char *
1939 continuation_line (char *p, int need)
1940 {
1941 if (incr == -1)
1942 {
1943 if (p < display_line + need)
1944 {
1945 *p-- = '/';
1946 put_line (p);
1947 putc ('\n', stdout);
1948 memset (display_line, '>', sizeof(display_line) - 1);
1949 p = display_line + sizeof (display_line) - 1;
1950 *p-- = '\0';
1951 }
1952 }
1953 else
1954 {
1955 if (p > display_line + sizeof(display_line) - need - 2)
1956 {
1957 *p++ = '\\';
1958 put_line (p);
1959 putc ('\n', stdout);
1960 memset (display_line, '<', sizeof(display_line) - 1);
1961 p = display_line;
1962 }
1963 }
1964
1965 return p;
1966 }
1967
1968 int main (int argc, char *argv[])
1969 {
1970 bidi_dir_t default_dir = NEUTRAL_DIR;
1971 char lots_of_equals[] = "\n===============================================================================\n";
1972
1973
1974 if (argc > 1 && argv[1][0] == '-')
1975 {
1976 switch (argv[1][1])
1977 {
1978 case 'R':
1979 default_dir = R2L;
1980 simulate_display = 1;
1981 ++argv;
1982 break;
1983 case 'L':
1984 default_dir = L2R;
1985 simulate_display = 1;
1986 ++argv;
1987 break;
1988 case 'N':
1989 simulate_display = 1;
1990 ++argv;
1991 break;
1992 default:
1993 break;
1994 }
1995 bidi_overriding_paragraph_direction = default_dir;
1996 }
1997
1998 for (argv++; *argv; argv++)
1999 {
2000 FILE *in = fopen (*argv, "rb");
2001 struct stat stat_buf;
2002 struct bidi_it iterator;
2003 size_t i;
2004 char *p = display_line;
2005 int base_level;
2006 unsigned char *s, *d, *s_end;
2007
2008 if (!in || stat (*argv, &stat_buf))
2009 {
2010 perror (*argv);
2011 continue;
2012 }
2013
2014 if (stat_buf.st_size > input_buf_size)
2015 {
2016 input_buf = realloc (input_buf, stat_buf.st_size + 1);
2017 if (!input_buf)
2018 {
2019 perror ("realloc input buffer");
2020 continue;
2021 }
2022 input_buf_size = stat_buf.st_size;
2023 }
2024 if (fread (input_buf, 1, stat_buf.st_size, in) != stat_buf.st_size)
2025 {
2026 perror ("reading input");
2027 continue;
2028 }
2029 input_buf[stat_buf.st_size] = '\0';
2030 for (d = s = input_buf, s_end = s + stat_buf.st_size - 1; *s; s++)
2031 {
2032 if (*s != '\r' || s >= s_end || s[1] != '\n')
2033 *d++ = *s;
2034 }
2035 stat_buf.st_size = d - input_buf;
2036 input_buf[stat_buf.st_size] = '\0';
2037
2038 /* Done with administrivia, now for some real work... */
2039 signal (SIGABRT, signal_catcher);
2040 signal (SIGINT, signal_catcher);
2041 bidi_init_it (-1, default_dir, &iterator);
2042 if (simulate_display)
2043 {
2044 p = init_display_direction (default_dir,
2045 iterator.level_stack[0].level);
2046 }
2047
2048 memset (display_line, incr == -1 ? '>' : '<', sizeof (display_line) - 1);
2049 display_line[sizeof (display_line) - 1] = '\0';
2050 base_level = iterator.level_stack[0].level;
2051
2052 for (i = 0; i <= stat_buf.st_size; i++)
2053 {
2054 int c;
2055
2056 bidi_get_next_char_visually (&iterator);
2057 c = iterator.ch;
2058
2059 if (c == '\n' || c == BIDI_EOB)
2060 {
2061 if (simulate_display)
2062 {
2063 put_line (p);
2064 /* FIXME: if -R or -L, need to init paragraph here. */
2065 }
2066 if (c == BIDI_EOB)
2067 break;
2068 putc (c, stdout);
2069 }
2070 else if (c >= LRE_CHAR && c <= LRM_CHAR)
2071 {
2072 if (simulate_display)
2073 {
2074 p = continuation_line (p, 5);
2075 if (incr == -1)
2076 {
2077 memcpy (p - 4, bidi_name[c], 5);
2078 p -= 5;
2079 }
2080 else
2081 {
2082 memcpy (p, bidi_name[c], 5);
2083 p += 5;
2084 }
2085 }
2086 else
2087 fputs (bidi_name[c], stdout);
2088 }
2089 else if (c < ' ')
2090 {
2091 if (simulate_display)
2092 {
2093 p = continuation_line (p, 2);
2094 if (incr == -1)
2095 {
2096 *p-- = '@' + c;
2097 *p-- = '^';
2098 }
2099 else
2100 {
2101 *p++ = '^';
2102 *p++ = '@' + c;
2103 }
2104 }
2105 else
2106 printf ("^%c", (c | 0x40));
2107 }
2108 else
2109 {
2110 int c1 = (iterator.type == STRONG_R) ? bidi_mirror_char (c) : c;
2111
2112 if (simulate_display)
2113 {
2114 p = continuation_line (p, 1);
2115 *p = c1;
2116 p += incr;
2117 }
2118 else
2119 putc (c1, stdout);
2120 }
2121
2122 if (iterator.ch == '\n')
2123 {
2124 if (base_level != iterator.level_stack[0].level)
2125 base_level = iterator.level_stack[0].level;
2126 p = init_display_direction (default_dir, base_level);
2127 memset (display_line, incr == -1 ? '>' : '<',
2128 sizeof (display_line) - 1);
2129 }
2130 }
2131 fputs (lots_of_equals, stdout);
2132 fclose (in);
2133 }
2134 return 0;
2135 }
2136 #endif