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:
parent
8cddbdd785
commit
796f34e81f
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue