[PATCH 5/5] dwrite: Partially implement GetBaseline().

Nikolay Sivov nsivov at codeweavers.com
Tue Jun 2 03:48:53 CDT 2020


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/dwrite/analyzer.c       | 58 ++++++++++++++++++++++++++++---
 dlls/dwrite/tests/analyzer.c | 67 ++++++++++++++++++++----------------
 2 files changed, 92 insertions(+), 33 deletions(-)

diff --git a/dlls/dwrite/analyzer.c b/dlls/dwrite/analyzer.c
index cb58f362990..a8a3e7c359b 100644
--- a/dlls/dwrite/analyzer.c
+++ b/dlls/dwrite/analyzer.c
@@ -1539,13 +1539,63 @@ static HRESULT WINAPI dwritetextanalyzer1_ApplyCharacterSpacing(IDWriteTextAnaly
     return S_OK;
 }
 
-static HRESULT WINAPI dwritetextanalyzer1_GetBaseline(IDWriteTextAnalyzer2 *iface, IDWriteFontFace *face,
+static HRESULT WINAPI dwritetextanalyzer1_GetBaseline(IDWriteTextAnalyzer2 *iface, IDWriteFontFace *fontface,
     DWRITE_BASELINE baseline, BOOL vertical, BOOL is_simulation_allowed, DWRITE_SCRIPT_ANALYSIS sa,
     const WCHAR *localeName, INT32 *baseline_coord, BOOL *exists)
 {
-    FIXME("(%p %d %d %u %s %p %p): stub\n", face, vertical, is_simulation_allowed, sa.script, debugstr_w(localeName),
-        baseline_coord, exists);
-    return E_NOTIMPL;
+    struct dwrite_fontface *font_obj;
+    const DWRITE_FONT_METRICS1 *metrics;
+
+    TRACE("%p, %d, %d, %u, %s, %p, %p.\n", fontface, vertical, is_simulation_allowed, sa.script, debugstr_w(localeName),
+            baseline_coord, exists);
+
+    *exists = FALSE;
+    *baseline_coord = 0;
+
+    if (baseline == DWRITE_BASELINE_DEFAULT)
+        baseline = vertical ? DWRITE_BASELINE_CENTRAL : DWRITE_BASELINE_ROMAN;
+
+    if ((unsigned int)baseline > DWRITE_BASELINE_MAXIMUM)
+        return E_INVALIDARG;
+
+    /* TODO: fetch BASE table data if available. */
+
+    if (!*exists && is_simulation_allowed)
+    {
+        font_obj = unsafe_impl_from_IDWriteFontFace(fontface);
+        metrics = &font_obj->metrics;
+
+        switch (baseline)
+        {
+            case DWRITE_BASELINE_ROMAN:
+                *baseline_coord = vertical ? metrics->descent : 0;
+                break;
+            case DWRITE_BASELINE_CENTRAL:
+                *baseline_coord = vertical ? (metrics->ascent + metrics->descent) / 2 :
+                        -(metrics->ascent - metrics->descent) / 2;
+                break;
+            case DWRITE_BASELINE_MATH:
+                *baseline_coord = vertical ? (metrics->ascent + metrics->descent) / 2 :
+                        -(metrics->ascent + metrics->descent) / 2;
+                break;
+            case DWRITE_BASELINE_HANGING:
+                /* FIXME: this one isn't accurate, but close. */
+                *baseline_coord = vertical ? metrics->capHeight * 6 / 7 + metrics->descent : metrics->capHeight * 6 / 7;
+                break;
+            case DWRITE_BASELINE_IDEOGRAPHIC_BOTTOM:
+            case DWRITE_BASELINE_MINIMUM:
+                *baseline_coord = vertical ? 0 : metrics->descent;
+                break;
+            case DWRITE_BASELINE_IDEOGRAPHIC_TOP:
+            case DWRITE_BASELINE_MAXIMUM:
+                *baseline_coord = vertical ? metrics->ascent + metrics->descent : -metrics->ascent;
+                break;
+            default:
+                ;
+        }
+    }
+
+    return S_OK;
 }
 
 static HRESULT WINAPI dwritetextanalyzer1_AnalyzeVerticalGlyphOrientation(IDWriteTextAnalyzer2 *iface,
diff --git a/dlls/dwrite/tests/analyzer.c b/dlls/dwrite/tests/analyzer.c
index c5cf0954fee..70becb55ee5 100644
--- a/dlls/dwrite/tests/analyzer.c
+++ b/dlls/dwrite/tests/analyzer.c
@@ -2484,39 +2484,48 @@ static void test_GetBaseline(void)
 
     fontface = create_fontface();
 
-    /* Tahoma doesn't have BASE table, it doesn't work even with simulation enabled */
+    /* Tahoma does not have a BASE table. */
+
     exists = TRUE;
     baseline = 456;
-    hr = IDWriteTextAnalyzer1_GetBaseline(analyzer1,
-       fontface,
-       DWRITE_BASELINE_DEFAULT,
-       FALSE,
-       TRUE,
-       sa,
-       NULL,
-       &baseline,
-       &exists);
-todo_wine {
-    ok(hr == S_OK, "got 0x%08x\n", hr);
-    ok(baseline == 0, "got %d\n", baseline);
-    ok(exists == FALSE, "got %d\n", exists);
-}
+    hr = IDWriteTextAnalyzer1_GetBaseline(analyzer1, fontface, DWRITE_BASELINE_DEFAULT, FALSE,
+           TRUE, sa, NULL, &baseline, &exists);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(!baseline, "Unexpected baseline %d.\n", baseline);
+    ok(!exists, "Unexpected flag %d.\n", exists);
+
     exists = TRUE;
     baseline = 456;
-    hr = IDWriteTextAnalyzer1_GetBaseline(analyzer1,
-       fontface,
-       DWRITE_BASELINE_ROMAN,
-       FALSE,
-       TRUE,
-       sa,
-       NULL,
-       &baseline,
-       &exists);
-todo_wine {
-    ok(hr == S_OK, "got 0x%08x\n", hr);
-    ok(baseline == 0, "got %d\n", baseline);
-    ok(exists == FALSE, "got %d\n", exists);
-}
+    hr = IDWriteTextAnalyzer1_GetBaseline(analyzer1, fontface, DWRITE_BASELINE_DEFAULT, FALSE,
+           FALSE, sa, NULL, &baseline, &exists);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(!baseline, "Unexpected baseline %d.\n", baseline);
+    ok(!exists, "Unexpected flag %d.\n", exists);
+
+    exists = TRUE;
+    baseline = 0;
+    hr = IDWriteTextAnalyzer1_GetBaseline(analyzer1, fontface, DWRITE_BASELINE_CENTRAL, FALSE,
+           TRUE, sa, NULL, &baseline, &exists);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(baseline != 0, "Unexpected baseline %d.\n", baseline);
+    ok(!exists, "Unexpected flag %d.\n", exists);
+
+    exists = TRUE;
+    baseline = 0;
+    hr = IDWriteTextAnalyzer1_GetBaseline(analyzer1, fontface, DWRITE_BASELINE_CENTRAL, FALSE,
+           FALSE, sa, NULL, &baseline, &exists);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(!baseline, "Unexpected baseline %d.\n", baseline);
+    ok(!exists, "Unexpected flag %d.\n", exists);
+
+    exists = TRUE;
+    baseline = 456;
+    hr = IDWriteTextAnalyzer1_GetBaseline(analyzer1, fontface, DWRITE_BASELINE_DEFAULT + 100, FALSE,
+           TRUE, sa, NULL, &baseline, &exists);
+    ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+    ok(!baseline, "Unexpected baseline %d.\n", baseline);
+    ok(!exists, "Unexpected flag %d.\n", exists);
+
     IDWriteFontFace_Release(fontface);
     IDWriteTextAnalyzer1_Release(analyzer1);
 }
-- 
2.26.2




More information about the wine-devel mailing list