mirror of
git://source.winehq.org/git/wine.git
synced 2024-07-21 17:14:10 +00:00
dwrite: Reuse streams when initializing font data and creating faces.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
ab31843808
commit
aa9fc63514
|
@ -151,6 +151,7 @@ struct fontface_desc
|
|||
IDWriteFactory5 *factory;
|
||||
DWRITE_FONT_FACE_TYPE face_type;
|
||||
IDWriteFontFile * const *files;
|
||||
IDWriteFontFileStream *stream;
|
||||
UINT32 files_number;
|
||||
UINT32 index;
|
||||
DWRITE_FONT_SIMULATIONS simulations;
|
||||
|
@ -228,7 +229,7 @@ struct file_stream_desc {
|
|||
UINT32 face_index;
|
||||
};
|
||||
|
||||
extern HRESULT opentype_analyze_font(IDWriteFontFileStream*,UINT32*,DWRITE_FONT_FILE_TYPE*,DWRITE_FONT_FACE_TYPE*,BOOL*) DECLSPEC_HIDDEN;
|
||||
extern HRESULT opentype_analyze_font(IDWriteFontFileStream*,BOOL*,DWRITE_FONT_FILE_TYPE*,DWRITE_FONT_FACE_TYPE*,UINT32*) DECLSPEC_HIDDEN;
|
||||
extern HRESULT opentype_get_font_table(struct file_stream_desc*,UINT32,const void**,void**,UINT32*,BOOL*) DECLSPEC_HIDDEN;
|
||||
extern HRESULT opentype_cmap_get_unicode_ranges(void*,UINT32,DWRITE_UNICODE_RANGE*,UINT32*) DECLSPEC_HIDDEN;
|
||||
extern void opentype_get_font_properties(struct file_stream_desc*,struct dwrite_font_props*) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -217,7 +217,7 @@ struct dwrite_fontface {
|
|||
IDWriteFontFace4 IDWriteFontFace4_iface;
|
||||
LONG ref;
|
||||
|
||||
IDWriteFontFileStream **streams;
|
||||
IDWriteFontFileStream *stream;
|
||||
IDWriteFontFile **files;
|
||||
UINT32 file_count;
|
||||
UINT32 index;
|
||||
|
@ -515,12 +515,11 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace4 *iface)
|
|||
if (This->colr.context)
|
||||
IDWriteFontFace4_ReleaseFontTable(iface, This->colr.context);
|
||||
for (i = 0; i < This->file_count; i++) {
|
||||
if (This->streams[i])
|
||||
IDWriteFontFileStream_Release(This->streams[i]);
|
||||
if (This->files[i])
|
||||
IDWriteFontFile_Release(This->files[i]);
|
||||
}
|
||||
heap_free(This->streams);
|
||||
if (This->stream)
|
||||
IDWriteFontFileStream_Release(This->stream);
|
||||
heap_free(This->files);
|
||||
|
||||
for (i = 0; i < sizeof(This->glyphs)/sizeof(This->glyphs[0]); i++)
|
||||
|
@ -665,7 +664,7 @@ static HRESULT WINAPI dwritefontface_TryGetFontTable(IDWriteFontFace4 *iface, UI
|
|||
|
||||
TRACE("(%p)->(%s %p %p %p %p)\n", This, debugstr_tag(table_tag), table_data, table_size, context, exists);
|
||||
|
||||
stream_desc.stream = This->streams[0];
|
||||
stream_desc.stream = This->stream;
|
||||
stream_desc.face_type = This->type;
|
||||
stream_desc.face_index = This->index;
|
||||
return opentype_get_font_table(&stream_desc, table_tag, table_data, context, table_size, exists);
|
||||
|
@ -677,7 +676,7 @@ static void WINAPI dwritefontface_ReleaseFontTable(IDWriteFontFace4 *iface, void
|
|||
|
||||
TRACE("(%p)->(%p)\n", This, table_context);
|
||||
|
||||
IDWriteFontFileStream_ReleaseFileFragment(This->streams[0], table_context);
|
||||
IDWriteFontFileStream_ReleaseFileFragment(This->stream, table_context);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI dwritefontface_GetGlyphRunOutline(IDWriteFontFace4 *iface, FLOAT emSize,
|
||||
|
@ -1395,6 +1394,9 @@ static HRESULT get_fontface_from_font(struct dwrite_font *font, IDWriteFontFace4
|
|||
if (hr == S_OK)
|
||||
return hr;
|
||||
|
||||
if (FAILED(hr = get_filestream_from_file(data->file, &desc.stream)))
|
||||
return hr;
|
||||
|
||||
desc.factory = font->family->collection->factory;
|
||||
desc.face_type = data->face_type;
|
||||
desc.files = &data->file;
|
||||
|
@ -1402,7 +1404,10 @@ static HRESULT get_fontface_from_font(struct dwrite_font *font, IDWriteFontFace4
|
|||
desc.index = data->face_index;
|
||||
desc.simulations = data->simulations;
|
||||
desc.font_data = data;
|
||||
return create_fontface(&desc, cached_list, fontface);
|
||||
hr = create_fontface(&desc, cached_list, fontface);
|
||||
|
||||
IDWriteFontFileStream_Release(desc.stream);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI dwritefont_QueryInterface(IDWriteFont3 *iface, REFIID riid, void **obj)
|
||||
|
@ -3322,26 +3327,21 @@ static BOOL font_apply_differentiation_rules(struct dwrite_font_data *font, WCHA
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static HRESULT init_font_data(const struct fontface_desc *desc, IDWriteLocalizedStrings **family_name, struct dwrite_font_data **ret)
|
||||
static HRESULT init_font_data(const struct fontface_desc *desc, IDWriteLocalizedStrings **family_name,
|
||||
struct dwrite_font_data **ret)
|
||||
{
|
||||
struct file_stream_desc stream_desc;
|
||||
struct dwrite_font_props props;
|
||||
struct dwrite_font_data *data;
|
||||
IDWriteFontFileStream *stream;
|
||||
WCHAR familyW[255], faceW[255];
|
||||
HRESULT hr;
|
||||
|
||||
*ret = NULL;
|
||||
|
||||
data = heap_alloc_zero(sizeof(*data));
|
||||
if (!data)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
hr = get_filestream_from_file(desc->files[0], &stream);
|
||||
if (FAILED(hr)) {
|
||||
heap_free(data);
|
||||
return hr;
|
||||
}
|
||||
|
||||
data->ref = 1;
|
||||
data->file = desc->files[0];
|
||||
data->face_index = desc->index;
|
||||
|
@ -3351,7 +3351,7 @@ static HRESULT init_font_data(const struct fontface_desc *desc, IDWriteLocalized
|
|||
data->oblique_sim_tested = 0;
|
||||
IDWriteFontFile_AddRef(data->file);
|
||||
|
||||
stream_desc.stream = stream;
|
||||
stream_desc.stream = desc->stream;
|
||||
stream_desc.face_type = desc->face_type;
|
||||
stream_desc.face_index = desc->index;
|
||||
opentype_get_font_properties(&stream_desc, &props);
|
||||
|
@ -3360,7 +3360,6 @@ static HRESULT init_font_data(const struct fontface_desc *desc, IDWriteLocalized
|
|||
|
||||
/* get family name from font file */
|
||||
hr = opentype_get_font_familyname(&stream_desc, family_name);
|
||||
IDWriteFontFileStream_Release(stream);
|
||||
if (FAILED(hr)) {
|
||||
WARN("unable to get family name from font\n");
|
||||
release_font_data(data);
|
||||
|
@ -3700,6 +3699,7 @@ HRESULT create_font_collection(IDWriteFactory5 *factory, IDWriteFontFileEnumerat
|
|||
DWRITE_FONT_FACE_TYPE face_type;
|
||||
DWRITE_FONT_FILE_TYPE file_type;
|
||||
BOOL supported, same = FALSE;
|
||||
IDWriteFontFileStream *stream;
|
||||
IDWriteFontFile *file;
|
||||
UINT32 face_count;
|
||||
|
||||
|
@ -3723,10 +3723,16 @@ HRESULT create_font_collection(IDWriteFactory5 *factory, IDWriteFontFileEnumerat
|
|||
continue;
|
||||
}
|
||||
|
||||
/* failed font files are skipped */
|
||||
hr = IDWriteFontFile_Analyze(file, &supported, &file_type, &face_type, &face_count);
|
||||
if (FAILED(get_filestream_from_file(file, &stream))) {
|
||||
IDWriteFontFile_Release(file);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Unsupported formats are skipped. */
|
||||
hr = opentype_analyze_font(stream, &supported, &file_type, &face_type, &face_count);
|
||||
if (FAILED(hr) || !supported || face_count == 0) {
|
||||
TRACE("unsupported font (%p, 0x%08x, %d, %u)\n", file, hr, supported, face_count);
|
||||
TRACE("Unsupported font (%p, 0x%08x, %d, %u)\n", file, hr, supported, face_count);
|
||||
IDWriteFontFileStream_Release(stream);
|
||||
IDWriteFontFile_Release(file);
|
||||
hr = S_OK;
|
||||
continue;
|
||||
|
@ -3747,6 +3753,7 @@ HRESULT create_font_collection(IDWriteFactory5 *factory, IDWriteFontFileEnumerat
|
|||
desc.factory = factory;
|
||||
desc.face_type = face_type;
|
||||
desc.files = &file;
|
||||
desc.stream = stream;
|
||||
desc.files_number = 1;
|
||||
desc.index = i;
|
||||
desc.simulations = DWRITE_FONT_SIMULATIONS_NONE;
|
||||
|
@ -4031,24 +4038,31 @@ static HRESULT eudc_collection_add_family(IDWriteFactory5 *factory, struct dwrit
|
|||
{
|
||||
static const WCHAR defaultfontW[] = {'S','y','s','t','e','m','D','e','f','a','u','l','t','E','U','D','C','F','o','n','t',0};
|
||||
static const WCHAR emptyW[] = {0};
|
||||
struct dwrite_fontfamily_data *family_data;
|
||||
IDWriteLocalizedStrings *names;
|
||||
DWRITE_FONT_FACE_TYPE face_type;
|
||||
DWRITE_FONT_FILE_TYPE file_type;
|
||||
BOOL supported;
|
||||
UINT32 face_count, i;
|
||||
IDWriteFontFileStream *stream;
|
||||
IDWriteFontFile *file;
|
||||
UINT32 face_count, i;
|
||||
BOOL supported;
|
||||
HRESULT hr;
|
||||
struct dwrite_fontfamily_data *family_data;
|
||||
|
||||
/* create font file from this path */
|
||||
hr = create_local_file_reference(factory, pathW, &file);
|
||||
if (FAILED(hr))
|
||||
return S_FALSE;
|
||||
|
||||
/* failed font files are skipped */
|
||||
hr = IDWriteFontFile_Analyze(file, &supported, &file_type, &face_type, &face_count);
|
||||
if (FAILED(get_filestream_from_file(file, &stream))) {
|
||||
IDWriteFontFile_Release(file);
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
/* Unsupported formats are skipped. */
|
||||
hr = opentype_analyze_font(stream, &supported, &file_type, &face_type, &face_count);
|
||||
if (FAILED(hr) || !supported || face_count == 0) {
|
||||
TRACE("unsupported font (%p, 0x%08x, %d, %u)\n", file, hr, supported, face_count);
|
||||
TRACE("Unsupported font (%p, 0x%08x, %d, %u)\n", file, hr, supported, face_count);
|
||||
IDWriteFontFileStream_Release(stream);
|
||||
IDWriteFontFile_Release(file);
|
||||
return S_FALSE;
|
||||
}
|
||||
|
@ -4080,6 +4094,7 @@ static HRESULT eudc_collection_add_family(IDWriteFactory5 *factory, struct dwrit
|
|||
desc.face_type = face_type;
|
||||
desc.index = i;
|
||||
desc.files = &file;
|
||||
desc.stream = stream;
|
||||
desc.files_number = 1;
|
||||
desc.simulations = DWRITE_FONT_SIMULATIONS_NONE;
|
||||
desc.font_data = NULL;
|
||||
|
@ -4100,6 +4115,7 @@ static HRESULT eudc_collection_add_family(IDWriteFactory5 *factory, struct dwrit
|
|||
hr = fontcollection_add_family(collection, family_data);
|
||||
if (FAILED(hr))
|
||||
release_fontfamily_data(family_data);
|
||||
IDWriteFontFileStream_Release(stream);
|
||||
IDWriteFontFile_Release(file);
|
||||
|
||||
return hr;
|
||||
|
@ -4243,26 +4259,26 @@ static HRESULT WINAPI dwritefontfile_GetLoader(IDWriteFontFile *iface, IDWriteFo
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI dwritefontfile_Analyze(IDWriteFontFile *iface, BOOL *isSupportedFontType, DWRITE_FONT_FILE_TYPE *fontFileType,
|
||||
DWRITE_FONT_FACE_TYPE *fontFaceType, UINT32 *numberOfFaces)
|
||||
static HRESULT WINAPI dwritefontfile_Analyze(IDWriteFontFile *iface, BOOL *is_supported, DWRITE_FONT_FILE_TYPE *file_type,
|
||||
DWRITE_FONT_FACE_TYPE *face_type, UINT32 *face_count)
|
||||
{
|
||||
struct dwrite_fontfile *This = impl_from_IDWriteFontFile(iface);
|
||||
IDWriteFontFileStream *stream;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p)->(%p, %p, %p, %p)\n", This, isSupportedFontType, fontFileType, fontFaceType, numberOfFaces);
|
||||
TRACE("(%p)->(%p, %p, %p, %p)\n", This, is_supported, file_type, face_type, face_count);
|
||||
|
||||
*isSupportedFontType = FALSE;
|
||||
*fontFileType = DWRITE_FONT_FILE_TYPE_UNKNOWN;
|
||||
if (fontFaceType)
|
||||
*fontFaceType = DWRITE_FONT_FACE_TYPE_UNKNOWN;
|
||||
*numberOfFaces = 0;
|
||||
*is_supported = FALSE;
|
||||
*file_type = DWRITE_FONT_FILE_TYPE_UNKNOWN;
|
||||
if (face_type)
|
||||
*face_type = DWRITE_FONT_FACE_TYPE_UNKNOWN;
|
||||
*face_count = 0;
|
||||
|
||||
hr = IDWriteFontFileLoader_CreateStreamFromKey(This->loader, This->reference_key, This->key_size, &stream);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
hr = opentype_analyze_font(stream, numberOfFaces, fontFileType, fontFaceType, isSupportedFontType);
|
||||
hr = opentype_analyze_font(stream, is_supported, file_type, face_type, face_count);
|
||||
|
||||
/* TODO: Further Analysis */
|
||||
IDWriteFontFileStream_Release(stream);
|
||||
|
@ -4308,30 +4324,6 @@ HRESULT create_font_file(IDWriteFontFileLoader *loader, const void *reference_ke
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT get_stream_from_file(IDWriteFontFile *file, IDWriteFontFileStream **stream)
|
||||
{
|
||||
IDWriteFontFileLoader *loader;
|
||||
UINT32 key_size;
|
||||
const void *key;
|
||||
HRESULT hr;
|
||||
|
||||
*stream = NULL;
|
||||
hr = IDWriteFontFile_GetLoader(file, &loader);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
hr = IDWriteFontFile_GetReferenceKey(file, &key, &key_size);
|
||||
if (FAILED(hr)) {
|
||||
IDWriteFontFileLoader_Release(loader);
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = IDWriteFontFileLoader_CreateStreamFromKey(loader, key, key_size, stream);
|
||||
IDWriteFontFileLoader_Release(loader);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_list, IDWriteFontFace4 **ret)
|
||||
{
|
||||
struct file_stream_desc stream_desc;
|
||||
|
@ -4347,11 +4339,7 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li
|
|||
return E_OUTOFMEMORY;
|
||||
|
||||
fontface->files = heap_alloc_zero(sizeof(*fontface->files) * desc->files_number);
|
||||
fontface->streams = heap_alloc_zero(sizeof(*fontface->streams) * desc->files_number);
|
||||
|
||||
if (!fontface->files || !fontface->streams) {
|
||||
heap_free(fontface->files);
|
||||
heap_free(fontface->streams);
|
||||
if (!fontface->files) {
|
||||
heap_free(fontface);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
@ -4370,17 +4358,13 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li
|
|||
IDWriteFactory5_AddRef(fontface->factory = desc->factory);
|
||||
|
||||
for (i = 0; i < fontface->file_count; i++) {
|
||||
hr = get_stream_from_file(desc->files[i], &fontface->streams[i]);
|
||||
if (FAILED(hr)) {
|
||||
IDWriteFontFace4_Release(&fontface->IDWriteFontFace4_iface);
|
||||
return hr;
|
||||
}
|
||||
|
||||
fontface->files[i] = desc->files[i];
|
||||
IDWriteFontFile_AddRef(fontface->files[i]);
|
||||
}
|
||||
fontface->stream = desc->stream;
|
||||
IDWriteFontFileStream_AddRef(fontface->stream);
|
||||
|
||||
stream_desc.stream = fontface->streams[0];
|
||||
stream_desc.stream = fontface->stream;
|
||||
stream_desc.face_type = desc->face_type;
|
||||
stream_desc.face_index = desc->index;
|
||||
opentype_get_font_metrics(&stream_desc, &fontface->metrics, &fontface->caret);
|
||||
|
|
|
@ -943,10 +943,11 @@ static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory5 *iface, DWRIT
|
|||
struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
|
||||
DWRITE_FONT_FILE_TYPE file_type;
|
||||
DWRITE_FONT_FACE_TYPE face_type;
|
||||
IDWriteFontFileStream *stream;
|
||||
struct fontface_desc desc;
|
||||
struct list *fontfaces;
|
||||
BOOL is_supported;
|
||||
UINT32 count;
|
||||
UINT32 face_count;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p)->(%d %u %p %u 0x%x %p)\n", This, req_facetype, files_number, font_files, index,
|
||||
|
@ -963,32 +964,44 @@ static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory5 *iface, DWRIT
|
|||
if (!is_simulation_valid(simulations))
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (FAILED(hr = get_filestream_from_file(*font_files, &stream)))
|
||||
return hr;
|
||||
|
||||
/* check actual file/face type */
|
||||
is_supported = FALSE;
|
||||
face_type = DWRITE_FONT_FACE_TYPE_UNKNOWN;
|
||||
hr = IDWriteFontFile_Analyze(*font_files, &is_supported, &file_type, &face_type, &count);
|
||||
hr = opentype_analyze_font(stream, &is_supported, &file_type, &face_type, &face_count);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
goto failed;
|
||||
|
||||
if (!is_supported)
|
||||
return E_FAIL;
|
||||
if (!is_supported) {
|
||||
hr = E_FAIL;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (face_type != req_facetype)
|
||||
return DWRITE_E_FILEFORMAT;
|
||||
if (face_type != req_facetype) {
|
||||
hr = DWRITE_E_FILEFORMAT;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
hr = factory_get_cached_fontface(iface, font_files, index, simulations, &fontfaces,
|
||||
&IID_IDWriteFontFace, (void **)fontface);
|
||||
if (hr != S_FALSE)
|
||||
return hr;
|
||||
goto failed;
|
||||
|
||||
desc.factory = iface;
|
||||
desc.face_type = req_facetype;
|
||||
desc.files = font_files;
|
||||
desc.stream = stream;
|
||||
desc.files_number = files_number;
|
||||
desc.index = index;
|
||||
desc.simulations = simulations;
|
||||
desc.font_data = NULL;
|
||||
return create_fontface(&desc, fontfaces, (IDWriteFontFace4 **)fontface);
|
||||
hr = create_fontface(&desc, fontfaces, (IDWriteFontFace4 **)fontface);
|
||||
|
||||
failed:
|
||||
IDWriteFontFileStream_Release(stream);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI dwritefactory_CreateRenderingParams(IDWriteFactory5 *iface, IDWriteRenderingParams **params)
|
||||
|
|
|
@ -1029,7 +1029,8 @@ static HRESULT opentype_type1_analyzer(IDWriteFontFileStream *stream, UINT32 *fo
|
|||
return *file_type != DWRITE_FONT_FILE_TYPE_UNKNOWN ? S_OK : S_FALSE;
|
||||
}
|
||||
|
||||
HRESULT opentype_analyze_font(IDWriteFontFileStream *stream, UINT32* font_count, DWRITE_FONT_FILE_TYPE *file_type, DWRITE_FONT_FACE_TYPE *face_type, BOOL *supported)
|
||||
HRESULT opentype_analyze_font(IDWriteFontFileStream *stream, BOOL *supported, DWRITE_FONT_FILE_TYPE *file_type,
|
||||
DWRITE_FONT_FACE_TYPE *face_type, UINT32 *face_count)
|
||||
{
|
||||
static dwrite_fontfile_analyzer fontfile_analyzers[] = {
|
||||
opentype_ttf_analyzer,
|
||||
|
@ -1047,10 +1048,10 @@ HRESULT opentype_analyze_font(IDWriteFontFileStream *stream, UINT32* font_count,
|
|||
|
||||
*file_type = DWRITE_FONT_FILE_TYPE_UNKNOWN;
|
||||
*face_type = DWRITE_FONT_FACE_TYPE_UNKNOWN;
|
||||
*font_count = 0;
|
||||
*face_count = 0;
|
||||
|
||||
while (*analyzer) {
|
||||
hr = (*analyzer)(stream, font_count, file_type, face_type);
|
||||
hr = (*analyzer)(stream, face_count, file_type, face_type);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
|
|
Loading…
Reference in a new issue