aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2010-01-01 09:57:27 -0500
committerEli Zaretskii2010-01-01 09:57:27 -0500
commitbc5a45f315808b1d7335bdc9ea0168b89782c101 (patch)
tree28bdf150710bb625327f9ec36ed74407e4627da6 /src
parente69a937075490a19d1b767e166d10f0e838b4173 (diff)
downloademacs-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/.gdbinit32
-rw-r--r--src/ChangeLog.bidi12
-rw-r--r--src/bidi.c192
-rw-r--r--src/buffer.c2
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
447Pretty print window structure w. 447Pretty print window structure w.
448end 448end
449 449
450define 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
472end
473document pbiditype
474Print textual description of bidi type given as first argument.
475end
476
450define pgx 477define 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 @@
12009-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
12009-12-12 Eli Zaretskii <eliz@gnu.org> 132009-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);