Commit a088f7d3 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

dwrite: Implement CreateFontFromLOGFONT() on top of system font collection.

parent ea11f85a
......@@ -89,7 +89,6 @@ static inline unsigned short get_table_entry(const unsigned short *table, WCHAR
return table[table[table[ch >> 8] + ((ch >> 4) & 0x0f)] + (ch & 0xf)];
}
extern HRESULT create_font_from_logfont(const LOGFONTW*, IDWriteFont**) DECLSPEC_HIDDEN;
extern HRESULT convert_fontface_to_logfont(IDWriteFontFace*, LOGFONTW*) DECLSPEC_HIDDEN;
extern HRESULT create_numbersubstitution(DWRITE_NUMBER_SUBSTITUTION_METHOD,const WCHAR *locale,BOOL,IDWriteNumberSubstitution**) DECLSPEC_HIDDEN;
extern HRESULT create_textformat(const WCHAR*,IDWriteFontCollection*,DWRITE_FONT_WEIGHT,DWRITE_FONT_STYLE,DWRITE_FONT_STRETCH,
......
......@@ -749,6 +749,129 @@ static HRESULT get_fontface_from_font(struct dwrite_font *font, IDWriteFontFace2
return S_OK;
}
static HRESULT create_font_base(IDWriteFont **font)
{
struct dwrite_font_data *data;
HRESULT ret;
*font = NULL;
data = heap_alloc(sizeof(*data));
if (!data) return E_OUTOFMEMORY;
data->ref = 0;
data->face_data = NULL;
ret = create_font_from_data( data, NULL, font );
if (FAILED(ret)) heap_free( data );
return ret;
}
static HRESULT create_font_from_logfont(const LOGFONTW *logfont, IDWriteFont **font)
{
const WCHAR* facename, *familyname;
IDWriteLocalizedStrings *name;
struct dwrite_font *This;
IDWriteFontFamily *family;
OUTLINETEXTMETRICW *otm;
HRESULT hr;
HFONT hfont;
HDC hdc;
int ret;
static const WCHAR enusW[] = {'e','n','-','u','s',0};
LPVOID tt_os2 = NULL;
LPVOID tt_head = NULL;
LPVOID tt_post = NULL;
LONG size;
hr = create_font_base(font);
if (FAILED(hr))
return hr;
This = impl_from_IDWriteFont2((IDWriteFont2*)*font);
hfont = CreateFontIndirectW(logfont);
if (!hfont)
{
heap_free(This->data);
heap_free(This);
return DWRITE_E_NOFONT;
}
hdc = CreateCompatibleDC(0);
SelectObject(hdc, hfont);
ret = GetOutlineTextMetricsW(hdc, 0, NULL);
otm = heap_alloc(ret);
if (!otm)
{
heap_free(This->data);
heap_free(This);
DeleteDC(hdc);
DeleteObject(hfont);
return E_OUTOFMEMORY;
}
otm->otmSize = ret;
ret = GetOutlineTextMetricsW(hdc, otm->otmSize, otm);
size = GetFontData(hdc, MS_OS2_TAG, 0, NULL, 0);
if (size != GDI_ERROR)
{
tt_os2 = heap_alloc(size);
GetFontData(hdc, MS_OS2_TAG, 0, tt_os2, size);
}
size = GetFontData(hdc, MS_HEAD_TAG, 0, NULL, 0);
if (size != GDI_ERROR)
{
tt_head = heap_alloc(size);
GetFontData(hdc, MS_HEAD_TAG, 0, tt_head, size);
}
size = GetFontData(hdc, MS_POST_TAG, 0, NULL, 0);
if (size != GDI_ERROR)
{
tt_post = heap_alloc(size);
GetFontData(hdc, MS_POST_TAG, 0, tt_post, size);
}
get_font_properties(tt_os2, tt_head, tt_post, &This->data->metrics, &This->data->stretch, &This->data->weight, &This->data->style);
heap_free(tt_os2);
heap_free(tt_head);
heap_free(tt_post);
if (logfont->lfItalic)
This->data->style = DWRITE_FONT_STYLE_ITALIC;
DeleteDC(hdc);
DeleteObject(hfont);
facename = (WCHAR*)((char*)otm + (ptrdiff_t)otm->otmpFaceName);
familyname = (WCHAR*)((char*)otm + (ptrdiff_t)otm->otmpFamilyName);
TRACE("facename=%s, familyname=%s\n", debugstr_w(facename), debugstr_w(familyname));
hr = create_localizedstrings(&name);
if (FAILED(hr))
{
heap_free(This);
return hr;
}
add_localizedstring(name, enusW, familyname);
hr = create_fontfamily(name, &family);
heap_free(otm);
if (hr != S_OK)
{
heap_free(This->data);
heap_free(This);
return hr;
}
This->is_system = TRUE;
This->family = family;
This->data->simulations = DWRITE_FONT_SIMULATIONS_NONE;
This->data->facename = heap_strdupW(logfont->lfFaceName);
return S_OK;
}
static HRESULT WINAPI dwritefont_QueryInterface(IDWriteFont2 *iface, REFIID riid, void **obj)
{
struct dwrite_font *This = impl_from_IDWriteFont2(iface);
......@@ -1404,129 +1527,6 @@ static HRESULT create_font_from_data(struct dwrite_font_data *data, IDWriteFontF
return S_OK;
}
static HRESULT create_font_base(IDWriteFont **font)
{
struct dwrite_font_data *data;
HRESULT ret;
*font = NULL;
data = heap_alloc(sizeof(*data));
if (!data) return E_OUTOFMEMORY;
data->ref = 0;
data->face_data = NULL;
ret = create_font_from_data( data, NULL, font );
if (FAILED(ret)) heap_free( data );
return ret;
}
HRESULT create_font_from_logfont(const LOGFONTW *logfont, IDWriteFont **font)
{
const WCHAR* facename, *familyname;
IDWriteLocalizedStrings *name;
struct dwrite_font *This;
IDWriteFontFamily *family;
OUTLINETEXTMETRICW *otm;
HRESULT hr;
HFONT hfont;
HDC hdc;
int ret;
static const WCHAR enusW[] = {'e','n','-','u','s',0};
LPVOID tt_os2 = NULL;
LPVOID tt_head = NULL;
LPVOID tt_post = NULL;
LONG size;
hr = create_font_base(font);
if (FAILED(hr))
return hr;
This = impl_from_IDWriteFont2((IDWriteFont2*)*font);
hfont = CreateFontIndirectW(logfont);
if (!hfont)
{
heap_free(This->data);
heap_free(This);
return DWRITE_E_NOFONT;
}
hdc = CreateCompatibleDC(0);
SelectObject(hdc, hfont);
ret = GetOutlineTextMetricsW(hdc, 0, NULL);
otm = heap_alloc(ret);
if (!otm)
{
heap_free(This->data);
heap_free(This);
DeleteDC(hdc);
DeleteObject(hfont);
return E_OUTOFMEMORY;
}
otm->otmSize = ret;
ret = GetOutlineTextMetricsW(hdc, otm->otmSize, otm);
size = GetFontData(hdc, MS_OS2_TAG, 0, NULL, 0);
if (size != GDI_ERROR)
{
tt_os2 = heap_alloc(size);
GetFontData(hdc, MS_OS2_TAG, 0, tt_os2, size);
}
size = GetFontData(hdc, MS_HEAD_TAG, 0, NULL, 0);
if (size != GDI_ERROR)
{
tt_head = heap_alloc(size);
GetFontData(hdc, MS_HEAD_TAG, 0, tt_head, size);
}
size = GetFontData(hdc, MS_POST_TAG, 0, NULL, 0);
if (size != GDI_ERROR)
{
tt_post = heap_alloc(size);
GetFontData(hdc, MS_POST_TAG, 0, tt_post, size);
}
get_font_properties(tt_os2, tt_head, tt_post, &This->data->metrics, &This->data->stretch, &This->data->weight, &This->data->style);
heap_free(tt_os2);
heap_free(tt_head);
heap_free(tt_post);
if (logfont->lfItalic)
This->data->style = DWRITE_FONT_STYLE_ITALIC;
DeleteDC(hdc);
DeleteObject(hfont);
facename = (WCHAR*)((char*)otm + (ptrdiff_t)otm->otmpFaceName);
familyname = (WCHAR*)((char*)otm + (ptrdiff_t)otm->otmpFamilyName);
TRACE("facename=%s, familyname=%s\n", debugstr_w(facename), debugstr_w(familyname));
hr = create_localizedstrings(&name);
if (FAILED(hr))
{
heap_free(This);
return hr;
}
add_localizedstring(name, enusW, familyname);
hr = create_fontfamily(name, &family);
heap_free(otm);
if (hr != S_OK)
{
heap_free(This->data);
heap_free(This);
return hr;
}
This->is_system = TRUE;
This->family = family;
This->data->simulations = DWRITE_FONT_SIMULATIONS_NONE;
This->data->facename = heap_strdupW(logfont->lfFaceName);
return S_OK;
}
static HRESULT WINAPI dwritefontfile_QueryInterface(IDWriteFontFile *iface, REFIID riid, void **obj)
{
struct dwrite_fontfile *This = impl_from_IDWriteFontFile(iface);
......
......@@ -271,11 +271,47 @@ static HRESULT WINAPI gdiinterop_CreateFontFromLOGFONT(IDWriteGdiInterop *iface,
LOGFONTW const *logfont, IDWriteFont **font)
{
struct gdiinterop *This = impl_from_IDWriteGdiInterop(iface);
IDWriteFontCollection *collection;
IDWriteFontFamily *family;
DWRITE_FONT_STYLE style;
BOOL exists = FALSE;
UINT32 index;
HRESULT hr;
TRACE("(%p)->(%p %p)\n", This, logfont, font);
*font = NULL;
if (!logfont) return E_INVALIDARG;
return create_font_from_logfont(logfont, font);
hr = IDWriteFactory_GetSystemFontCollection(This->factory, &collection, FALSE);
if (FAILED(hr)) {
ERR("failed to get system font collection: 0x%08x.\n", hr);
return hr;
}
hr = IDWriteFontCollection_FindFamilyName(collection, logfont->lfFaceName, &index, &exists);
if (FAILED(hr)) {
IDWriteFontCollection_Release(collection);
goto done;
}
if (!exists) {
hr = DWRITE_E_NOFONT;
goto done;
}
hr = IDWriteFontCollection_GetFontFamily(collection, index, &family);
if (FAILED(hr))
goto done;
style = logfont->lfItalic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL;
hr = IDWriteFontFamily_GetFirstMatchingFont(family, logfont->lfWeight, DWRITE_FONT_STRETCH_NORMAL, style, font);
IDWriteFontFamily_Release(family);
done:
IDWriteFontCollection_Release(collection);
return hr;
}
static HRESULT WINAPI gdiinterop_ConvertFontToLOGFONT(IDWriteGdiInterop *iface,
......
......@@ -312,8 +312,9 @@ todo_wine {
logfont.lfWeight = 550;
lstrcpyW(logfont.lfFaceName, tahomaW);
font = NULL;
hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
EXPECT_HR(hr, S_OK);
ok(hr == S_OK, "got 0x%08x\n", hr);
weight = IDWriteFont_GetWeight(font);
ok(weight == DWRITE_FONT_WEIGHT_NORMAL || broken(weight == DWRITE_FONT_WEIGHT_BOLD) /* win7 w/o SP */,
......@@ -329,12 +330,10 @@ todo_wine {
font = (void*)0xdeadbeef;
hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
todo_wine {
EXPECT_HR(hr, DWRITE_E_NOFONT);
ok(hr == DWRITE_E_NOFONT, "got 0x%08x\n", hr);
ok(font == NULL, "got %p\n", font);
if(font) IDWriteFont_Release(font);
}
/* Try with name 'Tahoma ' */
memset(&logfont, 0, sizeof(logfont));
logfont.lfHeight = 12;
logfont.lfWidth = 12;
......@@ -343,12 +342,10 @@ todo_wine {
font = (void*)0xdeadbeef;
hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
todo_wine {
EXPECT_HR(hr, DWRITE_E_NOFONT);
ok(hr == DWRITE_E_NOFONT, "got 0x%08x\n", hr);
ok(font == NULL, "got %p\n", font);
if(font) IDWriteFont_Release(font);
}
/* empty string as a facename */
memset(&logfont, 0, sizeof(logfont));
logfont.lfHeight = 12;
logfont.lfWidth = 12;
......@@ -356,11 +353,8 @@ todo_wine {
font = (void*)0xdeadbeef;
hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
todo_wine {
EXPECT_HR(hr, DWRITE_E_NOFONT);
ok(hr == DWRITE_E_NOFONT, "got 0x%08x\n", hr);
ok(font == NULL, "got %p\n", font);
if(font) IDWriteFont_Release(font);
}
IDWriteGdiInterop_Release(interop);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment