Signed-off-by: Lucian Poston lucianposton@pm.me --- dlls/dwrite/tests/layout.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+)
diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c index c2dd273c6c..ac36aff5b5 100644 --- a/dlls/dwrite/tests/layout.c +++ b/dlls/dwrite/tests/layout.c @@ -32,6 +32,7 @@ #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
static const WCHAR tahomaW[] = {'T','a','h','o','m','a',0}; +static const WCHAR nonExistentFontW[] = {'B','l','a','h','!',0}; static const WCHAR enusW[] = {'e','n','-','u','s',0};
struct testanalysissink @@ -3294,6 +3295,51 @@ todo_wine ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount); IDWriteTextLayout_Release(layout);
+ IDWriteTextFormat_Release(format); + + /* nonexistent font */ + hr = IDWriteFactory_CreateTextFormat(factory, nonExistentFontW, NULL, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, + DWRITE_FONT_STRETCH_NORMAL, 10.0, enusW, &format); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDWriteFactory_CreateTextLayout(factory, strW, 4, format, 500.0, 1000.0, &layout); + ok(hr == S_OK, "got 0x%08x\n", hr); + + count = 0; + hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count); +todo_wine + ok(hr == S_OK, "got 0x%08x\n", hr); +todo_wine + ok(count == 4, "got %u\n", count); + for (i = 0, width = 0.0; i < count; i++) + width += clusters[i].width; + + memset(&metrics, 0xcc, sizeof(metrics)); + hr = IDWriteTextLayout_GetMetrics(layout, &metrics); +todo_wine + ok(hr == S_OK, "got 0x%08x\n", hr); +todo_wine + ok(metrics.left == 0.0, "got %.2f\n", metrics.left); +todo_wine + ok(metrics.top == 0.0, "got %.2f\n", metrics.top); +todo_wine + ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width); +todo_wine + ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", + metrics.widthIncludingTrailingWhitespace, width); +todo_wine + ok(metrics.height > 0.0, "got %.2f\n", metrics.height); +todo_wine + ok(metrics.layoutWidth == 500.0, "got %.2f\n", metrics.layoutWidth); +todo_wine + ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight); +todo_wine + ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth); +todo_wine + ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount); + + IDWriteTextLayout_Release(layout); + IDWriteTextFormat_Release(format); IDWriteFactory_Release(factory); }
Signed-off-by: Lucian Poston lucianposton@pm.me --- dlls/dwrite/tests/layout.c | 278 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 278 insertions(+)
diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c index ac36aff5b5..2b665fd74e 100644 --- a/dlls/dwrite/tests/layout.c +++ b/dlls/dwrite/tests/layout.c @@ -4491,6 +4491,7 @@ static void test_SetWordWrapping(void) /* Collection dedicated to fallback testing */
static const WCHAR g_blahfontW[] = {'B','l','a','h',0}; +static const WCHAR g_fontNotInCollectionW[] = {'n','o','t','B','l','a','h',0}; static HRESULT WINAPI fontcollection_QI(IDWriteFontCollection *iface, REFIID riid, void **obj) { if (IsEqualIID(riid, &IID_IDWriteFontCollection) || IsEqualIID(riid, &IID_IUnknown)) { @@ -4550,6 +4551,9 @@ static HRESULT WINAPI fontcollection_FindFamilyName(IDWriteFontCollection *iface *index = 123456; *exists = TRUE; return S_OK; + } else if (!lstrcmpW(name, g_fontNotInCollectionW)) { + *exists = FALSE; + return S_OK; } ok(0, "unexpected call, name %s\n", wine_dbgstr_w(name)); return E_NOTIMPL; @@ -5570,6 +5574,279 @@ static void test_GetOverhangMetrics(void) IDWriteFactory_Release(factory); }
+static void test_GetMetrics_with_custom_fontcollection(void) +{ + static const WCHAR emptystringW[] = {0}; + static const WCHAR mappedW[] = {'a','b','c','d',0}; + static const WCHAR notmappedW[] = {'a',0xffff,'b',0}; // u+ffff = not a unicode character + DWRITE_CLUSTER_METRICS clusters[4]; + DWRITE_TEXT_METRICS metrics; + IDWriteTextFormat *format; + IDWriteTextLayout *layout; + IDWriteFactory *factory; + UINT32 count, i; + FLOAT width; + HRESULT hr; + + factory = create_factory(); + + /* font is in font collection */ + hr = IDWriteFactory_CreateTextFormat(factory, g_blahfontW, &fallbackcollection, + DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, + DWRITE_FONT_STRETCH_NORMAL, 10.0, enusW, &format); + ok(hr == S_OK, "got 0x%08x\n", hr); + + /* text is mapped by fontfallback */ + hr = IDWriteFactory_CreateTextLayout(factory, mappedW, 4, format, 1000.0, 1000.0, &layout); + ok(hr == S_OK, "got 0x%08x\n", hr); + count = 9999; + hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(count == 4, "got %u\n", count); + for (i = 0, width = 0.0; i < count; i++) + width += clusters[i].width; + memset(&metrics, 0xcc, sizeof(metrics)); + hr = IDWriteTextLayout_GetMetrics(layout, &metrics); + 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); + ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width); + ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", + metrics.widthIncludingTrailingWhitespace, width); + ok(metrics.height > 0.0, "got %.2f\n", metrics.height); + ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth); + 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); + + /* text is not mapped by fontfallback */ + hr = IDWriteFactory_CreateTextLayout(factory, notmappedW, 4, format, 1000.0, 1000.0, &layout); + ok(hr == S_OK, "got 0x%08x\n", hr); + count = 9999; + hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(count == 4, "got %u\n", count); + for (i = 0, width = 0.0; i < count; i++) + width += clusters[i].width; + memset(&metrics, 0xcc, sizeof(metrics)); + hr = IDWriteTextLayout_GetMetrics(layout, &metrics); + 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); + ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width); + ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", + metrics.widthIncludingTrailingWhitespace, width); + ok(metrics.height > 0.0, "got %.2f\n", metrics.height); + ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth); + 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); + + /* empty string */ + hr = IDWriteFactory_CreateTextLayout(factory, emptystringW, 4, format, 1000.0, 1000.0, &layout); + ok(hr == S_OK, "got 0x%08x\n", hr); + count = 9999; + hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(count == 4, "got %u\n", count); + for (i = 0, width = 0.0; i < count; i++) + width += clusters[i].width; + memset(&metrics, 0xcc, sizeof(metrics)); + hr = IDWriteTextLayout_GetMetrics(layout, &metrics); + 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); + ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width); + ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", + metrics.widthIncludingTrailingWhitespace, width); + ok(metrics.height > 0.0, "got %.2f\n", metrics.height); + ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth); + 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); + + /* zero-length empty string */ + hr = IDWriteFactory_CreateTextLayout(factory, emptystringW, 0, format, 1000.0, 1000.0, &layout); + ok(hr == S_OK, "got 0x%08x\n", hr); + count = 9999; + hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(count == 0, "got %u\n", count); + for (i = 0, width = 0.0; i < count; i++) + width += clusters[i].width; + memset(&metrics, 0xcc, sizeof(metrics)); + hr = IDWriteTextLayout_GetMetrics(layout, &metrics); + 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); + ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width); + ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", + metrics.widthIncludingTrailingWhitespace, width); + ok(metrics.height > 0.0, "got %.2f\n", metrics.height); + ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth); + 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); + + IDWriteTextFormat_Release(format); + + /* font not in font collection */ + hr = IDWriteFactory_CreateTextFormat(factory, g_fontNotInCollectionW, &fallbackcollection, + DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, + DWRITE_FONT_STRETCH_NORMAL, 10.0, enusW, &format); + ok(hr == S_OK, "got 0x%08x\n", hr); + + /* text is mapped by fontfallback */ + hr = IDWriteFactory_CreateTextLayout(factory, mappedW, 4, format, 1000.0, 1000.0, &layout); + ok(hr == S_OK, "got 0x%08x\n", hr); + count = 9999; + hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count); + todo_wine + ok(hr == S_OK, "got 0x%08x\n", hr); + todo_wine + ok(count == 4, "got %u\n", count); + for (i = 0, width = 0.0; i < count; i++) + width += clusters[i].width; + memset(&metrics, 0xcc, sizeof(metrics)); + hr = IDWriteTextLayout_GetMetrics(layout, &metrics); + todo_wine + ok(hr == S_OK, "got 0x%08x\n", hr); + todo_wine + ok(metrics.left == 0.0, "got %.2f\n", metrics.left); + todo_wine + ok(metrics.top == 0.0, "got %.2f\n", metrics.top); + todo_wine + ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width); + todo_wine + ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", + metrics.widthIncludingTrailingWhitespace, width); + todo_wine + ok(metrics.height > 0.0, "got %.2f\n", metrics.height); + todo_wine + ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth); + todo_wine + ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight); + todo_wine + ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth); + todo_wine + ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount); + IDWriteTextLayout_Release(layout); + + /* text is not mapped by fontfallback */ + hr = IDWriteFactory_CreateTextLayout(factory, notmappedW, 4, format, 1000.0, 1000.0, &layout); + ok(hr == S_OK, "got 0x%08x\n", hr); + count = 9999; + hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count); + todo_wine + ok(hr == S_OK, "got 0x%08x\n", hr); + todo_wine + ok(count == 4, "got %u\n", count); + for (i = 0, width = 0.0; i < count; i++) + width += clusters[i].width; + memset(&metrics, 0xcc, sizeof(metrics)); + hr = IDWriteTextLayout_GetMetrics(layout, &metrics); + todo_wine + ok(hr == S_OK, "got 0x%08x\n", hr); + todo_wine + ok(metrics.left == 0.0, "got %.2f\n", metrics.left); + todo_wine + ok(metrics.top == 0.0, "got %.2f\n", metrics.top); + todo_wine + ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width); + todo_wine + ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", + metrics.widthIncludingTrailingWhitespace, width); + todo_wine + ok(metrics.height > 0.0, "got %.2f\n", metrics.height); + todo_wine + ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth); + todo_wine + ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight); + todo_wine + ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth); + todo_wine + ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount); + IDWriteTextLayout_Release(layout); + + /* empty string */ + hr = IDWriteFactory_CreateTextLayout(factory, emptystringW, 4, format, 1000.0, 1000.0, &layout); + ok(hr == S_OK, "got 0x%08x\n", hr); + count = 9999; + hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count); + todo_wine + ok(hr == S_OK, "got 0x%08x\n", hr); + todo_wine + ok(count == 4, "got %u\n", count); + for (i = 0, width = 0.0; i < count; i++) + width += clusters[i].width; + memset(&metrics, 0xcc, sizeof(metrics)); + hr = IDWriteTextLayout_GetMetrics(layout, &metrics); + todo_wine + ok(hr == S_OK, "got 0x%08x\n", hr); + todo_wine + ok(metrics.left == 0.0, "got %.2f\n", metrics.left); + todo_wine + ok(metrics.top == 0.0, "got %.2f\n", metrics.top); + todo_wine + ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width); + todo_wine + ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", + metrics.widthIncludingTrailingWhitespace, width); + todo_wine + ok(metrics.height > 0.0, "got %.2f\n", metrics.height); + todo_wine + ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth); + todo_wine + ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight); + todo_wine + ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth); + todo_wine + ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount); + IDWriteTextLayout_Release(layout); + + /* zero-length empty string */ + hr = IDWriteFactory_CreateTextLayout(factory, emptystringW, 0, format, 1000.0, 1000.0, &layout); + ok(hr == S_OK, "got 0x%08x\n", hr); + count = 9999; + hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(count == 0, "got %u\n", count); + for (i = 0, width = 0.0; i < count; i++) + width += clusters[i].width; + memset(&metrics, 0xcc, sizeof(metrics)); + hr = IDWriteTextLayout_GetMetrics(layout, &metrics); + todo_wine + ok(hr == S_OK, "got 0x%08x\n", hr); + todo_wine + ok(metrics.left == 0.0, "got %.2f\n", metrics.left); + todo_wine + ok(metrics.top == 0.0, "got %.2f\n", metrics.top); + todo_wine + ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width); + todo_wine + ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", + metrics.widthIncludingTrailingWhitespace, width); + todo_wine + ok(metrics.height > 0.0, "got %.2f\n", metrics.height); + todo_wine + ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth); + todo_wine + ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight); + todo_wine + ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth); + todo_wine + ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount); + IDWriteTextLayout_Release(layout); + + IDWriteTextFormat_Release(format); + + IDWriteFactory_Release(factory); +} + START_TEST(layout) { IDWriteFactory *factory; @@ -5603,6 +5880,7 @@ START_TEST(layout) test_SetFontStretch(); test_SetStrikethrough(); test_GetMetrics(); + test_GetMetrics_with_custom_fontcollection(); test_SetFlowDirection(); test_SetDrawingEffect(); test_GetLineMetrics();
Signed-off-by: Lucian Poston lucianposton@pm.me --- dlls/dwrite/tests/layout.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c index 2b665fd74e..5157d0562d 100644 --- a/dlls/dwrite/tests/layout.c +++ b/dlls/dwrite/tests/layout.c @@ -622,6 +622,7 @@ static HRESULT WINAPI testrenderer_DrawUnderline(IDWriteTextRenderer *iface, { struct renderer_context *ctxt = (struct renderer_context*)context; struct drawcall_entry entry = { 0 }; + static const WCHAR gohaW[] = {'G','o','h','a','-','T','i','b','e','b',' ','Z','e','m','e','n',0};
if (ctxt) TEST_MEASURING_MODE(ctxt, underline->measuringMode); @@ -637,9 +638,13 @@ static HRESULT WINAPI testrenderer_DrawUnderline(IDWriteTextRenderer *iface, IDWriteFontFace_GetMetrics(fontface, &metrics);
ok(emsize == metrics.designUnitsPerEm, "Unexpected font size %f\n", emsize); - /* Expected height is in design units, allow some absolute difference from it. Seems to only happen on Vista */ - ok(fabs(metrics.capHeight - underline->runHeight) < 2.0f, "Expected runHeight %u, got %f, family %s\n", - metrics.capHeight, underline->runHeight, wine_dbgstr_w(ctxt->familyW)); + if (lstrcmpW(gohaW, ctxt->familyW)) { + /* Expected height is in design units, allow some absolute difference from it. Seems to only happen on Vista */ + ok(fabs(metrics.capHeight - underline->runHeight) < 2.0f, "Expected runHeight %u, got %f, family %s\n", + metrics.capHeight, underline->runHeight, wine_dbgstr_w(ctxt->familyW)); + } else { + skip("%s is an invalid font, rejected by windows.\n", wine_dbgstr_w(gohaW)); + }
IDWriteFontFace_Release(fontface); }
On 05/23/2018 09:06 PM, Lucian Poston wrote:
Signed-off-by: Lucian Poston lucianposton@pm.me
dlls/dwrite/tests/layout.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c index 2b665fd74e..5157d0562d 100644 --- a/dlls/dwrite/tests/layout.c +++ b/dlls/dwrite/tests/layout.c @@ -622,6 +622,7 @@ static HRESULT WINAPI testrenderer_DrawUnderline(IDWriteTextRenderer *iface, { struct renderer_context *ctxt = (struct renderer_context*)context; struct drawcall_entry entry = { 0 };
static const WCHAR gohaW[] = {'G','o','h','a','-','T','i','b','e','b',' ','Z','e','m','e','n',0};
if (ctxt) TEST_MEASURING_MODE(ctxt, underline->measuringMode);
@@ -637,9 +638,13 @@ static HRESULT WINAPI testrenderer_DrawUnderline(IDWriteTextRenderer *iface, IDWriteFontFace_GetMetrics(fontface, &metrics);
ok(emsize == metrics.designUnitsPerEm, "Unexpected font size %f\n", emsize);
/* Expected height is in design units, allow some absolute difference from it. Seems to only happen on Vista */
ok(fabs(metrics.capHeight - underline->runHeight) < 2.0f, "Expected runHeight %u, got %f, family %s\n",
metrics.capHeight, underline->runHeight, wine_dbgstr_w(ctxt->familyW));
if (lstrcmpW(gohaW, ctxt->familyW)) {
/* Expected height is in design units, allow some absolute difference from it. Seems to only happen on Vista */
ok(fabs(metrics.capHeight - underline->runHeight) < 2.0f, "Expected runHeight %u, got %f, family %s\n",
metrics.capHeight, underline->runHeight, wine_dbgstr_w(ctxt->familyW));
} else {
skip("%s is an invalid font, rejected by windows.\n", wine_dbgstr_w(gohaW));
} IDWriteFontFace_Release(fontface); }
How do I test this?I installed this font by manually extracting it from Arch's xorg-fonts-misc 1.0.3-5, but I don't see any failures. The fact that it's not working on Windows is not very important, we still should try to make it usable.
On Sat, May 26, 2018 at 06:05:00AM -0700, Nikolay Sivov wrote:
How do I test this?I installed this font by manually extracting it from Arch's xorg-fonts-misc 1.0.3-5, but I don't see any failures.
The failure arises only when you apply the subsequent patches (patch 4/6 I believe), which cause that test map characters to the Goha font from the system fonts. So you could apply the whoel patch series except this one to see the failure.
If it doesn't fail with arch's versoin, perhaps mine is corrupted, and it is a non-issue. I isolated this change so that in such a case, you can just drop this patch.
I uploaded the one from my system, in case you wanted to risk trying it. https://transfer.sh/br8lo/GohaTibebZemen.otf
The fact that it's not working on Windows is not very important, we still should try to make it usable.
How would you define the test's expected values if we can't get them from windows?
On 05/26/2018 04:42 PM, Lucian Poston wrote:
On Sat, May 26, 2018 at 06:05:00AM -0700, Nikolay Sivov wrote:
How do I test this?I installed this font by manually extracting it from Arch's xorg-fonts-misc 1.0.3-5, but I don't see any failures.
The failure arises only when you apply the subsequent patches (patch 4/6 I believe), which cause that test map characters to the Goha font from the system fonts. So you could apply the whoel patch series except this one to see the failure.
If it doesn't fail with arch's versoin, perhaps mine is corrupted, and it is a non-issue. I isolated this change so that in such a case, you can just drop this patch.
I uploaded the one from my system, in case you wanted to risk trying it. https://transfer.sh/br8lo/GohaTibebZemen.otf
The fact that it's not working on Windows is not very important, we still should try to make it usable.
How would you define the test's expected values if we can't get them from windows?
Depends on the test. Some tests estimate using actual font data, and compare that to what windows returns, so expected values are not defined but computed.
Signed-off-by: Lucian Poston lucianposton@pm.me --- dlls/dwrite/analyzer.c | 77 +++++++++++++++++++++++++++--------- dlls/dwrite/layout.c | 6 +++ dlls/dwrite/tests/layout.c | 97 ++++++++++++++++------------------------------ 3 files changed, 98 insertions(+), 82 deletions(-)
diff --git a/dlls/dwrite/analyzer.c b/dlls/dwrite/analyzer.c index 8d553c6d56..21da783fe6 100644 --- a/dlls/dwrite/analyzer.c +++ b/dlls/dwrite/analyzer.c @@ -2078,6 +2078,7 @@ static HRESULT fallback_get_fallback_font(struct dwrite_fontfallback *fallback, IDWriteFont **mapped_font) { const struct fallback_mapping *mapping; + IDWriteFontCollection *collection; HRESULT hr; UINT32 i;
@@ -2089,9 +2090,15 @@ static HRESULT fallback_get_fallback_font(struct dwrite_fontfallback *fallback, return E_FAIL; }
+ if (mapping->collection) { + collection = mapping->collection; + } else { + collection = (IDWriteFontCollection *)fallback->systemcollection; + } + /* Now let's see what fallback can handle. Pick first font that could be created. */ for (i = 0; i < mapping->families_count; i++) { - hr = create_matching_font((IDWriteFontCollection *)fallback->systemcollection, mapping->families[i], + hr = create_matching_font(collection, mapping->families[i], weight, style, stretch, mapped_font); if (hr == S_OK) { TRACE("Created fallback font using family %s.\n", debugstr_w(mapping->families[i])); @@ -2148,30 +2155,64 @@ static HRESULT WINAPI fontfallback_MapCharacters(IDWriteFontFallback *iface, IDW
if (basefamily && *basefamily) { hr = create_matching_font(basecollection, basefamily, weight, style, stretch, ret_font); - if (FAILED(hr)) - goto done; - - hr = fallback_map_characters(*ret_font, text, length, mapped_length); - if (FAILED(hr)) - goto done; + if (SUCCEEDED(hr)) { + hr = fallback_map_characters(*ret_font, text, length, mapped_length); + if (FAILED(hr)) { + IDWriteFont_Release(*ret_font); + *ret_font = NULL; + WARN("Mapping with requested family %s failed, hr %#x.\n", debugstr_w(basefamily), hr); + } + } }
if (!*mapped_length) { - IDWriteFont *mapped_font; + if (*ret_font) { + IDWriteFont_Release(*ret_font); + *ret_font = NULL; + }
- hr = fallback_get_fallback_font(fallback, text, length, weight, style, stretch, mapped_length, &mapped_font); + hr = fallback_get_fallback_font(fallback, text, length, weight, style, stretch, mapped_length, ret_font); if (FAILED(hr)) { - /* fallback wasn't found, keep base font if any, so we can get at least some visual output */ - if (*ret_font) { - *mapped_length = length; - hr = S_OK; + WARN("Mapping with fallback families failed, hr %#x.\n", hr); + } + } + + /** + * This is a rough hack. We search the system font collection because + * the system fontfallback, which would have been searched above, is not + * fully implemented as it isn't populated with any system fonts. Once + * implemented, the block below can be removed. + * */ + if (!*mapped_length) { + IDWriteFontFamily *family; + IDWriteFont *font; + UINT32 i, count = IDWriteFontCollection_GetFontFamilyCount((IDWriteFontCollection *)fallback->systemcollection); + for (i = 0; i < count; i++) { + hr = IDWriteFontCollection_GetFontFamily((IDWriteFontCollection *)fallback->systemcollection, i, &family); + if (FAILED(hr)) { + ERR("Failed to get font family.\n"); + continue; } + + hr = IDWriteFontFamily_GetFirstMatchingFont(family, weight, stretch, style, &font); + IDWriteFontFamily_Release(family); + if (FAILED(hr)) { + continue; + } + + hr = fallback_map_characters(font, text, length, mapped_length); + if (SUCCEEDED(hr) && mapped_length > 0) { + *ret_font = font; + break; + } + + IDWriteFont_Release(font); } - else { - if (*ret_font) - IDWriteFont_Release(*ret_font); - *ret_font = mapped_font; - } + } + + if (!*mapped_length) { + *mapped_length = length == 0 ? 0 : 1; + hr = S_OK; }
done: diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c index 65e0a57678..df3f3beabb 100644 --- a/dlls/dwrite/layout.c +++ b/dlls/dwrite/layout.c @@ -878,6 +878,12 @@ static HRESULT layout_resolve_fonts(struct dwrite_textlayout *layout) goto fatal; }
+ if (!font) { + hr = E_FAIL; + WARN("Failed to create font face, hr %#x.\n", hr); + goto fatal; + } + hr = IDWriteFont_CreateFontFace(font, &run->run.fontFace); IDWriteFont_Release(font); if (FAILED(hr)) { diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c index 5157d0562d..85967e7ee8 100644 --- a/dlls/dwrite/tests/layout.c +++ b/dlls/dwrite/tests/layout.c @@ -3312,35 +3312,23 @@ todo_wine
count = 0; hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count); -todo_wine ok(hr == S_OK, "got 0x%08x\n", hr); -todo_wine ok(count == 4, "got %u\n", count); for (i = 0, width = 0.0; i < count; i++) width += clusters[i].width;
memset(&metrics, 0xcc, sizeof(metrics)); hr = IDWriteTextLayout_GetMetrics(layout, &metrics); -todo_wine ok(hr == S_OK, "got 0x%08x\n", hr); -todo_wine ok(metrics.left == 0.0, "got %.2f\n", metrics.left); -todo_wine ok(metrics.top == 0.0, "got %.2f\n", metrics.top); -todo_wine ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width); -todo_wine ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", metrics.widthIncludingTrailingWhitespace, width); -todo_wine ok(metrics.height > 0.0, "got %.2f\n", metrics.height); -todo_wine ok(metrics.layoutWidth == 500.0, "got %.2f\n", metrics.layoutWidth); -todo_wine ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight); -todo_wine ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth); -todo_wine ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
IDWriteTextLayout_Release(layout); @@ -4639,16 +4627,13 @@ static void test_MapCharacters(void) font = NULL; hr = IDWriteFontFallback_MapCharacters(fallback, &analysissource, 0, 1, NULL, NULL, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, &mappedlength, &font, &scale); -todo_wine { ok(hr == S_OK, "got 0x%08x\n", hr); ok(mappedlength == 1, "got %u\n", mappedlength); -} ok(scale == 1.0f, "got %f\n", scale); -todo_wine ok(font != NULL, "got %p\n", font); -if (font) { - IDWriteFont_Release(font); -} + if (font) { + IDWriteFont_Release(font); + } /* same latin text, full length */ g_source = strW; mappedlength = 0; @@ -4656,16 +4641,13 @@ if (font) { font = NULL; hr = IDWriteFontFallback_MapCharacters(fallback, &analysissource, 0, 3, NULL, NULL, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, &mappedlength, &font, &scale); -todo_wine { ok(hr == S_OK, "got 0x%08x\n", hr); ok(mappedlength == 3, "got %u\n", mappedlength); -} ok(scale == 1.0f, "got %f\n", scale); -todo_wine ok(font != NULL, "got %p\n", font); -if (font) { - IDWriteFont_Release(font); -} + if (font) { + IDWriteFont_Release(font); + } /* string 'a\x3058b' */ g_source = str2W; mappedlength = 0; @@ -4673,38 +4655,32 @@ if (font) { font = NULL; hr = IDWriteFontFallback_MapCharacters(fallback, &analysissource, 0, 3, NULL, NULL, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, &mappedlength, &font, &scale); -todo_wine { ok(hr == S_OK, "got 0x%08x\n", hr); ok(mappedlength == 1, "got %u\n", mappedlength); -} ok(scale == 1.0f, "got %f\n", scale); -todo_wine ok(font != NULL, "got %p\n", font); -if (font) { - IDWriteFont_Release(font); -} + if (font) { + IDWriteFont_Release(font); + } g_source = str2W; mappedlength = 0; scale = 0.0f; font = NULL; hr = IDWriteFontFallback_MapCharacters(fallback, &analysissource, 1, 2, NULL, NULL, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, &mappedlength, &font, &scale); -todo_wine { ok(hr == S_OK, "got 0x%08x\n", hr); ok(mappedlength == 1, "got %u\n", mappedlength); -} ok(scale == 1.0f, "got %f\n", scale); -todo_wine ok(font != NULL, "got %p\n", font); -if (font) { - /* font returned for Hiragana character, check if it supports Latin too */ - exists = FALSE; - hr = IDWriteFont_HasCharacter(font, 'b', &exists); - ok(hr == S_OK, "got 0x%08x\n", hr); - ok(exists, "got %d\n", exists); + if (font) { + /* font returned for Hiragana character, check if it supports Latin too */ + exists = FALSE; + hr = IDWriteFont_HasCharacter(font, 'b', &exists); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(exists, "got %d\n", exists);
- IDWriteFont_Release(font); -} + IDWriteFont_Release(font); + } /* Try with explicit collection, Tahoma will be forced. */ /* 1. Latin part */ g_source = str2W; @@ -4727,7 +4703,10 @@ if (font) { IDWriteLocalizedStrings_Release(strings); IDWriteFont_Release(font);
- /* 2. Hiragana character, force Tahoma font does not support Japanese */ + /** + * 2. Hiragana character. Tahoma is requested, but it doesn't support + * Japanese. A NULL font is returned if there is no fallback for Japanese. + */ g_source = str2W; mappedlength = 0; scale = 0.0f; @@ -4737,17 +4716,19 @@ if (font) { ok(hr == S_OK, "got 0x%08x\n", hr); ok(mappedlength == 1, "got %u\n", mappedlength); ok(scale == 1.0f, "got %f\n", scale); - ok(font != NULL, "got %p\n", font);
- exists = FALSE; - hr = IDWriteFont_GetInformationalStrings(font, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES, &strings, &exists); - ok(hr == S_OK && exists, "got 0x%08x, exists %d\n", hr, exists); - hr = IDWriteLocalizedStrings_GetString(strings, 0, buffW, ARRAY_SIZE(buffW)); - ok(hr == S_OK, "got 0x%08x\n", hr); -todo_wine - ok(lstrcmpW(buffW, tahomaW), "%s\n", wine_dbgstr_w(buffW)); - IDWriteLocalizedStrings_Release(strings); - IDWriteFont_Release(font); + if (!font) { + skip("Missing system font for Japanese.\n"); + } else { + exists = FALSE; + hr = IDWriteFont_GetInformationalStrings(font, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES, &strings, &exists); + ok(hr == S_OK && exists, "got 0x%08x, exists %d\n", hr, exists); + hr = IDWriteLocalizedStrings_GetString(strings, 0, buffW, ARRAY_SIZE(buffW)); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(lstrcmpW(buffW, tahomaW), "%s\n", wine_dbgstr_w(buffW)); + IDWriteLocalizedStrings_Release(strings); + IDWriteFont_Release(font); + }
IDWriteFontFallback_Release(fallback); IDWriteFactory2_Release(factory2); @@ -5710,34 +5691,22 @@ static void test_GetMetrics_with_custom_fontcollection(void) ok(hr == S_OK, "got 0x%08x\n", hr); count = 9999; hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count); - todo_wine ok(hr == S_OK, "got 0x%08x\n", hr); - todo_wine ok(count == 4, "got %u\n", count); for (i = 0, width = 0.0; i < count; i++) width += clusters[i].width; memset(&metrics, 0xcc, sizeof(metrics)); hr = IDWriteTextLayout_GetMetrics(layout, &metrics); - todo_wine ok(hr == S_OK, "got 0x%08x\n", hr); - todo_wine ok(metrics.left == 0.0, "got %.2f\n", metrics.left); - todo_wine ok(metrics.top == 0.0, "got %.2f\n", metrics.top); - todo_wine ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width); - todo_wine ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", metrics.widthIncludingTrailingWhitespace, width); - todo_wine ok(metrics.height > 0.0, "got %.2f\n", metrics.height); - todo_wine ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth); - todo_wine ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight); - todo_wine ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth); - todo_wine ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount); IDWriteTextLayout_Release(layout);
On 05/23/2018 09:07 PM, Lucian Poston wrote:
- /**
* This is a rough hack. We search the system font collection because
* the system fontfallback, which would have been searched above, is not
* fully implemented as it isn't populated with any system fonts. Once
* implemented, the block below can be removed.
* */
- if (!*mapped_length) {
IDWriteFontFamily *family;
IDWriteFont *font;
UINT32 i, count = IDWriteFontCollection_GetFontFamilyCount((IDWriteFontCollection *)fallback->systemcollection);
for (i = 0; i < count; i++) {
hr = IDWriteFontCollection_GetFontFamily((IDWriteFontCollection *)fallback->systemcollection, i, &family);
if (FAILED(hr)) {
ERR("Failed to get font family.\n");
continue; }
hr = IDWriteFontFamily_GetFirstMatchingFont(family, weight, stretch, style, &font);
IDWriteFontFamily_Release(family);
if (FAILED(hr)) {
continue;
}
hr = fallback_map_characters(font, text, length, mapped_length);
if (SUCCEEDED(hr) && mapped_length > 0) {
*ret_font = font;
break;
}
IDWriteFont_Release(font); }
This block will pick arbitrary font, depending on fonts user has installed, and can change if user installs more or removes some. That doesn't sound like a good idea to me, and your comment already hints at that.
On Sat, May 26, 2018 at 06:13:30AM -0700, Nikolay Sivov wrote:
This block will pick arbitrary font, depending on fonts user has installed, and can change if user installs more or removes some. That doesn't sound like a good idea to me, and your comment already hints at that.
Yep. But at least the system fonts are considered at all.
That leads to a question that will arise when the system font fallback is implemented: In what order should the system font fallback mappings be defined? If you simply iterate over them as done here, the result can also change (perhaps unexpectedly) if the user (un)installs fonts.
I supposed you'd have probe windows behavior by running tests while installing and uninstalling system fonts.
Signed-off-by: Lucian Poston lucianposton@pm.me --- dlls/dwrite/layout.c | 22 +++++++++++++++------- dlls/dwrite/tests/layout.c | 24 ------------------------ 2 files changed, 15 insertions(+), 31 deletions(-)
diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c index df3f3beabb..5d06bf9348 100644 --- a/dlls/dwrite/layout.c +++ b/dlls/dwrite/layout.c @@ -822,7 +822,8 @@ static HRESULT layout_resolve_fonts(struct dwrite_textlayout *layout) LIST_FOR_EACH_ENTRY(r, &layout->runs, struct layout_run, entry) { struct regular_layout_run *run = &r->u.regular; IDWriteFont *font; - UINT32 length; + UINT32 length, mapped_length; + FLOAT scale;
if (r->kind == LAYOUT_RUN_INLINE) continue; @@ -830,12 +831,19 @@ static HRESULT layout_resolve_fonts(struct dwrite_textlayout *layout) range = get_layout_range_by_pos(layout, run->descr.textPosition);
if (run->sa.shapes == DWRITE_SCRIPT_SHAPES_NO_VISUAL) { - IDWriteFontCollection *collection; - - collection = range->collection ? range->collection : sys_collection; - - if (FAILED(hr = create_matching_font(collection, range->fontfamily, range->weight, range->style, - range->stretch, &font))) { + hr = IDWriteFontFallback_MapCharacters(fallback, + (IDWriteTextAnalysisSource *)&layout->IDWriteTextAnalysisSource1_iface, + run->descr.textPosition, + run->descr.stringLength, + range->collection, + range->fontfamily, + range->weight, + range->style, + range->stretch, + &mapped_length, + &font, + &scale); + if (FAILED(hr)) { WARN("%s: failed to create matching font for non visual run, family %s, collection %p\n", debugstr_rundescr(&run->descr), debugstr_w(range->fontfamily), range->collection); break; diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c index 85967e7ee8..975b6ac7b3 100644 --- a/dlls/dwrite/tests/layout.c +++ b/dlls/dwrite/tests/layout.c @@ -5715,34 +5715,22 @@ static void test_GetMetrics_with_custom_fontcollection(void) ok(hr == S_OK, "got 0x%08x\n", hr); count = 9999; hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count); - todo_wine ok(hr == S_OK, "got 0x%08x\n", hr); - todo_wine ok(count == 4, "got %u\n", count); for (i = 0, width = 0.0; i < count; i++) width += clusters[i].width; memset(&metrics, 0xcc, sizeof(metrics)); hr = IDWriteTextLayout_GetMetrics(layout, &metrics); - todo_wine ok(hr == S_OK, "got 0x%08x\n", hr); - todo_wine ok(metrics.left == 0.0, "got %.2f\n", metrics.left); - todo_wine ok(metrics.top == 0.0, "got %.2f\n", metrics.top); - todo_wine ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width); - todo_wine ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", metrics.widthIncludingTrailingWhitespace, width); - todo_wine ok(metrics.height > 0.0, "got %.2f\n", metrics.height); - todo_wine ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth); - todo_wine ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight); - todo_wine ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth); - todo_wine ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount); IDWriteTextLayout_Release(layout);
@@ -5751,34 +5739,22 @@ static void test_GetMetrics_with_custom_fontcollection(void) ok(hr == S_OK, "got 0x%08x\n", hr); count = 9999; hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count); - todo_wine ok(hr == S_OK, "got 0x%08x\n", hr); - todo_wine ok(count == 4, "got %u\n", count); for (i = 0, width = 0.0; i < count; i++) width += clusters[i].width; memset(&metrics, 0xcc, sizeof(metrics)); hr = IDWriteTextLayout_GetMetrics(layout, &metrics); - todo_wine ok(hr == S_OK, "got 0x%08x\n", hr); - todo_wine ok(metrics.left == 0.0, "got %.2f\n", metrics.left); - todo_wine ok(metrics.top == 0.0, "got %.2f\n", metrics.top); - todo_wine ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width); - todo_wine ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", metrics.widthIncludingTrailingWhitespace, width); - todo_wine ok(metrics.height > 0.0, "got %.2f\n", metrics.height); - todo_wine ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth); - todo_wine ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight); - todo_wine ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth); - todo_wine ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount); IDWriteTextLayout_Release(layout);
On 05/23/2018 09:07 PM, Lucian Poston wrote:
Signed-off-by: Lucian Poston lucianposton@pm.me
dlls/dwrite/layout.c | 22 +++++++++++++++------- dlls/dwrite/tests/layout.c | 24 ------------------------ 2 files changed, 15 insertions(+), 31 deletions(-)
diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c index df3f3beabb..5d06bf9348 100644 --- a/dlls/dwrite/layout.c +++ b/dlls/dwrite/layout.c @@ -822,7 +822,8 @@ static HRESULT layout_resolve_fonts(struct dwrite_textlayout *layout) LIST_FOR_EACH_ENTRY(r, &layout->runs, struct layout_run, entry) { struct regular_layout_run *run = &r->u.regular; IDWriteFont *font;
UINT32 length;
UINT32 length, mapped_length;
FLOAT scale; if (r->kind == LAYOUT_RUN_INLINE) continue;
@@ -830,12 +831,19 @@ static HRESULT layout_resolve_fonts(struct dwrite_textlayout *layout) range = get_layout_range_by_pos(layout, run->descr.textPosition);
if (run->sa.shapes == DWRITE_SCRIPT_SHAPES_NO_VISUAL) {
IDWriteFontCollection *collection;
collection = range->collection ? range->collection : sys_collection;
if (FAILED(hr = create_matching_font(collection, range->fontfamily, range->weight, range->style,
range->stretch, &font))) {
hr = IDWriteFontFallback_MapCharacters(fallback,
(IDWriteTextAnalysisSource *)&layout->IDWriteTextAnalysisSource1_iface,
run->descr.textPosition,
run->descr.stringLength,
range->collection,
range->fontfamily,
range->weight,
range->style,
range->stretch,
&mapped_length,
&font,
&scale);
if (FAILED(hr)) { WARN("%s: failed to create matching font for non visual run, family %s, collection %p\n", debugstr_rundescr(&run->descr), debugstr_w(range->fontfamily), range->collection); break;
This only works together with patch 4/6, right? What we need to figure out here is which font is picked in NO_VISUAL case, does it change with range locale, or custom collection. Then we can either hardcode it here, or add corresponding char ranges.
diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c index 85967e7ee8..975b6ac7b3 100644 --- a/dlls/dwrite/tests/layout.c +++ b/dlls/dwrite/tests/layout.c @@ -5715,34 +5715,22 @@ static void test_GetMetrics_with_custom_fontcollection(void) ok(hr == S_OK, "got 0x%08x\n", hr); count = 9999; hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
- todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
- todo_wine ok(count == 4, "got %u\n", count); for (i = 0, width = 0.0; i < count; i++) width += clusters[i].width; memset(&metrics, 0xcc, sizeof(metrics)); hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
- todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
- todo_wine ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
- todo_wine ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
- todo_wine ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
- todo_wine ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", metrics.widthIncludingTrailingWhitespace, width);
- todo_wine ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
- todo_wine ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth);
- todo_wine ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
- todo_wine ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
- todo_wine ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount); IDWriteTextLayout_Release(layout);
@@ -5751,34 +5739,22 @@ static void test_GetMetrics_with_custom_fontcollection(void) ok(hr == S_OK, "got 0x%08x\n", hr); count = 9999; hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
- todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
- todo_wine ok(count == 4, "got %u\n", count); for (i = 0, width = 0.0; i < count; i++) width += clusters[i].width; memset(&metrics, 0xcc, sizeof(metrics)); hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
- todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
- todo_wine ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
- todo_wine ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
- todo_wine ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
- todo_wine ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", metrics.widthIncludingTrailingWhitespace, width);
- todo_wine ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
- todo_wine ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth);
- todo_wine ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
- todo_wine ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
- todo_wine ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount); IDWriteTextLayout_Release(layout);
On Sat, May 26, 2018 at 06:43:39AM -0700, Nikolay Sivov wrote:
This only works together with patch 4/6, right?
Yes. Some of the fixed tests in 5/6 will fail without 4/6 applied before this one.
What we need to figure out here is which font is picked in NO_VISUAL case, does it change with range locale, or custom collection. Then we can either hardcode it here, or add corresponding char ranges.
Going from memory, it was tahoma in win 10 (without custom collection), but I suspect that comes from the system font collection or system fontfallback object.
I don't know if you'd want to hardcode it here. The fontfallback allows you define a mapping between char ranges and font, so the system's fontfallback would seem like the appropriate place for that.
On 05/26/2018 05:01 PM, Lucian Poston wrote:
What we need to figure out here is which font is picked in NO_VISUAL case, does it change with range locale, or custom collection. Then we can either hardcode it here, or add corresponding char ranges.
Going from memory, it was tahoma in win 10 (without custom collection), but I suspect that comes from the system font collection or system fontfallback object.
I don't know if you'd want to hardcode it here. The fontfallback allows you define a mapping between char ranges and font, so the system's fontfallback would seem like the appropriate place for that.
Depends on how it works, but yes, doing that in fallback object is preferable.
Fixes: https://bugs.winehq.org/show_bug.cgi?id=44052
Signed-off-by: Lucian Poston lucianposton@pm.me --- dlls/dwrite/layout.c | 29 +++++++++++++++++++++++++++++ dlls/dwrite/tests/layout.c | 8 -------- 2 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c index 5d06bf9348..2213717f92 100644 --- a/dlls/dwrite/layout.c +++ b/dlls/dwrite/layout.c @@ -1808,8 +1808,11 @@ static HRESULT layout_set_dummy_line_metrics(struct dwrite_textlayout *layout, U DWRITE_FONT_METRICS fontmetrics; struct layout_range *range; IDWriteFontFace *fontface; + IDWriteFontFallback *fallback; IDWriteFont *font; HRESULT hr; + UINT32 mapped_length; + FLOAT scale;
range = get_layout_range_by_pos(layout, pos); hr = create_matching_font(range->collection, @@ -1818,8 +1821,34 @@ static HRESULT layout_set_dummy_line_metrics(struct dwrite_textlayout *layout, U range->style, range->stretch, &font); + + if (FAILED(hr)) { + if (layout->format.fallback) { + fallback = layout->format.fallback; + IDWriteFontFallback_AddRef(fallback); + } else if (FAILED(hr = IDWriteFactory5_GetSystemFontFallback(layout->factory, &fallback))) { + WARN("Failed to get system fallback, hr %#x.\n", hr); + return hr; + } + + hr = IDWriteFontFallback_MapCharacters(fallback, + (IDWriteTextAnalysisSource *)&layout->IDWriteTextAnalysisSource1_iface, + pos, + layout->len, + range->collection, + range->fontfamily, + range->weight, + range->style, + range->stretch, + &mapped_length, + &font, + &scale); + IDWriteFontFallback_Release(fallback); + } if (FAILED(hr)) return hr; + if (font == NULL) + return S_OK; hr = IDWriteFont_CreateFontFace(font, &fontface); IDWriteFont_Release(font); if (FAILED(hr)) diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c index 975b6ac7b3..e0748302ad 100644 --- a/dlls/dwrite/tests/layout.c +++ b/dlls/dwrite/tests/layout.c @@ -5769,24 +5769,16 @@ static void test_GetMetrics_with_custom_fontcollection(void) width += clusters[i].width; memset(&metrics, 0xcc, sizeof(metrics)); hr = IDWriteTextLayout_GetMetrics(layout, &metrics); - todo_wine ok(hr == S_OK, "got 0x%08x\n", hr); - todo_wine ok(metrics.left == 0.0, "got %.2f\n", metrics.left); - todo_wine ok(metrics.top == 0.0, "got %.2f\n", metrics.top); - todo_wine ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width); - todo_wine ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", metrics.widthIncludingTrailingWhitespace, width); todo_wine ok(metrics.height > 0.0, "got %.2f\n", metrics.height); - todo_wine ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth); - todo_wine ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight); - todo_wine ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth); todo_wine ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);