dwrite: Block creation of unsupported face types.

This commit is contained in:
Nikolay Sivov 2014-12-11 12:33:29 +03:00 committed by Alexandre Julliard
parent 3d5fe2074e
commit 44bb2ba295
4 changed files with 109 additions and 31 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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;