[3/5] gdi32: Add the ability to load a scalable font resource. Take 3.
Dmitry Timoshkov
dmitry at codeweavers.com
Wed Nov 17 09:44:59 CST 2010
From: Jeremy White <jwhite at codeweavers.com>
---
dlls/gdi32/freetype.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 124 insertions(+), 5 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index c952a47..9c75d9b 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -370,7 +370,7 @@ typedef struct {
#include "pshpack1.h"
-static const struct
+static const struct dos
{
WORD e_magic; /* 00: MZ Header signature */
WORD unused[29];
@@ -907,6 +907,114 @@ static inline BOOL is_win9x(void)
{
return GetVersion() & 0x80000000;
}
+
+static char *get_scalable_resource_name(const char *file, void *font_data_ptr, DWORD font_data_size)
+{
+ struct dos dos;
+ IMAGE_OS2_HEADER os2;
+ HANDLE hfile;
+ NE_TYPEINFO type;
+ NE_NAMEINFO name;
+ WORD resource_shift;
+ DWORD fontdir_off = 0, fontpath_off = 0, fontdir_len, fontpath_len;
+ LPSTR fot_path = NULL;
+ LPWSTR wide_path = NULL;
+ char *ret = NULL;
+ int len;
+ struct fontdir fd;
+
+ /* FIXME */
+ if (!file) return NULL;
+
+ hfile = CreateFileA(file, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hfile == INVALID_HANDLE_VALUE)
+ {
+ TRACE("Could not open %s for reading\n", file);
+ return NULL;
+ }
+
+ if (!ReadFile(hfile, &dos, sizeof(dos), NULL, NULL))
+ goto errexit;
+
+ if (dos.e_magic != IMAGE_DOS_SIGNATURE)
+ goto errexit;
+
+ if (SetFilePointer(hfile, dos.e_lfanew, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
+ goto errexit;
+
+ if (!ReadFile(hfile, &os2, sizeof(os2), NULL, NULL))
+ goto errexit;
+
+ if (os2.ne_magic != IMAGE_OS2_SIGNATURE)
+ goto errexit;
+
+ resource_shift = os2.ne_align;
+
+ if (os2.ne_rsrctab >= os2.ne_restab)
+ goto errexit;
+
+ if (SetFilePointer(hfile, dos.e_lfanew + os2.ne_rsrctab + 2, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
+ goto errexit;
+
+ while (ReadFile(hfile, &type, sizeof(type), NULL, NULL))
+ {
+ if (!type.type_id) break;
+
+ if (!ReadFile(hfile, &name, sizeof(name), NULL, NULL))
+ goto errexit;
+
+ switch (type.type_id)
+ {
+ case NE_RSCTYPE_FONTDIR:
+ fontdir_off = name.offset << resource_shift;
+ fontdir_len = name.length << resource_shift;
+ break;
+
+ case NE_RSCTYPE_SCALABLE_FONTPATH:
+ fontpath_off = name.offset << resource_shift;
+ fontpath_len = name.length << resource_shift;
+ break;
+ }
+ }
+
+ if (!fontdir_off || !fontpath_off)
+ goto errexit;
+
+ if (SetFilePointer(hfile, fontdir_off, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
+ goto errexit;
+
+ memset(&fd, 0, sizeof(fd));
+ if (fontdir_len > sizeof(fd)) fontdir_len = sizeof(fd);
+ if (!ReadFile(hfile, &fd, fontdir_len, NULL, NULL))
+ goto errexit;
+
+ if (SetFilePointer(hfile, fontpath_off, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
+ goto errexit;
+
+ fot_path = HeapAlloc(GetProcessHeap(), 0, fontpath_len);
+ if (!fot_path)
+ goto errexit;
+
+ if (!ReadFile(hfile, fot_path, fontpath_len, NULL, NULL))
+ goto errexit;
+
+ len = MultiByteToWideChar(CP_ACP, 0, fot_path, -1, NULL, 0);
+ wide_path = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, fot_path, -1, wide_path, len);
+
+ ret = wine_get_unix_file_name(wide_path);
+
+errexit:
+ CloseHandle(hfile);
+
+ HeapFree(GetProcessHeap(), 0, fot_path);
+ HeapFree(GetProcessHeap(), 0, wide_path);
+
+ TRACE("-> %s\n", ret);
+
+ return ret;
+}
+
/*
This function builds an FT_Fixed from a double. It fails if the absolute
value of the float number is greater than 32768.
@@ -1458,10 +1566,21 @@ static int load_font(const char *file, void *font_data_ptr, DWORD font_data_size
err = pFT_New_Memory_Face(library, font_data_ptr, font_data_size, face_index, &ft_face);
}
- if(err != 0) {
- WARN("Unable to load font %s/%p err = %x\n", debugstr_a(file), font_data_ptr, err);
- return 0;
- }
+ if (err != 0)
+ {
+ char *scalable_rsrc_name;
+
+ scalable_rsrc_name = get_scalable_resource_name(file, font_data_ptr, font_data_size);
+ if (scalable_rsrc_name)
+ {
+ int ret = load_font(scalable_rsrc_name, NULL, 0, flist, flags);
+ HeapFree(GetProcessHeap(), 0, scalable_rsrc_name);
+ return ret;
+ }
+
+ WARN("Unable to load font %s/%p err = %x\n", debugstr_a(file), font_data_ptr, err);
+ return 0;
+ }
if(!FT_IS_SFNT(ft_face) && (FT_IS_SCALABLE(ft_face) || !(flags & ADDFONT_FORCE_BITMAP))) { /* for now we'll accept TT/OT or bitmap fonts*/
WARN("Ignoring font %s/%p\n", debugstr_a(file), font_data_ptr);
--
1.7.0.6
More information about the wine-patches
mailing list