diff --git a/dlls/dwrite/bidi.c b/dlls/dwrite/bidi.c index 32c407506ee..3a7367e253c 100644 --- a/dlls/dwrite/bidi.c +++ b/dlls/dwrite/bidi.c @@ -46,7 +46,6 @@ #include "windef.h" #include "winbase.h" #include "wine/debug.h" -#include "wine/list.h" #include "dwrite_private.h" diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 61409c81495..3309f3f00c3 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -20,6 +20,7 @@ #include "d2d1.h" #include "wine/debug.h" +#include "wine/list.h" #include "wine/unicode.h" static const DWRITE_MATRIX identity = @@ -151,6 +152,17 @@ struct glyphrunanalysis_desc FLOAT ppdip; }; +struct fontface_desc +{ + IDWriteFactory3 *factory; + DWRITE_FONT_FACE_TYPE face_type; + IDWriteFontFile * const *files; + UINT32 files_number; + UINT32 index; + DWRITE_FONT_SIMULATIONS simulations; + struct dwrite_font_data *font_data; /* could be NULL when face is created directly with IDWriteFactory::CreateFontFace() */ +}; + 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, @@ -168,7 +180,7 @@ extern HRESULT get_eudc_fontcollection(IDWriteFactory3*,IDWriteFontCollection**) 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; -extern HRESULT create_fontface(DWRITE_FONT_FACE_TYPE,UINT32,IDWriteFontFile* const*,UINT32,DWRITE_FONT_SIMULATIONS,IDWriteFontFace3**) DECLSPEC_HIDDEN; +extern HRESULT create_fontface(const struct fontface_desc*,IDWriteFontFace3**) DECLSPEC_HIDDEN; extern HRESULT create_font_collection(IDWriteFactory3*,IDWriteFontFileEnumerator*,BOOL,IDWriteFontCollection**) DECLSPEC_HIDDEN; extern HRESULT create_glyphrunanalysis(const struct glyphrunanalysis_desc*,IDWriteGlyphRunAnalysis**) DECLSPEC_HIDDEN; extern BOOL is_system_collection(IDWriteFontCollection*) DECLSPEC_HIDDEN; @@ -185,6 +197,9 @@ extern HRESULT create_matching_font(IDWriteFontCollection*,const WCHAR*,DWRITE_F IDWriteFont**) DECLSPEC_HIDDEN; extern HRESULT create_fontfacereference(IDWriteFactory3*,IDWriteFontFile*,UINT32,DWRITE_FONT_SIMULATIONS, IDWriteFontFaceReference**) DECLSPEC_HIDDEN; +extern HRESULT factory_get_cached_fontface(IDWriteFactory3*,IDWriteFontFile*const*,UINT32,DWRITE_FONT_SIMULATIONS,IDWriteFontFace**, + struct list**) DECLSPEC_HIDDEN; +extern void factory_cache_fontface(struct list*,IDWriteFontFace3*) DECLSPEC_HIDDEN; /* Opentype font table functions */ struct dwrite_font_props { diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index b625f7ace46..c99c5c3f901 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -23,7 +23,6 @@ #define COBJMACROS -#include "wine/list.h" #include "dwrite_private.h" WINE_DEFAULT_DEBUG_CHANNEL(dwrite); @@ -230,6 +229,11 @@ struct dwrite_fontface { struct dwrite_fonttable cpal; struct dwrite_fonttable colr; DWRITE_GLYPH_METRICS *glyphs[GLYPH_MAX/GLYPH_BLOCK_SIZE]; + + DWRITE_FONT_STYLE style; + DWRITE_FONT_STRETCH stretch; + DWRITE_FONT_WEIGHT weight; + DWRITE_PANOSE panose; }; struct dwrite_fontfile { @@ -1068,28 +1072,29 @@ static HRESULT WINAPI dwritefontface3_GetFontFaceReference(IDWriteFontFace3 *ifa static void WINAPI dwritefontface3_GetPanose(IDWriteFontFace3 *iface, DWRITE_PANOSE *panose) { struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); - FIXME("(%p)->(%p): stub\n", This, panose); + TRACE("(%p)->(%p)\n", This, panose); + *panose = This->panose; } static DWRITE_FONT_WEIGHT WINAPI dwritefontface3_GetWeight(IDWriteFontFace3 *iface) { struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); - FIXME("(%p): stub\n", This); - return DWRITE_FONT_WEIGHT_NORMAL; + TRACE("(%p)\n", This); + return This->weight; } static DWRITE_FONT_STRETCH WINAPI dwritefontface3_GetStretch(IDWriteFontFace3 *iface) { struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); - FIXME("(%p): stub\n", This); - return DWRITE_FONT_STRETCH_NORMAL; + TRACE("(%p)\n", This); + return This->stretch; } static DWRITE_FONT_STYLE WINAPI dwritefontface3_GetStyle(IDWriteFontFace3 *iface) { struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); - FIXME("(%p): stub\n", This); - return DWRITE_FONT_STYLE_NORMAL; + TRACE("(%p)\n", This); + return This->style; } static HRESULT WINAPI dwritefontface3_GetFamilyNames(IDWriteFontFace3 *iface, IDWriteLocalizedStrings **names) @@ -1275,20 +1280,31 @@ static const IDWriteFontFace3Vtbl dwritefontfacevtbl = { static HRESULT get_fontface_from_font(struct dwrite_font *font, IDWriteFontFace3 **fontface) { struct dwrite_font_data *data = font->data; - IDWriteFontFace *face; + struct fontface_desc desc; + struct list *cached_list; HRESULT hr; *fontface = NULL; - hr = IDWriteFactory3_CreateFontFace(data->factory, data->face_type, 1, &data->file, - data->face_index, font->data->simulations, &face); + hr = factory_get_cached_fontface(data->factory, &data->file, data->face_index, + font->data->simulations, (IDWriteFontFace**)fontface, &cached_list); + if (hr != S_FALSE) + return hr; + + desc.factory = data->factory; + desc.face_type = data->face_type; + desc.files = &data->file; + desc.files_number = 1; + desc.index = data->face_index; + desc.simulations = data->simulations; + desc.font_data = data; + hr = create_fontface(&desc, fontface); if (FAILED(hr)) return hr; - hr = IDWriteFontFace_QueryInterface(face, &IID_IDWriteFontFace3, (void**)fontface); - IDWriteFontFace_Release(face); + factory_cache_fontface(cached_list, *fontface); - return hr; + return S_OK; } static HRESULT WINAPI dwritefont_QueryInterface(IDWriteFont3 *iface, REFIID riid, void **obj) @@ -3136,8 +3152,7 @@ static BOOL font_apply_differentiation_rules(struct dwrite_font_data *font, WCHA return TRUE; } -static HRESULT init_font_data(IDWriteFactory3 *factory, IDWriteFontFile *file, DWRITE_FONT_FACE_TYPE face_type, UINT32 face_index, - 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; @@ -3151,26 +3166,26 @@ static HRESULT init_font_data(IDWriteFactory3 *factory, IDWriteFontFile *file, D if (!data) return E_OUTOFMEMORY; - hr = get_filestream_from_file(file, &stream); + hr = get_filestream_from_file(desc->files[0], &stream); if (FAILED(hr)) { heap_free(data); return hr; } data->ref = 1; - data->factory = factory; - data->file = file; - data->face_index = face_index; - data->face_type = face_type; + data->factory = desc->factory; + data->file = desc->files[0]; + data->face_index = desc->index; + data->face_type = desc->face_type; data->simulations = DWRITE_FONT_SIMULATIONS_NONE; data->bold_sim_tested = 0; data->oblique_sim_tested = 0; - IDWriteFontFile_AddRef(file); - IDWriteFactory3_AddRef(factory); + IDWriteFontFile_AddRef(data->file); + IDWriteFactory3_AddRef(data->factory); stream_desc.stream = stream; - stream_desc.face_type = face_type; - stream_desc.face_index = face_index; + stream_desc.face_type = desc->face_type; + stream_desc.face_index = desc->index; opentype_get_font_properties(&stream_desc, &props); opentype_get_font_metrics(&stream_desc, &data->metrics, NULL); opentype_get_font_facename(&stream_desc, &data->names); @@ -3550,11 +3565,20 @@ HRESULT create_font_collection(IDWriteFactory3 *factory, IDWriteFontFileEnumerat for (i = 0; i < face_count; i++) { IDWriteLocalizedStrings *family_name = NULL; struct dwrite_font_data *font_data; + struct fontface_desc desc; WCHAR familyW[255]; UINT32 index; + desc.factory = factory; + desc.face_type = face_type; + desc.files = &file; + desc.files_number = 1; + desc.index = i; + desc.simulations = DWRITE_FONT_SIMULATIONS_NONE; + desc.font_data = NULL; + /* alloc and init new font data structure */ - hr = init_font_data(factory, file, face_type, i, &family_name, &font_data); + hr = init_font_data(&desc, &family_name, &font_data); if (FAILED(hr)) { /* move to next one */ hr = S_OK; @@ -3855,9 +3879,18 @@ static HRESULT eudc_collection_add_family(IDWriteFactory3 *factory, struct dwrit /* fill with faces */ for (i = 0; i < face_count; i++) { struct dwrite_font_data *font_data; + struct fontface_desc desc; /* alloc and init new font data structure */ - hr = init_font_data(factory, file, face_type, i, &names, &font_data); + desc.factory = factory; + desc.face_type = face_type; + desc.index = i; + desc.files = &file; + desc.files_number = 1; + desc.simulations = DWRITE_FONT_SIMULATIONS_NONE; + desc.font_data = NULL; + + hr = init_font_data(&desc, &names, &font_data); if (FAILED(hr)) continue; @@ -4092,8 +4125,7 @@ static HRESULT get_stream_from_file(IDWriteFontFile *file, IDWriteFontFileStream return hr; } -HRESULT create_fontface(DWRITE_FONT_FACE_TYPE facetype, UINT32 files_number, IDWriteFontFile* const* font_files, UINT32 index, - DWRITE_FONT_SIMULATIONS simulations, IDWriteFontFace3 **ret) +HRESULT create_fontface(const struct fontface_desc *desc, IDWriteFontFace3 **ret) { struct file_stream_desc stream_desc; struct dwrite_fontface *fontface; @@ -4106,8 +4138,8 @@ HRESULT create_fontface(DWRITE_FONT_FACE_TYPE facetype, UINT32 files_number, IDW if (!fontface) return E_OUTOFMEMORY; - fontface->files = heap_alloc_zero(sizeof(*fontface->files) * files_number); - fontface->streams = heap_alloc_zero(sizeof(*fontface->streams) * files_number); + 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); @@ -4118,8 +4150,8 @@ HRESULT create_fontface(DWRITE_FONT_FACE_TYPE facetype, UINT32 files_number, IDW fontface->IDWriteFontFace3_iface.lpVtbl = &dwritefontfacevtbl; fontface->ref = 1; - fontface->type = facetype; - fontface->file_count = files_number; + fontface->type = desc->face_type; + fontface->file_count = desc->files_number; memset(&fontface->cmap, 0, sizeof(fontface->cmap)); memset(&fontface->vdmx, 0, sizeof(fontface->vdmx)); memset(&fontface->gasp, 0, sizeof(fontface->gasp)); @@ -4130,26 +4162,26 @@ HRESULT create_fontface(DWRITE_FONT_FACE_TYPE facetype, UINT32 files_number, IDW fontface->gasp.exists = TRUE; fontface->cpal.exists = TRUE; fontface->colr.exists = TRUE; - fontface->index = index; - fontface->simulations = simulations; + fontface->index = desc->index; + fontface->simulations = desc->simulations; memset(fontface->glyphs, 0, sizeof(fontface->glyphs)); for (i = 0; i < fontface->file_count; i++) { - hr = get_stream_from_file(font_files[i], &fontface->streams[i]); + hr = get_stream_from_file(desc->files[i], &fontface->streams[i]); if (FAILED(hr)) { IDWriteFontFace3_Release(&fontface->IDWriteFontFace3_iface); return hr; } - fontface->files[i] = font_files[i]; - IDWriteFontFile_AddRef(font_files[i]); + fontface->files[i] = desc->files[i]; + IDWriteFontFile_AddRef(fontface->files[i]); } stream_desc.stream = fontface->streams[0]; - stream_desc.face_type = facetype; - stream_desc.face_index = index; + stream_desc.face_type = desc->face_type; + stream_desc.face_index = desc->index; opentype_get_font_metrics(&stream_desc, &fontface->metrics, &fontface->caret); - if (simulations & DWRITE_FONT_SIMULATIONS_OBLIQUE) { + if (desc->simulations & DWRITE_FONT_SIMULATIONS_OBLIQUE) { /* TODO: test what happens if caret is already slanted */ if (fontface->caret.slopeRise == 1) { fontface->caret.slopeRise = fontface->metrics.designUnitsPerEm; @@ -4160,6 +4192,36 @@ HRESULT create_fontface(DWRITE_FONT_FACE_TYPE facetype, UINT32 files_number, IDW fontface->has_kerning_pairs = freetype_has_kerning_pairs(&fontface->IDWriteFontFace3_iface); fontface->is_monospaced = freetype_is_monospaced(&fontface->IDWriteFontFace3_iface); + /* Font properties are reused from font object when 'normal' face creation path is used: + collection -> family -> matching font -> fontface. + + If face is created directly from factory we have to go through properties resolution. + */ + if (desc->font_data) { + fontface->weight = desc->font_data->weight; + fontface->style = desc->font_data->style; + fontface->stretch = desc->font_data->stretch; + fontface->panose = desc->font_data->panose; + } + else { + IDWriteLocalizedStrings *names; + struct dwrite_font_data *data; + + hr = init_font_data(desc, &names, &data); + if (FAILED(hr)) { + IDWriteFontFace3_Release(&fontface->IDWriteFontFace3_iface); + return hr; + } + + fontface->weight = data->weight; + fontface->style = data->style; + fontface->stretch = data->stretch; + fontface->panose = data->panose; + + IDWriteLocalizedStrings_Release(names); + release_font_data(data); + } + *ret = &fontface->IDWriteFontFace3_iface; return S_OK; } diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c index 6d3d8b76f96..fd72875afdc 100644 --- a/dlls/dwrite/layout.c +++ b/dlls/dwrite/layout.c @@ -28,7 +28,6 @@ #include "wingdi.h" #include "dwrite_private.h" #include "scripts.h" -#include "wine/list.h" WINE_DEFAULT_DEBUG_CHANNEL(dwrite); diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index 9b1c50ffc10..fc69be49459 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -30,7 +30,6 @@ #include "dwrite_private.h" #include "wine/debug.h" -#include "wine/list.h" WINE_DEFAULT_DEBUG_CHANNEL(dwrite); @@ -509,7 +508,7 @@ struct collectionloader struct fontfacecached { struct list entry; - IDWriteFontFace *fontface; + IDWriteFontFace3 *fontface; }; struct fileloader @@ -545,7 +544,7 @@ 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); + IDWriteFontFace3_Release(fontface->fontface); heap_free(fontface); } } @@ -807,6 +806,88 @@ static HRESULT WINAPI dwritefactory_CreateCustomFontFileReference(IDWriteFactory return create_font_file(loader, reference_key, key_size, font_file); } +HRESULT factory_get_cached_fontface(IDWriteFactory3 *iface, IDWriteFontFile * const *font_files, + UINT32 index, DWRITE_FONT_SIMULATIONS simulations, IDWriteFontFace **font_face, struct list **cached_list) +{ + struct dwritefactory *factory = impl_from_IDWriteFactory3(iface); + struct fontfacecached *cached; + IDWriteFontFileLoader *loader; + struct list *fontfaces; + UINT32 key_size; + const void *key; + HRESULT hr; + + *font_face = NULL; + *cached_list = NULL; + + 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*)factory->localfontfileloader) { + fontfaces = &factory->localfontfaces; + IDWriteFontFileLoader_Release(loader); + } + else { + struct fileloader *fileloader = factory_get_file_loader(factory, loader); + IDWriteFontFileLoader_Release(loader); + if (!fileloader) + return E_INVALIDARG; + fontfaces = &fileloader->fontfaces; + } + + *cached_list = 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 = IDWriteFontFace3_GetIndex(cached->fontface); + cached_simulations = IDWriteFontFace3_GetSimulations(cached->fontface); + + /* skip earlier */ + if (cached_face_index != index || cached_simulations != simulations) + continue; + + hr = IDWriteFontFace3_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 = (IDWriteFontFace*)cached->fontface; + return S_OK; + } + } + + return S_FALSE; +} + +void factory_cache_fontface(struct list *fontfaces, IDWriteFontFace3 *fontface) +{ + struct fontfacecached *cached; + + /* new cache entry */ + cached = heap_alloc(sizeof(*cached)); + if (!cached) + return; + + cached->fontface = fontface; + list_add_tail(fontfaces, &cached->entry); +} + static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory3 *iface, DWRITE_FONT_FACE_TYPE req_facetype, UINT32 files_number, IDWriteFontFile* const* font_files, UINT32 index, DWRITE_FONT_SIMULATIONS simulations, IDWriteFontFace **font_face) @@ -814,13 +895,11 @@ static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory3 *iface, struct dwritefactory *This = impl_from_IDWriteFactory3(iface); DWRITE_FONT_FILE_TYPE file_type; DWRITE_FONT_FACE_TYPE face_type; - IDWriteFontFileLoader *loader; - struct fontfacecached *cached; + struct fontface_desc desc; struct list *fontfaces; IDWriteFontFace3 *face; - UINT32 key_size, count; BOOL is_supported; - const void *key; + UINT32 count; HRESULT hr; TRACE("(%p)->(%d %u %p %u 0x%x %p)\n", This, req_facetype, files_number, font_files, index, simulations, font_face); @@ -849,72 +928,27 @@ static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory3 *iface, if (face_type != req_facetype) return DWRITE_E_FILEFORMAT; - hr = IDWriteFontFile_GetReferenceKey(*font_files, &key, &key_size); + hr = factory_get_cached_fontface(iface, font_files, index, simulations, font_face, &fontfaces); + if (hr == S_OK) + IDWriteFontFace_AddRef(*font_face); + + if (hr != S_FALSE) + return hr; + + desc.factory = iface; + desc.face_type = req_facetype; + desc.files = font_files; + desc.files_number = files_number; + desc.index = index; + desc.simulations = simulations; + desc.font_data = NULL; + hr = create_fontface(&desc, &face); if (FAILED(hr)) return hr; - hr = IDWriteFontFile_GetLoader(*font_files, &loader); - if (FAILED(hr)) - return hr; + factory_cache_fontface(fontfaces, face); - 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(req_facetype, files_number, font_files, index, simulations, &face); - if (FAILED(hr)) - return hr; - - /* new cache entry */ - cached = heap_alloc(sizeof(*cached)); - if (!cached) { - IDWriteFontFace3_Release(face); - return E_OUTOFMEMORY; - } - - cached->fontface = (IDWriteFontFace*)face; - list_add_tail(fontfaces, &cached->entry); - - *font_face = cached->fontface; + *font_face = (IDWriteFontFace*)face; IDWriteFontFace_AddRef(*font_face); return S_OK; diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index 163b4812b68..e211712991d 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -600,19 +600,20 @@ static ULONG WINAPI resourcefontfileloader_Release(IDWriteFontFileLoader *iface) return 1; } -static HRESULT WINAPI resourcefontfileloader_CreateStreamFromKey(IDWriteFontFileLoader *iface, const void *fontFileReferenceKey, UINT32 fontFileReferenceKeySize, IDWriteFontFileStream **fontFileStream) +static HRESULT WINAPI resourcefontfileloader_CreateStreamFromKey(IDWriteFontFileLoader *iface, const void *ref_key, UINT32 key_size, + IDWriteFontFileStream **stream) { LPVOID data; DWORD size; HGLOBAL mem; - mem = LoadResource(GetModuleHandleA(NULL), *(HRSRC*)fontFileReferenceKey); + mem = LoadResource(GetModuleHandleA(NULL), *(HRSRC*)ref_key); ok(mem != NULL, "Failed to lock font resource\n"); if (mem) { - size = SizeofResource(GetModuleHandleA(NULL), *(HRSRC*)fontFileReferenceKey); + size = SizeofResource(GetModuleHandleA(NULL), *(HRSRC*)ref_key); data = LockResource(mem); - return create_fontdatastream(data, size, fontFileStream); + return create_fontdatastream(data, size, stream); } return E_FAIL; } @@ -2452,7 +2453,8 @@ static ULONG WINAPI fontfileloader_Release(IDWriteFontFileLoader *iface) return 1; } -static HRESULT WINAPI fontfileloader_CreateStreamFromKey(IDWriteFontFileLoader *iface, const void *fontFileReferenceKey, UINT32 fontFileReferenceKeySize, IDWriteFontFileStream **fontFileStream) +static HRESULT WINAPI fontfileloader_CreateStreamFromKey(IDWriteFontFileLoader *iface, const void *ref_key, UINT32 key_size, + IDWriteFontFileStream **stream) { return 0x8faecafe; } @@ -4476,7 +4478,6 @@ struct VDMX_vTable SHORT yMin; }; - static const struct VDMX_group *find_vdmx_group(const struct VDMX_Header *hdr) { WORD num_ratios, i, group_offset = 0; @@ -4813,6 +4814,8 @@ static void test_GetPanose(void) hr = IDWriteFont_QueryInterface(font, &IID_IDWriteFont1, (void**)&font1); IDWriteFont_Release(font); if (hr == S_OK) { + IDWriteFontFace3 *fontface3; + IDWriteFontFace *fontface; DWRITE_PANOSE panose; if (0) /* crashes on native */ @@ -4841,6 +4844,20 @@ static void test_GetPanose(void) ok(panose.text.xHeight == DWRITE_PANOSE_XHEIGHT_CONSTANT_LARGE, "got %u\n", panose.text.xHeight); + hr = IDWriteFont1_CreateFontFace(font1, &fontface); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace3, (void**)&fontface3); + IDWriteFontFace_Release(fontface); + if (hr == S_OK) { + DWRITE_PANOSE panose2; + + IDWriteFontFace3_GetPanose(fontface3, &panose2); + ok(!memcmp(&panose, &panose2, sizeof(panose)), "wrong panose data\n"); + + IDWriteFontFace3_Release(fontface3); + } + IDWriteFont1_Release(font1); } else @@ -6250,6 +6267,39 @@ static void test_GetFontSignature(void) IDWriteFactory_Release(factory); } +static void test_font_properties(void) +{ + IDWriteFontFace3 *fontface3; + IDWriteFontFace *fontface; + IDWriteFactory *factory; + DWRITE_FONT_STYLE style; + IDWriteFont *font; + HRESULT hr; + + factory = create_factory(); + + /* this creates simulated font */ + font = get_tahoma_instance(factory, DWRITE_FONT_STYLE_ITALIC); + + style = IDWriteFont_GetStyle(font); + ok(style == DWRITE_FONT_STYLE_OBLIQUE, "got %u\n", style); + + hr = IDWriteFont_CreateFontFace(font, &fontface); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace3, (void**)&fontface3); + IDWriteFontFace_Release(fontface); + if (hr == S_OK) { + style = IDWriteFontFace3_GetStyle(fontface3); + ok(style == DWRITE_FONT_STYLE_OBLIQUE, "got %u\n", style); + + IDWriteFontFace3_Release(fontface3); + } + + IDWriteFont_Release(font); + IDWriteFactory_Release(factory); +} + START_TEST(font) { IDWriteFactory *factory; @@ -6306,6 +6356,7 @@ START_TEST(font) test_HasCharacter(); test_CreateFontFaceReference(); test_GetFontSignature(); + test_font_properties(); IDWriteFactory_Release(factory); }