dwrite: Implement GetTextComplexity().

This commit is contained in:
Nikolay Sivov 2014-09-26 12:54:02 +04:00 committed by Alexandre Julliard
parent 59bdda006b
commit 7eac1f7156
2 changed files with 165 additions and 3 deletions

View File

@ -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,

View File

@ -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);
}