From 0ea60ffecd7b2848f55c365328a982131cb75ab7 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Mon, 28 Aug 2017 14:18:04 +0300 Subject: [PATCH] dwrite: Fix proportional spacing method. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/dwrite/layout.c | 68 +++++++++++++++----------------------- dlls/dwrite/tests/layout.c | 27 +++++++++++++++ 2 files changed, 53 insertions(+), 42 deletions(-) diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c index c04738a1967..9109107adb6 100644 --- a/dlls/dwrite/layout.c +++ b/dlls/dwrite/layout.c @@ -1358,6 +1358,27 @@ static HRESULT layout_add_effective_run(struct dwrite_textlayout *layout, const return S_OK; } +static void layout_apply_line_spacing(struct dwrite_textlayout *layout, UINT32 line) +{ + switch (layout->format.spacing.method) + { + case DWRITE_LINE_SPACING_METHOD_DEFAULT: + layout->linemetrics[line].height = layout->lines[line].height; + layout->linemetrics[line].baseline = layout->lines[line].baseline; + break; + case DWRITE_LINE_SPACING_METHOD_UNIFORM: + layout->linemetrics[line].height = layout->format.spacing.height; + layout->linemetrics[line].baseline = layout->format.spacing.baseline; + break; + case DWRITE_LINE_SPACING_METHOD_PROPORTIONAL: + layout->linemetrics[line].height = layout->lines[line].height * layout->format.spacing.height; + layout->linemetrics[line].baseline = layout->lines[line].baseline * layout->format.spacing.baseline; + break; + default: + ERR("Unknown spacing method %u\n", layout->format.spacing.method); + } +} + static HRESULT layout_set_line_metrics(struct dwrite_textlayout *layout, DWRITE_LINE_METRICS1 *metrics) { UINT32 i = layout->metrics.lineCount; @@ -1391,28 +1412,12 @@ static HRESULT layout_set_line_metrics(struct dwrite_textlayout *layout, DWRITE_ } layout->linemetrics[i] = *metrics; - - switch (layout->format.spacing.method) - { - case DWRITE_LINE_SPACING_METHOD_UNIFORM: - if (layout->format.spacing.method == DWRITE_LINE_SPACING_METHOD_UNIFORM) { - layout->linemetrics[i].height = layout->format.spacing.height; - layout->linemetrics[i].baseline = layout->format.spacing.baseline; - } - break; - case DWRITE_LINE_SPACING_METHOD_PROPORTIONAL: - if (layout->format.spacing.method == DWRITE_LINE_SPACING_METHOD_UNIFORM) { - layout->linemetrics[i].height = layout->format.spacing.height * metrics->height; - layout->linemetrics[i].baseline = layout->format.spacing.baseline * metrics->baseline; - } - break; - default: - /* using content values */; - } - layout->lines[i].height = metrics->height; layout->lines[i].baseline = metrics->baseline; + if (layout->format.spacing.method != DWRITE_LINE_SPACING_METHOD_DEFAULT) + layout_apply_line_spacing(layout, i); + layout->metrics.lineCount++; return S_OK; } @@ -3967,29 +3972,8 @@ static HRESULT WINAPI dwritetextlayout3_SetLineSpacing(IDWriteTextLayout3 *iface if (!(This->recompute & RECOMPUTE_LINES)) { UINT32 line; - switch (This->format.spacing.method) - { - case DWRITE_LINE_SPACING_METHOD_DEFAULT: - for (line = 0; line < This->metrics.lineCount; line++) { - This->linemetrics[line].height = This->lines[line].height; - This->linemetrics[line].baseline = This->lines[line].baseline; - } - break; - case DWRITE_LINE_SPACING_METHOD_UNIFORM: - for (line = 0; line < This->metrics.lineCount; line++) { - This->linemetrics[line].height = This->format.spacing.height; - This->linemetrics[line].baseline = This->format.spacing.baseline; - } - break; - case DWRITE_LINE_SPACING_METHOD_PROPORTIONAL: - for (line = 0; line < This->metrics.lineCount; line++) { - This->linemetrics[line].height = This->format.spacing.height * This->lines[line].height; - This->linemetrics[line].baseline = This->format.spacing.baseline * This->lines[line].baseline; - } - break; - default: - ; - } + for (line = 0; line < This->metrics.lineCount; line++) + layout_apply_line_spacing(This, line); layout_set_line_positions(This); } diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c index 8ca50f0c6a7..ba32977c31f 100644 --- a/dlls/dwrite/tests/layout.c +++ b/dlls/dwrite/tests/layout.c @@ -3774,6 +3774,33 @@ static void test_GetLineMetrics(void) IDWriteTextLayout_Release(layout); + /* Switch to proportional */ + hr = IDWriteTextFormat_SetLineSpacing(format, DWRITE_LINE_SPACING_METHOD_PROPORTIONAL, 2.0f, 4.0f); + if (hr == S_OK) { + hr = IDWriteFactory_CreateTextLayout(factory, str4W, 1, format, 100.0f, 300.0f, &layout); + ok(hr == S_OK, "Failed to create layout, hr %#x.\n", hr); + + hr = IDWriteTextLayout_GetLineMetrics(layout, metrics, sizeof(metrics)/sizeof(metrics[0]), &count); + ok(hr == S_OK, "Failed to get line metrics, hr %#x.\n", hr); + ok(count == 1, "Unexpected line count %u\n", count); + + /* Back to default mode. */ + hr = IDWriteTextLayout_SetLineSpacing(layout, DWRITE_LINE_SPACING_METHOD_DEFAULT, 0.0f, 0.0f); + ok(hr == S_OK, "Failed to set spacing method, hr %#x.\n", hr); + + hr = IDWriteTextLayout_GetLineMetrics(layout, metrics + 1, 1, &count); + ok(hr == S_OK, "Failed to get line metrics, hr %#x.\n", hr); + ok(count == 1, "Unexpected line count %u\n", count); + + /* Proportional spacing applies multipliers to default, content based spacing. */ + ok(metrics[0].height == 2.0f * metrics[1].height, "Unexpected line height %f.\n", metrics[0].height); + ok(metrics[0].baseline == 4.0f * metrics[1].baseline, "Unexpected line baseline %f.\n", metrics[0].baseline); + + IDWriteTextLayout_Release(layout); + } + else + win_skip("Proportional spacing is not supported.\n"); + IDWriteTextFormat_Release(format); IDWriteFontFace_Release(fontface); IDWriteFactory_Release(factory);