Module: wine Branch: master Commit: 4e6860433e72714ed1e500eb523710656e71ba02 URL: http://source.winehq.org/git/wine.git/?a=commit;h=4e6860433e72714ed1e500eb52...
Author: Huw Davies huw@codeweavers.com Date: Thu Dec 21 15:21:13 2006 +0000
gdi32: Extract the constituent TrueType files from Mac suitcase fonts into the user's caches directory and use these instead of the original suitcase.
---
configure | 6 +- configure.ac | 1 + dlls/gdi32/Makefile.in | 2 +- dlls/gdi32/freetype.c | 257 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 264 insertions(+), 2 deletions(-)
diff --git a/configure b/configure index 6779121..3e9b56e 100755 --- a/configure +++ b/configure @@ -759,6 +759,7 @@ IOKITLIB LDEXECFLAGS DISKARBITRATIONLIB COREAUDIO +CARBONLIB CROSSTEST CROSSCC CROSSWINDRES @@ -13462,6 +13463,8 @@ fi esac if test "$ac_cv_header_Carbon_Carbon_h" = "yes" then + CARBONLIB="-framework Carbon" + QUARTZFILES='$(QUARTZFILES)' fi ;; @@ -21426,6 +21429,7 @@ IOKITLIB!$IOKITLIB$ac_delim LDEXECFLAGS!$LDEXECFLAGS$ac_delim DISKARBITRATIONLIB!$DISKARBITRATIONLIB$ac_delim COREAUDIO!$COREAUDIO$ac_delim +CARBONLIB!$CARBONLIB$ac_delim CROSSTEST!$CROSSTEST$ac_delim CROSSCC!$CROSSCC$ac_delim CROSSWINDRES!$CROSSWINDRES$ac_delim @@ -21442,7 +21446,7 @@ LIBOBJS!$LIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF
- if test `sed -n "s/.*$ac_delim$/X/p" conf$$subs.sed | grep -c X` = 76; then + if test `sed -n "s/.*$ac_delim$/X/p" conf$$subs.sed | grep -c X` = 77; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 diff --git a/configure.ac b/configure.ac index efbf32d..9fc757b 100644 --- a/configure.ac +++ b/configure.ac @@ -1023,6 +1023,7 @@ case $host_os in dnl Enable quartz driver on Mac OS X if test "$ac_cv_header_Carbon_Carbon_h" = "yes" then + AC_SUBST(CARBONLIB,"-framework Carbon") QUARTZFILES='$(QUARTZFILES)' fi ;; diff --git a/dlls/gdi32/Makefile.in b/dlls/gdi32/Makefile.in index df6f89b..e3b2d67 100644 --- a/dlls/gdi32/Makefile.in +++ b/dlls/gdi32/Makefile.in @@ -7,7 +7,7 @@ MODULE = gdi32.dll IMPORTLIB = libgdi32.$(IMPLIBEXT) IMPORTS = advapi32 kernel32 ntdll EXTRAINCL = @FREETYPEINCL@ -EXTRALIBS = @ICULIBS@ +EXTRALIBS = @ICULIBS@ @CARBONLIB@
SPEC_SRCS16 = \ dispdib.spec \ diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c index 84daf4f..b9a46bc 100644 --- a/dlls/gdi32/freetype.c +++ b/dlls/gdi32/freetype.c @@ -37,6 +37,44 @@ #include <stdio.h> #include <assert.h>
+#ifdef HAVE_CARBON_CARBON_H +#define LoadResource __carbon_LoadResource +#define CompareString __carbon_CompareString +#define GetCurrentThread __carbon_GetCurrentThread +#define GetCurrentProcess __carbon_GetCurrentProcess +#define AnimatePalette __carbon_AnimatePalette +#define EqualRgn __carbon_EqualRgn +#define FillRgn __carbon_FillRgn +#define FrameRgn __carbon_FrameRgn +#define GetPixel __carbon_GetPixel +#define InvertRgn __carbon_InvertRgn +#define LineTo __carbon_LineTo +#define OffsetRgn __carbon_OffsetRgn +#define PaintRgn __carbon_PaintRgn +#define Polygon __carbon_Polygon +#define ResizePalette __carbon_ResizePalette +#define SetRectRgn __carbon_SetRectRgn +#include <Carbon/Carbon.h> +#undef LoadResource +#undef CompareString +#undef GetCurrentThread +#undef _CDECL +#undef DPRINTF +#undef GetCurrentProcess +#undef AnimatePalette +#undef EqualRgn +#undef FillRgn +#undef FrameRgn +#undef GetPixel +#undef InvertRgn +#undef LineTo +#undef OffsetRgn +#undef PaintRgn +#undef Polygon +#undef ResizePalette +#undef SetRectRgn +#endif /* HAVE_CARBON_CARBON_H */ + #include "windef.h" #include "winbase.h" #include "winternl.h" @@ -438,6 +476,204 @@ static const WCHAR font_mutex_nameW[] = * cga40woa.fon=cga40850.fon */
+#ifdef HAVE_CARBON_CARBON_H +static char *find_cache_dir(void) +{ + FSRef ref; + OSErr err; + static char cached_path[MAX_PATH]; + static const char *wine = "/Wine", *fonts = "/Fonts"; + + if(*cached_path) return cached_path; + + err = FSFindFolder(kUserDomain, kCachedDataFolderType, kCreateFolder, &ref); + if(err != noErr) + { + WARN("can't create cached data folder\n"); + return NULL; + } + err = FSRefMakePath(&ref, (unsigned char*)cached_path, sizeof(cached_path)); + if(err != noErr) + { + WARN("can't create cached data path\n"); + *cached_path = '\0'; + return NULL; + } + if(strlen(cached_path) + strlen(wine) + strlen(fonts) + 1 > sizeof(cached_path)) + { + ERR("Could not create full path\n"); + *cached_path = '\0'; + return NULL; + } + strcat(cached_path, wine); + + if(mkdir(cached_path, 0700) == -1 && errno != EEXIST) + { + WARN("Couldn't mkdir %s\n", cached_path); + *cached_path = '\0'; + return NULL; + } + strcat(cached_path, fonts); + if(mkdir(cached_path, 0700) == -1 && errno != EEXIST) + { + WARN("Couldn't mkdir %s\n", cached_path); + *cached_path = '\0'; + return NULL; + } + return cached_path; +} + +/****************************************************************** + * expand_mac_font + * + * Extracts individual TrueType font files from a Mac suitcase font + * and saves them into the user's caches directory (see + * find_cache_dir()). + * Returns a NULL terminated array of filenames. + * + * We do this because they are apps that try to read ttf files + * themselves and they don't like Mac suitcase files. + */ +static char **expand_mac_font(const char *path) +{ + FSRef ref; + SInt16 res_ref; + OSStatus s; + unsigned int idx; + const char *out_dir; + const char *filename; + int output_len; + struct { + char **array; + unsigned int size, max_size; + } ret; + + TRACE("path %s\n", path); + + s = FSPathMakeRef((unsigned char*)path, &ref, FALSE); + if(s != noErr) + { + WARN("failed to get ref\n"); + return NULL; + } + + s = FSOpenResourceFile(&ref, 0, NULL, fsRdPerm, &res_ref); + if(s != noErr) + { + TRACE("no data fork, so trying resource fork\n"); + res_ref = FSOpenResFile(&ref, fsRdPerm); + if(res_ref == -1) + { + TRACE("unable to open resource fork\n"); + return NULL; + } + } + + ret.size = 0; + ret.max_size = 10; + ret.array = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ret.max_size * sizeof(*ret.array)); + if(!ret.array) + { + CloseResFile(res_ref); + return NULL; + } + + out_dir = find_cache_dir(); + + filename = strrchr(path, '/'); + if(!filename) filename = path; + else filename++; + + /* output filename has the form out_dir/filename_%04x.ttf */ + output_len = strlen(out_dir) + 1 + strlen(filename) + 5 + 5; + + UseResFile(res_ref); + idx = 1; + while(1) + { + FamRec *fam_rec; + unsigned short *num_faces_ptr, num_faces, face; + AsscEntry *assoc; + Handle fond; + + fond = Get1IndResource('FOND', idx); + if(!fond) break; + TRACE("got fond resource %d\n", idx); + HLock(fond); + + fam_rec = *(FamRec**)fond; + num_faces_ptr = (unsigned short *)(fam_rec + 1); + num_faces = GET_BE_WORD(*num_faces_ptr); + num_faces++; + assoc = (AsscEntry*)(num_faces_ptr + 1); + TRACE("num faces %04x\n", num_faces); + for(face = 0; face < num_faces; face++, assoc++) + { + Handle sfnt; + unsigned short size, font_id; + char *output; + + size = GET_BE_WORD(assoc->fontSize); + font_id = GET_BE_WORD(assoc->fontID); + if(size != 0) + { + TRACE("skipping id %04x because it's not scalable (fixed size %d)\n", font_id, size); + continue; + } + + TRACE("trying to load sfnt id %04x\n", font_id); + sfnt = GetResource('sfnt', font_id); + if(!sfnt) + { + TRACE("can't get sfnt resource %04x\n", font_id); + continue; + } + + output = HeapAlloc(GetProcessHeap(), 0, output_len); + if(output) + { + int fd; + + sprintf(output, "%s/%s_%04x.ttf", out_dir, filename, font_id); + + fd = open(output, O_CREAT | O_EXCL | O_WRONLY, 0600); + if(fd != -1 || errno == EEXIST) + { + if(fd != -1) + { + unsigned char *sfnt_data; + + HLock(sfnt); + sfnt_data = *(unsigned char**)sfnt; + write(fd, sfnt_data, GetHandleSize(sfnt)); + HUnlock(sfnt); + close(fd); + } + if(ret.size >= ret.max_size - 1) /* Always want the last element to be NULL */ + { + ret.max_size *= 2; + ret.array = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ret.array, ret.max_size * sizeof(*ret.array)); + } + ret.array[ret.size++] = output; + } + else + { + WARN("unable to create %s\n", output); + HeapFree(GetProcessHeap(), 0, output); + } + } + ReleaseResource(sfnt); + } + HUnlock(fond); + ReleaseResource(fond); + idx++; + } + CloseResFile(res_ref); + + return ret.array; +} + +#endif /* HAVE_CARBON_CARBON_H */
static inline BOOL is_win9x(void) { @@ -722,6 +958,27 @@ static BOOL AddFontFileToList(const char int i, bitmap_num, internal_leading; FONTSIGNATURE fs;
+#ifdef HAVE_CARBON_CARBON_H + if(!fake_family) + { + char **mac_list = expand_mac_font(file); + if(mac_list) + { + BOOL had_one = FALSE; + char **cursor; + for(cursor = mac_list; *cursor; cursor++) + { + had_one = TRUE; + AddFontFileToList(*cursor, NULL, flags); + HeapFree(GetProcessHeap(), 0, *cursor); + } + HeapFree(GetProcessHeap(), 0, mac_list); + if(had_one) + return TRUE; + } + } +#endif /* HAVE_CARBON_CARBON_H */ + do { char *family_name = fake_family;