[ot-shape] Numeric runs native direction is LTR

See inline comments. Slightly modified version of the code from Jonathan
Kew on the linked issue.

Fixes https://github.com/harfbuzz/harfbuzz/issues/501
This commit is contained in:
Khaled Hosny 2021-06-23 17:39:23 +02:00 committed by Behdad Esfahbod
parent 71a6296620
commit c3be28ea26
9 changed files with 43 additions and 0 deletions

View File

@ -574,6 +574,35 @@ hb_ensure_native_direction (hb_buffer_t *buffer)
hb_direction_t direction = buffer->props.direction;
hb_direction_t horiz_dir = hb_script_get_horizontal_direction (buffer->props.script);
/* Numeric runs in natively-RTL scripts are actually native-LTR, so we reset
* the horiz_dir if the run contains at least one decimal-number char, and no
* letter chars (ideally we should be checking for chars with strong
* directionality but hb-unicode currently lacks bidi categories).
*
* This allows digit sequences in Arabic etc to be shaped in "native"
* direction, so that features like ligatures will work as intended.
*
* https://github.com/harfbuzz/harfbuzz/issues/501
*/
if (unlikely (horiz_dir == HB_DIRECTION_RTL && direction == HB_DIRECTION_LTR))
{
bool found_number = false, found_letter = false;
const auto* info = buffer->info;
foreach_grapheme (buffer, start, end)
{
auto gc = _hb_glyph_info_get_general_category (&info[start]);
if (gc == HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER)
found_number = true;
else if (HB_UNICODE_GENERAL_CATEGORY_IS_LETTER (gc))
{
found_letter = true;
break;
}
}
if (found_number && !found_letter)
horiz_dir = HB_DIRECTION_LTR;
}
/* TODO vertical:
* The only BTT vertical script is Ogham, but it's not clear to me whether OpenType
* Ogham fonts are supposed to be implemented BTT or not. Need to research that

View File

@ -359,6 +359,13 @@ DECLARE_NULL_INSTANCE (hb_unicode_funcs_t);
FLAG (HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | \
FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)))
#define HB_UNICODE_GENERAL_CATEGORY_IS_LETTER(gen_cat) \
(FLAG_UNSAFE (gen_cat) & \
(FLAG (HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER) | \
FLAG (HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER) | \
FLAG (HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER) | \
FLAG (HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER) | \
FLAG (HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER)))
/*
* Ranges, used for bsearch tables.

View File

@ -14,6 +14,7 @@ TESTS = \
tests/context-matching.tests \
tests/cursive-positioning.tests \
tests/default-ignorables.tests \
tests/digits.tests \
tests/emoji.tests \
tests/fallback-positioning.tests \
tests/hangul-jamo.tests \

View File

@ -14,6 +14,7 @@ in_house_tests = [
'context-matching.tests',
'cursive-positioning.tests',
'default-ignorables.tests',
'digits.tests',
'emoji.tests',
'fallback-positioning.tests',
'hangul-jamo.tests',

View File

@ -0,0 +1,5 @@
../fonts/a6b17da98b9f1565ba428719777bbf94a66403c1.ttf:--direction=ltr --script=arab:U+06DD,U+0661,U+0662,U+0663:[uni06DD=0+1279|uni0661.small=1@-1079,0+0|uni0662.small=2@-786,0+0|uni0663.small=3@-493,0+0]
../fonts/e5ff44940364c2247abed50bdda30d2ef5aedfe4.ttf:--direction=ltr --script=arab --features=pnum:U+0661,U+0662,U+0668,U+0663,U+0667:[uni0661.prop=0+361|uni0662.prop=1+436|uni0668.prop=2+478|uni0663.prop=3+597|uni0667.prop=4+527]
../fonts/b082211be29a3e2cf91f0fd43497e40b2a27b344.ttf:--direction=ltr --script=arab:U+06DD,U+0661,U+0662,U+0628:[uni06DD=0+1279|uni0661=1+585|uni0662=2+585|uni0628=3+926]
../fonts/3b791518a9ba89675df02f1eefbc9026a50648a6.ttf:--direction=ltr --script=arab:U+06DD,U+0661,U+0662,U+0663:[AyahEnd.alt3=0+1724|OneArabic.encl=0@-1143,444+0|TwoArabic.encl=0@-864,444+0|ThreeArabic.encl=0@-584,444+0]
../fonts/3b791518a9ba89675df02f1eefbc9026a50648a6.ttf:--direction=rtl --script=arab:U+06DD,U+0661,U+0662,U+0663:[ThreeArabic.encl=0@1140,444+0|TwoArabic.encl=0@860,444+0|OneArabic.encl=0@581,444+0|AyahEnd.alt3=0+1724]