Commit 90bcff0e authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

dwrite: Return some of font properties from IDWriteFontFace3 methods.

parent 8acdf5e7
......@@ -46,7 +46,6 @@
#include "windef.h"
#include "winbase.h"
#include "wine/debug.h"
#include "wine/list.h"
#include "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 {
......
......@@ -28,7 +28,6 @@
#include "wingdi.h"
#include "dwrite_private.h"
#include "scripts.h"
#include "wine/list.h"
WINE_DEFAULT_DEBUG_CHANNEL(dwrite);
......
......@@ -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,47 +806,19 @@ static HRESULT WINAPI dwritefactory_CreateCustomFontFileReference(IDWriteFactory
return create_font_file(loader, reference_key, key_size, font_file);
}
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)
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 *This = impl_from_IDWriteFactory3(iface);
DWRITE_FONT_FILE_TYPE file_type;
DWRITE_FONT_FACE_TYPE face_type;
IDWriteFontFileLoader *loader;
struct dwritefactory *factory = impl_from_IDWriteFactory3(iface);
struct fontfacecached *cached;
IDWriteFontFileLoader *loader;
struct list *fontfaces;
IDWriteFontFace3 *face;
UINT32 key_size, count;
BOOL is_supported;
UINT32 key_size;
const void *key;
HRESULT hr;
TRACE("(%p)->(%d %u %p %u 0x%x %p)\n", This, req_facetype, files_number, font_files, index, simulations, font_face);
*font_face = NULL;
if (!is_face_type_supported(req_facetype))
return E_INVALIDARG;
if (req_facetype != DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION && index)
return E_INVALIDARG;
if (!is_simulation_valid(simulations))
return E_INVALIDARG;
/* 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);
if (FAILED(hr))
return hr;
if (!is_supported)
return E_FAIL;
if (face_type != req_facetype)
return DWRITE_E_FILEFORMAT;
*cached_list = NULL;
hr = IDWriteFontFile_GetReferenceKey(*font_files, &key, &key_size);
if (FAILED(hr))
......@@ -857,18 +828,20 @@ static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory3 *iface,
if (FAILED(hr))
return hr;
if (loader == (IDWriteFontFileLoader*)This->localfontfileloader) {
fontfaces = &This->localfontfaces;
if (loader == (IDWriteFontFileLoader*)factory->localfontfileloader) {
fontfaces = &factory->localfontfaces;
IDWriteFontFileLoader_Release(loader);
}
else {
struct fileloader *fileloader = factory_get_file_loader(This, loader);
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;
......@@ -876,14 +849,14 @@ static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory3 *iface,
const void *cached_key;
IDWriteFontFile *file;
cached_face_index = IDWriteFontFace_GetIndex(cached->fontface);
cached_simulations = IDWriteFontFace_GetSimulations(cached->fontface);
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 = IDWriteFontFace_GetFiles(cached->fontface, &count, &file);
hr = IDWriteFontFace3_GetFiles(cached->fontface, &count, &file);
if (FAILED(hr))
return hr;
......@@ -894,27 +867,88 @@ static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory3 *iface,
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);
*font_face = (IDWriteFontFace*)cached->fontface;
return S_OK;
}
}
hr = create_fontface(req_facetype, files_number, font_files, index, simulations, &face);
if (FAILED(hr))
return hr;
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) {
IDWriteFontFace3_Release(face);
return E_OUTOFMEMORY;
}
if (!cached)
return;
cached->fontface = (IDWriteFontFace*)face;
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)
{
struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
DWRITE_FONT_FILE_TYPE file_type;
DWRITE_FONT_FACE_TYPE face_type;
struct fontface_desc desc;
struct list *fontfaces;
IDWriteFontFace3 *face;
BOOL is_supported;
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);
*font_face = NULL;
if (!is_face_type_supported(req_facetype))
return E_INVALIDARG;
if (req_facetype != DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION && index)
return E_INVALIDARG;
if (!is_simulation_valid(simulations))
return E_INVALIDARG;
/* 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);
if (FAILED(hr))
return hr;
if (!is_supported)
return E_FAIL;
if (face_type != req_facetype)
return DWRITE_E_FILEFORMAT;
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;
factory_cache_fontface(fontfaces, face);
*font_face = cached->fontface;
*font_face = (IDWriteFontFace*)face;
IDWriteFontFace_AddRef(*font_face);
return S_OK;
......
......@@ -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);
}
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