Aric Stewart : dwrite: Beginning implementation of IDWriteFontFile_Analyze.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Aug 20 14:30:34 CDT 2014


Module: wine
Branch: master
Commit: 366c40813ce8342191b974d81e5ddd1121cc1064
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=366c40813ce8342191b974d81e5ddd1121cc1064

Author: Aric Stewart <aric at codeweavers.com>
Date:   Tue Aug 12 14:11:37 2014 -0500

dwrite: Beginning implementation of IDWriteFontFile_Analyze.

---

 dlls/dwrite/Makefile.in      |  3 +-
 dlls/dwrite/dwrite_private.h |  3 ++
 dlls/dwrite/font.c           | 25 ++++++++++++-
 dlls/dwrite/opentype.c       | 83 ++++++++++++++++++++++++++++++++++++++++++++
 dlls/dwrite/tests/font.c     | 14 ++++++++
 5 files changed, 126 insertions(+), 2 deletions(-)

diff --git a/dlls/dwrite/Makefile.in b/dlls/dwrite/Makefile.in
index 9ee7181..c714419 100644
--- a/dlls/dwrite/Makefile.in
+++ b/dlls/dwrite/Makefile.in
@@ -7,4 +7,5 @@ C_SRCS = \
 	font.c \
 	gdiinterop.c \
 	layout.c \
-	main.c
+	main.c \
+	opentype.c
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index fcc9b7f..64f55e2 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -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;
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index afeca27..0c75271 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -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 = {
diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c
new file mode 100644
index 0000000..538db98
--- /dev/null
+++ b/dlls/dwrite/opentype.c
@@ -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;
+}
diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c
index 4368bcf..44e7ee6 100644
--- a/dlls/dwrite/tests/font.c
+++ b/dlls/dwrite/tests/font.c
@@ -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);




More information about the wine-cvs mailing list