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
21dbe1c9
Commit
21dbe1c9
authored
Apr 30, 2013
by
Sam Edwards
Committed by
Alexandre Julliard
May 02, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gdi32: Clip font glyphs to fit within text metrics.
parent
a7dee44c
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
119 additions
and
23 deletions
+119
-23
freetype.c
dlls/gdi32/freetype.c
+28
-13
font.c
dlls/gdi32/tests/font.c
+41
-0
wine_test.sfd
dlls/gdi32/tests/wine_test.sfd
+50
-10
wine_test.ttf
dlls/gdi32/tests/wine_test.ttf
+0
-0
No files found.
dlls/gdi32/freetype.c
View file @
21dbe1c9
...
...
@@ -538,6 +538,7 @@ static BOOL use_default_fallback = FALSE;
static
BOOL
get_glyph_index_linked
(
GdiFont
*
font
,
UINT
c
,
GdiFont
**
linked_font
,
FT_UInt
*
glyph
);
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
void
remove_face_from_cache
(
Face
*
face
);
...
...
@@ -5868,6 +5869,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
static
const
FT_Matrix
identityMat
=
{(
1
<<
16
),
0
,
0
,
(
1
<<
16
)};
FT_Face
ft_face
=
incoming_font
->
ft_face
;
GdiFont
*
font
=
incoming_font
;
FT_Glyph_Metrics
metrics
;
FT_UInt
glyph_index
;
DWORD
width
,
height
,
pitch
,
needed
=
0
;
FT_Bitmap
ft_bitmap
;
...
...
@@ -6019,6 +6021,22 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
return
GDI_ERROR
;
}
/* 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. */
metrics
=
ft_face
->
glyph
->
metrics
;
if
(
incoming_font
->
potm
||
get_outline_text_metrics
(
incoming_font
)
||
get_bitmap_text_metrics
(
incoming_font
))
{
TEXTMETRICW
*
ptm
=
&
incoming_font
->
potm
->
otmTextMetrics
;
top
=
min
(
metrics
.
horiBearingY
,
ptm
->
tmAscent
<<
6
);
bottom
=
max
(
metrics
.
horiBearingY
-
metrics
.
height
,
-
(
ptm
->
tmDescent
<<
6
)
);
metrics
.
horiBearingY
=
top
;
metrics
.
height
=
top
-
bottom
;
/* TODO: Are we supposed to clip the width as well...? */
/* metrics.width = min( metrics.width, ptm->tmMaxCharWidth << 6 ); */
}
if
(
FT_IS_SCALABLE
(
incoming_font
->
ft_face
))
{
TEXTMETRICW
tm
;
if
(
get_text_metrics
(
incoming_font
,
&
tm
)
&&
...
...
@@ -6026,7 +6044,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
em_scale
=
MulDiv
(
incoming_font
->
ppem
,
1
<<
16
,
incoming_font
->
ft_face
->
units_per_EM
);
avgAdvance
=
pFT_MulFix
(
incoming_font
->
ntmAvgWidth
,
em_scale
);
if
(
avgAdvance
&&
(
ft_face
->
glyph
->
metrics
.
horiAdvance
+
63
)
>>
6
==
pFT_MulFix
(
incoming_font
->
ntmAvgWidth
*
2
,
em_scale
))
(
metrics
.
horiAdvance
+
63
)
>>
6
==
pFT_MulFix
(
incoming_font
->
ntmAvgWidth
*
2
,
em_scale
))
TRACE
(
"Fixed-pitch full-width character detected
\n
"
);
else
avgAdvance
=
0
;
/* cancel this feature */
...
...
@@ -6034,16 +6052,15 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
}
if
(
!
needsTransform
)
{
left
=
(
INT
)(
ft_face
->
glyph
->
metrics
.
horiBearingX
)
&
-
64
;
right
=
(
INT
)((
ft_face
->
glyph
->
metrics
.
horiBearingX
+
ft_face
->
glyph
->
metrics
.
width
)
+
63
)
&
-
64
;
left
=
(
INT
)(
metrics
.
horiBearingX
)
&
-
64
;
right
=
(
INT
)((
metrics
.
horiBearingX
+
metrics
.
width
)
+
63
)
&
-
64
;
if
(
!
avgAdvance
)
adv
=
(
INT
)(
ft_face
->
glyph
->
metrics
.
horiAdvance
+
63
)
>>
6
;
adv
=
(
INT
)(
metrics
.
horiAdvance
+
63
)
>>
6
;
else
adv
=
(
INT
)
avgAdvance
*
2
;
top
=
(
ft_face
->
glyph
->
metrics
.
horiBearingY
+
63
)
&
-
64
;
bottom
=
(
ft_face
->
glyph
->
metrics
.
horiBearingY
-
ft_face
->
glyph
->
metrics
.
height
)
&
-
64
;
top
=
(
metrics
.
horiBearingY
+
63
)
&
-
64
;
bottom
=
(
metrics
.
horiBearingY
-
metrics
.
height
)
&
-
64
;
lpgm
->
gmCellIncX
=
adv
;
lpgm
->
gmCellIncY
=
0
;
}
else
{
...
...
@@ -6054,10 +6071,8 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
for
(
xc
=
0
;
xc
<
2
;
xc
++
)
{
for
(
yc
=
0
;
yc
<
2
;
yc
++
)
{
vec
.
x
=
(
ft_face
->
glyph
->
metrics
.
horiBearingX
+
xc
*
ft_face
->
glyph
->
metrics
.
width
);
vec
.
y
=
ft_face
->
glyph
->
metrics
.
horiBearingY
-
yc
*
ft_face
->
glyph
->
metrics
.
height
;
vec
.
x
=
metrics
.
horiBearingX
+
xc
*
metrics
.
width
;
vec
.
y
=
metrics
.
horiBearingY
-
yc
*
metrics
.
height
;
TRACE
(
"Vec %ld,%ld
\n
"
,
vec
.
x
,
vec
.
y
);
pFT_Vector_Transform
(
&
vec
,
&
transMat
);
if
(
xc
==
0
&&
yc
==
0
)
{
...
...
@@ -6077,7 +6092,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
top
=
(
top
+
63
)
&
-
64
;
TRACE
(
"transformed box: (%d,%d - %d,%d)
\n
"
,
left
,
top
,
right
,
bottom
);
vec
.
x
=
ft_face
->
glyph
->
metrics
.
horiAdvance
;
vec
.
x
=
metrics
.
horiAdvance
;
vec
.
y
=
0
;
pFT_Vector_Transform
(
&
vec
,
&
transMat
);
lpgm
->
gmCellIncY
=
-
((
vec
.
y
+
63
)
>>
6
);
...
...
@@ -6090,7 +6105,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
lpgm
->
gmCellIncX
=
pFT_MulFix
(
vec
.
x
,
em_scale
)
*
2
;
}
vec
.
x
=
ft_face
->
glyph
->
metrics
.
horiAdvance
;
vec
.
x
=
metrics
.
horiAdvance
;
vec
.
y
=
0
;
pFT_Vector_Transform
(
&
vec
,
&
transMatUnrotated
);
if
(
!
avgAdvance
||
vec
.
y
)
...
...
dlls/gdi32/tests/font.c
View file @
21dbe1c9
...
...
@@ -4561,6 +4561,46 @@ static void test_GetGlyphOutline_empty_contour(void)
ReleaseDC
(
NULL
,
hdc
);
}
static
void
test_GetGlyphOutline_metric_clipping
(
void
)
{
HDC
hdc
;
LOGFONTA
lf
;
HFONT
hfont
,
hfont_prev
;
GLYPHMETRICS
gm
;
TEXTMETRICA
tm
;
DWORD
ret
;
memset
(
&
lf
,
0
,
sizeof
(
lf
));
lf
.
lfHeight
=
72
;
lstrcpyA
(
lf
.
lfFaceName
,
"wine_test"
);
SetLastError
(
0xdeadbeef
);
hfont
=
CreateFontIndirectA
(
&
lf
);
ok
(
hfont
!=
0
,
"CreateFontIndirectA error %u
\n
"
,
GetLastError
());
hdc
=
GetDC
(
NULL
);
hfont_prev
=
SelectObject
(
hdc
,
hfont
);
ok
(
hfont_prev
!=
NULL
,
"SelectObject failed
\n
"
);
SetLastError
(
0xdeadbeef
);
ret
=
GetTextMetrics
(
hdc
,
&
tm
);
ok
(
ret
,
"GetTextMetrics error %u
\n
"
,
GetLastError
());
GetGlyphOutlineA
(
hdc
,
'A'
,
GGO_METRICS
,
&
gm
,
0
,
NULL
,
&
mat
);
ok
(
gm
.
gmptGlyphOrigin
.
y
<=
tm
.
tmAscent
,
"Glyph top(%d) exceeds ascent(%d)
\n
"
,
gm
.
gmptGlyphOrigin
.
y
,
tm
.
tmAscent
);
GetGlyphOutlineA
(
hdc
,
'D'
,
GGO_METRICS
,
&
gm
,
0
,
NULL
,
&
mat
);
ok
(
gm
.
gmptGlyphOrigin
.
y
-
gm
.
gmBlackBoxY
>=
-
tm
.
tmDescent
,
"Glyph bottom(%d) exceeds descent(%d)
\n
"
,
gm
.
gmptGlyphOrigin
.
y
-
gm
.
gmBlackBoxY
,
-
tm
.
tmDescent
);
SelectObject
(
hdc
,
hfont_prev
);
DeleteObject
(
hfont
);
ReleaseDC
(
NULL
,
hdc
);
}
static
void
test_CreateScalableFontResource
(
void
)
{
char
ttf_name
[
MAX_PATH
];
...
...
@@ -4643,6 +4683,7 @@ static void test_CreateScalableFontResource(void)
ok
(
ret
,
"font wine_test should be enumerated
\n
"
);
test_GetGlyphOutline_empty_contour
();
test_GetGlyphOutline_metric_clipping
();
ret
=
pRemoveFontResourceExA
(
fot_name
,
FR_PRIVATE
,
0
);
ok
(
!
ret
,
"RemoveFontResourceEx() with not matching flags should fail
\n
"
);
...
...
dlls/gdi32/tests/wine_test.sfd
View file @
21dbe1c9
...
...
@@ -20,7 +20,7 @@ OS2Version: 2
OS2_WeightWidthSlopeOnly: 0
OS2_UseTypoMetrics: 1
CreationTime: 1288336343
ModificationTime: 13
52483620
ModificationTime: 13
66465321
PfmFamily: 17
TTFWeight: 500
TTFWidth: 5
...
...
@@ -32,10 +32,10 @@ OS2TypoAOffset: 1
OS2TypoDescent: 0
OS2TypoDOffset: 1
OS2TypoLinegap: 184
OS2WinAscent:
0
OS2WinAOffset:
1
OS2WinDescent: 0
OS2WinDOffset:
1
OS2WinAscent:
1638
OS2WinAOffset:
0
OS2WinDescent:
41
0
OS2WinDOffset:
0
HheadAscent: 0
HheadAOffset: 1
HheadDescent: 0
...
...
@@ -78,15 +78,17 @@ ShortTable: maxp 16
0
EndShort
LangName: 1033 "" "" "" "Wine : wine_test : 4-11-2010"
GaspTable: 1 65535 2
GaspTable: 1 65535 2
0
Encoding: UnicodeBmp
UnicodeInterp: none
NameList: Adobe Glyph List
DisplaySize: -24
AntiAlias: 1
FitToEm: 1
WinInfo: 65 65 19
BeginChars: 65539 5
WinInfo: 48 16 4
BeginPrivate: 0
EndPrivate
BeginChars: 65539 7
StartChar: .notdef
Encoding: 65536 -1 0
...
...
@@ -178,10 +180,10 @@ LayerCount: 2
EndChar
StartChar: dieresis
Encoding: 168 168
0
Encoding: 168 168
4
Width: 1000
VWidth: 0
Flags:
H
W
Flags: W
LayerCount: 2
Fore
SplineSet
...
...
@@ -201,5 +203,43 @@ SplineSet
310.707 834.805 310.707 834.805 254.492 773.213 c 1,12,13
EndSplineSet
EndChar
StartChar: A
Encoding: 65 65 5
Width: 1000
VWidth: 0
Flags: WO
LayerCount: 2
Fore
SplineSet
459 1258 m 29,0,-1
462 1639 l 5,1,-1
389 1638 l 5,2,-1
492 1815 l 5,3,-1
609 1638.5 l 5,4,-1
531 1637.5 l 5,5,-1
523 1258 l 5,6,-1
459 1258 l 29,0,-1
EndSplineSet
EndChar
StartChar: D
Encoding: 68 68 6
Width: 1000
VWidth: 0
Flags: WO
LayerCount: 2
Fore
SplineSet
461 -30.7998 m 29,0,-1
464 -411.8 l 5,1,-1
391 -410.8 l 5,2,-1
494 -587.8 l 5,3,-1
611 -411.3 l 5,4,-1
533 -410.3 l 5,5,-1
525 -30.7998 l 5,6,-1
461 -30.7998 l 29,0,-1
EndSplineSet
EndChar
EndChars
EndSplineFont
dlls/gdi32/tests/wine_test.ttf
View file @
21dbe1c9
No preview for this file type
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