dwrite: Implement CreateFontFromLOGFONT() on top of system font collection.
This commit is contained in:
parent
ea11f85a94
commit
a088f7d381
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue