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
e0872b64
Commit
e0872b64
authored
Oct 26, 2020
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gdi32: Move the text metrics cache into the generic font structure.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
a89595a2
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
298 additions
and
355 deletions
+298
-355
font.c
dlls/gdi32/font.c
+150
-9
freetype.c
dlls/gdi32/freetype.c
+142
-342
gdi_private.h
dlls/gdi32/gdi_private.h
+6
-4
No files found.
dlls/gdi32/font.c
View file @
e0872b64
...
...
@@ -463,14 +463,20 @@ void free_gdi_font( struct gdi_font *font )
if
(
font
->
private
)
font_funcs
->
destroy_font
(
font
);
free_font_handle
(
font
->
handle
);
for
(
i
=
0
;
i
<
font
->
gm_size
;
i
++
)
HeapFree
(
GetProcessHeap
(),
0
,
font
->
gm
[
i
]
);
HeapFree
(
GetProcessHeap
(),
0
,
font
->
otm
.
otmpFamilyName
);
HeapFree
(
GetProcessHeap
(),
0
,
font
->
otm
.
otmpStyleName
);
HeapFree
(
GetProcessHeap
(),
0
,
font
->
otm
.
otmpFaceName
);
HeapFree
(
GetProcessHeap
(),
0
,
font
->
otm
.
otmpFullName
);
HeapFree
(
GetProcessHeap
(),
0
,
font
->
gm
);
HeapFree
(
GetProcessHeap
(),
0
,
font
->
name
);
HeapFree
(
GetProcessHeap
(),
0
,
font
);
}
void
set_gdi_font_name
(
struct
gdi_font
*
font
,
const
WCHAR
*
name
)
void
set_gdi_font_names
(
struct
gdi_font
*
font
,
const
WCHAR
*
family_name
,
const
WCHAR
*
style_name
,
const
WCHAR
*
full_name
)
{
font
->
name
=
strdupW
(
name
);
font
->
otm
.
otmpFamilyName
=
(
char
*
)
strdupW
(
family_name
);
font
->
otm
.
otmpStyleName
=
(
char
*
)
strdupW
(
style_name
);
font
->
otm
.
otmpFaceName
=
(
char
*
)
strdupW
(
full_name
);
}
struct
glyph_metrics
...
...
@@ -1187,13 +1193,77 @@ static DWORD CDECL font_GetKerningPairs( PHYSDEV dev, DWORD count, KERNINGPAIR *
}
static
void
scale_outline_font_metrics
(
const
struct
gdi_font
*
font
,
OUTLINETEXTMETRICW
*
otm
)
{
double
scale_x
,
scale_y
;
if
(
font
->
aveWidth
)
{
scale_x
=
(
double
)
font
->
aveWidth
;
scale_x
/=
(
double
)
font
->
otm
.
otmTextMetrics
.
tmAveCharWidth
;
}
else
scale_x
=
font
->
scale_y
;
scale_x
*=
fabs
(
font
->
matrix
.
eM11
);
scale_y
=
font
->
scale_y
*
fabs
(
font
->
matrix
.
eM22
);
/* Windows scales these values as signed integers even if they are unsigned */
#define SCALE_X(x) (x) = GDI_ROUND((int)(x) * (scale_x))
#define SCALE_Y(y) (y) = GDI_ROUND((int)(y) * (scale_y))
SCALE_Y
(
otm
->
otmTextMetrics
.
tmHeight
);
SCALE_Y
(
otm
->
otmTextMetrics
.
tmAscent
);
SCALE_Y
(
otm
->
otmTextMetrics
.
tmDescent
);
SCALE_Y
(
otm
->
otmTextMetrics
.
tmInternalLeading
);
SCALE_Y
(
otm
->
otmTextMetrics
.
tmExternalLeading
);
SCALE_X
(
otm
->
otmTextMetrics
.
tmOverhang
);
if
(
font
->
fake_bold
)
{
if
(
!
font
->
scalable
)
otm
->
otmTextMetrics
.
tmOverhang
++
;
otm
->
otmTextMetrics
.
tmAveCharWidth
++
;
otm
->
otmTextMetrics
.
tmMaxCharWidth
++
;
}
SCALE_X
(
otm
->
otmTextMetrics
.
tmAveCharWidth
);
SCALE_X
(
otm
->
otmTextMetrics
.
tmMaxCharWidth
);
SCALE_Y
(
otm
->
otmAscent
);
SCALE_Y
(
otm
->
otmDescent
);
SCALE_Y
(
otm
->
otmLineGap
);
SCALE_Y
(
otm
->
otmsCapEmHeight
);
SCALE_Y
(
otm
->
otmsXHeight
);
SCALE_Y
(
otm
->
otmrcFontBox
.
top
);
SCALE_Y
(
otm
->
otmrcFontBox
.
bottom
);
SCALE_X
(
otm
->
otmrcFontBox
.
left
);
SCALE_X
(
otm
->
otmrcFontBox
.
right
);
SCALE_Y
(
otm
->
otmMacAscent
);
SCALE_Y
(
otm
->
otmMacDescent
);
SCALE_Y
(
otm
->
otmMacLineGap
);
SCALE_X
(
otm
->
otmptSubscriptSize
.
x
);
SCALE_Y
(
otm
->
otmptSubscriptSize
.
y
);
SCALE_X
(
otm
->
otmptSubscriptOffset
.
x
);
SCALE_Y
(
otm
->
otmptSubscriptOffset
.
y
);
SCALE_X
(
otm
->
otmptSuperscriptSize
.
x
);
SCALE_Y
(
otm
->
otmptSuperscriptSize
.
y
);
SCALE_X
(
otm
->
otmptSuperscriptOffset
.
x
);
SCALE_Y
(
otm
->
otmptSuperscriptOffset
.
y
);
SCALE_Y
(
otm
->
otmsStrikeoutSize
);
SCALE_Y
(
otm
->
otmsStrikeoutPosition
);
SCALE_Y
(
otm
->
otmsUnderscoreSize
);
SCALE_Y
(
otm
->
otmsUnderscorePosition
);
#undef SCALE_X
#undef SCALE_Y
}
/*************************************************************
* font_GetOutlineTextMetrics
*/
static
UINT
CDECL
font_GetOutlineTextMetrics
(
PHYSDEV
dev
,
UINT
size
,
OUTLINETEXTMETRICW
*
metrics
)
{
struct
font_physdev
*
physdev
=
get_font_dev
(
dev
);
UINT
ret
;
UINT
ret
=
0
;
if
(
!
physdev
->
font
)
{
...
...
@@ -1204,7 +1274,27 @@ static UINT CDECL font_GetOutlineTextMetrics( PHYSDEV dev, UINT size, OUTLINETEX
if
(
!
physdev
->
font
->
scalable
)
return
0
;
EnterCriticalSection
(
&
font_cs
);
ret
=
font_funcs
->
pGetOutlineTextMetrics
(
physdev
->
font
,
size
,
metrics
);
if
(
font_funcs
->
set_outline_text_metrics
(
physdev
->
font
))
{
ret
=
physdev
->
font
->
otm
.
otmSize
;
if
(
metrics
&&
size
>=
physdev
->
font
->
otm
.
otmSize
)
{
WCHAR
*
ptr
=
(
WCHAR
*
)(
metrics
+
1
);
*
metrics
=
physdev
->
font
->
otm
;
metrics
->
otmpFamilyName
=
(
char
*
)
ptr
-
(
ULONG_PTR
)
metrics
;
strcpyW
(
ptr
,
(
WCHAR
*
)
physdev
->
font
->
otm
.
otmpFamilyName
);
ptr
+=
strlenW
(
ptr
)
+
1
;
metrics
->
otmpStyleName
=
(
char
*
)
ptr
-
(
ULONG_PTR
)
metrics
;
strcpyW
(
ptr
,
(
WCHAR
*
)
physdev
->
font
->
otm
.
otmpStyleName
);
ptr
+=
strlenW
(
ptr
)
+
1
;
metrics
->
otmpFaceName
=
(
char
*
)
ptr
-
(
ULONG_PTR
)
metrics
;
strcpyW
(
ptr
,
(
WCHAR
*
)
physdev
->
font
->
otm
.
otmpFaceName
);
ptr
+=
strlenW
(
ptr
)
+
1
;
metrics
->
otmpFullName
=
(
char
*
)
ptr
-
(
ULONG_PTR
)
metrics
;
strcpyW
(
ptr
,
(
WCHAR
*
)
physdev
->
font
->
otm
.
otmpFullName
);
scale_outline_font_metrics
(
physdev
->
font
,
metrics
);
}
}
LeaveCriticalSection
(
&
font_cs
);
return
ret
;
}
...
...
@@ -1301,23 +1391,68 @@ static INT CDECL font_GetTextFace( PHYSDEV dev, INT count, WCHAR *str )
dev
=
GET_NEXT_PHYSDEV
(
dev
,
pGetTextFace
);
return
dev
->
funcs
->
pGetTextFace
(
dev
,
count
,
str
);
}
len
=
strlenW
(
physdev
->
font
->
name
)
+
1
;
len
=
strlenW
(
get_gdi_font_name
(
physdev
->
font
)
)
+
1
;
if
(
str
)
{
lstrcpynW
(
str
,
physdev
->
font
->
name
,
count
);
lstrcpynW
(
str
,
get_gdi_font_name
(
physdev
->
font
)
,
count
);
len
=
min
(
count
,
len
);
}
return
len
;
}
static
void
scale_font_metrics
(
struct
gdi_font
*
font
,
TEXTMETRICW
*
tm
)
{
double
scale_x
,
scale_y
;
/* Make sure that the font has sane width/height ratio */
if
(
font
->
aveWidth
&&
(
font
->
aveWidth
+
tm
->
tmHeight
-
1
)
/
tm
->
tmHeight
>
100
)
{
WARN
(
"Ignoring too large font->aveWidth %d
\n
"
,
font
->
aveWidth
);
font
->
aveWidth
=
0
;
}
if
(
font
->
aveWidth
)
{
scale_x
=
(
double
)
font
->
aveWidth
;
scale_x
/=
(
double
)
font
->
otm
.
otmTextMetrics
.
tmAveCharWidth
;
}
else
scale_x
=
font
->
scale_y
;
scale_x
*=
fabs
(
font
->
matrix
.
eM11
);
scale_y
=
font
->
scale_y
*
fabs
(
font
->
matrix
.
eM22
);
#define SCALE_X(x) (x) = GDI_ROUND((x) * scale_x)
#define SCALE_Y(y) (y) = GDI_ROUND((y) * scale_y)
SCALE_Y
(
tm
->
tmHeight
);
SCALE_Y
(
tm
->
tmAscent
);
SCALE_Y
(
tm
->
tmDescent
);
SCALE_Y
(
tm
->
tmInternalLeading
);
SCALE_Y
(
tm
->
tmExternalLeading
);
SCALE_X
(
tm
->
tmOverhang
);
if
(
font
->
fake_bold
)
{
if
(
!
font
->
scalable
)
tm
->
tmOverhang
++
;
tm
->
tmAveCharWidth
++
;
tm
->
tmMaxCharWidth
++
;
}
SCALE_X
(
tm
->
tmAveCharWidth
);
SCALE_X
(
tm
->
tmMaxCharWidth
);
#undef SCALE_X
#undef SCALE_Y
}
/*************************************************************
* font_GetTextMetrics
*/
static
BOOL
CDECL
font_GetTextMetrics
(
PHYSDEV
dev
,
TEXTMETRICW
*
metrics
)
{
struct
font_physdev
*
physdev
=
get_font_dev
(
dev
);
BOOL
ret
;
BOOL
ret
=
FALSE
;
if
(
!
physdev
->
font
)
{
...
...
@@ -1326,7 +1461,13 @@ static BOOL CDECL font_GetTextMetrics( PHYSDEV dev, TEXTMETRICW *metrics )
}
EnterCriticalSection
(
&
font_cs
);
ret
=
font_funcs
->
pGetTextMetrics
(
physdev
->
font
,
metrics
);
if
(
font_funcs
->
set_outline_text_metrics
(
physdev
->
font
)
||
font_funcs
->
set_bitmap_text_metrics
(
physdev
->
font
))
{
*
metrics
=
physdev
->
font
->
otm
.
otmTextMetrics
;
scale_font_metrics
(
physdev
->
font
,
metrics
);
ret
=
TRUE
;
}
LeaveCriticalSection
(
&
font_cs
);
return
ret
;
}
...
...
dlls/gdi32/freetype.c
View file @
e0872b64
...
...
@@ -302,7 +302,6 @@ typedef struct {
struct
tagGdiFont
{
struct
gdi_font
*
gdi_font
;
OUTLINETEXTMETRICW
*
potm
;
DWORD
total_kern_pairs
;
KERNINGPAIR
*
kern_pairs
;
struct
list
child_fonts
;
...
...
@@ -457,9 +456,8 @@ static const WCHAR szDefaultFallbackLink[] = {'M','i','c','r','o','s','o','f','t
static
BOOL
map_font_family
(
const
WCHAR
*
orig
,
const
WCHAR
*
repl
);
static
BOOL
get_glyph_index_linked
(
GdiFont
*
font
,
UINT
c
,
GdiFont
**
linked_font
,
FT_UInt
*
glyph
,
BOOL
*
vert
);
static
BOOL
get_outline_text_metrics
(
GdiFont
*
font
);
static
BOOL
get_bitmap_text_metrics
(
GdiFont
*
font
);
static
BOOL
get_text_metrics
(
GdiFont
*
font
,
LPTEXTMETRICW
ptm
);
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
void
remove_face_from_cache
(
Face
*
face
);
static
const
WCHAR
system_link
[]
=
{
'S'
,
'o'
,
'f'
,
't'
,
'w'
,
'a'
,
'r'
,
'e'
,
'\\'
,
'M'
,
'i'
,
'c'
,
'r'
,
'o'
,
's'
,
'o'
,
'f'
,
't'
,
'\\'
,
...
...
@@ -4023,7 +4021,6 @@ static UINT get_nearest_charset(const WCHAR *family_name, Face *face, UINT *cp)
static
BOOL
CDECL
freetype_alloc_font
(
struct
gdi_font
*
font
)
{
GdiFont
*
ret
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
*
ret
));
ret
->
potm
=
NULL
;
ret
->
total_kern_pairs
=
(
DWORD
)
-
1
;
ret
->
kern_pairs
=
NULL
;
list_init
(
&
ret
->
child_fonts
);
...
...
@@ -4052,7 +4049,6 @@ static void CDECL freetype_destroy_font( struct gdi_font *gdi_font )
if
(
font
->
ft_face
)
pFT_Done_Face
(
font
->
ft_face
);
if
(
font
->
mapping
)
unmap_font_file
(
font
->
mapping
);
HeapFree
(
GetProcessHeap
(),
0
,
font
->
kern_pairs
);
HeapFree
(
GetProcessHeap
(),
0
,
font
->
potm
);
HeapFree
(
GetProcessHeap
(),
0
,
font
->
GSUB_Table
);
HeapFree
(
GetProcessHeap
(),
0
,
font
);
}
...
...
@@ -4275,10 +4271,10 @@ static BOOL create_child_font_list(GdiFont *font)
SYSTEM_LINKS
*
font_link
;
CHILD_FONT
*
font_link_entry
,
*
new_child
;
FontSubst
*
psub
;
WCHAR
*
font_name
;
const
WCHAR
*
font_name
;
psub
=
get_font_subst
(
&
font_subst_list
,
g
di_font
->
name
,
-
1
);
font_name
=
psub
?
psub
->
to
.
name
:
g
di_font
->
name
;
psub
=
get_font_subst
(
&
font_subst_list
,
g
et_gdi_font_name
(
gdi_font
)
,
-
1
);
font_name
=
psub
?
psub
->
to
.
name
:
g
et_gdi_font_name
(
gdi_font
)
;
font_link
=
find_font_link
(
font_name
);
if
(
font_link
!=
NULL
)
{
...
...
@@ -5046,7 +5042,8 @@ found_face:
pick_charmap
(
ret
->
ft_face
,
gdi_font
->
charset
);
set_gdi_font_name
(
gdi_font
,
psub
?
psub
->
from
.
name
:
family
->
family_name
);
set_gdi_font_names
(
gdi_font
,
psub
?
psub
->
from
.
name
:
family
->
family_name
,
face
->
style_name
,
face
->
full_name
);
create_child_font_list
(
ret
);
if
(
face
->
flags
&
ADDFONT_VERTICAL_FONT
)
/* We need to try to load the GSUB table */
...
...
@@ -5257,30 +5254,24 @@ static void GetEnumStructs(Face *face, const WCHAR *family_name, LPENUMLOGFONTEX
return
;
}
set_gdi_font_name
(
gdi_font
,
family
_name
);
set_gdi_font_name
s
(
gdi_font
,
family_name
,
face
->
style_name
,
face
->
full
_name
);
gdi_font
->
ntmFlags
=
face
->
ntmFlags
;
if
(
get_outline_text_metrics
(
font
))
if
(
freetype_set_outline_text_metrics
(
gdi_
font
))
{
memcpy
(
&
pntm
->
ntmTm
,
&
font
->
potm
->
otmTextMetrics
,
sizeof
(
TEXTMETRICW
));
memcpy
(
&
pntm
->
ntmTm
,
&
gdi_font
->
otm
.
otmTextMetrics
,
sizeof
(
TEXTMETRICW
));
pntm
->
ntmTm
.
ntmSizeEM
=
font
->
potm
->
otmEMSquare
;
pntm
->
ntmTm
.
ntmSizeEM
=
gdi_font
->
otm
.
otmEMSquare
;
pntm
->
ntmTm
.
ntmCellHeight
=
gdi_font
->
ntmCellHeight
;
pntm
->
ntmTm
.
ntmAvgWidth
=
gdi_font
->
ntmAvgWidth
;
lstrcpynW
(
pelf
->
elfLogFont
.
lfFaceName
,
(
WCHAR
*
)((
char
*
)
font
->
potm
+
(
ULONG_PTR
)
font
->
potm
->
otmpFamilyName
),
LF_FACESIZE
);
lstrcpynW
(
pelf
->
elfFullName
,
(
WCHAR
*
)((
char
*
)
font
->
potm
+
(
ULONG_PTR
)
font
->
potm
->
otmpFaceName
),
LF_FULLFACESIZE
);
lstrcpynW
(
pelf
->
elfStyle
,
(
WCHAR
*
)((
char
*
)
font
->
potm
+
(
ULONG_PTR
)
font
->
potm
->
otmpStyleName
),
LF_FACESIZE
);
lstrcpynW
(
pelf
->
elfLogFont
.
lfFaceName
,
(
WCHAR
*
)
gdi_font
->
otm
.
otmpFamilyName
,
LF_FACESIZE
);
lstrcpynW
(
pelf
->
elfFullName
,
(
WCHAR
*
)
gdi_font
->
otm
.
otmpFaceName
,
LF_FULLFACESIZE
);
lstrcpynW
(
pelf
->
elfStyle
,
(
WCHAR
*
)
gdi_font
->
otm
.
otmpStyleName
,
LF_FACESIZE
);
}
else
else
if
(
freetype_set_bitmap_text_metrics
(
gdi_font
))
{
get_text_metrics
(
font
,
(
TEXTMETRICW
*
)
&
pntm
->
ntmTm
);
memcpy
(
&
pntm
->
ntmTm
,
&
gdi_font
->
otm
.
otmTextMetrics
,
sizeof
(
TEXTMETRICW
)
);
pntm
->
ntmTm
.
ntmSizeEM
=
pntm
->
ntmTm
.
tmHeight
-
pntm
->
ntmTm
.
tmInternalLeading
;
pntm
->
ntmTm
.
ntmCellHeight
=
pntm
->
ntmTm
.
tmHeight
;
...
...
@@ -5741,10 +5732,9 @@ enum matrices_index
matrix_unrotated
};
static
BOOL
get_transform_matrices
(
GdiF
ont
*
font
,
BOOL
vertical
,
const
MAT2
*
user_transform
,
static
BOOL
get_transform_matrices
(
struct
gdi_f
ont
*
font
,
BOOL
vertical
,
const
MAT2
*
user_transform
,
FT_Matrix
matrices
[
3
]
)
{
struct
gdi_font
*
gdi_font
=
font
->
gdi_font
;
static
const
FT_Matrix
identity_mat
=
{
(
1
<<
16
),
0
,
0
,
(
1
<<
16
)
};
BOOL
needs_transform
=
FALSE
;
double
width_ratio
;
...
...
@@ -5753,32 +5743,30 @@ static BOOL get_transform_matrices( GdiFont *font, BOOL vertical, const MAT2 *us
matrices
[
matrix_unrotated
]
=
identity_mat
;
/* Scaling factor */
if
(
gdi_
font
->
aveWidth
)
if
(
font
->
aveWidth
)
{
TEXTMETRICW
tm
;
get_text_metrics
(
font
,
&
tm
);
width_ratio
=
(
double
)
gdi_font
->
aveWidth
;
width_ratio
/=
(
double
)
font
->
potm
->
otmTextMetrics
.
tmAveCharWidth
;
if
(
!
freetype_set_outline_text_metrics
(
font
))
freetype_set_bitmap_text_metrics
(
font
);
width_ratio
=
(
double
)
font
->
aveWidth
;
width_ratio
/=
(
double
)
font
->
otm
.
otmTextMetrics
.
tmAveCharWidth
;
}
else
width_ratio
=
gdi_
font
->
scale_y
;
width_ratio
=
font
->
scale_y
;
/* Scaling transform */
if
(
width_ratio
!=
1
.
0
||
gdi_
font
->
scale_y
!=
1
.
0
)
if
(
width_ratio
!=
1
.
0
||
font
->
scale_y
!=
1
.
0
)
{
FT_Matrix
scale_mat
;
scale_mat
.
xx
=
FT_FixedFromFloat
(
width_ratio
);
scale_mat
.
xy
=
0
;
scale_mat
.
yx
=
0
;
scale_mat
.
yy
=
FT_FixedFromFloat
(
gdi_
font
->
scale_y
);
scale_mat
.
yy
=
FT_FixedFromFloat
(
font
->
scale_y
);
pFT_Matrix_Multiply
(
&
scale_mat
,
&
matrices
[
matrix_unrotated
]
);
needs_transform
=
TRUE
;
}
/* Slant transform */
if
(
gdi_
font
->
fake_italic
)
if
(
font
->
fake_italic
)
{
FT_Matrix
slant_mat
;
slant_mat
.
xx
=
(
1
<<
16
);
...
...
@@ -5792,12 +5780,12 @@ static BOOL get_transform_matrices( GdiFont *font, BOOL vertical, const MAT2 *us
/* Rotation transform */
matrices
[
matrix_hori
]
=
matrices
[
matrix_unrotated
];
if
(
gdi_font
->
scalable
&&
gdi_
font
->
lf
.
lfOrientation
%
3600
)
if
(
font
->
scalable
&&
font
->
lf
.
lfOrientation
%
3600
)
{
FT_Matrix
rotation_mat
;
FT_Vector
angle
;
pFT_Vector_Unit
(
&
angle
,
MulDiv
(
1
<<
16
,
gdi_
font
->
lf
.
lfOrientation
,
10
)
);
pFT_Vector_Unit
(
&
angle
,
MulDiv
(
1
<<
16
,
font
->
lf
.
lfOrientation
,
10
)
);
rotation_mat
.
xx
=
angle
.
x
;
rotation_mat
.
xy
=
-
angle
.
y
;
rotation_mat
.
yx
=
angle
.
y
;
...
...
@@ -5817,13 +5805,13 @@ static BOOL get_transform_matrices( GdiFont *font, BOOL vertical, const MAT2 *us
}
/* World transform */
if
(
!
is_identity_FMAT2
(
&
gdi_
font
->
matrix
))
if
(
!
is_identity_FMAT2
(
&
font
->
matrix
))
{
FT_Matrix
world_mat
;
world_mat
.
xx
=
FT_FixedFromFloat
(
gdi_
font
->
matrix
.
eM11
);
world_mat
.
xy
=
-
FT_FixedFromFloat
(
gdi_
font
->
matrix
.
eM21
);
world_mat
.
yx
=
-
FT_FixedFromFloat
(
gdi_
font
->
matrix
.
eM12
);
world_mat
.
yy
=
FT_FixedFromFloat
(
gdi_
font
->
matrix
.
eM22
);
world_mat
.
xx
=
FT_FixedFromFloat
(
font
->
matrix
.
eM11
);
world_mat
.
xy
=
-
FT_FixedFromFloat
(
font
->
matrix
.
eM21
);
world_mat
.
yx
=
-
FT_FixedFromFloat
(
font
->
matrix
.
eM12
);
world_mat
.
yy
=
FT_FixedFromFloat
(
font
->
matrix
.
eM22
);
for
(
i
=
0
;
i
<
3
;
i
++
)
pFT_Matrix_Multiply
(
&
world_mat
,
&
matrices
[
i
]
);
...
...
@@ -5897,12 +5885,10 @@ static BOOL check_unicode_tategaki(WCHAR uchar)
return
(
orientation
==
1
||
orientation
==
3
);
}
static
FT_Vector
get_advance_metric
(
GdiFont
*
incoming_font
,
GdiF
ont
*
font
,
static
FT_Vector
get_advance_metric
(
struct
gdi_font
*
incoming_font
,
struct
gdi_f
ont
*
font
,
const
FT_Glyph_Metrics
*
metrics
,
const
FT_Matrix
*
transMat
,
BOOL
vertical_metrics
)
{
struct
gdi_font
*
incoming_gdi_font
=
incoming_font
->
gdi_font
;
struct
gdi_font
*
gdi_font
=
font
->
gdi_font
;
FT_Vector
adv
;
FT_Fixed
base_advance
,
em_scale
=
0
;
BOOL
fixed_pitch_full
=
FALSE
;
...
...
@@ -5919,16 +5905,15 @@ static FT_Vector get_advance_metric(GdiFont *incoming_font, GdiFont *font,
they have double halfwidth character width. E.g. if the font is 19 ppem,
we return 20 (not 19) for fullwidth characters as we return 10 for
halfwidth characters. */
if
(
incoming_gdi_font
->
scalable
&&
(
incoming_font
->
potm
||
get_outline_text_metrics
(
incoming_font
))
&&
!
(
incoming_font
->
potm
->
otmTextMetrics
.
tmPitchAndFamily
&
TMPF_FIXED_PITCH
))
{
if
(
freetype_set_outline_text_metrics
(
incoming_font
)
&&
!
(
incoming_font
->
otm
.
otmTextMetrics
.
tmPitchAndFamily
&
TMPF_FIXED_PITCH
))
{
UINT
avg_advance
;
em_scale
=
MulDiv
(
incoming_
gdi_
font
->
ppem
,
1
<<
16
,
incoming_font
->
ft_face
->
units_per_EM
);
avg_advance
=
pFT_MulFix
(
incoming_
gdi_
font
->
ntmAvgWidth
,
em_scale
);
em_scale
=
MulDiv
(
incoming_font
->
ppem
,
1
<<
16
,
get_font_ptr
(
incoming_font
)
->
ft_face
->
units_per_EM
);
avg_advance
=
pFT_MulFix
(
incoming_font
->
ntmAvgWidth
,
em_scale
);
fixed_pitch_full
=
(
avg_advance
>
0
&&
(
base_advance
+
63
)
>>
6
==
pFT_MulFix
(
incoming_
gdi_
font
->
ntmAvgWidth
*
2
,
em_scale
));
pFT_MulFix
(
incoming_font
->
ntmAvgWidth
*
2
,
em_scale
));
if
(
fixed_pitch_full
&&
!
transMat
)
adv
.
x
=
(
avg_advance
*
2
)
<<
6
;
}
...
...
@@ -5937,14 +5922,14 @@ static FT_Vector get_advance_metric(GdiFont *incoming_font, GdiFont *font,
pFT_Vector_Transform
(
&
adv
,
transMat
);
if
(
fixed_pitch_full
&&
adv
.
y
==
0
)
{
FT_Vector
vec
;
vec
.
x
=
incoming_
gdi_
font
->
ntmAvgWidth
;
vec
.
x
=
incoming_font
->
ntmAvgWidth
;
vec
.
y
=
0
;
pFT_Vector_Transform
(
&
vec
,
transMat
);
adv
.
x
=
(
pFT_MulFix
(
vec
.
x
,
em_scale
)
*
2
)
<<
6
;
}
}
if
(
gdi_
font
->
fake_bold
)
{
if
(
font
->
fake_bold
)
{
if
(
!
transMat
)
adv
.
x
+=
1
<<
6
;
else
{
...
...
@@ -6010,7 +5995,7 @@ static FT_BBox get_transformed_bbox( const FT_Glyph_Metrics *metrics,
return
bbox
;
}
static
void
compute_metrics
(
GdiFont
*
incoming_font
,
GdiF
ont
*
font
,
static
void
compute_metrics
(
struct
gdi_font
*
incoming_font
,
struct
gdi_f
ont
*
font
,
FT_BBox
bbox
,
const
FT_Glyph_Metrics
*
metrics
,
BOOL
vertical
,
BOOL
vertical_metrics
,
BOOL
needs_transform
,
const
FT_Matrix
matrices
[
3
],
...
...
@@ -6032,14 +6017,14 @@ static void compute_metrics( GdiFont *incoming_font, GdiFont *font,
{
FT_Pos
lsb
;
if
(
vertical
&&
(
font
->
potm
||
get_outline_text_metrics
(
font
)
))
if
(
vertical
&&
freetype_set_outline_text_metrics
(
font
))
{
if
(
vertical_metrics
)
lsb
=
metrics
->
horiBearingY
+
metrics
->
vertBearingY
;
else
lsb
=
metrics
->
vertAdvance
+
(
font
->
potm
->
otmDescent
<<
6
);
lsb
=
metrics
->
vertAdvance
+
(
font
->
otm
.
otmDescent
<<
6
);
vec
.
x
=
lsb
;
vec
.
y
=
font
->
potm
->
otmDescent
<<
6
;
vec
.
y
=
font
->
otm
.
otmDescent
<<
6
;
TRACE
(
"Vec %ld,%ld
\n
"
,
vec
.
x
>>
6
,
vec
.
y
>>
6
);
pFT_Vector_Transform
(
&
vec
,
&
matrices
[
matrix_hori
]
);
origin
.
x
=
(
vec
.
x
+
bbox
.
xMin
)
&
-
64
;
...
...
@@ -6634,7 +6619,7 @@ static DWORD CDECL freetype_get_glyph_outline( struct gdi_font *incoming_gdi_fon
FT_Int
load_flags
=
get_load_flags
(
format
);
FT_Matrix
matrices
[
3
];
BOOL
needsTransform
=
FALSE
;
BOOL
tategaki
=
(
gdi_font
->
name
[
0
]
==
'@'
);
BOOL
tategaki
=
(
*
get_gdi_font_name
(
gdi_font
)
==
'@'
);
BOOL
vertical_metrics
;
TRACE
(
"%p, %04x, %08x, %p, %08x, %p, %p
\n
"
,
font
,
glyph
,
format
,
lpgm
,
...
...
@@ -6671,7 +6656,7 @@ static DWORD CDECL freetype_get_glyph_outline( struct gdi_font *incoming_gdi_fon
get_gdi_font_glyph_metrics
(
gdi_font
,
glyph_index
,
lpgm
,
abc
))
return
1
;
/* FIXME */
needsTransform
=
get_transform_matrices
(
font
,
tategaki
,
lpmat
,
matrices
);
needsTransform
=
get_transform_matrices
(
gdi_
font
,
tategaki
,
lpmat
,
matrices
);
vertical_metrics
=
(
tategaki
&&
FT_HAS_VERTICAL
(
ft_face
));
/* there is a freetype bug where vertical metrics are only
...
...
@@ -6704,9 +6689,9 @@ static DWORD CDECL freetype_get_glyph_outline( struct gdi_font *incoming_gdi_fon
/* Some poorly-created fonts contain glyphs that exceed the boundaries set
* by the text metrics. The proper behavior is to clip the glyph metrics to
* fit within the maximums specified in the text metrics. */
if
(
incoming_font
->
potm
||
get_outline_text_metrics
(
incoming
_font
)
||
get_bitmap_text_metrics
(
incoming
_font
))
{
TEXTMETRICW
*
ptm
=
&
incoming_
font
->
potm
->
otmTextMetrics
;
if
(
freetype_set_outline_text_metrics
(
incoming_gdi
_font
)
||
freetype_set_bitmap_text_metrics
(
incoming_gdi
_font
))
{
TEXTMETRICW
*
ptm
=
&
incoming_
gdi_font
->
otm
.
otmTextMetrics
;
INT
top
=
min
(
metrics
.
horiBearingY
,
ptm
->
tmAscent
<<
6
);
INT
bottom
=
max
(
metrics
.
horiBearingY
-
metrics
.
height
,
-
(
ptm
->
tmDescent
<<
6
)
);
metrics
.
horiBearingY
=
top
;
...
...
@@ -6717,7 +6702,7 @@ static DWORD CDECL freetype_get_glyph_outline( struct gdi_font *incoming_gdi_fon
}
bbox
=
get_transformed_bbox
(
&
metrics
,
needsTransform
,
matrices
);
compute_metrics
(
incoming_
font
,
font
,
bbox
,
&
metrics
,
compute_metrics
(
incoming_
gdi_font
,
gdi_
font
,
bbox
,
&
metrics
,
tategaki
,
vertical_metrics
,
needsTransform
,
matrices
,
&
gm
,
abc
);
...
...
@@ -6809,16 +6794,18 @@ static DWORD CDECL freetype_get_glyph_outline( struct gdi_font *incoming_gdi_fon
return
needed
;
}
static
BOOL
get_bitmap_text_metrics
(
GdiFont
*
font
)
/*************************************************************
* freetype_set_bitmap_text_metrics
*/
static
BOOL
CDECL
freetype_set_bitmap_text_metrics
(
struct
gdi_font
*
font
)
{
struct
gdi_font
*
gdi_font
=
font
->
gdi_font
;
FT_Face
ft_face
=
font
->
ft_face
;
FT_Face
ft_face
=
get_font_ptr
(
font
)
->
ft_face
;
FT_WinFNT_HeaderRec
winfnt_header
;
const
DWORD
size
=
offsetof
(
OUTLINETEXTMETRICW
,
otmFiller
);
font
->
potm
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
);
font
->
potm
->
otmSize
=
size
;
#define TM font->potm->otmTextMetrics
if
(
font
->
otm
.
otmSize
)
return
TRUE
;
/* already set */
font
->
otm
.
otmSize
=
offsetof
(
OUTLINETEXTMETRICW
,
otmFiller
);
#define TM font->otm.otmTextMetrics
if
(
!
pFT_Get_WinFNT_Header
(
ft_face
,
&
winfnt_header
))
{
TM
.
tmHeight
=
winfnt_header
.
pixel_height
;
...
...
@@ -6860,12 +6847,12 @@ static BOOL get_bitmap_text_metrics(GdiFont *font)
TM
.
tmItalic
=
ft_face
->
style_flags
&
FT_STYLE_FLAG_ITALIC
?
1
:
0
;
/* NB inverted meaning of TMPF_FIXED_PITCH */
TM
.
tmPitchAndFamily
=
FT_IS_FIXED_WIDTH
(
ft_face
)
?
0
:
TMPF_FIXED_PITCH
;
TM
.
tmCharSet
=
gdi_
font
->
charset
;
TM
.
tmCharSet
=
font
->
charset
;
}
TM
.
tmUnderlined
=
gdi_
font
->
lf
.
lfUnderline
?
0xff
:
0
;
TM
.
tmStruckOut
=
gdi_
font
->
lf
.
lfStrikeOut
?
0xff
:
0
;
TM
.
tmUnderlined
=
font
->
lf
.
lfUnderline
?
0xff
:
0
;
TM
.
tmStruckOut
=
font
->
lf
.
lfStrikeOut
?
0xff
:
0
;
if
(
gdi_
font
->
fake_bold
)
if
(
font
->
fake_bold
)
TM
.
tmWeight
=
FW_BOLD
;
#undef TM
...
...
@@ -6873,119 +6860,6 @@ static BOOL get_bitmap_text_metrics(GdiFont *font)
}
static
void
scale_font_metrics
(
const
GdiFont
*
font
,
LPTEXTMETRICW
ptm
)
{
const
struct
gdi_font
*
gdi_font
=
font
->
gdi_font
;
double
scale_x
,
scale_y
;
if
(
gdi_font
->
aveWidth
)
{
scale_x
=
(
double
)
gdi_font
->
aveWidth
;
scale_x
/=
(
double
)
font
->
potm
->
otmTextMetrics
.
tmAveCharWidth
;
}
else
scale_x
=
gdi_font
->
scale_y
;
scale_x
*=
fabs
(
gdi_font
->
matrix
.
eM11
);
scale_y
=
gdi_font
->
scale_y
*
fabs
(
gdi_font
->
matrix
.
eM22
);
#define SCALE_X(x) (x) = GDI_ROUND((double)(x) * (scale_x))
#define SCALE_Y(y) (y) = GDI_ROUND((double)(y) * (scale_y))
SCALE_Y
(
ptm
->
tmHeight
);
SCALE_Y
(
ptm
->
tmAscent
);
SCALE_Y
(
ptm
->
tmDescent
);
SCALE_Y
(
ptm
->
tmInternalLeading
);
SCALE_Y
(
ptm
->
tmExternalLeading
);
SCALE_X
(
ptm
->
tmOverhang
);
if
(
gdi_font
->
fake_bold
)
{
if
(
!
gdi_font
->
scalable
)
ptm
->
tmOverhang
++
;
ptm
->
tmAveCharWidth
++
;
ptm
->
tmMaxCharWidth
++
;
}
SCALE_X
(
ptm
->
tmAveCharWidth
);
SCALE_X
(
ptm
->
tmMaxCharWidth
);
#undef SCALE_X
#undef SCALE_Y
}
static
void
scale_outline_font_metrics
(
const
GdiFont
*
font
,
OUTLINETEXTMETRICW
*
potm
)
{
const
struct
gdi_font
*
gdi_font
=
font
->
gdi_font
;
double
scale_x
,
scale_y
;
if
(
gdi_font
->
aveWidth
)
{
scale_x
=
(
double
)
gdi_font
->
aveWidth
;
scale_x
/=
(
double
)
font
->
potm
->
otmTextMetrics
.
tmAveCharWidth
;
}
else
scale_x
=
gdi_font
->
scale_y
;
scale_x
*=
fabs
(
gdi_font
->
matrix
.
eM11
);
scale_y
=
gdi_font
->
scale_y
*
fabs
(
gdi_font
->
matrix
.
eM22
);
scale_font_metrics
(
font
,
&
potm
->
otmTextMetrics
);
/* Windows scales these values as signed integers even if they are unsigned */
#define SCALE_X(x) (x) = GDI_ROUND((int)(x) * (scale_x))
#define SCALE_Y(y) (y) = GDI_ROUND((int)(y) * (scale_y))
SCALE_Y
(
potm
->
otmAscent
);
SCALE_Y
(
potm
->
otmDescent
);
SCALE_Y
(
potm
->
otmLineGap
);
SCALE_Y
(
potm
->
otmsCapEmHeight
);
SCALE_Y
(
potm
->
otmsXHeight
);
SCALE_Y
(
potm
->
otmrcFontBox
.
top
);
SCALE_Y
(
potm
->
otmrcFontBox
.
bottom
);
SCALE_X
(
potm
->
otmrcFontBox
.
left
);
SCALE_X
(
potm
->
otmrcFontBox
.
right
);
SCALE_Y
(
potm
->
otmMacAscent
);
SCALE_Y
(
potm
->
otmMacDescent
);
SCALE_Y
(
potm
->
otmMacLineGap
);
SCALE_X
(
potm
->
otmptSubscriptSize
.
x
);
SCALE_Y
(
potm
->
otmptSubscriptSize
.
y
);
SCALE_X
(
potm
->
otmptSubscriptOffset
.
x
);
SCALE_Y
(
potm
->
otmptSubscriptOffset
.
y
);
SCALE_X
(
potm
->
otmptSuperscriptSize
.
x
);
SCALE_Y
(
potm
->
otmptSuperscriptSize
.
y
);
SCALE_X
(
potm
->
otmptSuperscriptOffset
.
x
);
SCALE_Y
(
potm
->
otmptSuperscriptOffset
.
y
);
SCALE_Y
(
potm
->
otmsStrikeoutSize
);
SCALE_Y
(
potm
->
otmsStrikeoutPosition
);
SCALE_Y
(
potm
->
otmsUnderscoreSize
);
SCALE_Y
(
potm
->
otmsUnderscorePosition
);
#undef SCALE_X
#undef SCALE_Y
}
static
BOOL
get_text_metrics
(
GdiFont
*
font
,
LPTEXTMETRICW
ptm
)
{
struct
gdi_font
*
gdi_font
=
font
->
gdi_font
;
if
(
!
font
->
potm
)
{
if
(
!
get_outline_text_metrics
(
font
)
&&
!
get_bitmap_text_metrics
(
font
))
return
FALSE
;
/* Make sure that the font has sane width/height ratio */
if
(
gdi_font
->
aveWidth
)
{
if
((
gdi_font
->
aveWidth
+
font
->
potm
->
otmTextMetrics
.
tmHeight
-
1
)
/
font
->
potm
->
otmTextMetrics
.
tmHeight
>
100
)
{
WARN
(
"Ignoring too large font->aveWidth %d
\n
"
,
gdi_font
->
aveWidth
);
gdi_font
->
aveWidth
=
0
;
}
}
}
*
ptm
=
font
->
potm
->
otmTextMetrics
;
scale_font_metrics
(
font
,
ptm
);
return
TRUE
;
}
static
BOOL
face_has_symbol_charmap
(
FT_Face
ft_face
)
{
int
i
;
...
...
@@ -6998,74 +6872,51 @@ static BOOL face_has_symbol_charmap(FT_Face ft_face)
return
FALSE
;
}
static
BOOL
get_outline_text_metrics
(
GdiFont
*
font
)
/*************************************************************
* freetype_set_outline_text_metrics
*/
static
BOOL
CDECL
freetype_set_outline_text_metrics
(
struct
gdi_font
*
font
)
{
BOOL
ret
=
FALSE
;
FT_Face
ft_face
=
font
->
ft_face
;
struct
gdi_font
*
gdi_font
=
font
->
gdi_font
;
UINT
needed
,
lenfam
,
lensty
,
lenface
,
lenfull
;
FT_Face
ft_face
=
get_font_ptr
(
font
)
->
ft_face
;
UINT
needed
;
TT_OS2
*
pOS2
;
TT_HoriHeader
*
pHori
;
TT_Postscript
*
pPost
;
FT_Fixed
em_scale
;
WCHAR
*
family_nameW
,
*
style_nameW
,
*
face_nameW
,
*
full_nameW
;
char
*
cp
;
INT
ascent
,
descent
;
USHORT
windescent
;
TRACE
(
"font=%p
\n
"
,
font
);
if
(
!
FT_IS_SCALABLE
(
ft_face
))
return
FALSE
;
needed
=
sizeof
(
*
font
->
potm
);
lenfam
=
(
strlenW
(
gdi_font
->
name
)
+
1
)
*
sizeof
(
WCHAR
);
family_nameW
=
strdupW
(
gdi_font
->
name
);
if
(
!
font
->
scalable
)
return
FALSE
;
if
(
font
->
otm
.
otmSize
)
return
TRUE
;
/* already set */
style_nameW
=
ft_face_get_style_name
(
ft_face
,
GetSystemDefaultLangID
()
);
lensty
=
(
strlenW
(
style_nameW
)
+
1
)
*
sizeof
(
WCHAR
);
face_nameW
=
ft_face_get_full_name
(
ft_face
,
GetSystemDefaultLangID
()
);
if
(
gdi_font
->
name
[
0
]
==
'@'
)
face_nameW
=
get_vertical_name
(
face_nameW
);
lenface
=
(
strlenW
(
face_nameW
)
+
1
)
*
sizeof
(
WCHAR
);
full_nameW
=
get_face_name
(
ft_face
,
TT_NAME_ID_UNIQUE_ID
,
GetSystemDefaultLangID
()
);
if
(
!
full_nameW
)
/* note: we store actual pointers in the names instead of offsets,
they are fixed up when returned to the app */
if
(
!
(
font
->
otm
.
otmpFullName
=
(
char
*
)
get_face_name
(
ft_face
,
TT_NAME_ID_UNIQUE_ID
,
GetSystemDefaultLangID
()
)))
{
static
const
WCHAR
fake_nameW
[]
=
{
'f'
,
'a'
,
'k'
,
'e'
,
' '
,
'n'
,
'a'
,
'm'
,
'e'
,
0
};
FIXME
(
"failed to read full_nameW for font %s!
\n
"
,
wine_dbgstr_w
(
g
di_font
->
name
));
f
ull_nameW
=
strdupW
(
fake_nameW
);
FIXME
(
"failed to read full_nameW for font %s!
\n
"
,
wine_dbgstr_w
(
g
et_gdi_font_name
(
font
)
));
f
ont
->
otm
.
otmpFullName
=
(
char
*
)
strdupW
(
fake_nameW
);
}
lenfull
=
(
strlenW
(
full_nameW
)
+
1
)
*
sizeof
(
WCHAR
);
/* These names should be read from the TT name table */
needed
=
sizeof
(
font
->
otm
)
+
(
strlenW
(
(
WCHAR
*
)
font
->
otm
.
otmpFamilyName
)
+
1
+
strlenW
(
(
WCHAR
*
)
font
->
otm
.
otmpStyleName
)
+
1
+
strlenW
(
(
WCHAR
*
)
font
->
otm
.
otmpFaceName
)
+
1
+
strlenW
(
(
WCHAR
*
)
font
->
otm
.
otmpFullName
)
+
1
)
*
sizeof
(
WCHAR
);
/* length of otmpFamilyName */
needed
+=
lenfam
;
/* length of otmpFaceName */
needed
+=
lenface
;
/* length of otmpStyleName */
needed
+=
lensty
;
/* length of otmpFullName */
needed
+=
lenfull
;
em_scale
=
(
FT_Fixed
)
MulDiv
(
gdi_font
->
ppem
,
1
<<
16
,
ft_face
->
units_per_EM
);
em_scale
=
(
FT_Fixed
)
MulDiv
(
font
->
ppem
,
1
<<
16
,
ft_face
->
units_per_EM
);
pOS2
=
pFT_Get_Sfnt_Table
(
ft_face
,
ft_sfnt_os2
);
if
(
!
pOS2
)
{
FIXME
(
"Can't find OS/2 table - not TT font?
\n
"
);
goto
end
;
return
FALSE
;
}
pHori
=
pFT_Get_Sfnt_Table
(
ft_face
,
ft_sfnt_hhea
);
if
(
!
pHori
)
{
FIXME
(
"Can't find HHEA table - not TT font?
\n
"
);
goto
end
;
return
FALSE
;
}
pPost
=
pFT_Get_Sfnt_Table
(
ft_face
,
ft_sfnt_post
);
/* we can live with this failing */
...
...
@@ -7078,10 +6929,9 @@ static BOOL get_outline_text_metrics(GdiFont *font)
pHori
->
Ascender
,
pHori
->
Descender
,
pHori
->
Line_Gap
,
ft_face
->
bbox
.
yMax
,
ft_face
->
bbox
.
yMin
);
font
->
potm
=
HeapAlloc
(
GetProcessHeap
(),
0
,
needed
);
font
->
potm
->
otmSize
=
needed
;
font
->
otm
.
otmSize
=
needed
;
#define TM font->
potm->
otmTextMetrics
#define TM font->
otm.
otmTextMetrics
windescent
=
get_fixed_windescent
(
pOS2
->
usWinDescent
);
if
(
pOS2
->
usWinAscent
+
windescent
==
0
)
{
...
...
@@ -7092,15 +6942,15 @@ static BOOL get_outline_text_metrics(GdiFont *font)
descent
=
windescent
;
}
gdi_
font
->
ntmCellHeight
=
ascent
+
descent
;
gdi_
font
->
ntmAvgWidth
=
pOS2
->
xAvgCharWidth
;
font
->
ntmCellHeight
=
ascent
+
descent
;
font
->
ntmAvgWidth
=
pOS2
->
xAvgCharWidth
;
#define SCALE_X(x) (pFT_MulFix(x, em_scale))
#define SCALE_Y(y) (pFT_MulFix(y, em_scale))
if
(
gdi_
font
->
yMax
)
{
TM
.
tmAscent
=
gdi_
font
->
yMax
;
TM
.
tmDescent
=
-
gdi_
font
->
yMin
;
if
(
font
->
yMax
)
{
TM
.
tmAscent
=
font
->
yMax
;
TM
.
tmDescent
=
-
font
->
yMin
;
TM
.
tmInternalLeading
=
(
TM
.
tmAscent
+
TM
.
tmDescent
)
-
ft_face
->
size
->
metrics
.
y_ppem
;
}
else
{
TM
.
tmAscent
=
SCALE_Y
(
ascent
);
...
...
@@ -7123,7 +6973,7 @@ static BOOL get_outline_text_metrics(GdiFont *font)
}
TM
.
tmMaxCharWidth
=
SCALE_X
(
ft_face
->
bbox
.
xMax
-
ft_face
->
bbox
.
xMin
);
TM
.
tmWeight
=
FW_REGULAR
;
if
(
gdi_
font
->
fake_bold
)
if
(
font
->
fake_bold
)
TM
.
tmWeight
=
FW_BOLD
;
else
{
...
...
@@ -7172,9 +7022,9 @@ static BOOL get_outline_text_metrics(GdiFont *font)
TM
.
tmBreakChar
=
pOS2
->
usFirstCharIndex
;
TM
.
tmDefaultChar
=
TM
.
tmBreakChar
-
1
;
}
TM
.
tmItalic
=
gdi_
font
->
fake_italic
?
255
:
((
ft_face
->
style_flags
&
FT_STYLE_FLAG_ITALIC
)
?
255
:
0
);
TM
.
tmUnderlined
=
gdi_
font
->
lf
.
lfUnderline
?
255
:
0
;
TM
.
tmStruckOut
=
gdi_
font
->
lf
.
lfStrikeOut
?
255
:
0
;
TM
.
tmItalic
=
font
->
fake_italic
?
255
:
((
ft_face
->
style_flags
&
FT_STYLE_FLAG_ITALIC
)
?
255
:
0
);
TM
.
tmUnderlined
=
font
->
lf
.
lfUnderline
?
255
:
0
;
TM
.
tmStruckOut
=
font
->
lf
.
lfStrikeOut
?
255
:
0
;
/* Yes TPMF_FIXED_PITCH is correct; braindead api */
if
(
!
FT_IS_FIXED_WIDTH
(
ft_face
)
&&
...
...
@@ -7242,112 +7092,61 @@ static BOOL get_outline_text_metrics(GdiFont *font)
if
(
FT_IS_SFNT
(
ft_face
))
{
if
(
gdi_
font
->
ntmFlags
&
NTM_PS_OPENTYPE
)
if
(
font
->
ntmFlags
&
NTM_PS_OPENTYPE
)
TM
.
tmPitchAndFamily
|=
TMPF_DEVICE
;
else
TM
.
tmPitchAndFamily
|=
TMPF_TRUETYPE
;
}
TM
.
tmCharSet
=
gdi_
font
->
charset
;
TM
.
tmCharSet
=
font
->
charset
;
font
->
potm
->
otmFiller
=
0
;
memcpy
(
&
font
->
potm
->
otmPanoseNumber
,
pOS2
->
panose
,
PANOSE_COUNT
);
font
->
potm
->
otmfsSelection
=
pOS2
->
fsSelection
;
if
(
gdi_
font
->
fake_italic
)
font
->
potm
->
otmfsSelection
|=
1
;
if
(
gdi_
font
->
fake_bold
)
font
->
potm
->
otmfsSelection
|=
1
<<
5
;
font
->
otm
.
otmFiller
=
0
;
memcpy
(
&
font
->
otm
.
otmPanoseNumber
,
pOS2
->
panose
,
PANOSE_COUNT
);
font
->
otm
.
otmfsSelection
=
pOS2
->
fsSelection
;
if
(
font
->
fake_italic
)
font
->
otm
.
otmfsSelection
|=
1
;
if
(
font
->
fake_bold
)
font
->
otm
.
otmfsSelection
|=
1
<<
5
;
/* Only return valid bits that define embedding and subsetting restrictions */
font
->
potm
->
otmfsType
=
pOS2
->
fsType
&
0x30e
;
font
->
potm
->
otmsCharSlopeRise
=
pHori
->
caret_Slope_Rise
;
font
->
potm
->
otmsCharSlopeRun
=
pHori
->
caret_Slope_Run
;
font
->
potm
->
otmItalicAngle
=
0
;
/* POST table */
font
->
potm
->
otmEMSquare
=
ft_face
->
units_per_EM
;
font
->
potm
->
otmAscent
=
SCALE_Y
(
pOS2
->
sTypoAscender
);
font
->
potm
->
otmDescent
=
SCALE_Y
(
pOS2
->
sTypoDescender
);
font
->
potm
->
otmLineGap
=
SCALE_Y
(
pOS2
->
sTypoLineGap
);
font
->
potm
->
otmsCapEmHeight
=
SCALE_Y
(
pOS2
->
sCapHeight
);
font
->
potm
->
otmsXHeight
=
SCALE_Y
(
pOS2
->
sxHeight
);
font
->
potm
->
otmrcFontBox
.
left
=
SCALE_X
(
ft_face
->
bbox
.
xMin
);
font
->
potm
->
otmrcFontBox
.
right
=
SCALE_X
(
ft_face
->
bbox
.
xMax
);
font
->
potm
->
otmrcFontBox
.
top
=
SCALE_Y
(
ft_face
->
bbox
.
yMax
);
font
->
potm
->
otmrcFontBox
.
bottom
=
SCALE_Y
(
ft_face
->
bbox
.
yMin
);
font
->
potm
->
otmMacAscent
=
TM
.
tmAscent
;
font
->
potm
->
otmMacDescent
=
-
TM
.
tmDescent
;
font
->
potm
->
otmMacLineGap
=
SCALE_Y
(
pHori
->
Line_Gap
);
font
->
potm
->
otmusMinimumPPEM
=
0
;
/* TT Header */
font
->
potm
->
otmptSubscriptSize
.
x
=
SCALE_X
(
pOS2
->
ySubscriptXSize
);
font
->
potm
->
otmptSubscriptSize
.
y
=
SCALE_Y
(
pOS2
->
ySubscriptYSize
);
font
->
potm
->
otmptSubscriptOffset
.
x
=
SCALE_X
(
pOS2
->
ySubscriptXOffset
);
font
->
potm
->
otmptSubscriptOffset
.
y
=
SCALE_Y
(
pOS2
->
ySubscriptYOffset
);
font
->
potm
->
otmptSuperscriptSize
.
x
=
SCALE_X
(
pOS2
->
ySuperscriptXSize
);
font
->
potm
->
otmptSuperscriptSize
.
y
=
SCALE_Y
(
pOS2
->
ySuperscriptYSize
);
font
->
potm
->
otmptSuperscriptOffset
.
x
=
SCALE_X
(
pOS2
->
ySuperscriptXOffset
);
font
->
potm
->
otmptSuperscriptOffset
.
y
=
SCALE_Y
(
pOS2
->
ySuperscriptYOffset
);
font
->
potm
->
otmsStrikeoutSize
=
SCALE_Y
(
pOS2
->
yStrikeoutSize
);
font
->
potm
->
otmsStrikeoutPosition
=
SCALE_Y
(
pOS2
->
yStrikeoutPosition
);
font
->
otm
.
otmfsType
=
pOS2
->
fsType
&
0x30e
;
font
->
otm
.
otmsCharSlopeRise
=
pHori
->
caret_Slope_Rise
;
font
->
otm
.
otmsCharSlopeRun
=
pHori
->
caret_Slope_Run
;
font
->
otm
.
otmItalicAngle
=
0
;
/* POST table */
font
->
otm
.
otmEMSquare
=
ft_face
->
units_per_EM
;
font
->
otm
.
otmAscent
=
SCALE_Y
(
pOS2
->
sTypoAscender
);
font
->
otm
.
otmDescent
=
SCALE_Y
(
pOS2
->
sTypoDescender
);
font
->
otm
.
otmLineGap
=
SCALE_Y
(
pOS2
->
sTypoLineGap
);
font
->
otm
.
otmsCapEmHeight
=
SCALE_Y
(
pOS2
->
sCapHeight
);
font
->
otm
.
otmsXHeight
=
SCALE_Y
(
pOS2
->
sxHeight
);
font
->
otm
.
otmrcFontBox
.
left
=
SCALE_X
(
ft_face
->
bbox
.
xMin
);
font
->
otm
.
otmrcFontBox
.
right
=
SCALE_X
(
ft_face
->
bbox
.
xMax
);
font
->
otm
.
otmrcFontBox
.
top
=
SCALE_Y
(
ft_face
->
bbox
.
yMax
);
font
->
otm
.
otmrcFontBox
.
bottom
=
SCALE_Y
(
ft_face
->
bbox
.
yMin
);
font
->
otm
.
otmMacAscent
=
TM
.
tmAscent
;
font
->
otm
.
otmMacDescent
=
-
TM
.
tmDescent
;
font
->
otm
.
otmMacLineGap
=
SCALE_Y
(
pHori
->
Line_Gap
);
font
->
otm
.
otmusMinimumPPEM
=
0
;
/* TT Header */
font
->
otm
.
otmptSubscriptSize
.
x
=
SCALE_X
(
pOS2
->
ySubscriptXSize
);
font
->
otm
.
otmptSubscriptSize
.
y
=
SCALE_Y
(
pOS2
->
ySubscriptYSize
);
font
->
otm
.
otmptSubscriptOffset
.
x
=
SCALE_X
(
pOS2
->
ySubscriptXOffset
);
font
->
otm
.
otmptSubscriptOffset
.
y
=
SCALE_Y
(
pOS2
->
ySubscriptYOffset
);
font
->
otm
.
otmptSuperscriptSize
.
x
=
SCALE_X
(
pOS2
->
ySuperscriptXSize
);
font
->
otm
.
otmptSuperscriptSize
.
y
=
SCALE_Y
(
pOS2
->
ySuperscriptYSize
);
font
->
otm
.
otmptSuperscriptOffset
.
x
=
SCALE_X
(
pOS2
->
ySuperscriptXOffset
);
font
->
otm
.
otmptSuperscriptOffset
.
y
=
SCALE_Y
(
pOS2
->
ySuperscriptYOffset
);
font
->
otm
.
otmsStrikeoutSize
=
SCALE_Y
(
pOS2
->
yStrikeoutSize
);
font
->
otm
.
otmsStrikeoutPosition
=
SCALE_Y
(
pOS2
->
yStrikeoutPosition
);
if
(
!
pPost
)
{
font
->
potm
->
otmsUnderscoreSize
=
0
;
font
->
potm
->
otmsUnderscorePosition
=
0
;
font
->
otm
.
otmsUnderscoreSize
=
0
;
font
->
otm
.
otmsUnderscorePosition
=
0
;
}
else
{
font
->
potm
->
otmsUnderscoreSize
=
SCALE_Y
(
pPost
->
underlineThickness
);
font
->
potm
->
otmsUnderscorePosition
=
SCALE_Y
(
pPost
->
underlinePosition
);
font
->
otm
.
otmsUnderscoreSize
=
SCALE_Y
(
pPost
->
underlineThickness
);
font
->
otm
.
otmsUnderscorePosition
=
SCALE_Y
(
pPost
->
underlinePosition
);
}
#undef SCALE_X
#undef SCALE_Y
#undef TM
/* otmp* members should clearly have type ptrdiff_t, but M$ knows best */
cp
=
(
char
*
)
font
->
potm
+
sizeof
(
*
font
->
potm
);
font
->
potm
->
otmpFamilyName
=
(
LPSTR
)(
cp
-
(
char
*
)
font
->
potm
);
strcpyW
((
WCHAR
*
)
cp
,
family_nameW
);
cp
+=
lenfam
;
font
->
potm
->
otmpStyleName
=
(
LPSTR
)(
cp
-
(
char
*
)
font
->
potm
);
strcpyW
((
WCHAR
*
)
cp
,
style_nameW
);
cp
+=
lensty
;
font
->
potm
->
otmpFaceName
=
(
LPSTR
)(
cp
-
(
char
*
)
font
->
potm
);
strcpyW
((
WCHAR
*
)
cp
,
face_nameW
);
cp
+=
lenface
;
font
->
potm
->
otmpFullName
=
(
LPSTR
)(
cp
-
(
char
*
)
font
->
potm
);
strcpyW
((
WCHAR
*
)
cp
,
full_nameW
);
ret
=
TRUE
;
end:
HeapFree
(
GetProcessHeap
(),
0
,
style_nameW
);
HeapFree
(
GetProcessHeap
(),
0
,
family_nameW
);
HeapFree
(
GetProcessHeap
(),
0
,
face_nameW
);
HeapFree
(
GetProcessHeap
(),
0
,
full_nameW
);
return
ret
;
}
/*************************************************************
* freetype_GetTextMetrics
*/
static
BOOL
CDECL
freetype_GetTextMetrics
(
struct
gdi_font
*
font
,
TEXTMETRICW
*
metrics
)
{
return
get_text_metrics
(
get_font_ptr
(
font
),
metrics
);
}
/*************************************************************
* freetype_GetOutlineTextMetrics
*/
static
UINT
CDECL
freetype_GetOutlineTextMetrics
(
struct
gdi_font
*
gdi_font
,
UINT
cbSize
,
OUTLINETEXTMETRICW
*
potm
)
{
GdiFont
*
font
=
get_font_ptr
(
gdi_font
);
UINT
ret
=
0
;
TRACE
(
"font=%p
\n
"
,
font
);
if
(
font
->
potm
||
get_outline_text_metrics
(
font
))
{
if
(
potm
&&
cbSize
>=
font
->
potm
->
otmSize
)
{
memcpy
(
potm
,
font
->
potm
,
font
->
potm
->
otmSize
);
scale_outline_font_metrics
(
font
,
potm
);
}
ret
=
font
->
potm
->
otmSize
;
}
return
ret
;
return
TRUE
;
}
static
BOOL
load_child_font
(
GdiFont
*
font
,
CHILD_FONT
*
child
)
...
...
@@ -7394,7 +7193,8 @@ static BOOL load_child_font(GdiFont *font, CHILD_FONT *child)
child_font
->
ntmFlags
=
child_face
->
ntmFlags
;
child_font
->
aa_flags
=
HIWORD
(
child_face
->
flags
);
child_font
->
scale_y
=
gdi_font
->
scale_y
;
set_gdi_font_name
(
child_font
,
child_face
->
family
->
family_name
);
set_gdi_font_names
(
child_font
,
child_face
->
family
->
family_name
,
child_face
->
style_name
,
child_face
->
full_name
);
child
->
font
->
base_font
=
font
;
TRACE
(
"created child font %p for base %p
\n
"
,
child
->
font
,
font
);
return
TRUE
;
...
...
@@ -7804,8 +7604,6 @@ static const struct font_backend_funcs font_funcs =
freetype_GetCharWidthInfo
,
freetype_GetFontUnicodeRanges
,
freetype_GetKerningPairs
,
freetype_GetOutlineTextMetrics
,
freetype_GetTextMetrics
,
freetype_SelectFont
,
freetype_AddFontResourceEx
,
freetype_RemoveFontResourceEx
,
...
...
@@ -7816,6 +7614,8 @@ static const struct font_backend_funcs font_funcs =
freetype_get_glyph_index
,
freetype_get_default_glyph
,
freetype_get_glyph_outline
,
freetype_set_outline_text_metrics
,
freetype_set_bitmap_text_metrics
,
freetype_destroy_font
};
...
...
dlls/gdi32/gdi_private.h
View file @
e0872b64
...
...
@@ -312,6 +312,7 @@ struct gdi_font
DWORD
refcount
;
DWORD
gm_size
;
struct
glyph_metrics
**
gm
;
OUTLINETEXTMETRICW
otm
;
/* the following members can be accessed without locking, they are never modified after creation */
void
*
private
;
/* font backend private data */
DWORD
handle
;
...
...
@@ -337,7 +338,6 @@ struct gdi_font
BOOL
fake_italic
:
1
;
BOOL
fake_bold
:
1
;
BOOL
scalable
:
1
;
WCHAR
*
name
;
void
*
data_ptr
;
SIZE_T
data_size
;
FILETIME
writetime
;
...
...
@@ -360,8 +360,6 @@ struct font_backend_funcs
BOOL
(
CDECL
*
pGetCharWidthInfo
)(
struct
gdi_font
*
font
,
struct
char_width_info
*
info
);
DWORD
(
CDECL
*
pGetFontUnicodeRanges
)(
struct
gdi_font
*
font
,
GLYPHSET
*
glyphset
);
DWORD
(
CDECL
*
pGetKerningPairs
)(
struct
gdi_font
*
font
,
DWORD
count
,
KERNINGPAIR
*
pairs
);
UINT
(
CDECL
*
pGetOutlineTextMetrics
)(
struct
gdi_font
*
font
,
UINT
size
,
OUTLINETEXTMETRICW
*
metrics
);
BOOL
(
CDECL
*
pGetTextMetrics
)(
struct
gdi_font
*
font
,
TEXTMETRICW
*
metrics
);
struct
gdi_font
*
(
CDECL
*
pSelectFont
)(
DC
*
dc
,
HFONT
hfont
,
UINT
*
aa_flags
,
UINT
default_aa_flags
);
INT
(
CDECL
*
pAddFontResourceEx
)(
LPCWSTR
file
,
DWORD
flags
,
PVOID
pdv
);
...
...
@@ -377,6 +375,8 @@ struct font_backend_funcs
UINT
(
CDECL
*
get_default_glyph
)(
struct
gdi_font
*
gdi_font
);
DWORD
(
CDECL
*
get_glyph_outline
)(
struct
gdi_font
*
font
,
UINT
glyph
,
UINT
format
,
GLYPHMETRICS
*
gm
,
ABC
*
abc
,
DWORD
buflen
,
void
*
buf
,
const
MAT2
*
mat
);
BOOL
(
CDECL
*
set_outline_text_metrics
)(
struct
gdi_font
*
font
);
BOOL
(
CDECL
*
set_bitmap_text_metrics
)(
struct
gdi_font
*
font
);
void
(
CDECL
*
destroy_font
)(
struct
gdi_font
*
font
);
};
...
...
@@ -385,7 +385,9 @@ extern void free_gdi_font( struct gdi_font *font ) DECLSPEC_HIDDEN;
extern
void
cache_gdi_font
(
struct
gdi_font
*
font
)
DECLSPEC_HIDDEN
;
extern
struct
gdi_font
*
find_cached_gdi_font
(
const
LOGFONTW
*
lf
,
const
FMAT2
*
matrix
,
BOOL
can_use_bitmap
)
DECLSPEC_HIDDEN
;
extern
void
set_gdi_font_name
(
struct
gdi_font
*
font
,
const
WCHAR
*
name
)
DECLSPEC_HIDDEN
;
static
inline
const
WCHAR
*
get_gdi_font_name
(
struct
gdi_font
*
font
)
{
return
(
WCHAR
*
)
font
->
otm
.
otmpFamilyName
;
}
extern
void
set_gdi_font_names
(
struct
gdi_font
*
font
,
const
WCHAR
*
family_name
,
const
WCHAR
*
style_name
,
const
WCHAR
*
full_name
)
DECLSPEC_HIDDEN
;
extern
BOOL
get_gdi_font_glyph_metrics
(
struct
gdi_font
*
font
,
UINT
index
,
GLYPHMETRICS
*
gm
,
ABC
*
abc
)
DECLSPEC_HIDDEN
;
extern
void
set_gdi_font_glyph_metrics
(
struct
gdi_font
*
font
,
UINT
index
,
...
...
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