Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
4cddf0d4
Commit
4cddf0d4
authored
Nov 04, 2020
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gdi32: Move the handling of font family fallbacks out of freetype.c.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
caf0b9c0
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
90 additions
and
103 deletions
+90
-103
font.c
dlls/gdi32/font.c
+48
-23
freetype.c
dlls/gdi32/freetype.c
+41
-77
gdi_private.h
dlls/gdi32/gdi_private.h
+1
-3
No files found.
dlls/gdi32/font.c
View file @
4cddf0d4
...
...
@@ -240,32 +240,25 @@ static const WCHAR liberation_sans[] = {'L','i','b','e','r','a','t','i','o','n',
static
const
WCHAR
liberation_serif
[]
=
{
'L'
,
'i'
,
'b'
,
'e'
,
'r'
,
'a'
,
't'
,
'i'
,
'o'
,
'n'
,
' '
,
'S'
,
'e'
,
'r'
,
'i'
,
'f'
,
0
};
static
const
WCHAR
times_new_roman
[]
=
{
'T'
,
'i'
,
'm'
,
'e'
,
's'
,
' '
,
'N'
,
'e'
,
'w'
,
' '
,
'R'
,
'o'
,
'm'
,
'a'
,
'n'
,
0
};
static
const
WCHAR
*
const
default_serif_list
[]
=
static
const
WCHAR
*
const
default_serif_list
[
3
]
=
{
times_new_roman
,
liberation_serif
,
bitstream_vera_serif
,
NULL
bitstream_vera_serif
};
static
const
WCHAR
*
const
default_fixed_list
[]
=
static
const
WCHAR
*
const
default_fixed_list
[
3
]
=
{
courier_new
,
liberation_mono
,
bitstream_vera_sans_mono
,
NULL
bitstream_vera_sans_mono
};
static
const
WCHAR
*
const
default_sans_list
[]
=
static
const
WCHAR
*
const
default_sans_list
[
3
]
=
{
arial
,
liberation_sans
,
bitstream_vera_sans
,
NULL
bitstream_vera_sans
};
const
WCHAR
*
default_serif
=
times_new_roman
;
const
WCHAR
*
default_fixed
=
courier_new
;
const
WCHAR
*
default_sans
=
arial
;
static
const
struct
nls_update_font_list
{
UINT
ansi_cp
,
oem_cp
;
...
...
@@ -732,26 +725,44 @@ static void dump_gdi_font_list(void)
}
}
static
const
WCHAR
*
set_default_family
(
const
WCHAR
*
const
*
name_list
)
static
BOOL
enum_fallbacks
(
DWORD
pitch_and_family
,
int
index
,
WCHAR
buffer
[
LF_FACESIZE
]
)
{
if
(
index
<
3
)
{
const
WCHAR
*
const
*
defaults
;
if
((
pitch_and_family
&
FIXED_PITCH
)
||
(
pitch_and_family
&
0xf0
)
==
FF_MODERN
)
defaults
=
default_fixed_list
;
else
if
((
pitch_and_family
&
0xf0
)
==
FF_ROMAN
)
defaults
=
default_serif_list
;
else
defaults
=
default_sans_list
;
lstrcpynW
(
buffer
,
defaults
[
index
],
LF_FACESIZE
);
return
TRUE
;
}
return
font_funcs
->
enum_family_fallbacks
(
pitch_and_family
,
index
-
3
,
buffer
);
}
static
void
set_default_family
(
DWORD
pitch_and_family
)
{
struct
gdi_font_family
*
family
;
const
WCHAR
*
const
*
entry
;
WCHAR
name
[
LF_FACESIZE
];
int
i
=
0
;
for
(
entry
=
name_list
;
*
entry
;
entry
++
)
while
(
enum_fallbacks
(
pitch_and_family
,
i
++
,
name
)
)
{
if
(
!
(
family
=
find_family_from_name
(
*
entry
)))
continue
;
if
(
!
(
family
=
find_family_from_name
(
name
)))
continue
;
list_remove
(
&
family
->
entry
);
list_add_head
(
&
font_list
,
&
family
->
entry
);
return
*
entry
;
return
;
}
return
*
name_list
;
}
static
void
reorder_font_list
(
void
)
{
default_serif
=
set_default_family
(
default_serif_list
);
default_fixed
=
set_default_family
(
default_fixed_list
);
default_sans
=
set_default_family
(
default_sans_list
);
set_default_family
(
FF_ROMAN
);
set_default_family
(
FF_MODERN
);
set_default_family
(
FF_SWISS
);
}
static
void
release_face
(
struct
gdi_font_face
*
face
)
...
...
@@ -1483,14 +1494,28 @@ struct gdi_font_face *find_any_face( const LOGFONTW *lf, FONTSIGNATURE fs,
{
struct
gdi_font_family
*
family
;
struct
gdi_font_face
*
face
;
WCHAR
name
[
LF_FACESIZE
];
int
i
=
0
;
/* first try only scalable */
/* first try the family fallbacks */
while
(
enum_fallbacks
(
lf
->
lfPitchAndFamily
,
i
++
,
name
))
{
LIST_FOR_EACH_ENTRY
(
family
,
&
font_list
,
struct
gdi_font_family
,
entry
)
{
if
((
family
->
family_name
[
0
]
==
'@'
)
==
!
want_vertical
)
continue
;
if
(
strcmpiW
(
family
->
family_name
+
want_vertical
,
name
)
&&
strcmpiW
(
family
->
second_name
+
want_vertical
,
name
))
continue
;
if
((
face
=
find_best_matching_face
(
family
,
lf
,
fs
,
FALSE
)))
return
face
;
}
}
/* otherwise try only scalable */
LIST_FOR_EACH_ENTRY
(
family
,
&
font_list
,
struct
gdi_font_family
,
entry
)
{
if
((
family
->
family_name
[
0
]
==
'@'
)
==
!
want_vertical
)
continue
;
if
((
face
=
find_best_matching_face
(
family
,
lf
,
fs
,
FALSE
)))
return
face
;
}
if
(
!
can_use_bitmap
)
return
NULL
;
/* then also bitmap fonts */
LIST_FOR_EACH_ENTRY
(
family
,
&
font_list
,
struct
gdi_font_family
,
entry
)
{
if
((
family
->
family_name
[
0
]
==
'@'
)
==
!
want_vertical
)
continue
;
...
...
dlls/gdi32/freetype.c
View file @
4cddf0d4
...
...
@@ -1218,6 +1218,9 @@ static BOOL ReadFontDir(const char *dirname, BOOL external_fonts)
#ifdef SONAME_LIBFONTCONFIG
static
BOOL
fontconfig_enabled
;
static
FcPattern
*
pattern_serif
;
static
FcPattern
*
pattern_fixed
;
static
FcPattern
*
pattern_sans
;
static
UINT
parse_aa_pattern
(
FcPattern
*
pattern
)
{
...
...
@@ -1242,6 +1245,23 @@ static UINT parse_aa_pattern( FcPattern *pattern )
return
aa_flags
;
}
static
FcPattern
*
create_family_pattern
(
const
char
*
name
)
{
FcPattern
*
ret
,
*
pattern
=
pFcPatternCreate
();
FcResult
result
;
pFcPatternAddString
(
pattern
,
FC_FAMILY
,
(
const
FcChar8
*
)
name
);
pFcPatternAddString
(
pattern
,
FC_NAMELANG
,
(
const
FcChar8
*
)
"en-us"
);
pFcPatternAddString
(
pattern
,
FC_PRGNAME
,
(
const
FcChar8
*
)
"wine"
);
pFcConfigSubstitute
(
NULL
,
pattern
,
FcMatchPattern
);
pFcDefaultSubstitute
(
pattern
);
ret
=
pFcFontMatch
(
NULL
,
pattern
,
&
result
);
pFcPatternDestroy
(
pattern
);
if
(
ret
&&
result
==
FcResultMatch
)
return
ret
;
pFcPatternDestroy
(
ret
);
return
NULL
;
}
static
void
init_fontconfig
(
void
)
{
void
*
fc_handle
=
dlopen
(
SONAME_LIBFONTCONFIG
,
RTLD_NOW
);
...
...
@@ -1281,6 +1301,9 @@ static void init_fontconfig(void)
default_aa_flags
=
parse_aa_pattern
(
pattern
);
pFcPatternDestroy
(
pattern
);
}
pattern_serif
=
create_family_pattern
(
"serif"
);
pattern_fixed
=
create_family_pattern
(
"monospace"
);
pattern_sans
=
create_family_pattern
(
"sans"
);
TRACE
(
"enabled, default flags = %x
\n
"
,
default_aa_flags
);
fontconfig_enabled
=
TRUE
;
...
...
@@ -2070,67 +2093,28 @@ done:
return
ret
;
}
#ifdef SONAME_LIBFONTCONFIG
static
struct
gdi_font_face
*
get_fontconfig_face
(
const
LOGFONTW
*
lf
,
FONTSIGNATURE
fs
,
BOOL
want_vertical
)
/*************************************************************
* fontconfig_enum_family_fallbacks
*/
static
BOOL
CDECL
fontconfig_enum_family_fallbacks
(
DWORD
pitch_and_family
,
int
index
,
WCHAR
buffer
[
LF_FACESIZE
]
)
{
const
char
*
name
;
WCHAR
nameW
[
LF_FACESIZE
]
;
#ifdef SONAME_LIBFONTCONFIG
FcPattern
*
pat
;
FcChar8
*
str
;
FcPattern
*
pat
=
NULL
,
*
best
=
NULL
;
FcResult
result
;
FcBool
r
;
int
ret
,
i
;
struct
gdi_font_face
*
face
=
NULL
;
if
(
!
fs
.
fsCsb
[
0
])
return
NULL
;
if
((
lf
->
lfPitchAndFamily
&
FIXED_PITCH
)
||
(
lf
->
lfPitchAndFamily
&
0xF0
)
==
FF_MODERN
)
name
=
"monospace"
;
else
if
((
lf
->
lfPitchAndFamily
&
0xF0
)
==
FF_ROMAN
)
name
=
"serif"
;
else
name
=
"sans-serif"
;
if
((
pitch_and_family
&
FIXED_PITCH
)
||
(
pitch_and_family
&
0xf0
)
==
FF_MODERN
)
pat
=
pattern_fixed
;
else
if
((
pitch_and_family
&
0xf0
)
==
FF_ROMAN
)
pat
=
pattern_serif
;
else
pat
=
pattern_sans
;
pat
=
pFcPatternCreate
();
if
(
!
pat
)
return
NULL
;
r
=
pFcPatternAddString
(
pat
,
FC_FAMILY
,
(
const
FcChar8
*
)
name
);
if
(
!
r
)
goto
end
;
r
=
pFcPatternAddString
(
pat
,
FC_NAMELANG
,
(
const
FcChar8
*
)
"en-us"
);
if
(
!
r
)
goto
end
;
r
=
pFcPatternAddString
(
pat
,
FC_PRGNAME
,
(
const
FcChar8
*
)
"wine"
);
if
(
!
r
)
goto
end
;
r
=
pFcConfigSubstitute
(
NULL
,
pat
,
FcMatchPattern
);
if
(
!
r
)
goto
end
;
pFcDefaultSubstitute
(
pat
);
best
=
pFcFontMatch
(
NULL
,
pat
,
&
result
);
if
(
!
best
||
result
!=
FcResultMatch
)
goto
end
;
for
(
i
=
0
;
pFcPatternGetString
(
best
,
FC_FAMILY
,
i
,
&
str
)
==
FcResultMatch
;
i
++
)
{
if
(
!
want_vertical
)
{
ret
=
MultiByteToWideChar
(
CP_UTF8
,
0
,
(
const
char
*
)
str
,
-
1
,
nameW
,
ARRAY_SIZE
(
nameW
));
}
else
{
nameW
[
0
]
=
'@'
;
ret
=
MultiByteToWideChar
(
CP_UTF8
,
0
,
(
const
char
*
)
str
,
-
1
,
nameW
+
1
,
ARRAY_SIZE
(
nameW
)
-
1
);
}
if
(
!
ret
)
continue
;
if
((
face
=
find_matching_face_by_name
(
nameW
,
NULL
,
lf
,
fs
,
FALSE
)))
break
;
}
if
(
face
)
TRACE
(
"got %s
\n
"
,
wine_dbgstr_w
(
nameW
));
end:
pFcPatternDestroy
(
pat
);
pFcPatternDestroy
(
best
);
return
face
;
}
if
(
!
pat
)
return
FALSE
;
if
(
pFcPatternGetString
(
pat
,
FC_FAMILY
,
index
,
&
str
)
!=
FcResultMatch
)
return
FALSE
;
if
(
!
MultiByteToWideChar
(
CP_UTF8
,
0
,
(
char
*
)
str
,
-
1
,
buffer
,
LF_FACESIZE
))
buffer
[
LF_FACESIZE
-
1
]
=
0
;
return
TRUE
;
#endif
return
FALSE
;
}
static
DWORD
get_ttc_offset
(
FT_Face
ft_face
,
UINT
face_index
)
{
...
...
@@ -2340,27 +2324,6 @@ static struct gdi_font * CDECL freetype_SelectFont( DC *dc, HFONT hfont )
want_vertical
=
(
lf
.
lfFaceName
[
0
]
==
'@'
);
/* Face families are in the top 4 bits of lfPitchAndFamily,
so mask with 0xF0 before testing */
if
((
lf
.
lfPitchAndFamily
&
FIXED_PITCH
)
||
(
lf
.
lfPitchAndFamily
&
0xF0
)
==
FF_MODERN
)
strcpyW
(
lf
.
lfFaceName
,
default_fixed
);
else
if
((
lf
.
lfPitchAndFamily
&
0xF0
)
==
FF_ROMAN
)
strcpyW
(
lf
.
lfFaceName
,
default_serif
);
else
if
((
lf
.
lfPitchAndFamily
&
0xF0
)
==
FF_SWISS
)
strcpyW
(
lf
.
lfFaceName
,
default_sans
);
else
strcpyW
(
lf
.
lfFaceName
,
default_sans
);
if
((
face
=
find_matching_face_by_name
(
lf
.
lfFaceName
,
NULL
,
&
lf
,
csi
.
fs
,
can_use_bitmap
)))
goto
found_face
;
#ifdef SONAME_LIBFONTCONFIG
/* Try FontConfig substitutions if the face isn't found */
if
((
face
=
get_fontconfig_face
(
&
lf
,
csi
.
fs
,
want_vertical
)))
goto
found_face
;
#endif
if
((
face
=
find_any_face
(
&
lf
,
csi
.
fs
,
can_use_bitmap
,
want_vertical
)))
goto
found_face
;
csi
.
fs
.
fsCsb
[
0
]
=
0
;
if
((
face
=
find_any_face
(
&
lf
,
csi
.
fs
,
can_use_bitmap
,
want_vertical
)))
goto
found_face
;
...
...
@@ -4231,6 +4194,7 @@ static const struct font_backend_funcs font_funcs =
{
freetype_SelectFont
,
freetype_load_fonts
,
fontconfig_enum_family_fallbacks
,
freetype_add_font
,
freetype_add_mem_font
,
freetype_load_font
,
...
...
dlls/gdi32/gdi_private.h
View file @
4cddf0d4
...
...
@@ -428,6 +428,7 @@ struct font_backend_funcs
struct
gdi_font
*
(
CDECL
*
pSelectFont
)(
DC
*
dc
,
HFONT
hfont
);
void
(
CDECL
*
load_fonts
)(
void
);
BOOL
(
CDECL
*
enum_family_fallbacks
)(
DWORD
pitch_and_family
,
int
index
,
WCHAR
buffer
[
LF_FACESIZE
]
);
INT
(
CDECL
*
add_font
)(
const
WCHAR
*
file
,
DWORD
flags
);
INT
(
CDECL
*
add_mem_font
)(
void
*
ptr
,
SIZE_T
size
,
DWORD
flags
);
...
...
@@ -474,9 +475,6 @@ extern struct gdi_font *create_gdi_font( const struct gdi_font_face *face, const
const
LOGFONTW
*
lf
)
DECLSPEC_HIDDEN
;
extern
void
*
get_GSUB_vert_feature
(
struct
gdi_font
*
font
)
DECLSPEC_HIDDEN
;
extern
void
font_init
(
void
)
DECLSPEC_HIDDEN
;
extern
const
WCHAR
*
default_serif
DECLSPEC_HIDDEN
;
extern
const
WCHAR
*
default_fixed
DECLSPEC_HIDDEN
;
extern
const
WCHAR
*
default_sans
DECLSPEC_HIDDEN
;
/* freetype.c */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment