mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-18 16:56:16 +00:00
dwrite: Cache fontface instances at factory level.
This commit is contained in:
parent
fefb947516
commit
42882f7f75
|
@ -105,7 +105,7 @@ extern HRESULT get_system_fontcollection(IDWriteFontCollection**) DECLSPEC_HIDDE
|
||||||
extern HRESULT get_textanalyzer(IDWriteTextAnalyzer**) 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_font_file(IDWriteFontFileLoader *loader, const void *reference_key, UINT32 key_size, IDWriteFontFile **font_file) DECLSPEC_HIDDEN;
|
||||||
extern HRESULT create_localfontfileloader(IDWriteLocalFontFileLoader** iface) DECLSPEC_HIDDEN;
|
extern HRESULT create_localfontfileloader(IDWriteLocalFontFileLoader** iface) DECLSPEC_HIDDEN;
|
||||||
extern HRESULT font_create_fontface(DWRITE_FONT_FACE_TYPE,UINT32,IDWriteFontFile* const*,UINT32,DWRITE_FONT_SIMULATIONS,IDWriteFontFace2 **) DECLSPEC_HIDDEN;
|
extern HRESULT create_fontface(DWRITE_FONT_FACE_TYPE,UINT32,IDWriteFontFile* const*,UINT32,DWRITE_FONT_SIMULATIONS,IDWriteFontFace2**) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
/* Opentype font table functions */
|
/* Opentype font table functions */
|
||||||
extern HRESULT opentype_analyze_font(IDWriteFontFileStream*,UINT32*,DWRITE_FONT_FILE_TYPE*,DWRITE_FONT_FACE_TYPE*,BOOL*) DECLSPEC_HIDDEN;
|
extern HRESULT opentype_analyze_font(IDWriteFontFileStream*,UINT32*,DWRITE_FONT_FILE_TYPE*,DWRITE_FONT_FACE_TYPE*,BOOL*) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -116,7 +116,13 @@ struct dwrite_fontface {
|
||||||
IDWriteFontFace2 IDWriteFontFace2_iface;
|
IDWriteFontFace2 IDWriteFontFace2_iface;
|
||||||
LONG ref;
|
LONG ref;
|
||||||
|
|
||||||
struct dwrite_fontface_data *data;
|
IDWriteFontFile **files;
|
||||||
|
UINT32 file_count;
|
||||||
|
UINT32 index;
|
||||||
|
|
||||||
|
DWRITE_FONT_SIMULATIONS simulations;
|
||||||
|
DWRITE_FONT_FACE_TYPE type;
|
||||||
|
|
||||||
struct dwrite_fonttable cmap;
|
struct dwrite_fonttable cmap;
|
||||||
|
|
||||||
BOOL is_system;
|
BOOL is_system;
|
||||||
|
@ -282,11 +288,13 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace2 *iface)
|
||||||
|
|
||||||
TRACE("(%p)->(%d)\n", This, ref);
|
TRACE("(%p)->(%d)\n", This, ref);
|
||||||
|
|
||||||
if (!ref)
|
if (!ref) {
|
||||||
{
|
UINT32 i;
|
||||||
|
|
||||||
if (This->cmap.context)
|
if (This->cmap.context)
|
||||||
IDWriteFontFace2_ReleaseFontTable(iface, This->cmap.context);
|
IDWriteFontFace2_ReleaseFontTable(iface, This->cmap.context);
|
||||||
_free_fontface_data(This->data);
|
for (i = 0; i < This->file_count; i++)
|
||||||
|
IDWriteFontFile_Release(This->files[i]);
|
||||||
heap_free(This);
|
heap_free(This);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,7 +305,7 @@ static DWRITE_FONT_FACE_TYPE WINAPI dwritefontface_GetType(IDWriteFontFace2 *ifa
|
||||||
{
|
{
|
||||||
struct dwrite_fontface *This = impl_from_IDWriteFontFace2(iface);
|
struct dwrite_fontface *This = impl_from_IDWriteFontFace2(iface);
|
||||||
TRACE("(%p)\n", This);
|
TRACE("(%p)\n", This);
|
||||||
return This->data->type;
|
return This->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI dwritefontface_GetFiles(IDWriteFontFace2 *iface, UINT32 *number_of_files,
|
static HRESULT WINAPI dwritefontface_GetFiles(IDWriteFontFace2 *iface, UINT32 *number_of_files,
|
||||||
|
@ -309,16 +317,16 @@ static HRESULT WINAPI dwritefontface_GetFiles(IDWriteFontFace2 *iface, UINT32 *n
|
||||||
TRACE("(%p)->(%p %p)\n", This, number_of_files, fontfiles);
|
TRACE("(%p)->(%p %p)\n", This, number_of_files, fontfiles);
|
||||||
if (fontfiles == NULL)
|
if (fontfiles == NULL)
|
||||||
{
|
{
|
||||||
*number_of_files = This->data->file_count;
|
*number_of_files = This->file_count;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
if (*number_of_files < This->data->file_count)
|
if (*number_of_files < This->file_count)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
|
||||||
for (i = 0; i < This->data->file_count; i++)
|
for (i = 0; i < This->file_count; i++)
|
||||||
{
|
{
|
||||||
IDWriteFontFile_AddRef(This->data->files[i]);
|
IDWriteFontFile_AddRef(This->files[i]);
|
||||||
fontfiles[i] = This->data->files[i];
|
fontfiles[i] = This->files[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -328,14 +336,14 @@ static UINT32 WINAPI dwritefontface_GetIndex(IDWriteFontFace2 *iface)
|
||||||
{
|
{
|
||||||
struct dwrite_fontface *This = impl_from_IDWriteFontFace2(iface);
|
struct dwrite_fontface *This = impl_from_IDWriteFontFace2(iface);
|
||||||
TRACE("(%p)\n", This);
|
TRACE("(%p)\n", This);
|
||||||
return This->data->index;
|
return This->index;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DWRITE_FONT_SIMULATIONS WINAPI dwritefontface_GetSimulations(IDWriteFontFace2 *iface)
|
static DWRITE_FONT_SIMULATIONS WINAPI dwritefontface_GetSimulations(IDWriteFontFace2 *iface)
|
||||||
{
|
{
|
||||||
struct dwrite_fontface *This = impl_from_IDWriteFontFace2(iface);
|
struct dwrite_fontface *This = impl_from_IDWriteFontFace2(iface);
|
||||||
TRACE("(%p)\n", This);
|
TRACE("(%p)\n", This);
|
||||||
return This->data->simulations;
|
return This->simulations;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL WINAPI dwritefontface_IsSymbolFont(IDWriteFontFace2 *iface)
|
static BOOL WINAPI dwritefontface_IsSymbolFont(IDWriteFontFace2 *iface)
|
||||||
|
@ -438,15 +446,15 @@ static HRESULT WINAPI dwritefontface_TryGetFontTable(IDWriteFontFace2 *iface, UI
|
||||||
tablecontext->magic = DWRITE_FONTTABLE_MAGIC;
|
tablecontext->magic = DWRITE_FONTTABLE_MAGIC;
|
||||||
|
|
||||||
*exists = FALSE;
|
*exists = FALSE;
|
||||||
for (i = 0; i < This->data->file_count && !(*exists); i++)
|
for (i = 0; i < This->file_count && !(*exists); i++)
|
||||||
{
|
{
|
||||||
IDWriteFontFileStream *stream;
|
IDWriteFontFileStream *stream;
|
||||||
hr = _dwritefontfile_GetFontFileStream(This->data->files[i], &stream);
|
hr = _dwritefontfile_GetFontFileStream(This->files[i], &stream);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
continue;
|
continue;
|
||||||
tablecontext->file_index = i;
|
tablecontext->file_index = i;
|
||||||
|
|
||||||
hr = opentype_get_font_table(stream, This->data->type, This->data->index, table_tag, table_data, &tablecontext->context, table_size, exists);
|
hr = opentype_get_font_table(stream, This->type, This->index, table_tag, table_data, &tablecontext->context, table_size, exists);
|
||||||
|
|
||||||
IDWriteFontFileStream_Release(stream);
|
IDWriteFontFileStream_Release(stream);
|
||||||
}
|
}
|
||||||
|
@ -472,7 +480,7 @@ static void WINAPI dwritefontface_ReleaseFontTable(IDWriteFontFace2 *iface, void
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = _dwritefontfile_GetFontFileStream(This->data->files[tablecontext->file_index], &stream);
|
hr = _dwritefontfile_GetFontFileStream(This->files[tablecontext->file_index], &stream);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
return;
|
return;
|
||||||
IDWriteFontFileStream_ReleaseFileFragment(stream, tablecontext->context);
|
IDWriteFontFileStream_ReleaseFileFragment(stream, tablecontext->context);
|
||||||
|
@ -702,20 +710,14 @@ static HRESULT create_system_fontface(struct dwrite_font *font, IDWriteFontFace2
|
||||||
|
|
||||||
This = heap_alloc(sizeof(struct dwrite_fontface));
|
This = heap_alloc(sizeof(struct dwrite_fontface));
|
||||||
if (!This) return E_OUTOFMEMORY;
|
if (!This) return E_OUTOFMEMORY;
|
||||||
This->data = heap_alloc(sizeof(struct dwrite_fontface_data));
|
|
||||||
if (!This->data)
|
|
||||||
{
|
|
||||||
heap_free(This);
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
This->IDWriteFontFace2_iface.lpVtbl = &dwritefontfacevtbl;
|
This->IDWriteFontFace2_iface.lpVtbl = &dwritefontfacevtbl;
|
||||||
This->ref = 1;
|
This->ref = 1;
|
||||||
This->data->type = DWRITE_FONT_FACE_TYPE_UNKNOWN;
|
This->type = DWRITE_FONT_FACE_TYPE_UNKNOWN;
|
||||||
This->data->file_count = 0;
|
This->file_count = 0;
|
||||||
This->data->files = NULL;
|
This->files = NULL;
|
||||||
This->data->index = 0;
|
This->index = 0;
|
||||||
This->data->simulations = DWRITE_FONT_SIMULATIONS_NONE;
|
This->simulations = DWRITE_FONT_SIMULATIONS_NONE;
|
||||||
This->cmap.data = NULL;
|
This->cmap.data = NULL;
|
||||||
This->cmap.context = NULL;
|
This->cmap.context = NULL;
|
||||||
This->cmap.size = 0;
|
This->cmap.size = 0;
|
||||||
|
@ -747,7 +749,7 @@ static HRESULT get_fontface_from_font(struct dwrite_font *font, IDWriteFontFace2
|
||||||
|
|
||||||
if (!font->face) {
|
if (!font->face) {
|
||||||
HRESULT hr = font->is_system ? create_system_fontface(font, &font->face) :
|
HRESULT hr = font->is_system ? create_system_fontface(font, &font->face) :
|
||||||
font_create_fontface(font->data->face_data->type, font->data->face_data->file_count, font->data->face_data->files,
|
create_fontface(font->data->face_data->type, font->data->face_data->file_count, font->data->face_data->files,
|
||||||
font->data->face_data->index, font->data->face_data->simulations, &font->face);
|
font->data->face_data->index, font->data->face_data->simulations, &font->face);
|
||||||
if (FAILED(hr)) return hr;
|
if (FAILED(hr)) return hr;
|
||||||
}
|
}
|
||||||
|
@ -1676,62 +1678,56 @@ HRESULT create_font_file(IDWriteFontFileLoader *loader, const void *reference_ke
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT font_create_fontface(DWRITE_FONT_FACE_TYPE facetype, UINT32 files_number, IDWriteFontFile* const* font_files, UINT32 index, DWRITE_FONT_SIMULATIONS sim_flags, IDWriteFontFace2 **font_face)
|
HRESULT create_fontface(DWRITE_FONT_FACE_TYPE facetype, UINT32 files_number, IDWriteFontFile* const* font_files, UINT32 index,
|
||||||
|
DWRITE_FONT_SIMULATIONS simulations, IDWriteFontFace2 **ret)
|
||||||
{
|
{
|
||||||
int i;
|
struct dwrite_fontface *fontface;
|
||||||
struct dwrite_fontface *This;
|
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
|
int i;
|
||||||
|
|
||||||
*font_face = NULL;
|
fontface = heap_alloc(sizeof(struct dwrite_fontface));
|
||||||
|
if (!fontface)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
if (facetype != DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION && index)
|
fontface->files = heap_alloc(sizeof(*fontface->files) * files_number);
|
||||||
return E_INVALIDARG;
|
if (!fontface->files) {
|
||||||
|
heap_free(fontface);
|
||||||
This = heap_alloc(sizeof(struct dwrite_fontface));
|
|
||||||
if (!This) return E_OUTOFMEMORY;
|
|
||||||
This->data = heap_alloc(sizeof(struct dwrite_fontface_data));
|
|
||||||
if (!This->data)
|
|
||||||
{
|
|
||||||
heap_free(This);
|
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
This->IDWriteFontFace2_iface.lpVtbl = &dwritefontfacevtbl;
|
fontface->IDWriteFontFace2_iface.lpVtbl = &dwritefontfacevtbl;
|
||||||
This->ref = 1;
|
fontface->ref = 1;
|
||||||
This->data->ref = 1;
|
fontface->type = facetype;
|
||||||
This->data->type = facetype;
|
fontface->file_count = files_number;
|
||||||
This->data->file_count = files_number;
|
fontface->cmap.data = NULL;
|
||||||
This->data->files = heap_alloc(sizeof(*This->data->files) * files_number);
|
fontface->cmap.context = NULL;
|
||||||
This->cmap.data = NULL;
|
fontface->cmap.size = 0;
|
||||||
This->cmap.context = NULL;
|
|
||||||
This->cmap.size = 0;
|
|
||||||
/* Verify font file streams */
|
/* Verify font file streams */
|
||||||
for (i = 0; i < This->data->file_count && SUCCEEDED(hr); i++)
|
for (i = 0; i < fontface->file_count && SUCCEEDED(hr); i++)
|
||||||
{
|
{
|
||||||
IDWriteFontFileStream *stream;
|
IDWriteFontFileStream *stream;
|
||||||
hr = _dwritefontfile_GetFontFileStream(font_files[i], &stream);
|
hr = _dwritefontfile_GetFontFileStream(font_files[i], &stream);
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
IDWriteFontFileStream_Release(stream);
|
IDWriteFontFileStream_Release(stream);
|
||||||
}
|
}
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
if (FAILED(hr)) {
|
||||||
heap_free(This->data->files);
|
heap_free(fontface->files);
|
||||||
heap_free(This->data);
|
heap_free(fontface);
|
||||||
heap_free(This);
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
for (i = 0; i < This->data->file_count; i++)
|
|
||||||
{
|
for (i = 0; i < fontface->file_count; i++) {
|
||||||
This->data->files[i] = font_files[i];
|
fontface->files[i] = font_files[i];
|
||||||
IDWriteFontFile_AddRef(font_files[i]);
|
IDWriteFontFile_AddRef(font_files[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
This->data->index = index;
|
fontface->index = index;
|
||||||
This->data->simulations = sim_flags;
|
fontface->simulations = simulations;
|
||||||
This->is_system = FALSE;
|
fontface->is_system = FALSE;
|
||||||
|
|
||||||
*font_face = &This->IDWriteFontFace2_iface;
|
|
||||||
|
|
||||||
|
*ret = &fontface->IDWriteFontFace2_iface;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -398,9 +398,16 @@ struct collectionloader
|
||||||
IDWriteFontCollectionLoader *loader;
|
IDWriteFontCollectionLoader *loader;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct fontfacecached
|
||||||
|
{
|
||||||
|
struct list entry;
|
||||||
|
IDWriteFontFace *fontface;
|
||||||
|
};
|
||||||
|
|
||||||
struct fileloader
|
struct fileloader
|
||||||
{
|
{
|
||||||
struct list entry;
|
struct list entry;
|
||||||
|
struct list fontfaces;
|
||||||
IDWriteFontFileLoader *loader;
|
IDWriteFontFileLoader *loader;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -408,10 +415,12 @@ struct dwritefactory {
|
||||||
IDWriteFactory IDWriteFactory_iface;
|
IDWriteFactory IDWriteFactory_iface;
|
||||||
LONG ref;
|
LONG ref;
|
||||||
|
|
||||||
IDWriteLocalFontFileLoader* localfontfileloader;
|
|
||||||
IDWriteFontCollection *system_collection;
|
IDWriteFontCollection *system_collection;
|
||||||
IDWriteGdiInterop *gdiinterop;
|
IDWriteGdiInterop *gdiinterop;
|
||||||
|
|
||||||
|
IDWriteLocalFontFileLoader* localfontfileloader;
|
||||||
|
struct list localfontfaces;
|
||||||
|
|
||||||
struct list collection_loaders;
|
struct list collection_loaders;
|
||||||
struct list file_loaders;
|
struct list file_loaders;
|
||||||
};
|
};
|
||||||
|
@ -421,6 +430,24 @@ static inline struct dwritefactory *impl_from_IDWriteFactory(IDWriteFactory *ifa
|
||||||
return CONTAINING_RECORD(iface, struct dwritefactory, IDWriteFactory_iface);
|
return CONTAINING_RECORD(iface, struct dwritefactory, IDWriteFactory_iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void release_fontface_cache(struct list *fontfaces)
|
||||||
|
{
|
||||||
|
struct fontfacecached *fontface, *fontface2;
|
||||||
|
LIST_FOR_EACH_ENTRY_SAFE(fontface, fontface2, fontfaces, struct fontfacecached, entry) {
|
||||||
|
list_remove(&fontface->entry);
|
||||||
|
IDWriteFontFace_Release(fontface->fontface);
|
||||||
|
heap_free(fontface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void release_fileloader(struct fileloader *fileloader)
|
||||||
|
{
|
||||||
|
list_remove(&fileloader->entry);
|
||||||
|
release_fontface_cache(&fileloader->fontfaces);
|
||||||
|
IDWriteFontFileLoader_Release(fileloader->loader);
|
||||||
|
heap_free(fileloader);
|
||||||
|
}
|
||||||
|
|
||||||
static void release_dwritefactory(struct dwritefactory *factory)
|
static void release_dwritefactory(struct dwritefactory *factory)
|
||||||
{
|
{
|
||||||
struct fileloader *fileloader, *fileloader2;
|
struct fileloader *fileloader, *fileloader2;
|
||||||
|
@ -428,6 +455,7 @@ static void release_dwritefactory(struct dwritefactory *factory)
|
||||||
|
|
||||||
if (factory->localfontfileloader)
|
if (factory->localfontfileloader)
|
||||||
IDWriteLocalFontFileLoader_Release(factory->localfontfileloader);
|
IDWriteLocalFontFileLoader_Release(factory->localfontfileloader);
|
||||||
|
release_fontface_cache(&factory->localfontfaces);
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY_SAFE(loader, loader2, &factory->collection_loaders, struct collectionloader, entry) {
|
LIST_FOR_EACH_ENTRY_SAFE(loader, loader2, &factory->collection_loaders, struct collectionloader, entry) {
|
||||||
list_remove(&loader->entry);
|
list_remove(&loader->entry);
|
||||||
|
@ -435,11 +463,8 @@ static void release_dwritefactory(struct dwritefactory *factory)
|
||||||
heap_free(loader);
|
heap_free(loader);
|
||||||
}
|
}
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY_SAFE(fileloader, fileloader2, &factory->file_loaders, struct fileloader, entry) {
|
LIST_FOR_EACH_ENTRY_SAFE(fileloader, fileloader2, &factory->file_loaders, struct fileloader, entry)
|
||||||
list_remove(&fileloader->entry);
|
release_fileloader(fileloader);
|
||||||
IDWriteFontFileLoader_Release(fileloader->loader);
|
|
||||||
heap_free(fileloader);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (factory->system_collection)
|
if (factory->system_collection)
|
||||||
IDWriteFontCollection_Release(factory->system_collection);
|
IDWriteFontCollection_Release(factory->system_collection);
|
||||||
|
@ -625,11 +650,93 @@ static HRESULT WINAPI dwritefactory_CreateCustomFontFileReference(IDWriteFactory
|
||||||
|
|
||||||
static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory *iface,
|
static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory *iface,
|
||||||
DWRITE_FONT_FACE_TYPE facetype, UINT32 files_number, IDWriteFontFile* const* font_files,
|
DWRITE_FONT_FACE_TYPE facetype, UINT32 files_number, IDWriteFontFile* const* font_files,
|
||||||
UINT32 index, DWRITE_FONT_SIMULATIONS sim_flags, IDWriteFontFace **font_face)
|
UINT32 index, DWRITE_FONT_SIMULATIONS simulations, IDWriteFontFace **font_face)
|
||||||
{
|
{
|
||||||
struct dwritefactory *This = impl_from_IDWriteFactory(iface);
|
struct dwritefactory *This = impl_from_IDWriteFactory(iface);
|
||||||
TRACE("(%p)->(%d %u %p %u 0x%x %p)\n", This, facetype, files_number, font_files, index, sim_flags, font_face);
|
IDWriteFontFileLoader *loader;
|
||||||
return font_create_fontface(facetype, files_number, font_files, index, sim_flags, (IDWriteFontFace2**)font_face);
|
struct fontfacecached *cached;
|
||||||
|
struct list *fontfaces;
|
||||||
|
IDWriteFontFace2 *face;
|
||||||
|
const void *key;
|
||||||
|
UINT32 key_size;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
TRACE("(%p)->(%d %u %p %u 0x%x %p)\n", This, facetype, files_number, font_files, index, simulations, font_face);
|
||||||
|
|
||||||
|
*font_face = NULL;
|
||||||
|
|
||||||
|
if (facetype != DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION && index)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
hr = IDWriteFontFile_GetReferenceKey(*font_files, &key, &key_size);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
hr = IDWriteFontFile_GetLoader(*font_files, &loader);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
if (loader == (IDWriteFontFileLoader*)This->localfontfileloader) {
|
||||||
|
fontfaces = &This->localfontfaces;
|
||||||
|
IDWriteFontFileLoader_Release(loader);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
struct fileloader *fileloader = factory_get_file_loader(This, loader);
|
||||||
|
IDWriteFontFileLoader_Release(loader);
|
||||||
|
if (!fileloader)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
fontfaces = &fileloader->fontfaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* search through cache list */
|
||||||
|
LIST_FOR_EACH_ENTRY(cached, fontfaces, struct fontfacecached, entry) {
|
||||||
|
UINT32 cached_key_size, count = 1, cached_face_index;
|
||||||
|
DWRITE_FONT_SIMULATIONS cached_simulations;
|
||||||
|
const void *cached_key;
|
||||||
|
IDWriteFontFile *file;
|
||||||
|
|
||||||
|
cached_face_index = IDWriteFontFace_GetIndex(cached->fontface);
|
||||||
|
cached_simulations = IDWriteFontFace_GetSimulations(cached->fontface);
|
||||||
|
|
||||||
|
/* skip earlier */
|
||||||
|
if (cached_face_index != index || cached_simulations != simulations)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
hr = IDWriteFontFace_GetFiles(cached->fontface, &count, &file);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
hr = IDWriteFontFile_GetReferenceKey(file, &cached_key, &cached_key_size);
|
||||||
|
IDWriteFontFile_Release(file);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
if (cached_key_size == key_size && !memcmp(cached_key, key, key_size)) {
|
||||||
|
TRACE("returning cached fontface %p\n", cached->fontface);
|
||||||
|
*font_face = cached->fontface;
|
||||||
|
IDWriteFontFace_AddRef(*font_face);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = create_fontface(facetype, files_number, font_files, index, simulations, &face);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
/* new cache entry */
|
||||||
|
cached = heap_alloc(sizeof(*cached));
|
||||||
|
if (!cached) {
|
||||||
|
IDWriteFontFace2_Release(face);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
cached->fontface = (IDWriteFontFace*)face;
|
||||||
|
list_add_tail(fontfaces, &cached->entry);
|
||||||
|
|
||||||
|
*font_face = cached->fontface;
|
||||||
|
IDWriteFontFace_AddRef(*font_face);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI dwritefactory_CreateRenderingParams(IDWriteFactory *iface, IDWriteRenderingParams **params)
|
static HRESULT WINAPI dwritefactory_CreateRenderingParams(IDWriteFactory *iface, IDWriteRenderingParams **params)
|
||||||
|
@ -687,6 +794,7 @@ static HRESULT WINAPI dwritefactory_RegisterFontFileLoader(IDWriteFactory *iface
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
entry->loader = loader;
|
entry->loader = loader;
|
||||||
|
list_init(&entry->fontfaces);
|
||||||
IDWriteFontFileLoader_AddRef(loader);
|
IDWriteFontFileLoader_AddRef(loader);
|
||||||
list_add_tail(&This->file_loaders, &entry->entry);
|
list_add_tail(&This->file_loaders, &entry->entry);
|
||||||
|
|
||||||
|
@ -707,10 +815,7 @@ static HRESULT WINAPI dwritefactory_UnregisterFontFileLoader(IDWriteFactory *ifa
|
||||||
if (!found)
|
if (!found)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
|
||||||
IDWriteFontFileLoader_Release(found->loader);
|
release_fileloader(found);
|
||||||
list_remove(&found->entry);
|
|
||||||
heap_free(found);
|
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -893,6 +998,7 @@ static void init_dwritefactory(struct dwritefactory *factory, const struct IDWri
|
||||||
|
|
||||||
list_init(&factory->collection_loaders);
|
list_init(&factory->collection_loaders);
|
||||||
list_init(&factory->file_loaders);
|
list_init(&factory->file_loaders);
|
||||||
|
list_init(&factory->localfontfaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT WINAPI DWriteCreateFactory(DWRITE_FACTORY_TYPE type, REFIID riid, IUnknown **ret)
|
HRESULT WINAPI DWriteCreateFactory(DWRITE_FACTORY_TYPE type, REFIID riid, IUnknown **ret)
|
||||||
|
|
|
@ -1113,19 +1113,20 @@ static void test_CreateCustomFontFileReference(void)
|
||||||
IDWriteFontFileLoader floader = { &dwritefontfileloadervtbl };
|
IDWriteFontFileLoader floader = { &dwritefontfileloadervtbl };
|
||||||
IDWriteFontFileLoader floader2 = { &dwritefontfileloadervtbl };
|
IDWriteFontFileLoader floader2 = { &dwritefontfileloadervtbl };
|
||||||
IDWriteFontFileLoader floader3 = { &dwritefontfileloadervtbl };
|
IDWriteFontFileLoader floader3 = { &dwritefontfileloadervtbl };
|
||||||
|
IDWriteFactory *factory, *factory2;
|
||||||
IDWriteFontFile *file, *file2;
|
IDWriteFontFile *file, *file2;
|
||||||
BOOL support;
|
BOOL support;
|
||||||
DWRITE_FONT_FILE_TYPE file_type;
|
DWRITE_FONT_FILE_TYPE file_type;
|
||||||
DWRITE_FONT_FACE_TYPE face_type;
|
DWRITE_FONT_FACE_TYPE face_type;
|
||||||
UINT32 count;
|
UINT32 count;
|
||||||
IDWriteFontFace *face, *face2;
|
IDWriteFontFace *face, *face2;
|
||||||
IDWriteFactory *factory;
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
HRSRC fontrsrc;
|
HRSRC fontrsrc;
|
||||||
UINT32 codePoints[1] = {0xa8};
|
UINT32 codePoints[1] = {0xa8};
|
||||||
UINT16 indices[1];
|
UINT16 indices[1];
|
||||||
|
|
||||||
factory = create_factory();
|
factory = create_factory();
|
||||||
|
factory2 = create_factory();
|
||||||
|
|
||||||
hr = IDWriteFactory_RegisterFontFileLoader(factory, NULL);
|
hr = IDWriteFactory_RegisterFontFileLoader(factory, NULL);
|
||||||
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
|
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
|
||||||
|
@ -1194,11 +1195,14 @@ static void test_CreateCustomFontFileReference(void)
|
||||||
|
|
||||||
hr = IDWriteFactory_CreateFontFace(factory, face_type, 1, &file, 0, DWRITE_FONT_SIMULATIONS_NONE, &face2);
|
hr = IDWriteFactory_CreateFontFace(factory, face_type, 1, &file, 0, DWRITE_FONT_SIMULATIONS_NONE, &face2);
|
||||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
todo_wine
|
|
||||||
/* fontface instances are reused starting with win7 */
|
/* fontface instances are reused starting with win7 */
|
||||||
ok(face == face2 || broken(face != face2), "got %p, %p\n", face, face2);
|
ok(face == face2 || broken(face != face2), "got %p, %p\n", face, face2);
|
||||||
IDWriteFontFace_Release(face2);
|
IDWriteFontFace_Release(face2);
|
||||||
|
|
||||||
|
/* file was created with different factory */
|
||||||
|
hr = IDWriteFactory_CreateFontFace(factory2, face_type, 1, &file, 0, DWRITE_FONT_SIMULATIONS_NONE, &face2);
|
||||||
|
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
file2 = NULL;
|
file2 = NULL;
|
||||||
hr = IDWriteFactory_CreateCustomFontFileReference(factory, &fontrsrc, sizeof(HRSRC), &rloader, &file2);
|
hr = IDWriteFactory_CreateCustomFontFileReference(factory, &fontrsrc, sizeof(HRSRC), &rloader, &file2);
|
||||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
@ -1206,7 +1210,6 @@ todo_wine
|
||||||
|
|
||||||
hr = IDWriteFactory_CreateFontFace(factory, face_type, 1, &file2, 0, DWRITE_FONT_SIMULATIONS_NONE, &face2);
|
hr = IDWriteFactory_CreateFontFace(factory, face_type, 1, &file2, 0, DWRITE_FONT_SIMULATIONS_NONE, &face2);
|
||||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
todo_wine
|
|
||||||
/* fontface instances are reused starting with win7 */
|
/* fontface instances are reused starting with win7 */
|
||||||
ok(face == face2 || broken(face != face2), "got %p, %p\n", face, face2);
|
ok(face == face2 || broken(face != face2), "got %p, %p\n", face, face2);
|
||||||
IDWriteFontFace_Release(face2);
|
IDWriteFontFace_Release(face2);
|
||||||
|
@ -1227,6 +1230,7 @@ todo_wine
|
||||||
hr = IDWriteFactory_UnregisterFontFileLoader(factory, &rloader);
|
hr = IDWriteFactory_UnregisterFontFileLoader(factory, &rloader);
|
||||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
IDWriteFactory_Release(factory2);
|
||||||
IDWriteFactory_Release(factory);
|
IDWriteFactory_Release(factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1268,8 +1272,8 @@ static void test_CreateFontFileReference(void)
|
||||||
ok(face == DWRITE_FONT_FACE_TYPE_TRUETYPE, "got %i\n", face);
|
ok(face == DWRITE_FONT_FACE_TYPE_TRUETYPE, "got %i\n", face);
|
||||||
ok(count == 1, "got %i\n", count);
|
ok(count == 1, "got %i\n", count);
|
||||||
|
|
||||||
hr = IDWriteFactory_CreateFontFace(factory, face, 1, &ffile, 0, 0, &fface);
|
hr = IDWriteFactory_CreateFontFace(factory, face, 1, &ffile, 0, DWRITE_FONT_SIMULATIONS_NONE, &fface);
|
||||||
ok(hr == S_OK, "got 0x%08x\n",hr);
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
IDWriteFontFace_Release(fface);
|
IDWriteFontFace_Release(fface);
|
||||||
IDWriteFontFile_Release(ffile);
|
IDWriteFontFile_Release(ffile);
|
||||||
|
|
Loading…
Reference in a new issue