Nikolay Sivov : dwrite: Implement GetTextComplexity().

Alexandre Julliard julliard at wine.codeweavers.com
Fri Sep 26 16:35:49 CDT 2014


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

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Fri Sep 26 12:54:02 2014 +0400

dwrite: Implement GetTextComplexity().

---

 dlls/dwrite/analyzer.c       |  54 +++++++++++++++++++-
 dlls/dwrite/tests/analyzer.c | 114 ++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 165 insertions(+), 3 deletions(-)

diff --git a/dlls/dwrite/analyzer.c b/dlls/dwrite/analyzer.c
index f9e3c11..46e3769 100644
--- a/dlls/dwrite/analyzer.c
+++ b/dlls/dwrite/analyzer.c
@@ -830,11 +830,61 @@ static HRESULT WINAPI dwritetextanalyzer1_GetScriptProperties(IDWriteTextAnalyze
     return S_OK;
 }
 
+static inline BOOL is_char_from_simple_script(WCHAR c)
+{
+    if (IS_HIGH_SURROGATE(c) || IS_LOW_SURROGATE(c))
+        return FALSE;
+    else {
+        UINT16 script = get_char_script(c);
+        return !dwritescripts_properties[script].is_complex;
+    }
+}
+
 static HRESULT WINAPI dwritetextanalyzer1_GetTextComplexity(IDWriteTextAnalyzer2 *iface, const WCHAR *text,
     UINT32 len, IDWriteFontFace *face, BOOL *is_simple, UINT32 *len_read, UINT16 *indices)
 {
-    FIXME("(%s:%u %p %p %p %p): stub\n", debugstr_wn(text, len), len, face, is_simple, len_read, indices);
-    return E_NOTIMPL;
+    HRESULT hr = S_OK;
+    int i;
+
+    TRACE("(%s:%u %p %p %p %p)\n", debugstr_wn(text, len), len, face, is_simple, len_read, indices);
+
+    *is_simple = FALSE;
+    *len_read = 0;
+
+    if (!face)
+        return E_INVALIDARG;
+
+    if (len == 0) {
+        *is_simple = TRUE;
+        return S_OK;
+    }
+
+    *is_simple = text[0] && is_char_from_simple_script(text[0]);
+    for (i = 1; i < len && text[i]; i++) {
+        if (is_char_from_simple_script(text[i])) {
+            if (!*is_simple)
+                break;
+        }
+        else
+            *is_simple = FALSE;
+    }
+
+    *len_read = i;
+
+    /* fetch indices */
+    if (*is_simple && indices) {
+        UINT32 *codepoints = heap_alloc(*len_read*sizeof(UINT32));
+        if (!codepoints)
+            return E_OUTOFMEMORY;
+
+        for (i = 0; i < *len_read; i++)
+            codepoints[i] = text[i];
+
+        hr = IDWriteFontFace_GetGlyphIndices(face, codepoints, *len_read, indices);
+        heap_free(codepoints);
+    }
+
+    return hr;
 }
 
 static HRESULT WINAPI dwritetextanalyzer1_GetJustificationOpportunities(IDWriteTextAnalyzer2 *iface,
diff --git a/dlls/dwrite/tests/analyzer.c b/dlls/dwrite/tests/analyzer.c
index 490165f..45e2e07 100644
--- a/dlls/dwrite/tests/analyzer.c
+++ b/dlls/dwrite/tests/analyzer.c
@@ -922,7 +922,7 @@ static void test_GetScriptProperties(void)
     hr = IDWriteTextAnalyzer_QueryInterface(analyzer, &IID_IDWriteTextAnalyzer1, (void**)&analyzer1);
     IDWriteTextAnalyzer_Release(analyzer);
     if (hr != S_OK) {
-        win_skip("IDWriteTextAnalyzer1 is not supported.\n");
+        win_skip("GetScriptProperties() is not supported.\n");
         return;
     }
 
@@ -940,6 +940,117 @@ if (0) /* crashes on native */
     IDWriteTextAnalyzer1_Release(analyzer1);
 }
 
