diff options
| author | Eli Zaretskii | 2010-01-01 09:57:27 -0500 |
|---|---|---|
| committer | Eli Zaretskii | 2010-01-01 09:57:27 -0500 |
| commit | bc5a45f315808b1d7335bdc9ea0168b89782c101 (patch) | |
| tree | 28bdf150710bb625327f9ec36ed74407e4627da6 /src | |
| parent | e69a937075490a19d1b767e166d10f0e838b4173 (diff) | |
| download | emacs-bc5a45f315808b1d7335bdc9ea0168b89782c101.tar.gz emacs-bc5a45f315808b1d7335bdc9ea0168b89782c101.zip | |
Retrospective commit from 2009-1219.
Fix reordering of Arabic text in etc/HELLO.
Extend .gdbinit commands to support bidirectional display.
buffer.c (Fbuffer_swap_text): Swap the values of
bidi_display_reordering and bidi_paragraph_direction.
bidi.c (bidi_resolve_weak): Fix nesting of conditions for Wn
processing. Move W3 after W1 and W2. Simplify W4 because it is
now always after W1.
.gdbinit (pbiditype): New command.
(pgx): Use it to display bidi level and type of the glyph.
Diffstat (limited to 'src')
| -rw-r--r-- | src/.gdbinit | 32 | ||||
| -rw-r--r-- | src/ChangeLog.bidi | 12 | ||||
| -rw-r--r-- | src/bidi.c | 192 | ||||
| -rw-r--r-- | src/buffer.c | 2 |
4 files changed, 141 insertions, 97 deletions
diff --git a/src/.gdbinit b/src/.gdbinit index e8a64f5dfe4..61e3da6c68c 100644 --- a/src/.gdbinit +++ b/src/.gdbinit | |||
| @@ -447,6 +447,33 @@ document pwin | |||
| 447 | Pretty print window structure w. | 447 | Pretty print window structure w. |
| 448 | end | 448 | end |
| 449 | 449 | ||
| 450 | define pbiditype | ||
| 451 | if ($arg0 == 1) | ||
| 452 | printf "L" | ||
| 453 | end | ||
| 454 | if ($arg0 == 2) | ||
| 455 | printf "R" | ||
| 456 | end | ||
| 457 | if ($arg0 == 3) | ||
| 458 | printf "EN" | ||
| 459 | end | ||
| 460 | if ($arg0 == 4) | ||
| 461 | printf "AN" | ||
| 462 | end | ||
| 463 | if ($arg0 == 5) | ||
| 464 | printf "BN" | ||
| 465 | end | ||
| 466 | if ($arg0 == 6) | ||
| 467 | printf "B" | ||
| 468 | end | ||
| 469 | if ($arg0 < 1 || $arg0 > 6) | ||
| 470 | printf "%d??", $arg0 | ||
| 471 | end | ||
| 472 | end | ||
| 473 | document pbiditype | ||
| 474 | Print textual description of bidi type given as first argument. | ||
| 475 | end | ||
| 476 | |||
| 450 | define pgx | 477 | define pgx |
| 451 | set $g = $arg0 | 478 | set $g = $arg0 |
| 452 | # CHAR_GLYPH | 479 | # CHAR_GLYPH |
| @@ -475,6 +502,11 @@ define pgx | |||
| 475 | else | 502 | else |
| 476 | printf " pos=%d", $g->charpos | 503 | printf " pos=%d", $g->charpos |
| 477 | end | 504 | end |
| 505 | # For characters, print their resolved level and bidi type | ||
| 506 | if ($g->type == 0) | ||
| 507 | printf " blev=%d,btyp=", $g->resolved_level | ||
| 508 | pbiditype $g->bidi_type | ||
| 509 | end | ||
| 478 | printf " w=%d a+d=%d+%d", $g->pixel_width, $g->ascent, $g->descent | 510 | printf " w=%d a+d=%d+%d", $g->pixel_width, $g->ascent, $g->descent |
| 479 | # If not DEFAULT_FACE_ID | 511 | # If not DEFAULT_FACE_ID |
| 480 | if ($g->face_id != 0) | 512 | if ($g->face_id != 0) |
diff --git a/src/ChangeLog.bidi b/src/ChangeLog.bidi index ef911354df8..b9fb7457cfd 100644 --- a/src/ChangeLog.bidi +++ b/src/ChangeLog.bidi | |||
| @@ -1,3 +1,15 @@ | |||
| 1 | 2009-12-19 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * buffer.c (Fbuffer_swap_text): Swap the values of | ||
| 4 | bidi_display_reordering and bidi_paragraph_direction. | ||
| 5 | |||
| 6 | * bidi.c (bidi_resolve_weak): Fix nesting of conditions for Wn | ||
| 7 | processing. Move W3 after W1 and W2. Simplify W4 because it is | ||
| 8 | now always after W1. | ||
| 9 | |||
| 10 | * .gdbinit (pbiditype): New command. | ||
| 11 | (pgx): Use it to display bidi level and type of the glyph. | ||
| 12 | |||
| 1 | 2009-12-12 Eli Zaretskii <eliz@gnu.org> | 13 | 2009-12-12 Eli Zaretskii <eliz@gnu.org> |
| 2 | 14 | ||
| 3 | * dispextern.h (struct it): New members prev_stop and | 15 | * dispextern.h (struct it): New members prev_stop and |
diff --git a/src/bidi.c b/src/bidi.c index 102326b41e8..d18629279d6 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -1342,123 +1342,121 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 1342 | type = STRONG_R; | 1342 | type = STRONG_R; |
| 1343 | else if (override == L2R) | 1343 | else if (override == L2R) |
| 1344 | type = STRONG_L; | 1344 | type = STRONG_L; |
| 1345 | else if (type == STRONG_AL) | 1345 | else |
| 1346 | type = STRONG_R; /* W3 */ | ||
| 1347 | else if (type == WEAK_NSM) /* W1 */ | ||
| 1348 | { | ||
| 1349 | /* Note that we don't need to consider the case where the prev | ||
| 1350 | character has its type overridden by an RLO or LRO: such | ||
| 1351 | characters are outside the current level run, and thus not | ||
| 1352 | relevant to this NSM. Thus, NSM gets the orig_type of the | ||
| 1353 | previous character. */ | ||
| 1354 | if (bidi_it->prev.type != UNKNOWN_BT) | ||
| 1355 | type = bidi_it->prev.orig_type; | ||
| 1356 | else if (bidi_it->sor == R2L) | ||
| 1357 | type = STRONG_R; | ||
| 1358 | else if (bidi_it->sor == L2R) | ||
| 1359 | type = STRONG_L; | ||
| 1360 | else /* shouldn't happen! */ | ||
| 1361 | abort (); | ||
| 1362 | if (type == WEAK_EN /* W2 after W1 */ | ||
| 1363 | && bidi_it->last_strong.type_after_w1 == STRONG_AL) | ||
| 1364 | type = WEAK_AN; | ||
| 1365 | } | ||
| 1366 | else if (type == WEAK_EN /* W2 */ | ||
| 1367 | && bidi_it->last_strong.type_after_w1 == STRONG_AL) | ||
| 1368 | type = WEAK_AN; | ||
| 1369 | else if ((type == WEAK_ES | ||
| 1370 | && (bidi_it->prev.type_after_w1 == WEAK_EN /* W4 */ | ||
| 1371 | && (bidi_it->prev.orig_type == WEAK_EN | ||
| 1372 | || bidi_it->prev.orig_type == WEAK_NSM))) /* aft W1 */ | ||
| 1373 | || (type == WEAK_CS | ||
| 1374 | && ((bidi_it->prev.type_after_w1 == WEAK_EN | ||
| 1375 | && (bidi_it->prev.orig_type == WEAK_EN /* W4 */ | ||
| 1376 | || bidi_it->prev.orig_type == WEAK_NSM)) /* a/W1 */ | ||
| 1377 | || bidi_it->prev.type_after_w1 == WEAK_AN))) /* W4 */ | ||
| 1378 | { | 1346 | { |
| 1379 | next_char = | 1347 | if (type == WEAK_NSM) /* W1 */ |
| 1380 | bidi_it->bytepos + bidi_it->ch_len >= ZV_BYTE | ||
| 1381 | ? BIDI_EOB : FETCH_CHAR (bidi_it->bytepos + bidi_it->ch_len); | ||
| 1382 | type_of_next = bidi_get_type (next_char, override); | ||
| 1383 | |||
| 1384 | if (type_of_next == WEAK_BN | ||
| 1385 | || bidi_explicit_dir_char (next_char)) | ||
| 1386 | { | 1348 | { |
| 1387 | bidi_copy_it (&saved_it, bidi_it); | 1349 | /* Note that we don't need to consider the case where the |
| 1388 | while (bidi_resolve_explicit (bidi_it) == new_level | 1350 | prev character has its type overridden by an RLO or LRO: |
| 1389 | && bidi_it->type == WEAK_BN) | 1351 | such characters are outside the current level run, and |
| 1390 | ; | 1352 | thus not relevant to this NSM. Thus, NSM gets the |
| 1391 | type_of_next = bidi_it->type; | 1353 | orig_type of the previous character. */ |
| 1392 | bidi_copy_it (bidi_it, &saved_it); | 1354 | if (bidi_it->prev.type != UNKNOWN_BT) |
| 1393 | } | 1355 | type = bidi_it->prev.orig_type; |
| 1394 | 1356 | else if (bidi_it->sor == R2L) | |
| 1395 | /* If the next character is EN, but the last strong-type | 1357 | type = STRONG_R; |
| 1396 | character is AL, that next EN will be changed to AN when we | 1358 | else if (bidi_it->sor == L2R) |
| 1397 | process it in W2 above. So in that case, this ES should not | 1359 | type = STRONG_L; |
| 1398 | be changed into EN. */ | 1360 | else /* shouldn't happen! */ |
| 1399 | if (type == WEAK_ES | 1361 | abort (); |
| 1400 | && type_of_next == WEAK_EN | ||
| 1401 | && bidi_it->last_strong.type_after_w1 != STRONG_AL) | ||
| 1402 | type = WEAK_EN; | ||
| 1403 | else if (type == WEAK_CS) | ||
| 1404 | { | ||
| 1405 | if (bidi_it->prev.type_after_w1 == WEAK_AN | ||
| 1406 | && (type_of_next == WEAK_AN | ||
| 1407 | /* If the next character is EN, but the last | ||
| 1408 | strong-type character is AL, EN will be later | ||
| 1409 | changed to AN when we process it in W2 above. So | ||
| 1410 | in that case, this ES should not be changed into | ||
| 1411 | EN. */ | ||
| 1412 | || (type_of_next == WEAK_EN | ||
| 1413 | && bidi_it->last_strong.type_after_w1 == STRONG_AL))) | ||
| 1414 | type = WEAK_AN; | ||
| 1415 | else if (bidi_it->prev.type_after_w1 == WEAK_EN | ||
| 1416 | && type_of_next == WEAK_EN | ||
| 1417 | && bidi_it->last_strong.type_after_w1 != STRONG_AL) | ||
| 1418 | type = WEAK_EN; | ||
| 1419 | } | 1362 | } |
| 1420 | } | 1363 | if (type == WEAK_EN /* W2 */ |
| 1421 | else if (type == WEAK_ET /* W5: ET with EN before or after it */ | 1364 | && bidi_it->last_strong.type_after_w1 == STRONG_AL) |
| 1422 | || type == WEAK_BN) /* W5/Retaining */ | 1365 | type = WEAK_AN; |
| 1423 | { | 1366 | else if (type == STRONG_AL) /* W3 */ |
| 1424 | if (bidi_it->prev.type_after_w1 == WEAK_EN /* ET/BN with EN before it */ | 1367 | type = STRONG_R; |
| 1425 | || bidi_it->next_en_pos > bidi_it->charpos) | 1368 | else if ((type == WEAK_ES /* W4 */ |
| 1426 | type = WEAK_EN; | 1369 | && bidi_it->prev.type_after_w1 == WEAK_EN |
| 1427 | /* W5: ET with EN after it. */ | 1370 | && bidi_it->prev.orig_type == WEAK_EN) |
| 1428 | else | 1371 | || (type == WEAK_CS |
| 1372 | && ((bidi_it->prev.type_after_w1 == WEAK_EN | ||
| 1373 | && bidi_it->prev.orig_type == WEAK_EN) | ||
| 1374 | || bidi_it->prev.type_after_w1 == WEAK_AN))) | ||
| 1429 | { | 1375 | { |
| 1430 | EMACS_INT en_pos = bidi_it->charpos + 1; | ||
| 1431 | |||
| 1432 | next_char = | 1376 | next_char = |
| 1433 | bidi_it->bytepos + bidi_it->ch_len >= ZV_BYTE | 1377 | bidi_it->bytepos + bidi_it->ch_len >= ZV_BYTE |
| 1434 | ? BIDI_EOB : FETCH_CHAR (bidi_it->bytepos + bidi_it->ch_len); | 1378 | ? BIDI_EOB : FETCH_CHAR (bidi_it->bytepos + bidi_it->ch_len); |
| 1435 | type_of_next = bidi_get_type (next_char, override); | 1379 | type_of_next = bidi_get_type (next_char, override); |
| 1436 | 1380 | ||
| 1437 | if (type_of_next == WEAK_ET | 1381 | if (type_of_next == WEAK_BN |
| 1438 | || type_of_next == WEAK_BN | ||
| 1439 | || bidi_explicit_dir_char (next_char)) | 1382 | || bidi_explicit_dir_char (next_char)) |
| 1440 | { | 1383 | { |
| 1441 | bidi_copy_it (&saved_it, bidi_it); | 1384 | bidi_copy_it (&saved_it, bidi_it); |
| 1442 | while (bidi_resolve_explicit (bidi_it) == new_level | 1385 | while (bidi_resolve_explicit (bidi_it) == new_level |
| 1443 | && (bidi_it->type == WEAK_BN || bidi_it->type == WEAK_ET)) | 1386 | && bidi_it->type == WEAK_BN) |
| 1444 | ; | 1387 | ; |
| 1445 | type_of_next = bidi_it->type; | 1388 | type_of_next = bidi_it->type; |
| 1446 | en_pos = bidi_it->charpos; | ||
| 1447 | bidi_copy_it (bidi_it, &saved_it); | 1389 | bidi_copy_it (bidi_it, &saved_it); |
| 1448 | } | 1390 | } |
| 1449 | if (type_of_next == WEAK_EN) | 1391 | |
| 1392 | /* If the next character is EN, but the last strong-type | ||
| 1393 | character is AL, that next EN will be changed to AN when | ||
| 1394 | we process it in W2 above. So in that case, this ES | ||
| 1395 | should not be changed into EN. */ | ||
| 1396 | if (type == WEAK_ES | ||
| 1397 | && type_of_next == WEAK_EN | ||
| 1398 | && bidi_it->last_strong.type_after_w1 != STRONG_AL) | ||
| 1399 | type = WEAK_EN; | ||
| 1400 | else if (type == WEAK_CS) | ||
| 1450 | { | 1401 | { |
| 1451 | /* If the last strong character is AL, the EN we've | 1402 | if (bidi_it->prev.type_after_w1 == WEAK_AN |
| 1452 | found will become AN when we get to it (W2). */ | 1403 | && (type_of_next == WEAK_AN |
| 1453 | if (bidi_it->last_strong.type_after_w1 != STRONG_AL) | 1404 | /* If the next character is EN, but the last |
| 1405 | strong-type character is AL, EN will be later | ||
| 1406 | changed to AN when we process it in W2 above. | ||
| 1407 | So in that case, this ES should not be | ||
| 1408 | changed into EN. */ | ||
| 1409 | || (type_of_next == WEAK_EN | ||
| 1410 | && bidi_it->last_strong.type_after_w1 == STRONG_AL))) | ||
| 1411 | type = WEAK_AN; | ||
| 1412 | else if (bidi_it->prev.type_after_w1 == WEAK_EN | ||
| 1413 | && type_of_next == WEAK_EN | ||
| 1414 | && bidi_it->last_strong.type_after_w1 != STRONG_AL) | ||
| 1415 | type = WEAK_EN; | ||
| 1416 | } | ||
| 1417 | } | ||
| 1418 | else if (type == WEAK_ET /* W5: ET with EN before or after it */ | ||
| 1419 | || type == WEAK_BN) /* W5/Retaining */ | ||
| 1420 | { | ||
| 1421 | if (bidi_it->prev.type_after_w1 == WEAK_EN /* ET/BN w/EN before it */ | ||
| 1422 | || bidi_it->next_en_pos > bidi_it->charpos) | ||
| 1423 | type = WEAK_EN; | ||
| 1424 | else /* W5: ET/BN with EN after it. */ | ||
| 1425 | { | ||
| 1426 | EMACS_INT en_pos = bidi_it->charpos + 1; | ||
| 1427 | |||
| 1428 | next_char = | ||
| 1429 | bidi_it->bytepos + bidi_it->ch_len >= ZV_BYTE | ||
| 1430 | ? BIDI_EOB : FETCH_CHAR (bidi_it->bytepos + bidi_it->ch_len); | ||
| 1431 | type_of_next = bidi_get_type (next_char, override); | ||
| 1432 | |||
| 1433 | if (type_of_next == WEAK_ET | ||
| 1434 | || type_of_next == WEAK_BN | ||
| 1435 | || bidi_explicit_dir_char (next_char)) | ||
| 1436 | { | ||
| 1437 | bidi_copy_it (&saved_it, bidi_it); | ||
| 1438 | while (bidi_resolve_explicit (bidi_it) == new_level | ||
| 1439 | && (bidi_it->type == WEAK_BN | ||
| 1440 | || bidi_it->type == WEAK_ET)) | ||
| 1441 | ; | ||
| 1442 | type_of_next = bidi_it->type; | ||
| 1443 | en_pos = bidi_it->charpos; | ||
| 1444 | bidi_copy_it (bidi_it, &saved_it); | ||
| 1445 | } | ||
| 1446 | if (type_of_next == WEAK_EN) | ||
| 1454 | { | 1447 | { |
| 1455 | type = WEAK_EN; | 1448 | /* If the last strong character is AL, the EN we've |
| 1456 | /* Remember this EN position, to speed up processing | 1449 | found will become AN when we get to it (W2). */ |
| 1457 | of the next ETs. */ | 1450 | if (bidi_it->last_strong.type_after_w1 != STRONG_AL) |
| 1458 | bidi_it->next_en_pos = en_pos; | 1451 | { |
| 1452 | type = WEAK_EN; | ||
| 1453 | /* Remember this EN position, to speed up processing | ||
| 1454 | of the next ETs. */ | ||
| 1455 | bidi_it->next_en_pos = en_pos; | ||
| 1456 | } | ||
| 1457 | else if (type == WEAK_BN) | ||
| 1458 | type = NEUTRAL_ON; /* W6/Retaining */ | ||
| 1459 | } | 1459 | } |
| 1460 | else if (type == WEAK_BN) | ||
| 1461 | type = NEUTRAL_ON; /* W6/Retaining */ | ||
| 1462 | } | 1460 | } |
| 1463 | } | 1461 | } |
| 1464 | } | 1462 | } |
diff --git a/src/buffer.c b/src/buffer.c index 521fe9b5019..ce9dc1c274d 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -2261,6 +2261,8 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text, | |||
| 2261 | swapfield (undo_list, Lisp_Object); | 2261 | swapfield (undo_list, Lisp_Object); |
| 2262 | swapfield (mark, Lisp_Object); | 2262 | swapfield (mark, Lisp_Object); |
| 2263 | swapfield (enable_multibyte_characters, Lisp_Object); | 2263 | swapfield (enable_multibyte_characters, Lisp_Object); |
| 2264 | swapfield (bidi_display_reordering, Lisp_Object); | ||
| 2265 | swapfield (bidi_paragraph_direction, Lisp_Object); | ||
| 2264 | /* FIXME: Not sure what we should do with these *_marker fields. | 2266 | /* FIXME: Not sure what we should do with these *_marker fields. |
| 2265 | Hopefully they're just nil anyway. */ | 2267 | Hopefully they're just nil anyway. */ |
| 2266 | swapfield (pt_marker, Lisp_Object); | 2268 | swapfield (pt_marker, Lisp_Object); |