gdi32: Extract the constituent TrueType files from Mac suitcase fonts into the user's caches directory
and use these instead of the original suitcase.
This commit is contained in:
parent
8cfd025164
commit
4e6860433e
|
@ -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
|
||||
|
|
|
@ -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
|
||||
;;
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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[] = {'_','_','W','I','N','E','_','F','O','N'
|
|||
* 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 *file, char *fake_family, DWORD flags)
|
|||
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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue