dwrite: Store factory pointer gdiinterop was created from.

This commit is contained in:
Nikolay Sivov 2014-10-19 23:57:53 +04:00 committed by Alexandre Julliard
parent 114f32c8b6
commit ea11f85a94
4 changed files with 176 additions and 20 deletions

View File

@ -97,7 +97,8 @@ extern HRESULT create_textformat(const WCHAR*,IDWriteFontCollection*,DWRITE_FONT
extern HRESULT create_textlayout(const WCHAR*,UINT32,IDWriteTextFormat*,FLOAT,FLOAT,IDWriteTextLayout**) DECLSPEC_HIDDEN;
extern HRESULT create_trimmingsign(IDWriteInlineObject**) DECLSPEC_HIDDEN;
extern HRESULT create_typography(IDWriteTypography**) DECLSPEC_HIDDEN;
extern HRESULT get_gdiinterop(IDWriteGdiInterop**) DECLSPEC_HIDDEN;
extern HRESULT create_gdiinterop(IDWriteFactory*,IDWriteGdiInterop**) DECLSPEC_HIDDEN;
extern void release_gdiinterop(IDWriteGdiInterop*) DECLSPEC_HIDDEN;
extern HRESULT create_localizedstrings(IDWriteLocalizedStrings**) DECLSPEC_HIDDEN;
extern HRESULT add_localizedstring(IDWriteLocalizedStrings*,const WCHAR*,const WCHAR*) DECLSPEC_HIDDEN;
extern HRESULT clone_localizedstring(IDWriteLocalizedStrings *iface, IDWriteLocalizedStrings **strings) DECLSPEC_HIDDEN;

View File

@ -33,7 +33,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dwrite);
struct gdiinterop {
IDWriteGdiInterop IDWriteGdiInterop_iface;
LONG ref;
IDWriteFactory *factory;
};
struct rendertarget {
@ -241,7 +241,8 @@ static HRESULT WINAPI gdiinterop_QueryInterface(IDWriteGdiInterop *iface, REFIID
TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDWriteGdiInterop))
if (IsEqualIID(riid, &IID_IDWriteGdiInterop) ||
IsEqualIID(riid, &IID_IUnknown))
{
*obj = iface;
IDWriteGdiInterop_AddRef(iface);
@ -255,23 +256,15 @@ static HRESULT WINAPI gdiinterop_QueryInterface(IDWriteGdiInterop *iface, REFIID
static ULONG WINAPI gdiinterop_AddRef(IDWriteGdiInterop *iface)
{
struct gdiinterop *This = impl_from_IDWriteGdiInterop(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p)->(%d)\n", This, ref);
return ref;
TRACE("(%p)\n", This);
return IDWriteFactory_AddRef(This->factory);
}
static ULONG WINAPI gdiinterop_Release(IDWriteGdiInterop *iface)
{
struct gdiinterop *This = impl_from_IDWriteGdiInterop(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p)->(%d)\n", This, ref);
if (!ref)
{
heap_free(This);
}
return ref;
TRACE("(%p)\n", This);
return IDWriteFactory_Release(This->factory);
}
static HRESULT WINAPI gdiinterop_CreateFontFromLOGFONT(IDWriteGdiInterop *iface,
@ -328,7 +321,7 @@ static const struct IDWriteGdiInteropVtbl gdiinteropvtbl = {
gdiinterop_CreateBitmapRenderTarget
};
HRESULT get_gdiinterop(IDWriteGdiInterop **ret)
HRESULT create_gdiinterop(IDWriteFactory *factory, IDWriteGdiInterop **ret)
{
struct gdiinterop *This;
@ -338,8 +331,14 @@ HRESULT get_gdiinterop(IDWriteGdiInterop **ret)
if (!This) return E_OUTOFMEMORY;
This->IDWriteGdiInterop_iface.lpVtbl = &gdiinteropvtbl;
This->ref = 1;
This->factory = factory;
*ret= &This->IDWriteGdiInterop_iface;
return S_OK;
}
void release_gdiinterop(IDWriteGdiInterop *iface)
{
struct gdiinterop *interop = impl_from_IDWriteGdiInterop(iface);
heap_free(interop);
}

View File

@ -397,6 +397,7 @@ struct dwritefactory {
IDWriteLocalFontFileLoader* localfontfileloader;
IDWriteFontCollection *system_collection;
IDWriteGdiInterop *gdiinterop;
IDWriteFontCollectionLoader **loaders;
LONG loader_count;
@ -425,6 +426,8 @@ static void release_dwritefactory(struct dwritefactory *factory)
heap_free(factory->file_loaders);
if (factory->system_collection)
IDWriteFontCollection_Release(factory->system_collection);
if (factory->gdiinterop)
release_gdiinterop(factory->gdiinterop);
heap_free(factory);
}
@ -727,8 +730,21 @@ static HRESULT WINAPI dwritefactory_CreateTypography(IDWriteFactory *iface, IDWr
static HRESULT WINAPI dwritefactory_GetGdiInterop(IDWriteFactory *iface, IDWriteGdiInterop **gdi_interop)
{
struct dwritefactory *This = impl_from_IDWriteFactory(iface);
TRACE("(%p)->(%p)\n", This, gdi_interop);
return get_gdiinterop(gdi_interop);
*gdi_interop = NULL;
if (!This->gdiinterop) {
HRESULT hr = create_gdiinterop(iface, &This->gdiinterop);
if (FAILED(hr))
return hr;
}
*gdi_interop = This->gdiinterop;
IDWriteGdiInterop_AddRef(*gdi_interop);
return S_OK;
}
static HRESULT WINAPI dwritefactory_CreateTextLayout(IDWriteFactory *iface, WCHAR const* string,
@ -864,6 +880,7 @@ static HRESULT init_dwritefactory(struct dwritefactory *factory, const struct ID
factory->file_loader_count = 2;
factory->file_loaders = heap_alloc_zero(sizeof(*factory->file_loaders) * 2);
factory->system_collection = NULL;
factory->gdiinterop = NULL;
if (!factory->loaders || !factory->file_loaders) {
heap_free(factory->loaders);

View File

@ -509,15 +509,20 @@ if (0) /* crashes on native */
static void test_GetFontFamily(void)
{
IDWriteFontCollection *collection, *collection2;
IDWriteFontCollection *syscoll;
IDWriteFontFamily *family, *family2;
IDWriteGdiInterop *interop;
IDWriteFont *font;
IDWriteFont *font, *font2;
LOGFONTW logfont;
HRESULT hr;
hr = IDWriteFactory_GetGdiInterop(factory, &interop);
EXPECT_HR(hr, S_OK);
hr = IDWriteFactory_GetSystemFontCollection(factory, &syscoll, FALSE);
ok(hr == S_OK, "got 0x%08x\n", hr);
memset(&logfont, 0, sizeof(logfont));
logfont.lfHeight = 12;
logfont.lfWidth = 12;
@ -526,7 +531,11 @@ static void test_GetFontFamily(void)
lstrcpyW(logfont.lfFaceName, tahomaW);
hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
EXPECT_HR(hr, S_OK);
ok(hr == S_OK, "got 0x%08x\n", hr);
hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font2);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(font2 != font, "got %p, %p\n", font2, font);
if (0) /* crashes on native */
hr = IDWriteFont_GetFontFamily(font, NULL);
@ -548,8 +557,32 @@ if (0) /* crashes on native */
EXPECT_HR(hr, E_NOINTERFACE);
ok(family2 == NULL, "got %p\n", family2);
hr = IDWriteFont_GetFontFamily(font2, &family2);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(family2 != family, "got %p, %p\n", family2, family);
collection = NULL;
hr = IDWriteFontFamily_GetFontCollection(family, &collection);
todo_wine
ok(hr == S_OK, "got 0x%08x\n", hr);
collection2 = NULL;
hr = IDWriteFontFamily_GetFontCollection(family2, &collection2);
todo_wine
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(collection == collection2, "got %p, %p\n", collection, collection2);
todo_wine
ok(collection == syscoll, "got %p, %p\n", collection, syscoll);
IDWriteFontCollection_Release(syscoll);
if (collection2)
IDWriteFontCollection_Release(collection2);
if (collection)
IDWriteFontCollection_Release(collection);
IDWriteFontFamily_Release(family2);
IDWriteFontFamily_Release(family);
IDWriteFont_Release(font);
IDWriteFont_Release(font2);
IDWriteGdiInterop_Release(interop);
}
@ -1276,6 +1309,110 @@ static void test_GetFirstMatchingFont(void)
IDWriteFontCollection_Release(collection);
}
static void test_GetInformationalStrings(void)
{
IDWriteLocalizedStrings *strings, *strings2;
IDWriteFontCollection *collection;
IDWriteFontFamily *family;
IDWriteFont *font;
BOOL exists;
HRESULT hr;
hr = IDWriteFactory_GetSystemFontCollection(factory, &collection, FALSE);
ok(hr == S_OK, "got 0x%08x\n", hr);
hr = IDWriteFontCollection_GetFontFamily(collection, 0, &family);
ok(hr == S_OK, "got 0x%08x\n", hr);
hr = IDWriteFontFamily_GetFirstMatchingFont(family, DWRITE_FONT_WEIGHT_NORMAL,
DWRITE_FONT_STRETCH_NORMAL, DWRITE_FONT_STYLE_NORMAL, &font);
ok(hr == S_OK, "got 0x%08x\n", hr);
exists = TRUE;
strings = (void*)0xdeadbeef;
hr = IDWriteFont_GetInformationalStrings(font, DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME+1, &strings, &exists);
todo_wine {
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(exists == FALSE, "got %d\n", exists);
ok(strings == NULL, "got %p\n", strings);
}
exists = FALSE;
strings = NULL;
hr = IDWriteFont_GetInformationalStrings(font, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES, &strings, &exists);
todo_wine {
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(exists == TRUE, "got %d\n", exists);
}
exists = TRUE;
strings = NULL;
hr = IDWriteFont_GetInformationalStrings(font, DWRITE_INFORMATIONAL_STRING_NONE, &strings, &exists);
todo_wine {
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(exists == FALSE, "got %d\n", exists);
}
/* strings instance is not reused */
strings2 = NULL;
hr = IDWriteFont_GetInformationalStrings(font, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES, &strings2, &exists);
todo_wine {
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(strings2 != strings, "got %p, %p\n", strings2, strings);
}
if (strings)
IDWriteLocalizedStrings_Release(strings);
if (strings2)
IDWriteLocalizedStrings_Release(strings2);
IDWriteFont_Release(font);
IDWriteFontFamily_Release(family);
IDWriteFontCollection_Release(collection);
}
static void test_GetGdiInterop(void)
{
IDWriteGdiInterop *interop, *interop2;
IDWriteFactory *factory2;
IDWriteFont *font;
LOGFONTW logfont;
HRESULT hr;
interop = NULL;
hr = IDWriteFactory_GetGdiInterop(factory, &interop);
ok(hr == S_OK, "got 0x%08x\n", hr);
interop2 = NULL;
hr = IDWriteFactory_GetGdiInterop(factory, &interop2);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(interop == interop2, "got %p, %p\n", interop, interop2);
IDWriteGdiInterop_Release(interop2);
hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED, &IID_IDWriteFactory, (IUnknown**)&factory2);
ok(hr == S_OK, "got 0x%08x\n", hr);
/* each factory gets its own interop */
interop2 = NULL;
hr = IDWriteFactory_GetGdiInterop(factory2, &interop2);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(interop != interop2, "got %p, %p\n", interop, interop2);
/* release factory - interop still works */
IDWriteFactory_Release(factory2);
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(interop2, &logfont, &font);
ok(hr == S_OK, "got 0x%08x\n", hr);
IDWriteGdiInterop_Release(interop2);
IDWriteGdiInterop_Release(interop);
}
START_TEST(font)
{
HRESULT hr;
@ -1303,6 +1440,8 @@ START_TEST(font)
test_GetUnicodeRanges();
test_GetFontFromFontFace();
test_GetFirstMatchingFont();
test_GetInformationalStrings();
test_GetGdiInterop();
IDWriteFactory_Release(factory);
}