dwrite: Block creation of unsupported face types.
This commit is contained in:
parent
3d5fe2074e
commit
44bb2ba295
|
@ -110,6 +110,7 @@ extern HRESULT create_font_collection(IDWriteFactory2*,IDWriteFontFileEnumerator
|
|||
extern BOOL is_system_collection(IDWriteFontCollection*) DECLSPEC_HIDDEN;
|
||||
extern HRESULT get_local_refkey(const WCHAR*,const FILETIME*,void**,UINT32*) DECLSPEC_HIDDEN;
|
||||
extern HRESULT get_filestream_from_file(IDWriteFontFile*,IDWriteFontFileStream**) DECLSPEC_HIDDEN;
|
||||
extern BOOL is_face_type_supported(DWRITE_FONT_FACE_TYPE) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Opentype font table functions */
|
||||
extern HRESULT opentype_analyze_font(IDWriteFontFileStream*,UINT32*,DWRITE_FONT_FILE_TYPE*,DWRITE_FONT_FACE_TYPE*,BOOL*) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -726,25 +726,41 @@ static HRESULT WINAPI dwritefactory_CreateCustomFontFileReference(IDWriteFactory
|
|||
}
|
||||
|
||||
static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory2 *iface,
|
||||
DWRITE_FONT_FACE_TYPE facetype, UINT32 files_number, IDWriteFontFile* const* font_files,
|
||||
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_IDWriteFactory2(iface);
|
||||
DWRITE_FONT_FILE_TYPE file_type;
|
||||
DWRITE_FONT_FACE_TYPE face_type;
|
||||
IDWriteFontFileLoader *loader;
|
||||
struct fontfacecached *cached;
|
||||
struct list *fontfaces;
|
||||
IDWriteFontFace2 *face;
|
||||
UINT32 key_size, count;
|
||||
BOOL is_supported;
|
||||
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);
|
||||
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 (facetype != DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION && index)
|
||||
if (!is_face_type_supported(req_facetype))
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (req_facetype != DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION && index)
|
||||
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 || (face_type != req_facetype))
|
||||
return E_FAIL;
|
||||
|
||||
hr = IDWriteFontFile_GetReferenceKey(*font_files, &key, &key_size);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
@ -796,7 +812,7 @@ static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory2 *iface,
|
|||
}
|
||||
}
|
||||
|
||||
hr = create_fontface(facetype, files_number, font_files, index, simulations, &face);
|
||||
hr = create_fontface(req_facetype, files_number, font_files, index, simulations, &face);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
|
|
|
@ -591,9 +591,18 @@ static const UINT16 dwriteid_to_opentypeid[DWRITE_INFORMATIONAL_STRING_POSTSCRIP
|
|||
OPENTYPE_STRING_POSTSCRIPT_CID_NAME
|
||||
};
|
||||
|
||||
BOOL is_face_type_supported(DWRITE_FONT_FACE_TYPE type)
|
||||
{
|
||||
return (type == DWRITE_FONT_FACE_TYPE_CFF) ||
|
||||
(type == DWRITE_FONT_FACE_TYPE_TRUETYPE) ||
|
||||
(type == DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION) ||
|
||||
(type == DWRITE_FONT_FACE_TYPE_RAW_CFF);
|
||||
}
|
||||
|
||||
HRESULT opentype_analyze_font(IDWriteFontFileStream *stream, UINT32* font_count, DWRITE_FONT_FILE_TYPE *file_type, DWRITE_FONT_FACE_TYPE *face_type, BOOL *supported)
|
||||
{
|
||||
/* TODO: Do font validation */
|
||||
DWRITE_FONT_FACE_TYPE face;
|
||||
const void *font_data;
|
||||
const char* tag;
|
||||
void *context;
|
||||
|
@ -604,10 +613,8 @@ HRESULT opentype_analyze_font(IDWriteFontFileStream *stream, UINT32* font_count,
|
|||
return hr;
|
||||
|
||||
tag = font_data;
|
||||
*supported = FALSE;
|
||||
*file_type = DWRITE_FONT_FILE_TYPE_UNKNOWN;
|
||||
if (face_type)
|
||||
*face_type = DWRITE_FONT_FACE_TYPE_UNKNOWN;
|
||||
face = DWRITE_FONT_FACE_TYPE_UNKNOWN;
|
||||
*font_count = 0;
|
||||
|
||||
if (DWRITE_MAKE_OPENTYPE_TAG(tag[0], tag[1], tag[2], tag[3]) == MS_TTCF_TAG)
|
||||
|
@ -615,23 +622,25 @@ HRESULT opentype_analyze_font(IDWriteFontFileStream *stream, UINT32* font_count,
|
|||
const TTC_Header_V1 *header = font_data;
|
||||
*font_count = GET_BE_DWORD(header->numFonts);
|
||||
*file_type = DWRITE_FONT_FILE_TYPE_TRUETYPE_COLLECTION;
|
||||
if (face_type)
|
||||
*face_type = DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION;
|
||||
*supported = TRUE;
|
||||
face = DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION;
|
||||
}
|
||||
else if (GET_BE_DWORD(*(DWORD*)font_data) == 0x10000)
|
||||
{
|
||||
*font_count = 1;
|
||||
*file_type = DWRITE_FONT_FILE_TYPE_TRUETYPE;
|
||||
if (face_type)
|
||||
*face_type = DWRITE_FONT_FACE_TYPE_TRUETYPE;
|
||||
*supported = TRUE;
|
||||
face = DWRITE_FONT_FACE_TYPE_TRUETYPE;
|
||||
}
|
||||
else if (DWRITE_MAKE_OPENTYPE_TAG(tag[0], tag[1], tag[2], tag[3]) == MS_OTTO_TAG)
|
||||
{
|
||||
*file_type = DWRITE_FONT_FILE_TYPE_CFF;
|
||||
face = DWRITE_FONT_FACE_TYPE_CFF;
|
||||
}
|
||||
|
||||
if (face_type)
|
||||
*face_type = face;
|
||||
|
||||
*supported = is_face_type_supported(face);
|
||||
|
||||
IDWriteFontFileStream_ReleaseFileFragment(stream, context);
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -66,6 +66,23 @@ static IDWriteFactory *create_factory(void)
|
|||
return factory;
|
||||
}
|
||||
|
||||
static void create_testfontfile(const WCHAR *filename)
|
||||
{
|
||||
DWORD written;
|
||||
HANDLE file;
|
||||
HRSRC res;
|
||||
void *ptr;
|
||||
file = CreateFileW(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
|
||||
ok( file != INVALID_HANDLE_VALUE, "file creation failed\n" );
|
||||
|
||||
res = FindResourceA(GetModuleHandleA(NULL), (LPCSTR)MAKEINTRESOURCE(1), (LPCSTR)RT_RCDATA);
|
||||
ok( res != 0, "couldn't find resource\n" );
|
||||
ptr = LockResource( LoadResource( GetModuleHandleA(NULL), res ));
|
||||
WriteFile( file, ptr, SizeofResource( GetModuleHandleA(NULL), res ), &written, NULL );
|
||||
ok( written == SizeofResource( GetModuleHandleA(NULL), res ), "couldn't write resource\n" );
|
||||
CloseHandle( file );
|
||||
}
|
||||
|
||||
struct test_fontenumerator
|
||||
{
|
||||
IDWriteFontFileEnumerator IDWriteFontFileEnumerator_iface;
|
||||
|
@ -909,11 +926,16 @@ static void test_CreateFontFace(void)
|
|||
{
|
||||
IDWriteFontFace *fontface, *fontface2;
|
||||
IDWriteFontCollection *collection;
|
||||
DWRITE_FONT_FILE_TYPE file_type;
|
||||
DWRITE_FONT_FACE_TYPE face_type;
|
||||
IDWriteGdiInterop *interop;
|
||||
IDWriteFont *font, *font2;
|
||||
IDWriteFontFamily *family;
|
||||
IDWriteFactory *factory;
|
||||
IDWriteFontFile *file;
|
||||
LOGFONTW logfont;
|
||||
BOOL supported;
|
||||
UINT32 count;
|
||||
HRESULT hr;
|
||||
|
||||
factory = create_factory();
|
||||
|
@ -1001,7 +1023,53 @@ if (0) /* crashes on native */
|
|||
IDWriteFont_Release(font);
|
||||
IDWriteFontFamily_Release(family);
|
||||
IDWriteFontCollection_Release(collection);
|
||||
|
||||
/* IDWriteFactory::CreateFontFace() */
|
||||
create_testfontfile(test_fontfile);
|
||||
factory = create_factory();
|
||||
|
||||
hr = IDWriteFactory_CreateFontFileReference(factory, test_fontfile, NULL, &file);
|
||||
ok(hr == S_OK, "got 0x%08x\n",hr);
|
||||
|
||||
supported = FALSE;
|
||||
file_type = DWRITE_FONT_FILE_TYPE_UNKNOWN;
|
||||
face_type = DWRITE_FONT_FACE_TYPE_CFF;
|
||||
count = 0;
|
||||
hr = IDWriteFontFile_Analyze(file, &supported, &file_type, &face_type, &count);
|
||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||
ok(supported == TRUE, "got %i\n", supported);
|
||||
ok(file_type == DWRITE_FONT_FILE_TYPE_TRUETYPE, "got %i\n", file_type);
|
||||
ok(face_type == DWRITE_FONT_FACE_TYPE_TRUETYPE, "got %i\n", face_type);
|
||||
ok(count == 1, "got %i\n", count);
|
||||
|
||||
/* try mismatching face type, the one that's not supported */
|
||||
hr = IDWriteFactory_CreateFontFace(factory, DWRITE_FONT_FACE_TYPE_CFF, 1, &file, 0, DWRITE_FONT_SIMULATIONS_NONE, &fontface);
|
||||
todo_wine
|
||||
ok(hr == DWRITE_E_FILEFORMAT, "got 0x%08x\n", hr);
|
||||
|
||||
hr = IDWriteFactory_CreateFontFace(factory, DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION, 1, &file, 0,
|
||||
DWRITE_FONT_SIMULATIONS_NONE, &fontface);
|
||||
ok(hr == E_FAIL, "got 0x%08x\n", hr);
|
||||
|
||||
hr = IDWriteFactory_CreateFontFace(factory, DWRITE_FONT_FACE_TYPE_RAW_CFF, 1, &file, 0, DWRITE_FONT_SIMULATIONS_NONE, &fontface);
|
||||
todo_wine
|
||||
ok(hr == DWRITE_E_UNSUPPORTEDOPERATION || broken(hr == E_INVALIDARG) /* older versions */, "got 0x%08x\n", hr);
|
||||
|
||||
hr = IDWriteFactory_CreateFontFace(factory, DWRITE_FONT_FACE_TYPE_TYPE1, 1, &file, 0, DWRITE_FONT_SIMULATIONS_NONE, &fontface);
|
||||
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
|
||||
|
||||
hr = IDWriteFactory_CreateFontFace(factory, DWRITE_FONT_FACE_TYPE_VECTOR, 1, &file, 0, DWRITE_FONT_SIMULATIONS_NONE, &fontface);
|
||||
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
|
||||
|
||||
hr = IDWriteFactory_CreateFontFace(factory, DWRITE_FONT_FACE_TYPE_BITMAP, 1, &file, 0, DWRITE_FONT_SIMULATIONS_NONE, &fontface);
|
||||
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
|
||||
|
||||
hr = IDWriteFactory_CreateFontFace(factory, DWRITE_FONT_FACE_TYPE_UNKNOWN, 1, &file, 0, DWRITE_FONT_SIMULATIONS_NONE, &fontface);
|
||||
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
|
||||
|
||||
IDWriteFontFile_Release(file);
|
||||
IDWriteFactory_Release(factory);
|
||||
DeleteFileW(test_fontfile);
|
||||
}
|
||||
|
||||
static void test_GetMetrics(void)
|
||||
|
@ -1648,6 +1716,7 @@ static void test_CreateCustomFontFileReference(void)
|
|||
ok(count == 0, "got %i\n", count);
|
||||
|
||||
hr = IDWriteFactory_CreateFontFace(factory, DWRITE_FONT_FACE_TYPE_CFF, 1, &file, 0, 0, &face);
|
||||
todo_wine
|
||||
ok(hr == 0x8faecafe, "got 0x%08x\n", hr);
|
||||
IDWriteFontFile_Release(file);
|
||||
|
||||
|
@ -1720,23 +1789,6 @@ if (face2)
|
|||
IDWriteFactory_Release(factory);
|
||||
}
|
||||
|
||||
static void create_testfontfile(const WCHAR *filename)
|
||||
{
|
||||
DWORD written;
|
||||
HANDLE file;
|
||||
HRSRC res;
|
||||
void *ptr;
|
||||
file = CreateFileW(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
|
||||
ok( file != INVALID_HANDLE_VALUE, "file creation failed\n" );
|
||||
|
||||
res = FindResourceA(GetModuleHandleA(NULL), (LPCSTR)MAKEINTRESOURCE(1), (LPCSTR)RT_RCDATA);
|
||||
ok( res != 0, "couldn't find resource\n" );
|
||||
ptr = LockResource( LoadResource( GetModuleHandleA(NULL), res ));
|
||||
WriteFile( file, ptr, SizeofResource( GetModuleHandleA(NULL), res ), &written, NULL );
|
||||
ok( written == SizeofResource( GetModuleHandleA(NULL), res ), "couldn't write resource\n" );
|
||||
CloseHandle( file );
|
||||
}
|
||||
|
||||
static void test_CreateFontFileReference(void)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
|
Loading…
Reference in New Issue