dwrite: Implement system font collection as any other font collection.

This commit is contained in:
Nikolay Sivov 2014-10-29 22:41:47 +03:00 committed by Alexandre Julliard
parent 2bc984a5b1
commit cae5d19338
4 changed files with 236 additions and 460 deletions

View File

@ -101,7 +101,7 @@ 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;
extern HRESULT get_system_fontcollection(IDWriteFontCollection**) DECLSPEC_HIDDEN;
extern HRESULT get_system_fontcollection(IDWriteFactory*,IDWriteFontCollection**) DECLSPEC_HIDDEN;
extern HRESULT get_textanalyzer(IDWriteTextAnalyzer**) DECLSPEC_HIDDEN;
extern HRESULT create_font_file(IDWriteFontFileLoader *loader, const void *reference_key, UINT32 key_size, IDWriteFontFile **font_file) DECLSPEC_HIDDEN;
extern HRESULT create_localfontfileloader(IDWriteLocalFontFileLoader** iface) DECLSPEC_HIDDEN;

View File

@ -65,10 +65,6 @@ struct dwrite_fontcollection {
IDWriteFontCollection IDWriteFontCollection_iface;
LONG ref;
WCHAR **families;
UINT32 count;
int alloc;
struct dwrite_fontfamily_data **family_data;
UINT32 family_count;
UINT32 family_alloc;
@ -87,7 +83,6 @@ struct dwrite_font {
IDWriteFont2 IDWriteFont2_iface;
LONG ref;
BOOL is_system;
IDWriteFontFamily *family;
DWRITE_FONT_SIMULATIONS simulations;
@ -120,9 +115,6 @@ struct dwrite_fontface {
DWRITE_FONT_FACE_TYPE type;
struct dwrite_fonttable cmap;
BOOL is_system;
LOGFONTW logfont;
};
struct dwrite_fontfile {
@ -135,9 +127,7 @@ struct dwrite_fontfile {
IDWriteFontFileStream *stream;
};
static HRESULT create_fontfamily(IDWriteLocalizedStrings *familyname, IDWriteFontFamily **family);
static HRESULT create_fontfamily_from_data(struct dwrite_fontfamily_data *data, IDWriteFontCollection *collection, IDWriteFontFamily **family);
static HRESULT create_font_base(IDWriteFont **font);
static HRESULT create_font_from_data(struct dwrite_font_data*,IDWriteFontFamily*,DWRITE_FONT_SIMULATIONS,IDWriteFont**);
static HRESULT get_filestream_from_file(IDWriteFontFile*,IDWriteFontFileStream**);
@ -369,91 +359,53 @@ static HRESULT WINAPI dwritefontface_GetGlyphIndices(IDWriteFontFace2 *iface, UI
{
struct dwrite_fontface *This = impl_from_IDWriteFontFace2(iface);
unsigned int i;
void *data;
if (This->is_system)
{
HFONT hfont;
WCHAR *str;
HDC hdc;
TRACE("(%p)->(%p %u %p)\n", This, codepoints, count, glyph_indices);
TRACE("(%p)->(%p %u %p)\n", This, codepoints, count, glyph_indices);
data = get_fontface_cmap(This);
if (!data)
return E_FAIL;
str = heap_alloc(count*sizeof(WCHAR));
if (!str) return E_OUTOFMEMORY;
for (i = 0; i < count; i++)
opentype_cmap_get_glyphindex(data, codepoints[i], &glyph_indices[i]);
for (i = 0; i < count; i++)
str[i] = codepoints[i] < 0x10000 ? codepoints[i] : '?';
hdc = CreateCompatibleDC(0);
hfont = CreateFontIndirectW(&This->logfont);
SelectObject(hdc, hfont);
GetGlyphIndicesW(hdc, str, count, glyph_indices, 0);
heap_free(str);
DeleteDC(hdc);
DeleteObject(hfont);
return S_OK;
}
else
{
void *data;
TRACE("(%p)->(%p %u %p)\n", This, codepoints, count, glyph_indices);
data = get_fontface_cmap(This);
if (!data)
return E_FAIL;
for (i = 0; i < count; i++)
opentype_cmap_get_glyphindex(data, codepoints[i], &glyph_indices[i]);
return S_OK;
}
return S_OK;
}
static HRESULT WINAPI dwritefontface_TryGetFontTable(IDWriteFontFace2 *iface, UINT32 table_tag,
const void **table_data, UINT32 *table_size, void **context, BOOL *exists)
{
struct dwrite_fontface *This = impl_from_IDWriteFontFace2(iface);
if (This->is_system)
{
FIXME("(%p)->(%u %p %p %p %p): stub\n", This, table_tag, table_data, table_size, context, exists);
return E_NOTIMPL;
struct dwrite_fonttablecontext *tablecontext;
HRESULT hr = S_OK;
int i;
TRACE("(%p)->(%u %p %p %p %p)\n", This, table_tag, table_data, table_size, context, exists);
tablecontext = heap_alloc(sizeof(struct dwrite_fonttablecontext));
if (!tablecontext)
return E_OUTOFMEMORY;
tablecontext->magic = DWRITE_FONTTABLE_MAGIC;
*exists = FALSE;
for (i = 0; i < This->file_count && !(*exists); i++) {
IDWriteFontFileStream *stream;
hr = _dwritefontfile_GetFontFileStream(This->files[i], &stream);
if (FAILED(hr))
continue;
tablecontext->file_index = i;
hr = opentype_get_font_table(stream, This->type, This->index, table_tag, table_data, &tablecontext->context, table_size, exists);
IDWriteFontFileStream_Release(stream);
}
if (FAILED(hr) && !*exists)
heap_free(tablecontext);
else
{
HRESULT hr = S_OK;
int i;
struct dwrite_fonttablecontext *tablecontext;
*context = (void*)tablecontext;
TRACE("(%p)->(%u %p %p %p %p)\n", This, table_tag, table_data, table_size, context, exists);
tablecontext = heap_alloc(sizeof(struct dwrite_fonttablecontext));
if (!tablecontext)
return E_OUTOFMEMORY;
tablecontext->magic = DWRITE_FONTTABLE_MAGIC;
*exists = FALSE;
for (i = 0; i < This->file_count && !(*exists); i++)
{
IDWriteFontFileStream *stream;
hr = _dwritefontfile_GetFontFileStream(This->files[i], &stream);
if (FAILED(hr))
continue;
tablecontext->file_index = i;
hr = opentype_get_font_table(stream, This->type, This->index, table_tag, table_data, &tablecontext->context, table_size, exists);
IDWriteFontFileStream_Release(stream);
}
if (FAILED(hr) && !*exists)
heap_free(tablecontext);
else
*context = (void*)tablecontext;
return hr;
}
return hr;
}
static void WINAPI dwritefontface_ReleaseFontTable(IDWriteFontFace2 *iface, void *table_context)
@ -692,38 +644,6 @@ static const IDWriteFontFace2Vtbl dwritefontfacevtbl = {
dwritefontface2_GetRecommendedRenderingMode
};
static HRESULT create_system_fontface(struct dwrite_font *font, IDWriteFontFace **face)
{
struct dwrite_fontface *This;
*face = NULL;
This = heap_alloc(sizeof(struct dwrite_fontface));
if (!This) return E_OUTOFMEMORY;
This->IDWriteFontFace2_iface.lpVtbl = &dwritefontfacevtbl;
This->ref = 1;
This->type = DWRITE_FONT_FACE_TYPE_UNKNOWN;
This->file_count = 0;
This->files = NULL;
This->index = 0;
This->simulations = DWRITE_FONT_SIMULATIONS_NONE;
This->cmap.data = NULL;
This->cmap.context = NULL;
This->cmap.size = 0;
This->is_system = TRUE;
memset(&This->logfont, 0, sizeof(This->logfont));
This->logfont.lfItalic = font->data->style == DWRITE_FONT_STYLE_ITALIC;
/* weight values from DWRITE_FONT_WEIGHT match values used for LOGFONT */
This->logfont.lfWeight = font->data->weight;
strcpyW(This->logfont.lfFaceName, font->data->facename);
*face = (IDWriteFontFace*)&This->IDWriteFontFace2_iface;
return S_OK;
}
static void get_font_properties_from_stream(IDWriteFontFileStream *stream, DWRITE_FONT_FACE_TYPE face_type,
UINT32 face_index, DWRITE_FONT_METRICS *metrics, DWRITE_FONT_STRETCH *stretch, DWRITE_FONT_WEIGHT *weight,
DWRITE_FONT_STYLE *style)
@ -797,8 +717,7 @@ static HRESULT get_fontface_from_font(struct dwrite_font *font, IDWriteFontFace2
struct dwrite_font_data *data = font->data;
IDWriteFontFace *face;
hr = font->is_system ? create_system_fontface(font, &face) :
IDWriteFactory_CreateFontFace(data->factory, data->face_type, 1, &data->file,
hr = IDWriteFactory_CreateFontFace(data->factory, data->face_type, 1, &data->file,
data->face_index, font->simulations, &face);
if (FAILED(hr))
return hr;
@ -811,126 +730,6 @@ static HRESULT get_fontface_from_font(struct dwrite_font *font, IDWriteFontFace2
return hr;
}
static HRESULT create_font_base(IDWriteFont **font)
{
struct dwrite_font_data *data;
HRESULT ret;
*font = NULL;
data = heap_alloc_zero(sizeof(*data));
if (!data) return E_OUTOFMEMORY;
ret = create_font_from_data( data, NULL, DWRITE_FONT_SIMULATIONS_NONE, 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->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);
@ -1231,14 +1030,10 @@ static HRESULT WINAPI dwritefontfamily_GetFontCollection(IDWriteFontFamily *ifac
{
struct dwrite_fontfamily *This = impl_from_IDWriteFontFamily(iface);
TRACE("(%p)->(%p)\n", This, collection);
if (This->collection)
{
IDWriteFontCollection_AddRef(This->collection);
*collection = This->collection;
return S_OK;
}
else
return E_NOTIMPL;
*collection = This->collection;
IDWriteFontCollection_AddRef(This->collection);
return S_OK;
}
static UINT32 WINAPI dwritefontfamily_GetFontCount(IDWriteFontFamily *iface)
@ -1251,15 +1046,18 @@ static UINT32 WINAPI dwritefontfamily_GetFontCount(IDWriteFontFamily *iface)
static HRESULT WINAPI dwritefontfamily_GetFont(IDWriteFontFamily *iface, UINT32 index, IDWriteFont **font)
{
struct dwrite_fontfamily *This = impl_from_IDWriteFontFamily(iface);
TRACE("(%p)->(%u %p)\n", This, index, font);
if (This->data->font_count > 0)
{
if (index >= This->data->font_count)
return E_INVALIDARG;
return create_font_from_data(This->data->fonts[index], iface, DWRITE_FONT_SIMULATIONS_NONE, font);
}
else
return E_NOTIMPL;
*font = NULL;
if (This->data->font_count == 0)
return S_FALSE;
if (index >= This->data->font_count)
return E_INVALIDARG;
return create_font_from_data(This->data->fonts[index], iface, DWRITE_FONT_SIMULATIONS_NONE, font);
}
static HRESULT WINAPI dwritefontfamily_GetFamilyNames(IDWriteFontFamily *iface, IDWriteLocalizedStrings **names)
@ -1283,49 +1081,34 @@ static HRESULT WINAPI dwritefontfamily_GetFirstMatchingFont(IDWriteFontFamily *i
DWRITE_FONT_STRETCH stretch, DWRITE_FONT_STYLE style, IDWriteFont **font)
{
struct dwrite_fontfamily *This = impl_from_IDWriteFontFamily(iface);
LOGFONTW lf;
UINT32 min_weight_diff = ~0u;
int found = -1, i;
TRACE("(%p)->(%d %d %d %p)\n", This, weight, stretch, style, font);
/* fallback for system font collections */
if (This->data->font_count == 0)
{
memset(&lf, 0, sizeof(lf));
lf.lfWeight = weight;
lf.lfItalic = style == DWRITE_FONT_STYLE_ITALIC;
IDWriteLocalizedStrings_GetString(This->data->familyname, 0, lf.lfFaceName, LF_FACESIZE);
return create_font_from_logfont(&lf, font);
for (i = 0; i < This->data->font_count; i++) {
if (is_matching_font_style(style, This->data->fonts[i]->style) && stretch == This->data->fonts[i]->stretch) {
DWRITE_FONT_WEIGHT font_weight = This->data->fonts[i]->weight;
UINT32 weight_diff = abs(font_weight - weight);
if (weight_diff < min_weight_diff) {
min_weight_diff = weight_diff;
found = i;
}
}
}
else
{
UINT32 min_weight_diff = ~0u;
int found = -1, i;
for (i = 0; i < This->data->font_count; i++) {
if (is_matching_font_style(style, This->data->fonts[i]->style) && stretch == This->data->fonts[i]->stretch) {
DWRITE_FONT_WEIGHT font_weight = This->data->fonts[i]->weight;
UINT32 weight_diff = abs(font_weight - weight);
if (weight_diff < min_weight_diff) {
min_weight_diff = weight_diff;
found = i;
}
}
}
if (found != -1) {
DWRITE_FONT_SIMULATIONS simulations = DWRITE_FONT_SIMULATIONS_NONE;
if (found != -1) {
DWRITE_FONT_SIMULATIONS simulations = DWRITE_FONT_SIMULATIONS_NONE;
if (((style == DWRITE_FONT_STYLE_ITALIC) || (style == DWRITE_FONT_STYLE_OBLIQUE)) &&
This->data->fonts[found]->style == DWRITE_FONT_STYLE_ITALIC) {
simulations = DWRITE_FONT_SIMULATIONS_OBLIQUE;
}
return create_font_from_data(This->data->fonts[found], iface, simulations, font);
}
else {
*font = NULL;
return DWRITE_E_NOFONT;
if (((style == DWRITE_FONT_STYLE_ITALIC) || (style == DWRITE_FONT_STYLE_OBLIQUE)) &&
This->data->fonts[found]->style == DWRITE_FONT_STYLE_ITALIC) {
simulations = DWRITE_FONT_SIMULATIONS_OBLIQUE;
}
return create_font_from_data(This->data->fonts[found], iface, simulations, font);
}
else {
*font = NULL;
return DWRITE_E_NOFONT;
}
}
@ -1381,11 +1164,7 @@ static ULONG WINAPI dwritefontcollection_Release(IDWriteFontCollection *iface)
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p)->(%d)\n", This, ref);
if (!ref)
{
for (i = 0; i < This->count; i++)
heap_free(This->families[i]);
heap_free(This->families);
if (!ref) {
for (i = 0; i < This->family_count; i++)
_free_fontfamily_data(This->family_data[i]);
heap_free(This->family_data);
@ -1399,45 +1178,21 @@ static UINT32 WINAPI dwritefontcollection_GetFontFamilyCount(IDWriteFontCollecti
{
struct dwrite_fontcollection *This = impl_from_IDWriteFontCollection(iface);
TRACE("(%p)\n", This);
if (This->family_count)
return This->family_count;
return This->count;
return This->family_count;
}
static HRESULT WINAPI dwritefontcollection_GetFontFamily(IDWriteFontCollection *iface, UINT32 index, IDWriteFontFamily **family)
{
struct dwrite_fontcollection *This = impl_from_IDWriteFontCollection(iface);
HRESULT hr;
IDWriteLocalizedStrings *familyname;
static const WCHAR enusW[] = {'e','n','-','u','s',0};
TRACE("(%p)->(%u %p)\n", This, index, family);
if (This->family_count)
{
if (index >= This->family_count)
{
*family = NULL;
return E_FAIL;
}
else
return create_fontfamily_from_data(This->family_data[index], iface, family);
if (index >= This->family_count) {
*family = NULL;
return E_FAIL;
}
else
{
if (index >= This->count)
{
*family = NULL;
return E_FAIL;
}
hr = create_localizedstrings(&familyname);
if (FAILED(hr))
return hr;
add_localizedstring(familyname, enusW, This->families[index]);
return create_fontfamily(familyname, family);
}
return create_fontfamily_from_data(This->family_data[index], iface, family);
}
static HRESULT collection_find_family(struct dwrite_fontcollection *collection, const WCHAR *name, UINT32 *index, BOOL *exists)
@ -1465,17 +1220,6 @@ static HRESULT collection_find_family(struct dwrite_fontcollection *collection,
*index = (UINT32)-1;
*exists = FALSE;
}
else {
for (i = 0; i < collection->count; i++)
if (!strcmpW(collection->families[i], name)) {
*index = i;
*exists = TRUE;
return S_OK;
}
*index = (UINT32)-1;
*exists = FALSE;
}
return S_OK;
}
@ -1538,24 +1282,6 @@ static const IDWriteFontCollectionVtbl fontcollectionvtbl = {
dwritefontcollection_GetFontFromFontFace
};
static HRESULT add_family_syscollection(struct dwrite_fontcollection *collection, const WCHAR *family)
{
/* check for duplicate family name */
if (collection->count && !strcmpW(collection->families[collection->count-1], family)) return S_OK;
/* double array length */
if (collection->count == collection->alloc)
{
collection->alloc *= 2;
collection->families = heap_realloc(collection->families, collection->alloc*sizeof(WCHAR*));
}
collection->families[collection->count++] = heap_strdupW(family);
TRACE("family name %s\n", debugstr_w(family));
return S_OK;
}
static HRESULT fontfamily_add_font(struct dwrite_fontfamily_data *family_data, struct dwrite_font_data *font_data)
{
if (family_data->font_count + 1 >= family_data->font_alloc) {
@ -1603,9 +1329,6 @@ static HRESULT init_font_collection(struct dwrite_fontcollection *collection)
collection->ref = 1;
collection->family_count = 0;
collection->family_alloc = 2;
collection->count = 0;
collection->alloc = 0;
collection->families = NULL;
collection->family_data = heap_alloc(sizeof(*collection->family_data)*2);
if (!collection->family_data)
@ -1796,56 +1519,163 @@ HRESULT create_font_collection(IDWriteFactory* factory, IDWriteFontFileEnumerato
return S_OK;
}
static INT CALLBACK enum_font_families(const LOGFONTW *lf, const TEXTMETRICW *tm, DWORD type, LPARAM lParam)
struct system_fontfile_enumerator
{
struct dwrite_fontcollection *collection = (struct dwrite_fontcollection*)lParam;
return add_family_syscollection(collection, lf->lfFaceName) == S_OK;
IDWriteFontFileEnumerator IDWriteFontFileEnumerator_iface;
LONG ref;
IDWriteFactory *factory;
HKEY hkey;
int index;
};
static inline struct system_fontfile_enumerator *impl_from_IDWriteFontFileEnumerator(IDWriteFontFileEnumerator* iface)
{
return CONTAINING_RECORD(iface, struct system_fontfile_enumerator, IDWriteFontFileEnumerator_iface);
}
HRESULT get_system_fontcollection(IDWriteFontCollection **collection)
static HRESULT WINAPI systemfontfileenumerator_QueryInterface(IDWriteFontFileEnumerator *iface, REFIID riid, void **obj)
{
struct dwrite_fontcollection *This;
LOGFONTW lf;
HDC hdc;
*obj = NULL;
if (IsEqualIID(riid, &IID_IDWriteFontFileEnumerator) || IsEqualIID(riid, &IID_IUnknown)) {
IDWriteFontFileEnumerator_AddRef(iface);
*obj = iface;
return S_OK;
}
return E_NOINTERFACE;
}
static ULONG WINAPI systemfontfileenumerator_AddRef(IDWriteFontFileEnumerator *iface)
{
struct system_fontfile_enumerator *enumerator = impl_from_IDWriteFontFileEnumerator(iface);
return InterlockedIncrement(&enumerator->ref);
}
static ULONG WINAPI systemfontfileenumerator_Release(IDWriteFontFileEnumerator *iface)
{
struct system_fontfile_enumerator *enumerator = impl_from_IDWriteFontFileEnumerator(iface);
ULONG ref = InterlockedDecrement(&enumerator->ref);
if (!ref) {
IDWriteFactory_Release(enumerator->factory);
RegCloseKey(enumerator->hkey);
heap_free(enumerator);
}
return ref;
}
static HRESULT WINAPI systemfontfileenumerator_GetCurrentFontFile(IDWriteFontFileEnumerator *iface, IDWriteFontFile **file)
{
struct system_fontfile_enumerator *enumerator = impl_from_IDWriteFontFileEnumerator(iface);
DWORD ret, type, count;
HRESULT hr;
BYTE *data;
*file = NULL;
if (enumerator->index < 0)
return E_FAIL;
if (RegEnumValueW(enumerator->hkey, enumerator->index, NULL, NULL, NULL, &type, NULL, &count))
return E_FAIL;
if (!(data = heap_alloc(count)))
return E_OUTOFMEMORY;
ret = RegEnumValueW(enumerator->hkey, enumerator->index, NULL, NULL, NULL, &type, data, &count);
if (ret) {
heap_free(data);
return E_FAIL;
}
hr = IDWriteFactory_CreateFontFileReference(enumerator->factory, (WCHAR*)data, NULL, file);
heap_free(data);
return hr;
}
static HRESULT WINAPI systemfontfileenumerator_MoveNext(IDWriteFontFileEnumerator *iface, BOOL *current)
{
struct system_fontfile_enumerator *enumerator = impl_from_IDWriteFontFileEnumerator(iface);
*current = FALSE;
enumerator->index++;
/* iterate until we find next string value */
while (1) {
DWORD type = 0, count;
if (RegEnumValueW(enumerator->hkey, enumerator->index, NULL, NULL, NULL, &type, NULL, &count))
break;
if (type == REG_SZ) {
*current = TRUE;
break;
}
enumerator->index++;
}
TRACE("index = %d, current = %d\n", enumerator->index, *current);
return S_OK;
}
static const struct IDWriteFontFileEnumeratorVtbl systemfontfileenumeratorvtbl =
{
systemfontfileenumerator_QueryInterface,
systemfontfileenumerator_AddRef,
systemfontfileenumerator_Release,
systemfontfileenumerator_MoveNext,
systemfontfileenumerator_GetCurrentFontFile
};
static HRESULT create_system_fontfile_enumerator(IDWriteFactory *factory, IDWriteFontFileEnumerator **ret)
{
struct system_fontfile_enumerator *enumerator;
static const WCHAR fontslistW[] = {
'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
'W','i','n','d','o','w','s',' ','N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
'F','o','n','t','s',0
};
*ret = NULL;
enumerator = heap_alloc(sizeof(*enumerator));
if (!enumerator)
return E_OUTOFMEMORY;
enumerator->IDWriteFontFileEnumerator_iface.lpVtbl = &systemfontfileenumeratorvtbl;
enumerator->ref = 1;
enumerator->factory = factory;
enumerator->index = -1;
IDWriteFactory_AddRef(factory);
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, fontslistW, 0, GENERIC_READ, &enumerator->hkey)) {
ERR("failed to open fonts list key\n");
IDWriteFactory_Release(factory);
heap_free(enumerator);
return E_FAIL;
}
*ret = &enumerator->IDWriteFontFileEnumerator_iface;
return S_OK;
}
HRESULT get_system_fontcollection(IDWriteFactory *factory, IDWriteFontCollection **collection)
{
IDWriteFontFileEnumerator *enumerator;
HRESULT hr;
*collection = NULL;
This = heap_alloc(sizeof(struct dwrite_fontcollection));
if (!This) return E_OUTOFMEMORY;
hr = create_system_fontfile_enumerator(factory, &enumerator);
if (FAILED(hr))
return hr;
This->IDWriteFontCollection_iface.lpVtbl = &fontcollectionvtbl;
This->ref = 1;
This->alloc = 50;
This->count = 0;
This->families = heap_alloc(This->alloc*sizeof(WCHAR*));
if (!This->families)
{
heap_free(This);
return E_OUTOFMEMORY;
}
This->family_count = 0;
This->family_alloc = 2;
This->family_data = heap_alloc(sizeof(*This->family_data)*2);
if (!This->family_data)
{
heap_free(This->families);
heap_free(This);
return E_OUTOFMEMORY;
}
TRACE("building system font collection:\n");
hdc = CreateCompatibleDC(0);
memset(&lf, 0, sizeof(lf));
lf.lfCharSet = DEFAULT_CHARSET;
lf.lfPitchAndFamily = DEFAULT_PITCH;
lf.lfFaceName[0] = 0;
EnumFontFamiliesExW(hdc, &lf, enum_font_families, (LPARAM)This, 0);
DeleteDC(hdc);
*collection = &This->IDWriteFontCollection_iface;
return S_OK;
TRACE("building system font collection for factory %p\n", factory);
hr = create_font_collection(factory, enumerator, collection);
IDWriteFontFileEnumerator_Release(enumerator);
return hr;
}
static HRESULT create_fontfamily_from_data(struct dwrite_fontfamily_data *data, IDWriteFontCollection *collection, IDWriteFontFamily **family)
@ -1870,35 +1700,6 @@ static HRESULT create_fontfamily_from_data(struct dwrite_fontfamily_data *data,
return S_OK;
}
static HRESULT create_fontfamily(IDWriteLocalizedStrings *familyname, IDWriteFontFamily **family)
{
struct dwrite_fontfamily_data *data;
HRESULT ret;
data = heap_alloc(sizeof(struct dwrite_fontfamily_data));
if (!data) return E_OUTOFMEMORY;
data->ref = 0;
data->font_count = 0;
data->font_alloc = 2;
data->fonts = heap_alloc(sizeof(*data->fonts) * 2);
if (!data->fonts)
{
heap_free(data);
return E_OUTOFMEMORY;
}
data->familyname = familyname;
ret = create_fontfamily_from_data(data, NULL, family);
if (FAILED(ret))
{
heap_free(data->fonts);
heap_free(data);
}
return ret;
}
static HRESULT create_font_from_data(struct dwrite_font_data *data, IDWriteFontFamily *family, DWRITE_FONT_SIMULATIONS simulations,
IDWriteFont **font)
{
@ -1913,7 +1714,6 @@ static HRESULT create_font_from_data(struct dwrite_font_data *data, IDWriteFontF
This->family = family;
if (family)
IDWriteFontFamily_AddRef(family);
This->is_system = FALSE;
This->simulations = simulations;
This->data = data;
InterlockedIncrement(&This->data->ref);
@ -2088,7 +1888,6 @@ HRESULT create_fontface(DWRITE_FONT_FACE_TYPE facetype, UINT32 files_number, IDW
fontface->index = index;
fontface->simulations = simulations;
fontface->is_system = FALSE;
*ret = &fontface->IDWriteFontFace2_iface;
return S_OK;

View File

@ -563,7 +563,7 @@ static HRESULT WINAPI dwritefactory_GetSystemFontCollection(IDWriteFactory *ifac
FIXME("checking for system font updates not implemented\n");
if (!This->system_collection)
hr = get_system_fontcollection(&This->system_collection);
hr = get_system_fontcollection(iface, &This->system_collection);
if (SUCCEEDED(hr))
IDWriteFontCollection_AddRef(This->system_collection);

View File

@ -311,6 +311,7 @@ todo_wine {
weight = IDWriteFont_GetWeight(font);
ok(weight == weights[i][1],
"%d: got %d, expected %d\n", i, weight, weights[i][1]);
IDWriteFont_Release(font);
}
@ -574,21 +575,16 @@ if (0) /* crashes on native */
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);
@ -745,7 +741,6 @@ if (0) /* crashes on native */
fontface2 = NULL;
hr = IDWriteFont_CreateFontFace(font2, &fontface2);
ok(hr == S_OK, "got 0x%08x\n", hr);
todo_wine
ok(fontface == fontface2, "got %p, was %p\n", fontface2, fontface);
IDWriteFontFace_Release(fontface2);
@ -783,7 +778,6 @@ todo_wine
fontface2 = NULL;
hr = IDWriteFont_CreateFontFace(font2, &fontface2);
ok(hr == S_OK, "got 0x%08x\n", hr);
todo_wine
ok(fontface == fontface2, "got %p, was %p\n", fontface2, fontface);
IDWriteFontFace_Release(fontface);
@ -925,10 +919,8 @@ static void test_system_fontcollection(void)
file = NULL;
hr = IDWriteFontFace_GetFiles(fontface, &i, &file);
ok(hr == S_OK, "got 0x%08x\n", hr);
todo_wine
ok(file != NULL, "got %p\n", file);
if (file) {
hr = IDWriteFontFile_GetLoader(file, &loader);
ok(hr == S_OK, "got 0x%08x\n", hr);
IDWriteFontFile_Release(file);
@ -956,7 +948,7 @@ if (file) {
IDWriteFactory_Release(factory2);
IDWriteFontFileLoader_Release(loader);
}
ret = TRUE;
i = 0;
hr = IDWriteFontCollection_FindFamilyName(collection, blahW, &i, &ret);
@ -1013,10 +1005,8 @@ if (0) /* crashes on native */
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(logfont.lfHeight == 0, "got %d\n", logfont.lfHeight);
ok(logfont.lfWidth == 0, "got %d\n", logfont.lfWidth);
todo_wine
ok(logfont.lfWeight == FW_NORMAL, "got %d\n", logfont.lfWeight);
ok(logfont.lfEscapement == 0, "got %d\n", logfont.lfEscapement);
todo_wine
ok(logfont.lfItalic == 1, "got %d\n", logfont.lfItalic);
ok(logfont.lfUnderline == 0, "got %d\n", logfont.lfUnderline);
ok(logfont.lfStrikeOut == 0, "got %d\n", logfont.lfStrikeOut);
@ -1439,36 +1429,26 @@ static void test_GetFontFromFontFace(void)
font2 = NULL;
hr = IDWriteFontCollection_GetFontFromFontFace(collection, fontface, &font2);
todo_wine
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(font2 != font, "got %p, %p\n", font2, font);
font3 = NULL;
hr = IDWriteFontCollection_GetFontFromFontFace(collection, fontface, &font3);
todo_wine {
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(font3 != font && font3 != font2, "got %p, %p, %p\n", font3, font2, font);
}
if (font2) {
hr = IDWriteFont_CreateFontFace(font2, &fontface2);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(fontface2 == fontface, "got %p, %p\n", fontface2, fontface);
IDWriteFontFace_Release(fontface2);
}
if (font3) {
hr = IDWriteFont_CreateFontFace(font3, &fontface2);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(fontface2 == fontface, "got %p, %p\n", fontface2, fontface);
IDWriteFontFace_Release(fontface2);
}
if (font)
IDWriteFont_Release(font);
if (font2)
IDWriteFont_Release(font2);
if (font3)
IDWriteFont_Release(font3);
IDWriteFontFace_Release(fontface);
IDWriteFontFamily_Release(family);
@ -1555,28 +1535,25 @@ static void test_GetInformationalStrings(void)
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);
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);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(exists == FALSE, "got %d\n", exists);
exists = FALSE;
strings = NULL;
hr = IDWriteFont_GetInformationalStrings(font, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES, &strings, &exists);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(exists == TRUE, "got %d\n", exists);
/* strings instance is not reused */
strings2 = NULL;
hr = IDWriteFont_GetInformationalStrings(font, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES, &strings2, &exists);
ok(hr == S_OK, "got 0x%08x\n", hr);
todo_wine
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);