Nikolay Sivov : dwrite: Fix proportional spacing method.

Alexandre Julliard julliard at winehq.org
Mon Aug 28 14:05:17 CDT 2017


Module: wine
Branch: master
Commit: 0ea60ffecd7b2848f55c365328a982131cb75ab7
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=0ea60ffecd7b2848f55c365328a982131cb75ab7

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Mon Aug 28 14:18:04 2017 +0300

dwrite: Fix proportional spacing method.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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 c04738a..9109107 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 8ca50f0..ba32977 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);




More information about the wine-cvs mailing list