[PATCH 1/2] dwrite: Initial layout GetMetrics() implementation

Nikolay Sivov nsivov at codeweavers.com
Wed Jul 1 12:43:30 CDT 2015


---

-------------- next part --------------
From 45d962b87943138ef9ed73be9a42d4a6f6522228 Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov at codeweavers.com>
Date: Wed, 1 Jul 2015 17:47:43 +0300
Subject: [PATCH 1/2] dwrite: Initial layout GetMetrics() implementation

---
 dlls/dwrite/layout.c       | 37 +++++++++++++++++++++++++++++++++----
 dlls/dwrite/tests/layout.c |  7 +++----
 2 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c
index 752bd50..a718538 100644
--- a/dlls/dwrite/layout.c
+++ b/dlls/dwrite/layout.c
@@ -248,6 +248,8 @@ struct dwrite_textlayout {
     UINT32 line_count;
     UINT32 line_alloc;
 
+    DWRITE_TEXT_METRICS1 metrics;
+
     /* gdi-compatible layout specifics */
     BOOL   gdicompatible;
     FLOAT  pixels_per_dip;
@@ -1125,7 +1127,7 @@ static HRESULT layout_compute_effective_runs(struct dwrite_textlayout *layout)
             i == layout->cluster_count - 1) /* end of the text */ {
 
             UINT32 strlength, last_cluster = i, index;
-            FLOAT descent;
+            FLOAT descent, trailingspacewidth;
 
             if (!overflow) {
                 metrics.length += layout->clustermetrics[i].length;
@@ -1145,6 +1147,7 @@ static HRESULT layout_compute_effective_runs(struct dwrite_textlayout *layout)
                trailing properties for current line */
             strlength = metrics.length;
             index = last_cluster;
+            trailingspacewidth = 0.0;
             while (strlength) {
                 DWRITE_CLUSTER_METRICS *cluster = &layout->clustermetrics[index];
 
@@ -1156,8 +1159,10 @@ static HRESULT layout_compute_effective_runs(struct dwrite_textlayout *layout)
                     metrics.newlineLength += cluster->length;
                 }
 
-                if (cluster->isWhitespace)
+                if (cluster->isWhitespace) {
                     metrics.trailingWhitespaceLength += cluster->length;
+                    trailingspacewidth += cluster->width;
+                }
 
                 strlength -= cluster->length;
                 index--;
@@ -1184,6 +1189,11 @@ static HRESULT layout_compute_effective_runs(struct dwrite_textlayout *layout)
             }
             metrics.height = descent + metrics.baseline;
 
+            if (width > layout->metrics.widthIncludingTrailingWhitespace)
+                layout->metrics.widthIncludingTrailingWhitespace = width;
+            if (width - trailingspacewidth > layout->metrics.width)
+                layout->metrics.width = width - trailingspacewidth;
+
             metrics.isTrimmed = width > layout->maxwidth;
             hr = layout_set_line_metrics(layout, &metrics, &line);
             if (FAILED(hr))
@@ -1203,6 +1213,12 @@ static HRESULT layout_compute_effective_runs(struct dwrite_textlayout *layout)
         textpos += layout->clustermetrics[i].length;
     }
 
+    layout->metrics.left = layout->metrics.top = 0.0;
+    layout->metrics.layoutWidth = layout->maxwidth;
+    layout->metrics.layoutHeight = layout->maxheight;
+    layout->metrics.maxBidiReorderingDepth = 1; /* FIXME */
+    layout->metrics.lineCount = layout->line_count;
+
     /* Now all line info is here, update effective runs positions in flow direction */
     erun = layout_get_next_erun(layout, NULL);
     inrun = layout_get_next_inline_run(layout, NULL);
@@ -1227,8 +1243,12 @@ static HRESULT layout_compute_effective_runs(struct dwrite_textlayout *layout)
             if (!inrun)
                 break;
         }
+
+        layout->metrics.height += layout->lines[line].height;
     }
 
+    layout->metrics.heightIncludingTrailingWhitespace = layout->metrics.height; /* FIXME: not true for vertical text */
+
     layout->recompute &= ~RECOMPUTE_EFFECTIVE_RUNS;
     return hr;
 }
@@ -2775,8 +2795,16 @@ static HRESULT WINAPI dwritetextlayout1_GetCharacterSpacing(IDWriteTextLayout2 *
 static HRESULT WINAPI dwritetextlayout2_GetMetrics(IDWriteTextLayout2 *iface, DWRITE_TEXT_METRICS1 *metrics)
 {
     struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
-    FIXME("(%p)->(%p): stub\n", This, metrics);
-    return E_NOTIMPL;
+    HRESULT hr;
+
+    TRACE("(%p)->(%p)\n", This, metrics);
+
+    hr = layout_compute_effective_runs(This);
+    if (FAILED(hr))
+        return hr;
+
+    *metrics = This->metrics;
+    return S_OK;
 }
 
 static HRESULT WINAPI dwritetextlayout2_SetVerticalGlyphOrientation(IDWriteTextLayout2 *iface, DWRITE_VERTICAL_GLYPH_ORIENTATION orientation)
@@ -3542,6 +3570,7 @@ static HRESULT init_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFormat *
     list_init(&layout->effects);
     list_init(&layout->spacing);
     memset(&layout->format, 0, sizeof(layout->format));
+    memset(&layout->metrics, 0, sizeof(layout->metrics));
 
     layout->gdicompatible = FALSE;
     layout->pixels_per_dip = 0.0;
diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c
index 43233f4..84e1a2b 100644
--- a/dlls/dwrite/tests/layout.c
+++ b/dlls/dwrite/tests/layout.c
@@ -2485,7 +2485,6 @@ static void test_GetMetrics(void)
 
     memset(&metrics, 0xcc, sizeof(metrics));
     hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
-todo_wine {
     ok(hr == S_OK, "got 0x%08x\n", hr);
     ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
     ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
@@ -2496,7 +2495,7 @@ todo_wine {
     ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
     ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
     ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
-}
+
     IDWriteTextLayout_Release(layout);
 
     /* a string with more complex bidi sequence */
@@ -2506,7 +2505,6 @@ todo_wine {
     memset(&metrics, 0xcc, sizeof(metrics));
     metrics.maxBidiReorderingDepth = 0;
     hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
-todo_wine {
     ok(hr == S_OK, "got 0x%08x\n", hr);
     ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
     ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
@@ -2515,9 +2513,10 @@ todo_wine {
     ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
     ok(metrics.layoutWidth == 500.0, "got %.2f\n", metrics.layoutWidth);
     ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
+todo_wine
     ok(metrics.maxBidiReorderingDepth > 1, "got %u\n", metrics.maxBidiReorderingDepth);
     ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
-}
+
     IDWriteTextLayout_Release(layout);
 
     IDWriteTextFormat_Release(format);
-- 
2.1.4



More information about the wine-patches mailing list