dwrite: Beginning implementation of IDWriteFontFile_Analyze.

This commit is contained in:
Aric Stewart 2014-08-12 14:11:37 -05:00 committed by Alexandre Julliard
parent bb9721bd29
commit 366c40813c
5 changed files with 126 additions and 2 deletions

View File

@ -7,4 +7,5 @@ C_SRCS = \
font.c \
gdiinterop.c \
layout.c \
main.c
main.c \
opentype.c

View File

@ -90,3 +90,6 @@ extern HRESULT get_system_fontcollection(IDWriteFontCollection**) DECLSPEC_HIDDE
extern void release_system_fontcollection(void) DECLSPEC_HIDDEN;
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;
/* Opentype font table functions */
extern HRESULT analyze_opentype_font(const void* font_data, UINT32* font_count, DWRITE_FONT_FILE_TYPE *file_type, DWRITE_FONT_FACE_TYPE *face_type, BOOL *supported) DECLSPEC_HIDDEN;

View File

@ -1057,9 +1057,32 @@ static HRESULT WINAPI dwritefontfile_GetLoader(IDWriteFontFile *iface, IDWriteFo
static HRESULT WINAPI dwritefontfile_Analyze(IDWriteFontFile *iface, BOOL *isSupportedFontType, DWRITE_FONT_FILE_TYPE *fontFileType, DWRITE_FONT_FACE_TYPE *fontFaceType, UINT32 *numberOfFaces)
{
HRESULT hr;
const void *font_data;
void *context;
IDWriteFontFileStream *stream;
struct dwrite_fontfile *This = impl_from_IDWriteFontFile(iface);
FIXME("(%p)->(%p, %p, %p, %p): Stub\n", This, isSupportedFontType, fontFileType, fontFaceType, numberOfFaces);
return E_NOTIMPL;
*isSupportedFontType = FALSE;
*fontFileType = DWRITE_FONT_FILE_TYPE_UNKNOWN;
if (fontFaceType)
*fontFaceType = DWRITE_FONT_FACE_TYPE_UNKNOWN;
*numberOfFaces = 0;
hr = IDWriteFontFileLoader_CreateStreamFromKey(This->loader, This->reference_key, This->key_size, &stream);
if (FAILED(hr))
return S_OK;
hr = IDWriteFontFileStream_ReadFileFragment(stream, &font_data, 0, 28, &context);
if (SUCCEEDED(hr))
{
hr = analyze_opentype_font(font_data, numberOfFaces, fontFileType, fontFaceType, isSupportedFontType);
IDWriteFontFileStream_ReleaseFileFragment(stream, context);
}
/* TODO: Further Analysis */
IDWriteFontFileStream_Release(stream);
return S_OK;
}
static const IDWriteFontFileVtbl dwritefontfilevtbl = {

83
dlls/dwrite/opentype.c Normal file
View File

@ -0,0 +1,83 @@
/*
* Methods for dealing with opentype font tables
*
* Copyright 2014 Aric Stewart for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define COBJMACROS
#include "dwrite.h"
#include "dwrite_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(dwrite);
#define DWRITE_MAKE_OPENTYPE_TAG(ch0, ch1, ch2, ch3) \
((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \
((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24))
#define MS_TTCF_TAG DWRITE_MAKE_OPENTYPE_TAG('t','t','c','f')
#define MS_OTTO_TAG DWRITE_MAKE_OPENTYPE_TAG('O','T','T','O')
#ifdef WORDS_BIGENDIAN
#define GET_BE_WORD(x) (x)
#define GET_BE_DWORD(x) (x)
#else
#define GET_BE_WORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x))
#define GET_BE_DWORD(x) MAKELONG(GET_BE_WORD(HIWORD(x)), GET_BE_WORD(LOWORD(x)))
#endif
typedef struct {
CHAR TTCTag[4];
DWORD Version;
DWORD numFonts;
DWORD OffsetTable[1];
} TTC_Header_V1;
HRESULT analyze_opentype_font(const void* font_data, UINT32* font_count, DWRITE_FONT_FILE_TYPE *file_type, DWRITE_FONT_FACE_TYPE *face_type, BOOL *supported)
{
/* TODO: Do font validation */
const char* tag = font_data;
*supported = FALSE;
*file_type = DWRITE_FONT_FILE_TYPE_UNKNOWN;
if (face_type)
*face_type = DWRITE_FONT_FACE_TYPE_UNKNOWN;
*font_count = 0;
if (DWRITE_MAKE_OPENTYPE_TAG(tag[0], tag[1], tag[2], tag[3]) == MS_TTCF_TAG)
{
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;
}
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;
}
else if (DWRITE_MAKE_OPENTYPE_TAG(tag[0], tag[1], tag[2], tag[3]) == MS_OTTO_TAG)
{
*file_type = DWRITE_FONT_FILE_TYPE_CFF;
}
return S_OK;
}

View File

@ -763,6 +763,10 @@ static void test_FontLoader(void)
IDWriteFontFileLoader floader2 = { &dwritefontfileloadervtbl };
IDWriteFontFileLoader floader3 = { &dwritefontfileloadervtbl };
IDWriteFontFile *ffile = NULL;
BOOL support = 1;
DWRITE_FONT_FILE_TYPE type = 1;
DWRITE_FONT_FACE_TYPE face = 1;
UINT32 count = 1;
HRESULT hr;
hr = IDWriteFactory_RegisterFontFileLoader(factory, NULL);
@ -789,6 +793,16 @@ static void test_FontLoader(void)
if (SUCCEEDED(hr))
IDWriteFontFile_Release(ffile);
hr = IDWriteFactory_CreateCustomFontFileReference(factory, "test", 4, &floader, &ffile);
ok(hr == S_OK, "got 0x%08x\n", hr);
IDWriteFontFile_Analyze(ffile, &support, &type, &face, &count);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(support == FALSE, "got %i\n", support);
ok(type == DWRITE_FONT_FILE_TYPE_UNKNOWN, "got %i\n", type);
ok(face == DWRITE_FONT_FACE_TYPE_UNKNOWN, "got %i\n", face);
ok(count == 0, "got %i\n", count);
IDWriteFontFile_Release(ffile);
hr = IDWriteFactory_UnregisterFontFileLoader(factory, &floader);
ok(hr == S_OK, "got 0x%08x\n", hr);
hr = IDWriteFactory_UnregisterFontFileLoader(factory, &floader);