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