diff options
| author | Eli Zaretskii | 2014-09-26 17:52:47 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2014-09-26 17:52:47 +0300 |
| commit | d51702fd71cf2d350c72079011075556f4eb6531 (patch) | |
| tree | 173f591311057bcd8528844d2c2bacd8420b8f4f /src | |
| parent | 0df5896cd2851947d2bc186ff82c5a43e7bdd0c7 (diff) | |
| download | emacs-d51702fd71cf2d350c72079011075556f4eb6531.tar.gz emacs-d51702fd71cf2d350c72079011075556f4eb6531.zip | |
Fix N1 and N2. Remove special level for PDF.
Improve glyphless glyph display in .gdbinit/pgx.
Diffstat (limited to 'src')
| -rw-r--r-- | src/.gdbinit | 12 | ||||
| -rw-r--r-- | src/bidi.c | 146 |
2 files changed, 74 insertions, 84 deletions
diff --git a/src/.gdbinit b/src/.gdbinit index c10fe3ddded..d76c3aa8e05 100644 --- a/src/.gdbinit +++ b/src/.gdbinit | |||
| @@ -468,18 +468,18 @@ define pgx | |||
| 468 | end | 468 | end |
| 469 | # GLYPHLESS_GLYPH | 469 | # GLYPHLESS_GLYPH |
| 470 | if ($g.type == 2) | 470 | if ($g.type == 2) |
| 471 | printf "GLYPHLESS[" | 471 | printf "G-LESS[" |
| 472 | if ($g.u.glyphless.method == 0) | 472 | if ($g.u.glyphless.method == 0) |
| 473 | printf "THIN]" | 473 | printf "THIN;0x%x]", $g.u.glyphless.ch |
| 474 | end | 474 | end |
| 475 | if ($g.u.glyphless.method == 1) | 475 | if ($g.u.glyphless.method == 1) |
| 476 | printf "EMPTY]" | 476 | printf "EMPTY;0x%x]", $g.u.glyphless.ch |
| 477 | end | 477 | end |
| 478 | if ($g.u.glyphless.method == 2) | 478 | if ($g.u.glyphless.method == 2) |
| 479 | printf "ACRO]" | 479 | printf "ACRO;0x%x]", $g.u.glyphless.ch |
| 480 | end | 480 | end |
| 481 | if ($g.u.glyphless.method == 3) | 481 | if ($g.u.glyphless.method == 3) |
| 482 | printf "HEX]" | 482 | printf "HEX;0x%x]", $g.u.glyphless.ch |
| 483 | end | 483 | end |
| 484 | end | 484 | end |
| 485 | # IMAGE_GLYPH | 485 | # IMAGE_GLYPH |
| @@ -498,7 +498,7 @@ define pgx | |||
| 498 | printf " pos=%d", $g.charpos | 498 | printf " pos=%d", $g.charpos |
| 499 | end | 499 | end |
| 500 | # For characters, print their resolved level and bidi type | 500 | # For characters, print their resolved level and bidi type |
| 501 | if ($g.type == 0) | 501 | if ($g.type == 0 || $g.type == 2) |
| 502 | printf " blev=%d,btyp=", $g.resolved_level | 502 | printf " blev=%d,btyp=", $g.resolved_level |
| 503 | pbiditype $g.bidi_type | 503 | pbiditype $g.bidi_type |
| 504 | end | 504 | end |
diff --git a/src/bidi.c b/src/bidi.c index 7beadb25455..5ef2dd1c31c 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -2219,6 +2219,7 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) | |||
| 2219 | int prev_level = bidi_it->level_stack[bidi_it->stack_idx].level; | 2219 | int prev_level = bidi_it->level_stack[bidi_it->stack_idx].level; |
| 2220 | bidi_type_t type = bidi_resolve_weak (bidi_it); | 2220 | bidi_type_t type = bidi_resolve_weak (bidi_it); |
| 2221 | int current_level = bidi_it->level_stack[bidi_it->stack_idx].level; | 2221 | int current_level = bidi_it->level_stack[bidi_it->stack_idx].level; |
| 2222 | bool is_neutral = bidi_get_category (type) == NEUTRAL; | ||
| 2222 | 2223 | ||
| 2223 | eassert ((type == STRONG_R | 2224 | eassert ((type == STRONG_R |
| 2224 | || type == STRONG_L | 2225 | || type == STRONG_L |
| @@ -2234,8 +2235,9 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) | |||
| 2234 | eassert (current_level >= 0); | 2235 | eassert (current_level >= 0); |
| 2235 | if ((type != NEUTRAL_B /* Don't risk entering the long loop below if | 2236 | if ((type != NEUTRAL_B /* Don't risk entering the long loop below if |
| 2236 | we are already at paragraph end. */ | 2237 | we are already at paragraph end. */ |
| 2237 | && bidi_get_category (type) == NEUTRAL) | 2238 | && is_neutral) |
| 2238 | || (type == WEAK_BN && prev_level == current_level)) | 2239 | /* N1-N2/Retaining */ |
| 2240 | || (type == WEAK_BN && bidi_explicit_dir_char (bidi_it->ch))) | ||
| 2239 | { | 2241 | { |
| 2240 | if (bidi_it->next_for_neutral.type != UNKNOWN_BT) | 2242 | if (bidi_it->next_for_neutral.type != UNKNOWN_BT) |
| 2241 | type = bidi_resolve_neutral_1 (bidi_it->prev_for_neutral.type, | 2243 | type = bidi_resolve_neutral_1 (bidi_it->prev_for_neutral.type, |
| @@ -2283,6 +2285,7 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) | |||
| 2283 | implementations! */ | 2285 | implementations! */ |
| 2284 | struct bidi_it saved_it; | 2286 | struct bidi_it saved_it; |
| 2285 | bidi_type_t next_type; | 2287 | bidi_type_t next_type; |
| 2288 | bool adjacent_to_neutrals = is_neutral; | ||
| 2286 | 2289 | ||
| 2287 | if (bidi_it->scan_dir == -1) | 2290 | if (bidi_it->scan_dir == -1) |
| 2288 | emacs_abort (); | 2291 | emacs_abort (); |
| @@ -2300,6 +2303,9 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) | |||
| 2300 | && bidi_it->type != WEAK_BN) | 2303 | && bidi_it->type != WEAK_BN) |
| 2301 | bidi_remember_char (&bidi_it->prev, bidi_it); | 2304 | bidi_remember_char (&bidi_it->prev, bidi_it); |
| 2302 | type = bidi_resolve_weak (bidi_it); | 2305 | type = bidi_resolve_weak (bidi_it); |
| 2306 | if (!adjacent_to_neutrals | ||
| 2307 | && bidi_get_category (type) == NEUTRAL) | ||
| 2308 | adjacent_to_neutrals = true; | ||
| 2303 | /* Paragraph separators have their levels fully resolved | 2309 | /* Paragraph separators have their levels fully resolved |
| 2304 | at this point, so cache them as resolved. */ | 2310 | at this point, so cache them as resolved. */ |
| 2305 | bidi_cache_iterator_state (bidi_it, type == NEUTRAL_B); | 2311 | bidi_cache_iterator_state (bidi_it, type == NEUTRAL_B); |
| @@ -2315,46 +2321,45 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) | |||
| 2315 | != current_level))); | 2321 | != current_level))); |
| 2316 | 2322 | ||
| 2317 | bidi_remember_char (&saved_it.next_for_neutral, bidi_it); | 2323 | bidi_remember_char (&saved_it.next_for_neutral, bidi_it); |
| 2318 | 2324 | if ((bidi_it->level_stack[bidi_it->stack_idx].level != current_level) | |
| 2319 | switch (type) | 2325 | || type == NEUTRAL_B) |
| 2320 | { | 2326 | { |
| 2321 | case STRONG_L: | 2327 | /* Marched all the way to the end of this level run. We |
| 2322 | case STRONG_R: | 2328 | need to use the eos type, whose information is stored |
| 2323 | case STRONG_AL: | 2329 | by bidi_set_sos_type in the prev_for_neutral |
| 2324 | /* Actually, STRONG_AL cannot happen here, because | 2330 | member. */ |
| 2325 | bidi_resolve_weak converts it to STRONG_R, per W3. */ | 2331 | if (adjacent_to_neutrals) |
| 2326 | eassert (type != STRONG_AL); | 2332 | next_type = bidi_it->prev_for_neutral.type; |
| 2327 | next_type = type; | 2333 | else |
| 2328 | break; | 2334 | { |
| 2329 | case WEAK_EN: | 2335 | /* This is a BN which does not adjoin neutrals. |
| 2330 | case WEAK_AN: | 2336 | Leave its type alone. */ |
| 2331 | /* N1: ``European and Arabic numbers are treated as | 2337 | bidi_copy_it (bidi_it, &saved_it); |
| 2332 | though they were R.'' */ | 2338 | return bidi_it->type; |
| 2333 | next_type = STRONG_R; | 2339 | } |
| 2334 | break; | 2340 | } |
| 2335 | default: | 2341 | else |
| 2336 | if ((bidi_it->level_stack[bidi_it->stack_idx].level | 2342 | { |
| 2337 | != current_level) | 2343 | switch (type) |
| 2338 | || type == NEUTRAL_B) | 2344 | { |
| 2339 | { | 2345 | case STRONG_L: |
| 2340 | /* Marched all the way to the end of this level | 2346 | case STRONG_R: |
| 2341 | run. We need to use the eos type, whose | 2347 | case STRONG_AL: |
| 2342 | information is stored by bidi_set_sos_type in | 2348 | /* Actually, STRONG_AL cannot happen here, because |
| 2343 | the prev_for_neutral member. */ | 2349 | bidi_resolve_weak converts it to STRONG_R, per W3. */ |
| 2344 | if (saved_it.type != WEAK_BN | 2350 | eassert (type != STRONG_AL); |
| 2345 | || bidi_get_category (bidi_it->prev.type_after_w1) == NEUTRAL) | 2351 | next_type = type; |
| 2346 | next_type = bidi_it->prev_for_neutral.type; | 2352 | break; |
| 2347 | else | 2353 | case WEAK_EN: |
| 2348 | { | 2354 | case WEAK_AN: |
| 2349 | /* This is a BN which does not adjoin | 2355 | /* N1: ``European and Arabic numbers are treated as |
| 2350 | neutrals. Leave its type alone. */ | 2356 | though they were R.'' */ |
| 2351 | bidi_copy_it (bidi_it, &saved_it); | 2357 | next_type = STRONG_R; |
| 2352 | return bidi_it->type; | 2358 | break; |
| 2353 | } | 2359 | default: |
| 2354 | } | ||
| 2355 | else | ||
| 2356 | emacs_abort (); | 2360 | emacs_abort (); |
| 2357 | break; | 2361 | break; |
| 2362 | } | ||
| 2358 | } | 2363 | } |
| 2359 | type = bidi_resolve_neutral_1 (saved_it.prev_for_neutral.type, | 2364 | type = bidi_resolve_neutral_1 (saved_it.prev_for_neutral.type, |
| 2360 | next_type, current_level); | 2365 | next_type, current_level); |
| @@ -2456,6 +2461,10 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 2456 | { | 2461 | { |
| 2457 | int bob = ((bidi_it->string.s || STRINGP (bidi_it->string.lstring)) | 2462 | int bob = ((bidi_it->string.s || STRINGP (bidi_it->string.lstring)) |
| 2458 | ? 0 : 1); | 2463 | ? 0 : 1); |
| 2464 | bidi_type_t prev_type = bidi_it->prev.type; | ||
| 2465 | bidi_type_t type_for_neutral = bidi_it->next_for_neutral.type; | ||
| 2466 | ptrdiff_t pos_for_neutral = bidi_it->next_for_neutral.charpos; | ||
| 2467 | |||
| 2459 | if (bidi_it->scan_dir > 0) | 2468 | if (bidi_it->scan_dir > 0) |
| 2460 | { | 2469 | { |
| 2461 | if (bidi_it->nchars <= 0) | 2470 | if (bidi_it->nchars <= 0) |
| @@ -2472,6 +2481,22 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 2472 | type = bidi_cache_find (next_char_pos, -1, bidi_it); | 2481 | type = bidi_cache_find (next_char_pos, -1, bidi_it); |
| 2473 | else | 2482 | else |
| 2474 | type = UNKNOWN_BT; | 2483 | type = UNKNOWN_BT; |
| 2484 | |||
| 2485 | /* For a sequence of BN and NI, copy the type from the previous | ||
| 2486 | character. This is because the loop in bidi_resolve_neutral | ||
| 2487 | that handles such sequences caches the characters it | ||
| 2488 | traverses, but does not (and cannot) store the | ||
| 2489 | next_for_neutral member for them, because it is only known | ||
| 2490 | when the loop ends. So when we find them in the cache, their | ||
| 2491 | type needs to be updated, but we don't have next_for_neutral | ||
| 2492 | to do that. However, whatever type is resolved as result of | ||
| 2493 | that loop, it will be the same for all the traversed | ||
| 2494 | characters, by virtue of N1 and N2. */ | ||
| 2495 | if (type == WEAK_BN && bidi_it->scan_dir > 0 | ||
| 2496 | && bidi_explicit_dir_char (bidi_it->ch) | ||
| 2497 | && type_for_neutral != UNKNOWN_BT | ||
| 2498 | && bidi_it->charpos < pos_for_neutral) | ||
| 2499 | type = prev_type; | ||
| 2475 | } | 2500 | } |
| 2476 | else | 2501 | else |
| 2477 | type = UNKNOWN_BT; | 2502 | type = UNKNOWN_BT; |
| @@ -2510,8 +2535,7 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 2510 | } | 2535 | } |
| 2511 | 2536 | ||
| 2512 | level = bidi_it->level_stack[bidi_it->stack_idx].level; | 2537 | level = bidi_it->level_stack[bidi_it->stack_idx].level; |
| 2513 | if ((bidi_get_category (type) == NEUTRAL /* && type != NEUTRAL_B */) | 2538 | if (bidi_get_category (type) == NEUTRAL /* && type != NEUTRAL_B */) |
| 2514 | || (type == WEAK_BN && prev_level == level)) | ||
| 2515 | { | 2539 | { |
| 2516 | if (bidi_it->next_for_neutral.type == UNKNOWN_BT) | 2540 | if (bidi_it->next_for_neutral.type == UNKNOWN_BT) |
| 2517 | emacs_abort (); | 2541 | emacs_abort (); |
| @@ -2562,42 +2586,8 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 2562 | bidi_it->next_for_ws.bytepos = bpos; | 2586 | bidi_it->next_for_ws.bytepos = bpos; |
| 2563 | } | 2587 | } |
| 2564 | 2588 | ||
| 2565 | /* Resolve implicit levels, with a twist: PDFs get the embedding | 2589 | /* Resolve implicit levels. */ |
| 2566 | level of the embedding they terminate. See below for the | 2590 | if (bidi_it->orig_type == NEUTRAL_B /* L1 */ |
| 2567 | reason. */ | ||
| 2568 | if (bidi_it->orig_type == PDF | ||
| 2569 | /* Don't do this if this formatting code didn't change the | ||
| 2570 | embedding level due to invalid or empty embeddings. */ | ||
| 2571 | && prev_level != level) | ||
| 2572 | { | ||
| 2573 | /* Don't look in UAX#9 for the reason for this: it's our own | ||
| 2574 | private quirk. The reason is that we want the formatting | ||
| 2575 | codes to be delivered so that they bracket the text of their | ||
| 2576 | embedding. For example, given the text | ||
| 2577 | |||
| 2578 | {RLO}teST{PDF} | ||
| 2579 | |||
| 2580 | we want it to be displayed as | ||
| 2581 | |||
| 2582 | {PDF}STet{RLO} | ||
| 2583 | |||
| 2584 | not as | ||
| 2585 | |||
| 2586 | STet{RLO}{PDF} | ||
| 2587 | |||
| 2588 | which will result because we bump up the embedding level as | ||
| 2589 | soon as we see the RLO and pop it as soon as we see the PDF, | ||
| 2590 | so RLO itself has the same embedding level as "teST", and | ||
| 2591 | thus would be normally delivered last, just before the PDF. | ||
| 2592 | The switch below fiddles with the level of PDF so that this | ||
| 2593 | ugly side effect does not happen. | ||
| 2594 | |||
| 2595 | (This is, of course, only important if the formatting codes | ||
| 2596 | are actually displayed, but Emacs does need to display them | ||
| 2597 | if the user wants to.) */ | ||
| 2598 | level = prev_level; | ||
| 2599 | } | ||
| 2600 | else if (bidi_it->orig_type == NEUTRAL_B /* L1 */ | ||
| 2601 | || bidi_it->orig_type == NEUTRAL_S | 2591 | || bidi_it->orig_type == NEUTRAL_S |
| 2602 | || bidi_it->ch == '\n' || bidi_it->ch == BIDI_EOB | 2592 | || bidi_it->ch == '\n' || bidi_it->ch == BIDI_EOB |
| 2603 | || (bidi_it->orig_type == NEUTRAL_WS | 2593 | || (bidi_it->orig_type == NEUTRAL_WS |