+struct textcomplexity_test {
+    const WCHAR text[5];
+    UINT32 length;
+    BOOL simple;
+    UINT32 len_read;
+};
+
+static const struct textcomplexity_test textcomplexity_tests[] = {
+    { {0},                     1, FALSE, 1 },
+    { {0},                     0,  TRUE, 0 },
+    { {0x610,0},               0,  TRUE, 0 },
+    { {'A','B','C','D',0},     3,  TRUE, 3 },
+    { {'A','B','C','D',0},     5,  TRUE, 4 },
+    { {'A','B','C','D',0},    10,  TRUE, 4 },
+    { {'A',0x610,'C','D',0},   1,  TRUE, 1 },
+    { {'A',0x610,'C','D',0},   2, FALSE, 2 },
+    { {0x610,'A','C','D',0},   1, FALSE, 1 },
+    { {0x610,'A','C','D',0},   2, FALSE, 1 },
+    { {0x610,0x610,'C','D',0}, 2, FALSE, 2 },
+    { {0xd800,'A','B',0},      1, FALSE, 1 },
+    { {0xd800,'A','B',0},      2, FALSE, 1 },
+    { {0xdc00,'A','B',0},      2, FALSE, 1 }
+};
+
+static void test_GetTextComplexity(void)
+{
+    static const WCHAR tahomaW[] = {'T','a','h','o','m','a',0};
+    static const WCHAR textW[] = {'A','B','C',0};
+    IDWriteTextAnalyzer1 *analyzer1;
+    IDWriteTextAnalyzer *analyzer;
+    IDWriteGdiInterop *interop;
+    IDWriteFontFace *fontface;
+    UINT16 indices[10];
+    IDWriteFont *font;
+    LOGFONTW logfont;
+    BOOL simple;
+    HRESULT hr;
+    UINT32 len;
+    int i;
+
+    hr = IDWriteFactory_CreateTextAnalyzer(factory, &analyzer);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = IDWriteTextAnalyzer_QueryInterface(analyzer, &IID_IDWriteTextAnalyzer1, (void**)&analyzer1);
+    IDWriteTextAnalyzer_Release(analyzer);
+    if (hr != S_OK) {
+        win_skip("GetTextComplexity() is not supported.\n");
+        return;
+    }
+
+if (0) { /* crashes on native */
+    hr = IDWriteTextAnalyzer1_GetTextComplexity(analyzer1, NULL, 0, NULL, NULL, NULL, NULL);
+    hr = IDWriteTextAnalyzer1_GetTextComplexity(analyzer1, NULL, 0, NULL, NULL, &len, NULL);
+    hr = IDWriteTextAnalyzer1_GetTextComplexity(analyzer1, textW, 3, NULL, NULL, NULL, NULL);
+    hr = IDWriteTextAnalyzer1_GetTextComplexity(analyzer1, textW, 3, NULL, NULL, &len, NULL);
+    hr = IDWriteTextAnalyzer1_GetTextComplexity(analyzer1, textW, 3, NULL, &simple, NULL, NULL);
+}
+
+    len = 1;
+    simple = TRUE;
+    hr = IDWriteTextAnalyzer1_GetTextComplexity(analyzer1, NULL, 0, NULL, &simple, &len, NULL);
+    ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+    ok(len == 0, "got %d\n", len);
+    ok(simple == FALSE, "got %d\n", simple);
+
+    len = 1;
+    simple = TRUE;
+    indices[0] = 1;
+    hr = IDWriteTextAnalyzer1_GetTextComplexity(analyzer1, textW, 3, NULL, &simple, &len, NULL);
+    ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+    ok(len == 0, "got %d\n", len);
+    ok(simple == FALSE, "got %d\n", simple);
+    ok(indices[0] == 1, "got %d\n", indices[0]);
+
+    /* so font face is required, create one */
+    hr = IDWriteFactory_GetGdiInterop(factory, &interop);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    memset(&logfont, 0, sizeof(logfont));
+    logfont.lfHeight = 12;
+    logfont.lfWidth  = 12;
+    logfont.lfWeight = FW_NORMAL;
+    logfont.lfItalic = 1;
+    lstrcpyW(logfont.lfFaceName, tahomaW);
+
+    hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = IDWriteFont_CreateFontFace(font, &fontface);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    for (i = 0; i < sizeof(textcomplexity_tests)/sizeof(struct textcomplexity_test); i++) {
+       const struct textcomplexity_test *ptr = &textcomplexity_tests[i];
+       len = 1;
+       simple = !ptr->simple;
+       indices[0] = 0;
+       hr = IDWriteTextAnalyzer1_GetTextComplexity(analyzer1, ptr->text, ptr->length, fontface, &simple, &len, indices);
+       ok(hr == S_OK, "%d: got 0x%08x\n", i, hr);
+       ok(len == ptr->len_read, "%d: read length: got %d, expected %d\n", i, len, ptr->len_read);
+       ok(simple == ptr->simple, "%d: simple: got %d, expected %d\n", i, simple, ptr->simple);
+       if (simple && ptr->length)
+           ok(indices[0] > 0, "%d: got %d\n", i, indices[0]);
+       else
+           ok(indices[0] == 0, "%d: got %d\n", i, indices[0]);
+    }
+
+    IDWriteFontFace_Release(fontface);
+    IDWriteGdiInterop_Release(interop);
+    IDWriteTextAnalyzer1_Release(analyzer1);
+}
+
 START_TEST(analyzer)
 {
     HRESULT hr;
@@ -958,6 +1069,7 @@ START_TEST(analyzer)
     test_AnalyzeScript();
     test_AnalyzeLineBreakpoints();
     test_GetScriptProperties();
+    test_GetTextComplexity();
 
     IDWriteFactory_Release(factory);
 }




More information about the wine-cvs mailing list