< prev index next >
src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-arabic.cc
Print this page
*** 22,35 ****
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Google Author(s): Behdad Esfahbod
*/
! #include "hb-private.hh"
! #include "hb-debug.hh"
! #include "hb-ot-shape-complex-arabic-private.hh"
! #include "hb-ot-shape-private.hh"
/* buffer var allocations */
#define arabic_shaping_action() complex_var_u8_0() /* arabic shaping action */
--- 22,34 ----
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Google Author(s): Behdad Esfahbod
*/
! #include "hb.hh"
! #include "hb-ot-shape-complex-arabic.hh"
! #include "hb-ot-shape.hh"
/* buffer var allocations */
#define arabic_shaping_action() complex_var_u8_0() /* arabic shaping action */
*** 158,172 ****
{ {NONE,NONE,0}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN3,5}, {NONE,ISOL,6}, }
};
static void
- nuke_joiners (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer);
-
- static void
arabic_fallback_shape (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
--- 157,166 ----
*** 199,259 ****
*
* A pause after calt is required to make KFGQPC Uthmanic Script HAFS
* work correctly. See https://github.com/harfbuzz/harfbuzz/issues/505
*/
- map->add_gsub_pause (nuke_joiners);
! map->add_global_bool_feature (HB_TAG('s','t','c','h'));
map->add_gsub_pause (record_stch);
! map->add_global_bool_feature (HB_TAG('c','c','m','p'));
! map->add_global_bool_feature (HB_TAG('l','o','c','l'));
map->add_gsub_pause (nullptr);
for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++)
{
bool has_fallback = plan->props.script == HB_SCRIPT_ARABIC && !FEATURE_IS_SYRIAC (arabic_features[i]);
! map->add_feature (arabic_features[i], 1, has_fallback ? F_HAS_FALLBACK : F_NONE);
map->add_gsub_pause (nullptr);
}
! map->add_feature (HB_TAG('r','l','i','g'), 1, F_GLOBAL|F_HAS_FALLBACK);
if (plan->props.script == HB_SCRIPT_ARABIC)
map->add_gsub_pause (arabic_fallback_shape);
/* No pause after rclt. See 98460779bae19e4d64d29461ff154b3527bf8420. */
! map->add_global_bool_feature (HB_TAG('r','c','l','t'));
! map->add_global_bool_feature (HB_TAG('c','a','l','t'));
map->add_gsub_pause (nullptr);
/* The spec includes 'cswh'. Earlier versions of Windows
* used to enable this by default, but testing suggests
* that Windows 8 and later do not enable it by default,
* and spec now says 'Off by default'.
* We disabled this in ae23c24c32.
* Note that IranNastaliq uses this feature extensively
* to fixup broken glyph sequences. Oh well...
* Test case: U+0643,U+0640,U+0631. */
! //map->add_global_bool_feature (HB_TAG('c','s','w','h'));
! map->add_global_bool_feature (HB_TAG('m','s','e','t'));
}
#include "hb-ot-shape-complex-arabic-fallback.hh"
struct arabic_shape_plan_t
{
- ASSERT_POD ();
-
/* The "+ 1" in the next array is to accommodate for the "NONE" command,
* which is not an OpenType feature, but this simplifies the code by not
* having to do a "if (... < NONE) ..." and just rely on the fact that
* mask_array[NONE] == 0. */
hb_mask_t mask_array[ARABIC_NUM_FEATURES + 1];
! arabic_fallback_plan_t *fallback_plan;
unsigned int do_fallback : 1;
unsigned int has_stch : 1;
};
--- 193,257 ----
*
* A pause after calt is required to make KFGQPC Uthmanic Script HAFS
* work correctly. See https://github.com/harfbuzz/harfbuzz/issues/505
*/
! map->enable_feature (HB_TAG('s','t','c','h'));
map->add_gsub_pause (record_stch);
! map->enable_feature (HB_TAG('c','c','m','p'));
! map->enable_feature (HB_TAG('l','o','c','l'));
map->add_gsub_pause (nullptr);
for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++)
{
bool has_fallback = plan->props.script == HB_SCRIPT_ARABIC && !FEATURE_IS_SYRIAC (arabic_features[i]);
! map->add_feature (arabic_features[i], has_fallback ? F_HAS_FALLBACK : F_NONE);
map->add_gsub_pause (nullptr);
}
! /* Normally, Unicode says a ZWNJ means "don't ligate". In Arabic script
! * however, it says a ZWJ should also mean "don't ligate". So we run
! * the main ligating features as MANUAL_ZWJ. */
!
! map->enable_feature (HB_TAG('r','l','i','g'), F_MANUAL_ZWJ | F_HAS_FALLBACK);
!
if (plan->props.script == HB_SCRIPT_ARABIC)
map->add_gsub_pause (arabic_fallback_shape);
/* No pause after rclt. See 98460779bae19e4d64d29461ff154b3527bf8420. */
! map->enable_feature (HB_TAG('r','c','l','t'), F_MANUAL_ZWJ);
! map->enable_feature (HB_TAG('c','a','l','t'), F_MANUAL_ZWJ);
map->add_gsub_pause (nullptr);
+ /* And undo here. */
+
/* The spec includes 'cswh'. Earlier versions of Windows
* used to enable this by default, but testing suggests
* that Windows 8 and later do not enable it by default,
* and spec now says 'Off by default'.
* We disabled this in ae23c24c32.
* Note that IranNastaliq uses this feature extensively
* to fixup broken glyph sequences. Oh well...
* Test case: U+0643,U+0640,U+0631. */
! //map->enable_feature (HB_TAG('c','s','w','h'));
! map->enable_feature (HB_TAG('m','s','e','t'));
}
#include "hb-ot-shape-complex-arabic-fallback.hh"
struct arabic_shape_plan_t
{
/* The "+ 1" in the next array is to accommodate for the "NONE" command,
* which is not an OpenType feature, but this simplifies the code by not
* having to do a "if (... < NONE) ..." and just rely on the fact that
* mask_array[NONE] == 0. */
hb_mask_t mask_array[ARABIC_NUM_FEATURES + 1];
! hb_atomic_ptr_t<arabic_fallback_plan_t> fallback_plan;
unsigned int do_fallback : 1;
unsigned int has_stch : 1;
};
*** 378,400 ****
{
const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data;
setup_masks_arabic_plan (arabic_plan, buffer, plan->props.script);
}
-
- static void
- nuke_joiners (const hb_ot_shape_plan_t *plan HB_UNUSED,
- hb_font_t *font HB_UNUSED,
- hb_buffer_t *buffer)
- {
- unsigned int count = buffer->len;
- hb_glyph_info_t *info = buffer->info;
- for (unsigned int i = 0; i < count; i++)
- if (_hb_glyph_info_is_zwj (&info[i]))
- _hb_glyph_info_flip_joiners (&info[i]);
- }
-
static void
arabic_fallback_shape (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
--- 376,385 ----
*** 402,417 ****
if (!arabic_plan->do_fallback)
return;
retry:
! arabic_fallback_plan_t *fallback_plan = (arabic_fallback_plan_t *) hb_atomic_ptr_get (&arabic_plan->fallback_plan);
if (unlikely (!fallback_plan))
{
/* This sucks. We need a font to build the fallback plan... */
fallback_plan = arabic_fallback_plan_create (plan, font);
! if (unlikely (!hb_atomic_ptr_cmpexch (&(const_cast<arabic_shape_plan_t *> (arabic_plan))->fallback_plan, nullptr, fallback_plan))) {
arabic_fallback_plan_destroy (fallback_plan);
goto retry;
}
}
--- 387,403 ----
if (!arabic_plan->do_fallback)
return;
retry:
! arabic_fallback_plan_t *fallback_plan = arabic_plan->fallback_plan;
if (unlikely (!fallback_plan))
{
/* This sucks. We need a font to build the fallback plan... */
fallback_plan = arabic_fallback_plan_create (plan, font);
! if (unlikely (!arabic_plan->fallback_plan.cmpexch (nullptr, fallback_plan)))
! {
arabic_fallback_plan_destroy (fallback_plan);
goto retry;
}
}
*** 426,436 ****
* marks can use it as well.
*/
static void
record_stch (const hb_ot_shape_plan_t *plan,
! hb_font_t *font,
hb_buffer_t *buffer)
{
const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data;
if (!arabic_plan->has_stch)
return;
--- 412,422 ----
* marks can use it as well.
*/
static void
record_stch (const hb_ot_shape_plan_t *plan,
! hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data;
if (!arabic_plan->has_stch)
return;
*** 450,460 ****
buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH;
}
}
static void
! apply_stch (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
hb_font_t *font)
{
if (likely (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH)))
return;
--- 436,446 ----
buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH;
}
}
static void
! apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_buffer_t *buffer,
hb_font_t *font)
{
if (likely (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH)))
return;
*** 468,480 ****
* Second pass applies the stretch, copying things to the end of buffer.
*/
int sign = font->x_scale < 0 ? -1 : +1;
unsigned int extra_glyphs_needed = 0; // Set during MEASURE, used during CUT
! typedef enum { MEASURE, CUT } step_t;
! for (step_t step = MEASURE; step <= CUT; step = (step_t) (step + 1))
{
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
hb_glyph_position_t *pos = buffer->pos;
unsigned int new_len = count + extra_glyphs_needed; // write head during CUT
--- 454,466 ----
* Second pass applies the stretch, copying things to the end of buffer.
*/
int sign = font->x_scale < 0 ? -1 : +1;
unsigned int extra_glyphs_needed = 0; // Set during MEASURE, used during CUT
! enum { MEASURE, CUT } /* step_t */;
! for (unsigned int step = MEASURE; step <= CUT; step = step + 1)
{
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
hb_glyph_position_t *pos = buffer->pos;
unsigned int new_len = count + extra_glyphs_needed; // write head during CUT
*** 609,619 ****
apply_stch (plan, buffer, font);
HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
}
! /* https://unicode.org/reports/tr53/tr53-1.pdf */
static hb_codepoint_t
modifier_combining_marks[] =
{
0x0654u, /* ARABIC HAMZA ABOVE */
--- 595,605 ----
apply_stch (plan, buffer, font);
HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
}
! /* http://www.unicode.org/reports/tr53/ */
static hb_codepoint_t
modifier_combining_marks[] =
{
0x0654u, /* ARABIC HAMZA ABOVE */
*** 621,630 ****
--- 607,617 ----
0x0658u, /* ARABIC MARK NOON GHUNNA */
0x06DCu, /* ARABIC SMALL HIGH SEEN */
0x06E3u, /* ARABIC SMALL LOW SEEN */
0x06E7u, /* ARABIC SMALL HIGH YEH */
0x06E8u, /* ARABIC SMALL HIGH NOON */
+ 0x08D3u, /* ARABIC SMALL LOW WAW */
0x08F3u, /* ARABIC SMALL HIGH WAW */
};
static inline bool
info_is_mcm (const hb_glyph_info_t &info)
*** 635,645 ****
return true;
return false;
}
static void
! reorder_marks_arabic (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
unsigned int start,
unsigned int end)
{
hb_glyph_info_t *info = buffer->info;
--- 622,632 ----
return true;
return false;
}
static void
! reorder_marks_arabic (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_buffer_t *buffer,
unsigned int start,
unsigned int end)
{
hb_glyph_info_t *info = buffer->info;
*** 712,721 ****
postprocess_glyphs_arabic,
HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
nullptr, /* decompose */
nullptr, /* compose */
setup_masks_arabic,
! nullptr, /* disable_otl */
reorder_marks_arabic,
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
true, /* fallback_position */
};
--- 699,708 ----
postprocess_glyphs_arabic,
HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
nullptr, /* decompose */
nullptr, /* compose */
setup_masks_arabic,
! HB_TAG_NONE, /* gpos_tag */
reorder_marks_arabic,
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
true, /* fallback_position */
};
< prev index next >