gdi32: Move the loading of font replacements out of freetype.c.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
5537f38e97
commit
d27a9d77ee
|
@ -551,6 +551,85 @@ struct gdi_font_family *find_family_from_any_name( const WCHAR *name )
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL add_family_replacement( const WCHAR *new_name, const WCHAR *replace )
|
||||||
|
{
|
||||||
|
struct gdi_font_family *new_family, *family;
|
||||||
|
struct gdi_font_face *face;
|
||||||
|
WCHAR new_name_vert[LF_FACESIZE], replace_vert[LF_FACESIZE];
|
||||||
|
|
||||||
|
if (!(family = find_family_from_any_name( replace )))
|
||||||
|
{
|
||||||
|
TRACE( "%s is not available. Skip this replacement.\n", debugstr_w(replace) );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(new_family = create_family( new_name, NULL ))) return FALSE;
|
||||||
|
new_family->replacement = &family->faces;
|
||||||
|
TRACE( "mapping %s to %s\n", debugstr_w(replace), debugstr_w(new_name) );
|
||||||
|
|
||||||
|
/* also add replacement for vertical font if necessary */
|
||||||
|
if (replace[0] == '@') return TRUE;
|
||||||
|
if (list_empty( &family->faces )) return TRUE;
|
||||||
|
face = LIST_ENTRY( list_head(&family->faces), struct gdi_font_face, entry );
|
||||||
|
if (!(face->fs.fsCsb[0] & FS_DBCS_MASK)) return TRUE;
|
||||||
|
|
||||||
|
new_name_vert[0] = '@';
|
||||||
|
lstrcpynW( new_name_vert + 1, new_name, LF_FACESIZE - 1 );
|
||||||
|
if (find_family_from_any_name( new_name_vert )) return TRUE; /* already exists */
|
||||||
|
|
||||||
|
replace_vert[0] = '@';
|
||||||
|
lstrcpynW( replace_vert + 1, replace, LF_FACESIZE - 1 );
|
||||||
|
add_family_replacement( new_name_vert, replace_vert );
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The replacement list is a way to map an entire font
|
||||||
|
* family onto another family. For example adding
|
||||||
|
*
|
||||||
|
* [HKCU\Software\Wine\Fonts\Replacements]
|
||||||
|
* "Wingdings"="Winedings"
|
||||||
|
*
|
||||||
|
* would enumerate the Winedings font both as Winedings and
|
||||||
|
* Wingdings. However if a real Wingdings font is present the
|
||||||
|
* replacement does not take place.
|
||||||
|
*/
|
||||||
|
void load_gdi_font_replacements(void)
|
||||||
|
{
|
||||||
|
HKEY hkey;
|
||||||
|
DWORD i = 0, type, dlen, vlen;
|
||||||
|
WCHAR value[LF_FACESIZE], data[1024];
|
||||||
|
|
||||||
|
/* @@ Wine registry key: HKCU\Software\Wine\Fonts\Replacements */
|
||||||
|
if (RegOpenKeyA( wine_fonts_key, "Replacements", &hkey )) return;
|
||||||
|
|
||||||
|
dlen = sizeof(data);
|
||||||
|
vlen = ARRAY_SIZE(value);
|
||||||
|
while (!RegEnumValueW( hkey, i++, value, &vlen, NULL, &type, (BYTE *)data, &dlen ))
|
||||||
|
{
|
||||||
|
/* "NewName"="Oldname" */
|
||||||
|
if (!find_family_from_any_name( value ))
|
||||||
|
{
|
||||||
|
if (type == REG_MULTI_SZ)
|
||||||
|
{
|
||||||
|
WCHAR *replace = data;
|
||||||
|
while (*replace)
|
||||||
|
{
|
||||||
|
if (add_family_replacement( value, replace )) break;
|
||||||
|
replace += strlenW(replace) + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type == REG_SZ) add_family_replacement( value, data );
|
||||||
|
}
|
||||||
|
else TRACE("%s is available. Skip this replacement.\n", debugstr_w(value));
|
||||||
|
|
||||||
|
/* reset dlen and vlen */
|
||||||
|
dlen = sizeof(data);
|
||||||
|
vlen = ARRAY_SIZE(value);
|
||||||
|
}
|
||||||
|
RegCloseKey( hkey );
|
||||||
|
}
|
||||||
|
|
||||||
struct gdi_font_face *create_face( const WCHAR *style, const WCHAR *fullname, const WCHAR *file,
|
struct gdi_font_face *create_face( const WCHAR *style, const WCHAR *fullname, const WCHAR *file,
|
||||||
UINT index, FONTSIGNATURE fs, DWORD ntmflags, DWORD version,
|
UINT index, FONTSIGNATURE fs, DWORD ntmflags, DWORD version,
|
||||||
DWORD flags, const struct bitmap_font_size *size )
|
DWORD flags, const struct bitmap_font_size *size )
|
||||||
|
|
|
@ -235,8 +235,6 @@ typedef struct {
|
||||||
|
|
||||||
typedef struct gdi_font_face Face;
|
typedef struct gdi_font_face Face;
|
||||||
|
|
||||||
#define FS_DBCS_MASK (FS_JISJAPAN|FS_CHINESESIMP|FS_WANSUNG|FS_CHINESETRAD|FS_JOHAB)
|
|
||||||
|
|
||||||
typedef struct gdi_font_family Family;
|
typedef struct gdi_font_family Family;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -365,7 +363,6 @@ static const WCHAR font_mutex_nameW[] = {'_','_','W','I','N','E','_','F','O','N'
|
||||||
|
|
||||||
static const WCHAR szDefaultFallbackLink[] = {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f',0};
|
static const WCHAR szDefaultFallbackLink[] = {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f',0};
|
||||||
|
|
||||||
static BOOL map_font_family(const WCHAR *orig, const WCHAR *repl);
|
|
||||||
static BOOL CDECL freetype_set_outline_text_metrics( struct gdi_font *font );
|
static BOOL CDECL freetype_set_outline_text_metrics( struct gdi_font *font );
|
||||||
static BOOL CDECL freetype_set_bitmap_text_metrics( struct gdi_font *font );
|
static BOOL CDECL freetype_set_bitmap_text_metrics( struct gdi_font *font );
|
||||||
static void remove_face_from_cache( Face *face );
|
static void remove_face_from_cache( Face *face );
|
||||||
|
@ -1735,117 +1732,6 @@ static void DumpFontList(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL map_vertical_font_family(const WCHAR *orig, const WCHAR *repl, const Family *family)
|
|
||||||
{
|
|
||||||
Face *face;
|
|
||||||
BOOL ret = FALSE;
|
|
||||||
WCHAR *at_orig, *at_repl = NULL;
|
|
||||||
|
|
||||||
face = LIST_ENTRY(list_head(&family->faces), Face, entry);
|
|
||||||
if (!face || !(face->fs.fsCsb[0] & FS_DBCS_MASK))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
at_orig = get_vertical_name( strdupW( orig ) );
|
|
||||||
if (at_orig && !find_family_from_any_name(at_orig))
|
|
||||||
{
|
|
||||||
at_repl = get_vertical_name( strdupW( repl ) );
|
|
||||||
if (at_repl)
|
|
||||||
ret = map_font_family(at_orig, at_repl);
|
|
||||||
}
|
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, at_orig);
|
|
||||||
HeapFree(GetProcessHeap(), 0, at_repl);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL map_font_family(const WCHAR *orig, const WCHAR *repl)
|
|
||||||
{
|
|
||||||
Family *family = find_family_from_any_name(repl);
|
|
||||||
if (family != NULL)
|
|
||||||
{
|
|
||||||
Family *new_family = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_family));
|
|
||||||
if (new_family != NULL)
|
|
||||||
{
|
|
||||||
TRACE("mapping %s to %s\n", debugstr_w(repl), debugstr_w(orig));
|
|
||||||
lstrcpynW( new_family->family_name, orig, LF_FACESIZE );
|
|
||||||
new_family->second_name[0] = 0;
|
|
||||||
list_init(&new_family->faces);
|
|
||||||
new_family->replacement = &family->faces;
|
|
||||||
list_add_tail(&font_list, &new_family->entry);
|
|
||||||
|
|
||||||
if (repl[0] != '@')
|
|
||||||
map_vertical_font_family(orig, repl, family);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TRACE("%s is not available. Skip this replacement.\n", debugstr_w(repl));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************
|
|
||||||
* The replacement list is a way to map an entire font
|
|
||||||
* family onto another family. For example adding
|
|
||||||
*
|
|
||||||
* [HKCU\Software\Wine\Fonts\Replacements]
|
|
||||||
* "Wingdings"="Winedings"
|
|
||||||
*
|
|
||||||
* would enumerate the Winedings font both as Winedings and
|
|
||||||
* Wingdings. However if a real Wingdings font is present the
|
|
||||||
* replacement does not take place.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static void LoadReplaceList(void)
|
|
||||||
{
|
|
||||||
HKEY hkey;
|
|
||||||
DWORD valuelen, datalen, i = 0, type, dlen, vlen;
|
|
||||||
LPWSTR value;
|
|
||||||
LPVOID data;
|
|
||||||
|
|
||||||
/* @@ Wine registry key: HKCU\Software\Wine\Fonts\Replacements */
|
|
||||||
if(RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Fonts\\Replacements", &hkey) == ERROR_SUCCESS)
|
|
||||||
{
|
|
||||||
RegQueryInfoKeyW(hkey, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
||||||
&valuelen, &datalen, NULL, NULL);
|
|
||||||
|
|
||||||
valuelen++; /* returned value doesn't include room for '\0' */
|
|
||||||
value = HeapAlloc(GetProcessHeap(), 0, valuelen * sizeof(WCHAR));
|
|
||||||
data = HeapAlloc(GetProcessHeap(), 0, datalen);
|
|
||||||
|
|
||||||
dlen = datalen;
|
|
||||||
vlen = valuelen;
|
|
||||||
while(RegEnumValueW(hkey, i++, value, &vlen, NULL, &type, data, &dlen) == ERROR_SUCCESS)
|
|
||||||
{
|
|
||||||
/* "NewName"="Oldname" */
|
|
||||||
if(!find_family_from_any_name(value))
|
|
||||||
{
|
|
||||||
if (type == REG_MULTI_SZ)
|
|
||||||
{
|
|
||||||
WCHAR *replace = data;
|
|
||||||
while(*replace)
|
|
||||||
{
|
|
||||||
if (map_font_family(value, replace))
|
|
||||||
break;
|
|
||||||
replace += strlenW(replace) + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (type == REG_SZ)
|
|
||||||
map_font_family(value, data);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
TRACE("%s is available. Skip this replacement.\n", debugstr_w(value));
|
|
||||||
|
|
||||||
/* reset dlen and vlen */
|
|
||||||
dlen = datalen;
|
|
||||||
vlen = valuelen;
|
|
||||||
}
|
|
||||||
HeapFree(GetProcessHeap(), 0, data);
|
|
||||||
HeapFree(GetProcessHeap(), 0, value);
|
|
||||||
RegCloseKey(hkey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static const WCHAR *font_links_list[] =
|
static const WCHAR *font_links_list[] =
|
||||||
{
|
{
|
||||||
Lucida_Sans_Unicode,
|
Lucida_Sans_Unicode,
|
||||||
|
@ -2780,7 +2666,7 @@ BOOL WineEngInit( const struct font_backend_funcs **funcs )
|
||||||
|
|
||||||
DumpFontList();
|
DumpFontList();
|
||||||
load_gdi_font_subst();
|
load_gdi_font_subst();
|
||||||
LoadReplaceList();
|
load_gdi_font_replacements();
|
||||||
|
|
||||||
if(disposition == REG_CREATED_NEW_KEY)
|
if(disposition == REG_CREATED_NEW_KEY)
|
||||||
update_reg_entries();
|
update_reg_entries();
|
||||||
|
|
|
@ -405,6 +405,8 @@ struct gdi_font
|
||||||
#define MS_TTCF_TAG MS_MAKE_TAG('t', 't', 'c', 'f')
|
#define MS_TTCF_TAG MS_MAKE_TAG('t', 't', 'c', 'f')
|
||||||
#define MS_VDMX_TAG MS_MAKE_TAG('V', 'D', 'M', 'X')
|
#define MS_VDMX_TAG MS_MAKE_TAG('V', 'D', 'M', 'X')
|
||||||
|
|
||||||
|
#define FS_DBCS_MASK (FS_JISJAPAN | FS_CHINESESIMP | FS_WANSUNG | FS_CHINESETRAD | FS_JOHAB)
|
||||||
|
|
||||||
#define ADDFONT_EXTERNAL_FONT 0x01
|
#define ADDFONT_EXTERNAL_FONT 0x01
|
||||||
#define ADDFONT_ALLOW_BITMAP 0x02
|
#define ADDFONT_ALLOW_BITMAP 0x02
|
||||||
#define ADDFONT_ADD_TO_CACHE 0x04
|
#define ADDFONT_ADD_TO_CACHE 0x04
|
||||||
|
@ -449,6 +451,7 @@ extern struct gdi_font_family *create_family( const WCHAR *name, const WCHAR *se
|
||||||
extern void release_family( struct gdi_font_family *family ) DECLSPEC_HIDDEN;
|
extern void release_family( struct gdi_font_family *family ) DECLSPEC_HIDDEN;
|
||||||
extern struct gdi_font_family *find_family_from_name( const WCHAR *name ) DECLSPEC_HIDDEN;
|
extern struct gdi_font_family *find_family_from_name( const WCHAR *name ) DECLSPEC_HIDDEN;
|
||||||
extern struct gdi_font_family *find_family_from_any_name( const WCHAR *name ) DECLSPEC_HIDDEN;
|
extern struct gdi_font_family *find_family_from_any_name( const WCHAR *name ) DECLSPEC_HIDDEN;
|
||||||
|
extern void load_gdi_font_replacements(void) DECLSPEC_HIDDEN;
|
||||||
extern struct gdi_font_face *create_face( const WCHAR *style, const WCHAR *fullname, const WCHAR *file,
|
extern struct gdi_font_face *create_face( const WCHAR *style, const WCHAR *fullname, const WCHAR *file,
|
||||||
UINT index, FONTSIGNATURE fs, DWORD ntmflags,
|
UINT index, FONTSIGNATURE fs, DWORD ntmflags,
|
||||||
DWORD version, DWORD flags, const struct bitmap_font_size *size ) DECLSPEC_HIDDEN;
|
DWORD version, DWORD flags, const struct bitmap_font_size *size ) DECLSPEC_HIDDEN;
|
||||||
|
|
Loading…
Reference in New Issue