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

dwrite: Reuse streams when initializing font data and creating faces.

parent ab318438
......@@ -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;
......
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