Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/opentype.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-)
diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index 7dc4a1f7b55..8885306a84d 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -5126,10 +5126,28 @@ static BOOL opentype_layout_context_match_input(const struct match_context *mc, return TRUE; }
-static void opentype_layout_unsafe_to_break(struct scriptshaping_context *context, unsigned int idx) +/* Marks text segment as unsafe to break between [start, end) glyphs. */ +static void opentype_layout_unsafe_to_break(struct scriptshaping_context *context, unsigned int start, + unsigned int end) { - if (context->u.buffer.glyph_props[idx].isClusterStart) - context->u.buffer.text_props[context->glyph_infos[idx].start_text_idx].canBreakShapingAfter = 0; + unsigned int i; + + while (start && !context->u.buffer.glyph_props[start].isClusterStart) + --start; + + while (--end && !context->u.buffer.glyph_props[end].isClusterStart) + ; + + if (start == end) + { + context->u.buffer.text_props[context->glyph_infos[start].start_text_idx].canBreakShapingAfter = 0; + return; + } + + for (i = context->glyph_infos[start].start_text_idx; i < context->glyph_infos[end].start_text_idx; ++i) + { + context->u.buffer.text_props[i].canBreakShapingAfter = 0; + } }
static void opentype_layout_delete_glyph(struct scriptshaping_context *context, unsigned int idx) @@ -5194,10 +5212,8 @@ static BOOL opentype_layout_apply_ligature(struct scriptshaping_context *context { context->u.buffer.glyph_props[j++].lig_component = comp_count - i; } - opentype_layout_unsafe_to_break(context, i); - context->u.buffer.glyph_props[i].isClusterStart = 0; - context->glyph_infos[i].start_text_idx = 0; } + opentype_layout_unsafe_to_break(context, match_positions[0], match_positions[comp_count - 1] + 1);
/* Delete ligated glyphs, backwards to preserve index. */ for (i = 1; i < comp_count; ++i)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 1 + dlls/dwrite/opentype.c | 1 + dlls/dwrite/shapers/arabic.c | 6 +++--- 3 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index fa36e92bde5..e03ad6c6c6d 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -521,6 +521,7 @@ struct shaping_glyph_info int attach_chain; /* Only relevant for isClusterStart glyphs. Indicates text position for this cluster. */ unsigned int start_text_idx; + unsigned int codepoint; };
struct shaping_glyph_properties diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index 8885306a84d..515d2440fcf 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -5949,6 +5949,7 @@ static void opentype_get_nominal_glyphs(struct scriptshaping_context *context, c if (*context->u.subst.digits && codepoint >= '0' && codepoint <= '9') codepoint = context->u.subst.digits[codepoint - '0'];
+ context->glyph_infos[g].codepoint = codepoint; context->u.buffer.glyphs[g] = font->get_glyph(context->cache->context, codepoint); context->u.buffer.glyph_props[g].justification = SCRIPT_JUSTIFY_CHARACTER; opentype_set_subst_glyph_props(context, g); diff --git a/dlls/dwrite/shapers/arabic.c b/dlls/dwrite/shapers/arabic.c index cc701150a56..cc598f834e5 100644 --- a/dlls/dwrite/shapers/arabic.c +++ b/dlls/dwrite/shapers/arabic.c @@ -147,9 +147,9 @@ static void arabic_setup_masks(struct scriptshaping_context *context, unsigned int i, prev = ~0u, state = 0; unsigned int masks[NUM_FEATURES];
- for (i = 0; i < context->length; ++i) + for (i = 0; i < context->glyph_count; ++i) { - unsigned short this_type = arabic_get_joining_type(context->text[i]); + unsigned short this_type = arabic_get_joining_type(context->glyph_infos[i].codepoint); const struct arabic_state_table_entry *entry;
if (this_type == JOINING_TYPE_T) @@ -173,7 +173,7 @@ static void arabic_setup_masks(struct scriptshaping_context *context, masks[i] = shape_get_feature_1_mask(features, arabic_features[i]);
/* Unaffected glyphs get action NONE with zero mask. */ - for (i = 0; i < context->length; ++i) + for (i = 0; i < context->glyph_count; ++i) context->glyph_infos[i].mask |= masks[arabic_get_shaping_action(context, i)]; }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 2 ++ dlls/dwrite/opentype.c | 2 +- dlls/dwrite/shapers/arabic.c | 7 ++++++- 3 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index e03ad6c6c6d..fa82a8d4376 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -690,6 +690,8 @@ extern void opentype_layout_apply_gpos_features(struct scriptshaping_context *co extern BOOL opentype_layout_check_feature(struct scriptshaping_context *context, unsigned int script_index, unsigned int language_index, struct shaping_feature *feature, unsigned int glyph_count, const UINT16 *glyphs, UINT8 *feature_applies) DECLSPEC_HIDDEN; +extern void opentype_layout_unsafe_to_break(struct scriptshaping_context *context, unsigned int start, + unsigned int end) DECLSPEC_HIDDEN; extern BOOL opentype_has_vertical_variants(struct dwrite_fontface *fontface) DECLSPEC_HIDDEN; extern HRESULT opentype_get_vertical_glyph_variants(struct dwrite_fontface *fontface, unsigned int glyph_count, const UINT16 *nominal_glyphs, UINT16 *glyphs) DECLSPEC_HIDDEN; diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index 515d2440fcf..afae1b69d07 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -5127,7 +5127,7 @@ static BOOL opentype_layout_context_match_input(const struct match_context *mc, }
/* Marks text segment as unsafe to break between [start, end) glyphs. */ -static void opentype_layout_unsafe_to_break(struct scriptshaping_context *context, unsigned int start, +void opentype_layout_unsafe_to_break(struct scriptshaping_context *context, unsigned int start, unsigned int end) { unsigned int i; diff --git a/dlls/dwrite/shapers/arabic.c b/dlls/dwrite/shapers/arabic.c index cc598f834e5..720f18915a4 100644 --- a/dlls/dwrite/shapers/arabic.c +++ b/dlls/dwrite/shapers/arabic.c @@ -174,7 +174,12 @@ static void arabic_setup_masks(struct scriptshaping_context *context,
/* Unaffected glyphs get action NONE with zero mask. */ for (i = 0; i < context->glyph_count; ++i) - context->glyph_infos[i].mask |= masks[arabic_get_shaping_action(context, i)]; + { + enum arabic_shaping_action action = arabic_get_shaping_action(context, i); + if (action != NONE) + opentype_layout_unsafe_to_break(context, i, i + 1); + context->glyph_infos[i].mask |= masks[action]; + } }
const struct shaper arabic_shaper =