dwrite: Share same cluster for bases and following diacritics in initial map.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2020-06-10 17:21:33 +03:00 committed by Alexandre Julliard
parent 8cddbdd785
commit 796f34e81f
2 changed files with 28 additions and 14 deletions

View File

@ -5834,13 +5834,23 @@ static unsigned int opentype_is_default_ignorable(unsigned int codepoint)
(codepoint >= 0x180b && codepoint <= 0x180e) || (codepoint >= 0x200b && codepoint <= 0x200f); (codepoint >= 0x180b && codepoint <= 0x180e) || (codepoint >= 0x200b && codepoint <= 0x200f);
} }
static unsigned int opentype_is_diacritic(unsigned int codepoint)
{
WCHAR ch = codepoint;
WORD type = 0;
/* Ignore higher planes for now. */
if (codepoint > 0xffff) return 0;
GetStringTypeW(CT_CTYPE3, &ch, 1, &type);
return !!(type & C3_DIACRITIC);
}
static void opentype_get_nominal_glyphs(struct scriptshaping_context *context, const struct shaping_features *features) static void opentype_get_nominal_glyphs(struct scriptshaping_context *context, const struct shaping_features *features)
{ {
unsigned int rtlm_mask = shaping_features_get_mask(features, DWRITE_MAKE_OPENTYPE_TAG('r','t','l','m'), NULL); unsigned int rtlm_mask = shaping_features_get_mask(features, DWRITE_MAKE_OPENTYPE_TAG('r','t','l','m'), NULL);
const struct shaping_font_ops *font = context->cache->font; const struct shaping_font_ops *font = context->cache->font;
unsigned int i, g, c, codepoint, cluster_start_idx = 0;
UINT16 *clustermap = context->u.subst.clustermap; UINT16 *clustermap = context->u.subst.clustermap;
const WCHAR *text = context->text; const WCHAR *text = context->text;
unsigned int i, g, c, codepoint;
BOOL bmp; BOOL bmp;
memset(context->u.subst.glyph_props, 0, context->u.subst.max_glyph_count * sizeof(*context->u.subst.glyph_props)); memset(context->u.subst.glyph_props, 0, context->u.subst.max_glyph_count * sizeof(*context->u.subst.glyph_props));
@ -5873,17 +5883,25 @@ static void opentype_get_nominal_glyphs(struct scriptshaping_context *context, c
context->u.buffer.glyphs[g] = font->get_glyph(context->cache->context, codepoint); context->u.buffer.glyphs[g] = font->get_glyph(context->cache->context, codepoint);
context->u.buffer.glyph_props[g].justification = SCRIPT_JUSTIFY_CHARACTER; context->u.buffer.glyph_props[g].justification = SCRIPT_JUSTIFY_CHARACTER;
context->u.buffer.glyph_props[g].isClusterStart = 1;
opentype_set_subst_glyph_props(context, g); opentype_set_subst_glyph_props(context, g);
/* Group diacritics with preceding base. Glyph class is ignored here. */
if (!g || !opentype_is_diacritic(codepoint))
{
context->u.buffer.glyph_props[g].isClusterStart = 1;
cluster_start_idx = g;
}
if (opentype_is_default_ignorable(codepoint)) if (opentype_is_default_ignorable(codepoint))
context->u.buffer.glyph_props[g].isZeroWidthSpace = 1; context->u.buffer.glyph_props[g].isZeroWidthSpace = 1;
context->u.buffer.glyph_props[g].components = 1; context->u.buffer.glyph_props[g].components = 1;
context->glyph_count++; context->glyph_count++;
clustermap[i] = i; /* Set initial cluster map here, it's used for setting user features masks. */
clustermap[i] = cluster_start_idx;
if (!bmp) if (!bmp)
{ {
clustermap[i + 1] = i; clustermap[i + 1] = cluster_start_idx;
++i; ++i;
} }
} }

View File

@ -2630,13 +2630,11 @@ if (0) { /* crashes on native */
count = 0; count = 0;
hr = IDWriteTextLayout1_GetClusterMetrics(layout1, clusters, 4, &count); hr = IDWriteTextLayout1_GetClusterMetrics(layout1, clusters, 4, &count);
ok(hr == S_OK, "got 0x%08x\n", hr); ok(hr == S_OK, "got 0x%08x\n", hr);
todo_wine ok(count == 3, "Unexpected cluster count %u.\n", count);
ok(count == 3, "got %u\n", count);
if (count == 3) {
ok(clusters[0].length == 1, "got %u\n", clusters[0].length); ok(clusters[0].length == 1, "got %u\n", clusters[0].length);
ok(clusters[1].length == 2, "got %u\n", clusters[1].length); ok(clusters[1].length == 2, "got %u\n", clusters[1].length);
ok(clusters[2].length == 1, "got %u\n", clusters[2].length); ok(clusters[2].length == 1, "got %u\n", clusters[2].length);
}
/* pair kerning flag participates in itemization - combining characters /* pair kerning flag participates in itemization - combining characters
breaks */ breaks */
range.startPosition = 0; range.startPosition = 0;
@ -5235,9 +5233,8 @@ static void test_SetUnderline(void)
count = 0; count = 0;
hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, ARRAY_SIZE(clusters), &count); hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, ARRAY_SIZE(clusters), &count);
ok(hr == S_OK, "got 0x%08x\n", hr); ok(hr == S_OK, "Failed to get cluster metrics, hr %#x.\n", hr);
todo_wine ok(count == 3, "Unexpected cluster count %u.\n", count);
ok(count == 3, "got %u\n", count);
range.startPosition = 0; range.startPosition = 0;
range.length = 2; range.length = 2;
@ -5246,9 +5243,8 @@ todo_wine
count = 0; count = 0;
hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, ARRAY_SIZE(clusters), &count); hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, ARRAY_SIZE(clusters), &count);
ok(hr == S_OK, "got 0x%08x\n", hr); ok(hr == S_OK, "Failed to get cluster metrics, hr %#x.\n", hr);
todo_wine ok(count == 3, "Unexpected cluster count %u.\n", count);
ok(count == 3, "got %u\n", count);
flush_sequence(sequences, RENDERER_ID); flush_sequence(sequences, RENDERER_ID);
hr = IDWriteTextLayout_Draw(layout, NULL, &testrenderer, 0.0, 0.0); hr = IDWriteTextLayout_Draw(layout, NULL, &testrenderer, 0.0, 0.0);