Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/main.c | 84 ++++++++++++++-------------------------- dlls/dwrite/tests/font.c | 1 - 2 files changed, 28 insertions(+), 57 deletions(-)
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index 40c82b6cd05..3b0505231bf 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -1551,76 +1551,48 @@ static HRESULT WINAPI dwritefactory4_TranslateColorGlyphRun(IDWriteFactory7 *ifa }
static HRESULT compute_glyph_origins(DWRITE_GLYPH_RUN const *run, DWRITE_MEASURING_MODE measuring_mode, - D2D1_POINT_2F baseline_origin, DWRITE_MATRIX const *transform, D2D1_POINT_2F *origins) + D2D1_POINT_2F baseline_origin, DWRITE_MATRIX const *transform, D2D1_POINT_2F *origins) { - IDWriteFontFace1 *fontface1 = NULL; - DWRITE_FONT_METRICS metrics; - FLOAT rtl_factor; - HRESULT hr; - UINT32 i; + struct dwrite_fontface *font_obj; + unsigned int i; + float advance;
- rtl_factor = run->bidiLevel & 1 ? -1.0f : 1.0f; + font_obj = unsafe_impl_from_IDWriteFontFace(run->fontFace);
- if (run->fontFace) { - IDWriteFontFace_GetMetrics(run->fontFace, &metrics); - if (FAILED(hr = IDWriteFontFace_QueryInterface(run->fontFace, &IID_IDWriteFontFace1, (void **)&fontface1))) - WARN("Failed to get IDWriteFontFace1, %#x.\n", hr); - } + for (i = 0; i < run->glyphCount; ++i) + { + origins[i] = baseline_origin;
- for (i = 0; i < run->glyphCount; i++) { - FLOAT advance; + if (run->bidiLevel & 1) + { + advance = fontface_get_scaled_design_advance(font_obj, measuring_mode, run->fontEmSize, + 1.0f, transform, run->glyphIndices[i], run->isSideways);
- /* Use nominal advances if not provided by caller. */ - if (run->glyphAdvances) - advance = rtl_factor * run->glyphAdvances[i]; - else { - INT32 a; + origins[i].x -= advance;
- advance = 0.0f; - switch (measuring_mode) + if (run->glyphOffsets) { - case DWRITE_MEASURING_MODE_NATURAL: - if (SUCCEEDED(IDWriteFontFace1_GetDesignGlyphAdvances(fontface1, 1, run->glyphIndices + i, &a, - run->isSideways))) - advance = rtl_factor * get_scaled_advance_width(a, run->fontEmSize, &metrics); - break; - case DWRITE_MEASURING_MODE_GDI_CLASSIC: - case DWRITE_MEASURING_MODE_GDI_NATURAL: - if (SUCCEEDED(IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1, run->fontEmSize, - 1.0f, transform, measuring_mode == DWRITE_MEASURING_MODE_GDI_NATURAL, - run->isSideways, 1, run->glyphIndices + i, &a))) - advance = rtl_factor * floorf(a * run->fontEmSize / metrics.designUnitsPerEm + 0.5f); - break; - default: - ; + origins[i].x -= run->glyphOffsets[i].advanceOffset; + origins[i].y -= run->glyphOffsets[i].ascenderOffset; } - }
- origins[i] = baseline_origin; + baseline_origin.x -= run->glyphAdvances ? run->glyphAdvances[i] : advance; + } + else + { + if (run->glyphOffsets) + { + origins[i].x += run->glyphOffsets[i].advanceOffset; + origins[i].y -= run->glyphOffsets[i].ascenderOffset; + }
- /* Apply offsets. */ - if (run->glyphOffsets) { - FLOAT advanceoffset = rtl_factor * run->glyphOffsets[i].advanceOffset; - FLOAT ascenderoffset = -run->glyphOffsets[i].ascenderOffset; + baseline_origin.x += run->glyphAdvances ? run->glyphAdvances[i] : + fontface_get_scaled_design_advance(font_obj, measuring_mode, run->fontEmSize, 1.0f, transform, + run->glyphIndices[i], run->isSideways);
- if (run->isSideways) { - origins[i].x += ascenderoffset; - origins[i].y += advanceoffset; - } - else { - origins[i].x += advanceoffset; - origins[i].y += ascenderoffset; - } } - - if (run->isSideways) - baseline_origin.y += advance; - else - baseline_origin.x += advance; }
- if (fontface1) - IDWriteFontFace1_Release(fontface1); return S_OK; }
diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index 872405b1639..d7ced109a2f 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -8468,7 +8468,6 @@ static void test_ComputeGlyphOrigins(void) ok(hr == S_OK, "%u: failed to compute glyph origins, hr %#x.\n", i, hr); for (j = 0; j < run.glyphCount; ++j) { - todo_wine_if(run.bidiLevel & 1) ok(!memcmp(&origins[j], &expected_origins[j], sizeof(origins[j])), "%u: unexpected origin[%u] (%f, %f) - (%f, %f).\n", i, j, origins[j].x, origins[j].y, expected_origins[j].x, expected_origins[j].y);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 2 ++ dlls/dwrite/font.c | 57 ++++-------------------------------- dlls/dwrite/freetype.c | 36 +++++++++++++---------- dlls/dwrite/main.c | 2 +- 4 files changed, 29 insertions(+), 68 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 830c71f0abf..13bef3ad36b 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -347,6 +347,8 @@ extern HRESULT create_inmemory_fileloader(IDWriteInMemoryFontFileLoader **loader extern HRESULT create_font_resource(IDWriteFactory7 *factory, IDWriteFontFile *file, UINT32 face_index, IDWriteFontResource **resource) DECLSPEC_HIDDEN; extern HRESULT create_fontset_builder(IDWriteFactory7 *factory, IDWriteFontSetBuilder2 **ret) DECLSPEC_HIDDEN; +extern HRESULT compute_glyph_origins(DWRITE_GLYPH_RUN const *run, DWRITE_MEASURING_MODE measuring_mode, + D2D1_POINT_2F baseline_origin, DWRITE_MATRIX const *transform, D2D1_POINT_2F *origins) DECLSPEC_HIDDEN;
struct dwrite_fontface;
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index e22e4abf271..ac8f5c0a7bb 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -5918,10 +5918,7 @@ float fontface_get_scaled_design_advance(struct dwrite_fontface *fontface, DWRIT HRESULT create_glyphrunanalysis(const struct glyphrunanalysis_desc *desc, IDWriteGlyphRunAnalysis **ret) { struct dwrite_glyphrunanalysis *analysis; - struct dwrite_fontface *fontface; - D2D_POINT_2F origin; - FLOAT rtl_factor; - UINT32 i; + unsigned int i;
*ret = NULL;
@@ -5977,57 +5974,13 @@ HRESULT create_glyphrunanalysis(const struct glyphrunanalysis_desc *desc, IDWrit }
analysis->run.glyphIndices = analysis->glyphs; - - rtl_factor = desc->run->bidiLevel & 1 ? -1.0f : 1.0f; - memcpy(analysis->glyphs, desc->run->glyphIndices, desc->run->glyphCount*sizeof(*desc->run->glyphIndices));
- fontface = unsafe_impl_from_IDWriteFontFace(desc->run->fontFace); - - origin.x = desc->origin.x; - origin.y = desc->origin.y; - for (i = 0; i < desc->run->glyphCount; ++i) + compute_glyph_origins(desc->run, desc->measuring_mode, desc->origin, desc->transform, analysis->origins); + if (analysis->flags & RUNANALYSIS_USE_TRANSFORM) { - float advance; - - /* Use nominal advances if not provided by caller. */ - if (desc->run->glyphAdvances) - advance = rtl_factor * desc->run->glyphAdvances[i]; - else - advance = rtl_factor * fontface_get_scaled_design_advance(fontface, desc->measuring_mode, - desc->run->fontEmSize, 1.0f, desc->transform, desc->run->glyphIndices[i], desc->run->isSideways); - - analysis->origins[i] = origin; - if (desc->run->bidiLevel & 1) - { - if (desc->run->isSideways) - analysis->origins[i].y += advance; - else - analysis->origins[i].x += advance; - } - - /* Offsets are optional, appled to pre-transformed origin. */ - if (desc->run->glyphOffsets) { - FLOAT advanceoffset = rtl_factor * desc->run->glyphOffsets[i].advanceOffset; - FLOAT ascenderoffset = -desc->run->glyphOffsets[i].ascenderOffset; - - if (desc->run->isSideways) { - analysis->origins[i].x += ascenderoffset; - analysis->origins[i].y += advanceoffset; - } - else { - analysis->origins[i].x += advanceoffset; - analysis->origins[i].y += ascenderoffset; - } - } - - if (analysis->flags & RUNANALYSIS_USE_TRANSFORM) - transform_point(analysis->origins + i, &analysis->m); - - if (desc->run->isSideways) - origin.y += advance; - else - origin.x += advance; + for (i = 0; i < desc->run->glyphCount; ++i) + transform_point(&analysis->origins[i], &analysis->m); }
*ret = &analysis->IDWriteGlyphRunAnalysis_iface; diff --git a/dlls/dwrite/freetype.c b/dlls/dwrite/freetype.c index 91e44d82f2b..32fa4cc97c3 100644 --- a/dlls/dwrite/freetype.c +++ b/dlls/dwrite/freetype.c @@ -488,8 +488,8 @@ HRESULT freetype_get_glyphrun_outline(IDWriteFontFace5 *fontface, float emSize, scaler.y_res = 0;
EnterCriticalSection(&freetype_cs); - if (pFTC_Manager_LookupSize(cache_manager, &scaler, &size) == 0) { - float rtl_factor = is_rtl ? -1.0f : 1.0f; + if (pFTC_Manager_LookupSize(cache_manager, &scaler, &size) == 0) + { D2D1_POINT_2F origin; unsigned int i;
@@ -501,7 +501,6 @@ HRESULT freetype_get_glyphrun_outline(IDWriteFontFace5 *fontface, float emSize, FLOAT ft_advance = size->face->glyph->metrics.horiAdvance >> 6; FT_Outline *outline = &size->face->glyph->outline; D2D1_POINT_2F glyph_origin; - float advance; FT_Matrix m;
if (simulations & DWRITE_FONT_SIMULATIONS_BOLD) @@ -514,25 +513,32 @@ HRESULT freetype_get_glyphrun_outline(IDWriteFontFace5 *fontface, float emSize,
pFT_Outline_Transform(outline, &m);
- if (advances) - advance = rtl_factor * advances[i]; - else - advance = rtl_factor * ft_advance; - glyph_origin = origin; + if (is_rtl) - glyph_origin.x += advance; + { + glyph_origin.x -= ft_advance;
- /* glyph offsets act as current glyph adjustment */ - if (offsets) + if (offsets) + { + glyph_origin.x -= offsets[i].advanceOffset; + glyph_origin.y -= offsets[i].ascenderOffset; + } + + origin.x -= advances ? advances[i] : ft_advance; + } + else { - glyph_origin.x += rtl_factor * offsets[i].advanceOffset; - glyph_origin.y -= offsets[i].ascenderOffset; + if (offsets) + { + glyph_origin.x += offsets[i].advanceOffset; + glyph_origin.y -= offsets[i].ascenderOffset; + } + + origin.x += advances ? advances[i] : ft_advance; }
decompose_outline(outline, glyph_origin, sink); - - origin.x += advance; } } } diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index 3b0505231bf..560661983d0 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -1550,7 +1550,7 @@ static HRESULT WINAPI dwritefactory4_TranslateColorGlyphRun(IDWriteFactory7 *ifa return E_NOTIMPL; }
-static HRESULT compute_glyph_origins(DWRITE_GLYPH_RUN const *run, DWRITE_MEASURING_MODE measuring_mode, +HRESULT compute_glyph_origins(DWRITE_GLYPH_RUN const *run, DWRITE_MEASURING_MODE measuring_mode, D2D1_POINT_2F baseline_origin, DWRITE_MATRIX const *transform, D2D1_POINT_2F *origins) { struct dwrite_fontface *font_obj;
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/analyzer.c | 4 ++-- dlls/dwrite/dwrite_private.h | 2 +- dlls/dwrite/layout.c | 21 +++++++++++---------- dlls/dwrite/main.c | 2 +- 4 files changed, 15 insertions(+), 14 deletions(-)
diff --git a/dlls/dwrite/analyzer.c b/dlls/dwrite/analyzer.c index d0d769cb346..6b74a23540a 100644 --- a/dlls/dwrite/analyzer.c +++ b/dlls/dwrite/analyzer.c @@ -1844,9 +1844,9 @@ static const IDWriteTextAnalyzer2Vtbl textanalyzervtbl =
static IDWriteTextAnalyzer2 textanalyzer = { &textanalyzervtbl };
-IDWriteTextAnalyzer *get_text_analyzer(void) +IDWriteTextAnalyzer2 *get_text_analyzer(void) { - return (IDWriteTextAnalyzer *)&textanalyzer; + return &textanalyzer; }
static HRESULT WINAPI dwritenumbersubstitution_QueryInterface(IDWriteNumberSubstitution *iface, REFIID riid, void **obj) diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 13bef3ad36b..6528970635b 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -304,7 +304,7 @@ extern void set_en_localizedstring(IDWriteLocalizedStrings*,const WCHAR*) DEC extern void sort_localizedstrings(IDWriteLocalizedStrings*) DECLSPEC_HIDDEN; extern HRESULT get_system_fontcollection(IDWriteFactory7 *factory, IDWriteFontCollection1 **collection) DECLSPEC_HIDDEN; extern HRESULT get_eudc_fontcollection(IDWriteFactory7 *factory, IDWriteFontCollection3 **collection) DECLSPEC_HIDDEN; -extern IDWriteTextAnalyzer *get_text_analyzer(void) DECLSPEC_HIDDEN; +extern IDWriteTextAnalyzer2 *get_text_analyzer(void) DECLSPEC_HIDDEN; extern HRESULT create_font_file(IDWriteFontFileLoader *loader, const void *reference_key, UINT32 key_size, IDWriteFontFile **font_file) DECLSPEC_HIDDEN; extern void init_local_fontfile_loader(void) DECLSPEC_HIDDEN; extern IDWriteFontFileLoader *get_local_fontfile_loader(void) DECLSPEC_HIDDEN; diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c index fc874541d74..3e5c0379609 100644 --- a/dlls/dwrite/layout.c +++ b/dlls/dwrite/layout.c @@ -790,7 +790,7 @@ static void layout_get_font_height(FLOAT emsize, DWRITE_FONT_METRICS *fontmetric
static HRESULT layout_itemize(struct dwrite_textlayout *layout) { - IDWriteTextAnalyzer *analyzer; + IDWriteTextAnalyzer2 *analyzer; struct layout_range *range; struct layout_run *r; HRESULT hr = S_OK; @@ -818,14 +818,14 @@ static HRESULT layout_itemize(struct dwrite_textlayout *layout) }
/* Initial splitting by script. */ - hr = IDWriteTextAnalyzer_AnalyzeScript(analyzer, (IDWriteTextAnalysisSource *)&layout->IDWriteTextAnalysisSource1_iface, + hr = IDWriteTextAnalyzer2_AnalyzeScript(analyzer, (IDWriteTextAnalysisSource *)&layout->IDWriteTextAnalysisSource1_iface, range->h.range.startPosition, get_clipped_range_length(layout, range), (IDWriteTextAnalysisSink *)&layout->IDWriteTextAnalysisSink1_iface); if (FAILED(hr)) break;
/* Splitting further by bidi levels. */ - hr = IDWriteTextAnalyzer_AnalyzeBidi(analyzer, (IDWriteTextAnalysisSource *)&layout->IDWriteTextAnalysisSource1_iface, + hr = IDWriteTextAnalyzer2_AnalyzeBidi(analyzer, (IDWriteTextAnalysisSource *)&layout->IDWriteTextAnalysisSource1_iface, range->h.range.startPosition, get_clipped_range_length(layout, range), (IDWriteTextAnalysisSink *)&layout->IDWriteTextAnalysisSink1_iface); if (FAILED(hr)) @@ -962,7 +962,7 @@ fatal:
struct shaping_context { - IDWriteTextAnalyzer *analyzer; + IDWriteTextAnalyzer2 *analyzer; struct regular_layout_run *run; DWRITE_SHAPING_GLYPH_PROPERTIES *glyph_props; DWRITE_SHAPING_TEXT_PROPERTIES *text_props; @@ -1109,7 +1109,7 @@ static HRESULT layout_shape_get_glyphs(struct dwrite_textlayout *layout, struct
for (;;) { - hr = IDWriteTextAnalyzer_GetGlyphs(context->analyzer, run->descr.string, run->descr.stringLength, run->run.fontFace, + hr = IDWriteTextAnalyzer2_GetGlyphs(context->analyzer, run->descr.string, run->descr.stringLength, run->run.fontFace, run->run.isSideways, run->run.bidiLevel & 1, &run->sa, run->descr.localeName, NULL /* FIXME */, (const DWRITE_TYPOGRAPHIC_FEATURES **)context->user_features.features, context->user_features.range_lengths, context->user_features.range_count, max_count, run->clustermap, context->text_props, run->glyphs, @@ -1156,14 +1156,14 @@ static HRESULT layout_shape_get_positions(struct dwrite_textlayout *layout, stru
/* Get advances and offsets. */ if (is_layout_gdi_compatible(layout)) - hr = IDWriteTextAnalyzer_GetGdiCompatibleGlyphPlacements(context->analyzer, run->descr.string, run->descr.clusterMap, + hr = IDWriteTextAnalyzer2_GetGdiCompatibleGlyphPlacements(context->analyzer, run->descr.string, run->descr.clusterMap, context->text_props, run->descr.stringLength, run->run.glyphIndices, context->glyph_props, run->glyphcount, run->run.fontFace, run->run.fontEmSize, layout->ppdip, &layout->transform, layout->measuringmode == DWRITE_MEASURING_MODE_GDI_NATURAL, run->run.isSideways, run->run.bidiLevel & 1, &run->sa, run->descr.localeName, (const DWRITE_TYPOGRAPHIC_FEATURES **)context->user_features.features, context->user_features.range_lengths, context->user_features.range_count, run->advances, run->offsets); else - hr = IDWriteTextAnalyzer_GetGlyphPlacements(context->analyzer, run->descr.string, run->descr.clusterMap, + hr = IDWriteTextAnalyzer2_GetGlyphPlacements(context->analyzer, run->descr.string, run->descr.clusterMap, context->text_props, run->descr.stringLength, run->run.glyphIndices, context->glyph_props, run->glyphcount, run->run.fontFace, run->run.fontEmSize, run->run.isSideways, run->run.bidiLevel & 1, &run->sa, run->descr.localeName, (const DWRITE_TYPOGRAPHIC_FEATURES **)context->user_features.features, @@ -1302,8 +1302,9 @@ static HRESULT layout_compute(struct dwrite_textlayout *layout) return S_OK;
/* nominal breakpoints are evaluated only once, because string never changes */ - if (!layout->nominal_breakpoints) { - IDWriteTextAnalyzer *analyzer; + if (!layout->nominal_breakpoints) + { + IDWriteTextAnalyzer2 *analyzer;
layout->nominal_breakpoints = heap_calloc(layout->len, sizeof(*layout->nominal_breakpoints)); if (!layout->nominal_breakpoints) @@ -1311,7 +1312,7 @@ static HRESULT layout_compute(struct dwrite_textlayout *layout)
analyzer = get_text_analyzer();
- if (FAILED(hr = IDWriteTextAnalyzer_AnalyzeLineBreakpoints(analyzer, + if (FAILED(hr = IDWriteTextAnalyzer2_AnalyzeLineBreakpoints(analyzer, (IDWriteTextAnalysisSource *)&layout->IDWriteTextAnalysisSource1_iface, 0, layout->len, (IDWriteTextAnalysisSink *)&layout->IDWriteTextAnalysisSink1_iface))) WARN("Line breakpoints analysis failed, hr %#x.\n", hr); diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index 560661983d0..864a44936c1 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -1243,7 +1243,7 @@ static HRESULT WINAPI dwritefactory_CreateTextAnalyzer(IDWriteFactory7 *iface, I { TRACE("%p, %p.\n", iface, analyzer);
- *analyzer = get_text_analyzer(); + *analyzer = (IDWriteTextAnalyzer *)get_text_analyzer();
return S_OK; }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/layout.c | 79 ++++++++++++++++++++++++++++++++++++++ dlls/dwrite/tests/layout.c | 4 +- 2 files changed, 81 insertions(+), 2 deletions(-)
diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c index 3e5c0379609..38be4eeb2da 100644 --- a/dlls/dwrite/layout.c +++ b/dlls/dwrite/layout.c @@ -1144,6 +1144,82 @@ static HRESULT layout_shape_get_glyphs(struct dwrite_textlayout *layout, struct return hr; }
+static struct layout_range_spacing *layout_get_next_spacing_range(struct dwrite_textlayout *layout, + struct layout_range_spacing *cur) +{ + return (struct layout_range_spacing *)LIST_ENTRY(list_next(&layout->spacing, &cur->h.entry), + struct layout_range_header, entry); +} + +static HRESULT layout_shape_apply_character_spacing(struct dwrite_textlayout *layout, struct shaping_context *context) +{ + struct regular_layout_run *run = context->run; + struct layout_range_spacing *first = NULL, *last = NULL, *cur; + unsigned int i, length, pos, start, end, g0, glyph_count; + struct layout_range_header *h; + UINT16 *clustermap; + + LIST_FOR_EACH_ENTRY(h, &layout->spacing, struct layout_range_header, entry) + { + if ((h->range.startPosition >= run->descr.textPosition && + h->range.startPosition <= run->descr.textPosition + run->descr.stringLength) || + (run->descr.textPosition >= h->range.startPosition && + run->descr.textPosition <= h->range.startPosition + h->range.length)) + { + if (!first) first = last = (struct layout_range_spacing *)h; + } + else if (last) break; + } + if (!first) return S_OK; + + if (!(clustermap = heap_calloc(run->descr.stringLength, sizeof(*clustermap)))) return E_OUTOFMEMORY; + + pos = run->descr.textPosition; + + for (cur = first;; cur = layout_get_next_spacing_range(layout, cur)) + { + float leading, trailing; + + /* The range current spacing settings apply to. */ + start = max(pos, cur->h.range.startPosition); + pos = end = min(pos + run->descr.stringLength, cur->h.range.startPosition + cur->h.range.length); + + /* Back to run-relative index. */ + start -= run->descr.textPosition; + end -= run->descr.textPosition; + + length = end - start; + + g0 = run->descr.clusterMap[start]; + + for (i = 0; i < length; ++i) + clustermap[i] = run->descr.clusterMap[start + i] - run->descr.clusterMap[start]; + + glyph_count = (end < run->descr.stringLength ? run->descr.clusterMap[end] + 1 : run->glyphcount) - g0; + + /* There is no direction argument for spacing interface, we have to swap arguments here to get desired output. */ + if (run->run.bidiLevel & 1) + { + leading = cur->trailing; + trailing = cur->leading; + } + else + { + leading = cur->leading; + trailing = cur->trailing; + } + IDWriteTextAnalyzer2_ApplyCharacterSpacing(context->analyzer, leading, trailing, cur->min_advance, + length, glyph_count, clustermap, &run->advances[g0], &run->offsets[g0], &context->glyph_props[g0], + &run->advances[g0], &run->offsets[g0]); + + if (cur == last) break; + } + + heap_free(clustermap); + + return S_OK; +} + static HRESULT layout_shape_get_positions(struct dwrite_textlayout *layout, struct shaping_context *context) { struct regular_layout_run *run = context->run; @@ -1176,6 +1252,9 @@ static HRESULT layout_shape_get_positions(struct dwrite_textlayout *layout, stru WARN("%s: failed to get glyph placement info, hr %#x.\n", debugstr_rundescr(&run->descr), hr); }
+ if (SUCCEEDED(hr)) + hr = layout_shape_apply_character_spacing(layout, context); + run->run.glyphAdvances = run->advances; run->run.glyphOffsets = run->offsets;
diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c index adc9503ffd9..43e62a39956 100644 --- a/dlls/dwrite/tests/layout.c +++ b/dlls/dwrite/tests/layout.c @@ -2121,8 +2121,8 @@ static void test_GetClusterMetrics(void) hr = IDWriteTextLayout_GetClusterMetrics(layout, metrics2, ARRAY_SIZE(metrics2), &count); ok(hr == S_OK, "got 0x%08x\n", hr); ok(count == 4, "got %u\n", count); - for (i = 0; i < count; i++) { -todo_wine + for (i = 0; i < count; ++i) + { ok(metrics2[i].width > metrics[i].width, "%u: got width %.2f, was %.2f\n", i, metrics2[i].width, metrics[i].width); ok(metrics2[i].length == 1, "%u: got length %u\n", i, metrics2[i].length);