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
9aa8300f
Commit
9aa8300f
authored
Feb 07, 2013
by
Akihiro Sagawa
Committed by
Alexandre Julliard
Feb 07, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gdi32: Ensure a fixed-pitch full-width character has double advance of a half-width character.
parent
68d72f47
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
122 additions
and
3 deletions
+122
-3
freetype.c
dlls/gdi32/freetype.c
+34
-3
font.c
dlls/gdi32/tests/font.c
+88
-0
No files found.
dlls/gdi32/freetype.c
View file @
9aa8300f
...
...
@@ -5821,6 +5821,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
BOOL
needsTransform
=
FALSE
;
BOOL
tategaki
=
(
font
->
GSUB_Table
!=
NULL
);
UINT
original_index
;
FT_Fixed
avgAdvance
=
0
;
TRACE
(
"%p, %04x, %08x, %p, %08x, %p, %p
\n
"
,
font
,
glyph
,
format
,
lpgm
,
buflen
,
buf
,
lpmat
);
...
...
@@ -5957,10 +5958,26 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
return
GDI_ERROR
;
}
if
(
FT_IS_SCALABLE
(
incoming_font
->
ft_face
))
{
TEXTMETRICW
tm
;
if
(
get_text_metrics
(
incoming_font
,
&
tm
)
&&
!
(
tm
.
tmPitchAndFamily
&
TMPF_FIXED_PITCH
))
{
avgAdvance
=
pFT_MulFix
(
incoming_font
->
ntmAvgWidth
,
incoming_font
->
ft_face
->
size
->
metrics
.
x_scale
);
if
(
avgAdvance
&&
(
ft_face
->
glyph
->
metrics
.
horiAdvance
+
63
)
>>
6
==
(
avgAdvance
*
2
+
63
)
>>
6
)
TRACE
(
"Fixed-pitch full-width character detected
\n
"
);
else
avgAdvance
=
0
;
/* cancel this feature */
}
}
if
(
!
needsTransform
)
{
left
=
(
INT
)(
ft_face
->
glyph
->
metrics
.
horiBearingX
)
&
-
64
;
right
=
(
INT
)((
ft_face
->
glyph
->
metrics
.
horiBearingX
+
ft_face
->
glyph
->
metrics
.
width
)
+
63
)
&
-
64
;
adv
=
(
INT
)(
ft_face
->
glyph
->
metrics
.
horiAdvance
+
63
)
>>
6
;
if
(
!
avgAdvance
)
adv
=
(
INT
)(
ft_face
->
glyph
->
metrics
.
horiAdvance
+
63
)
>>
6
;
else
adv
=
(
INT
)((
avgAdvance
+
32
)
>>
6
)
*
2
;
top
=
(
ft_face
->
glyph
->
metrics
.
horiBearingY
+
63
)
&
-
64
;
bottom
=
(
ft_face
->
glyph
->
metrics
.
horiBearingY
-
...
...
@@ -6001,13 +6018,27 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
vec
.
x
=
ft_face
->
glyph
->
metrics
.
horiAdvance
;
vec
.
y
=
0
;
pFT_Vector_Transform
(
&
vec
,
&
transMat
);
lpgm
->
gmCellIncX
=
(
vec
.
x
+
63
)
>>
6
;
lpgm
->
gmCellIncY
=
-
((
vec
.
y
+
63
)
>>
6
);
if
(
!
avgAdvance
||
vec
.
y
)
lpgm
->
gmCellIncX
=
(
vec
.
x
+
63
)
>>
6
;
else
{
vec
.
x
=
avgAdvance
;
vec
.
y
=
0
;
pFT_Vector_Transform
(
&
vec
,
&
transMat
);
lpgm
->
gmCellIncX
=
((
vec
.
x
+
32
)
>>
6
)
*
2
;
}
vec
.
x
=
ft_face
->
glyph
->
metrics
.
horiAdvance
;
vec
.
y
=
0
;
pFT_Vector_Transform
(
&
vec
,
&
transMatUnrotated
);
adv
=
(
vec
.
x
+
63
)
>>
6
;
if
(
!
avgAdvance
||
vec
.
y
)
adv
=
(
vec
.
x
+
63
)
>>
6
;
else
{
vec
.
x
=
avgAdvance
;
vec
.
y
=
0
;
pFT_Vector_Transform
(
&
vec
,
&
transMatUnrotated
);
adv
=
((
vec
.
x
+
32
)
>>
6
)
*
2
;
}
}
lpgm
->
gmBlackBoxX
=
(
right
-
left
)
>>
6
;
...
...
dlls/gdi32/tests/font.c
View file @
9aa8300f
...
...
@@ -3552,6 +3552,38 @@ todo_wine
DeleteDC
(
hdc
);
}
static
int
CALLBACK
create_fixed_pitch_font_proc
(
const
LOGFONT
*
lpelfe
,
const
TEXTMETRIC
*
lpntme
,
DWORD
FontType
,
LPARAM
lParam
)
{
const
NEWTEXTMETRICEX
*
lpntmex
=
(
const
NEWTEXTMETRICEX
*
)
lpntme
;
CHARSETINFO
csi
;
LOGFONT
lf
=
*
lpelfe
;
HFONT
hfont
;
/* skip bitmap, proportional or vertical font */
if
((
FontType
&
TRUETYPE_FONTTYPE
)
==
0
||
(
lf
.
lfPitchAndFamily
&
0xf
)
!=
FIXED_PITCH
||
lf
.
lfFaceName
[
0
]
==
'@'
)
return
1
;
/* skip linked font */
if
(
!
TranslateCharsetInfo
((
DWORD
*
)(
INT_PTR
)
lpelfe
->
lfCharSet
,
&
csi
,
TCI_SRCCHARSET
)
||
(
lpntmex
->
ntmFontSig
.
fsCsb
[
0
]
&
csi
.
fs
.
fsCsb
[
0
])
==
0
)
return
1
;
/* test with an odd height */
lf
.
lfHeight
=
-
19
;
lf
.
lfWidth
=
0
;
hfont
=
CreateFontIndirect
(
&
lf
);
if
(
hfont
)
{
*
(
HFONT
*
)
lParam
=
hfont
;
return
0
;
}
return
1
;
}
static
void
test_GetGlyphOutline
(
void
)
{
HDC
hdc
;
...
...
@@ -3640,6 +3672,8 @@ static void test_GetGlyphOutline(void)
for
(
i
=
0
;
i
<
sizeof
c
/
sizeof
c
[
0
];
++
i
)
{
static
const
MAT2
rotate_mat
=
{{
0
,
0
},
{
0
,
-
1
},
{
0
,
1
},
{
0
,
0
}};
lf
.
lfFaceName
[
0
]
=
'\0'
;
lf
.
lfCharSet
=
c
[
i
].
cs
;
lf
.
lfPitchAndFamily
=
0
;
...
...
@@ -3670,6 +3704,60 @@ static void test_GetGlyphOutline(void)
ret2
=
GetGlyphOutlineW
(
hdc
,
c
[
i
].
w
,
GGO_BITMAP
,
&
gm2
,
0
,
NULL
,
&
mat
);
ok
(
ret
==
ret2
&&
memcmp
(
&
gm
,
&
gm2
,
sizeof
gm
)
==
0
,
"%d %d
\n
"
,
ret
,
ret2
);
if
(
EnumFontFamiliesEx
(
hdc
,
&
lf
,
create_fixed_pitch_font_proc
,
(
LPARAM
)
&
hfont
,
0
))
{
skip
(
"Fixed-pitch TrueType font for charset %u is not available
\n
"
,
c
[
i
].
cs
);
continue
;
}
DeleteObject
(
SelectObject
(
hdc
,
hfont
));
if
(
c
[
i
].
a
<=
0xff
)
{
DeleteObject
(
SelectObject
(
hdc
,
old_hfont
));
continue
;
}
ret
=
GetObject
(
hfont
,
sizeof
lf
,
&
lf
);
ok
(
ret
>
0
,
"GetObject error %u
\n
"
,
GetLastError
());
ret
=
GetGlyphOutlineA
(
hdc
,
'A'
,
GGO_METRICS
,
&
gm
,
0
,
NULL
,
&
mat
);
ok
(
ret
!=
GDI_ERROR
,
"GetGlyphOutlineA error %u
\n
"
,
GetLastError
());
ret
=
GetGlyphOutlineA
(
hdc
,
c
[
i
].
a
,
GGO_METRICS
,
&
gm2
,
0
,
NULL
,
&
mat
);
ok
(
ret
!=
GDI_ERROR
,
"GetGlyphOutlineA error %u
\n
"
,
GetLastError
());
trace
(
"Tests with height=%d,half=%d,full=%d,face=%s,charset=%d
\n
"
,
-
lf
.
lfHeight
,
gm
.
gmCellIncX
,
gm2
.
gmCellIncX
,
lf
.
lfFaceName
,
lf
.
lfCharSet
);
ok
(
gm2
.
gmCellIncX
==
gm
.
gmCellIncX
*
2
||
broken
(
gm2
.
gmCellIncX
==
-
lf
.
lfHeight
),
"expected %d, got %d (%s:%d)
\n
"
,
gm
.
gmCellIncX
*
2
,
gm2
.
gmCellIncX
,
lf
.
lfFaceName
,
lf
.
lfCharSet
);
ret
=
GetGlyphOutlineA
(
hdc
,
c
[
i
].
a
,
GGO_METRICS
,
&
gm2
,
0
,
NULL
,
&
rotate_mat
);
ok
(
ret
!=
GDI_ERROR
,
"GetGlyphOutlineA error %u
\n
"
,
GetLastError
());
ok
(
gm2
.
gmCellIncY
==
-
lf
.
lfHeight
,
"expected %d, got %d (%s:%d)
\n
"
,
-
lf
.
lfHeight
,
gm2
.
gmCellIncY
,
lf
.
lfFaceName
,
lf
.
lfCharSet
);
lf
.
lfItalic
=
TRUE
;
hfont
=
CreateFontIndirect
(
&
lf
);
ok
(
hfont
!=
NULL
,
"CreateFontIndirect error %u
\n
"
,
GetLastError
());
DeleteObject
(
SelectObject
(
hdc
,
hfont
));
ret
=
GetGlyphOutlineA
(
hdc
,
'A'
,
GGO_METRICS
,
&
gm
,
0
,
NULL
,
&
mat
);
ok
(
ret
!=
GDI_ERROR
,
"GetGlyphOutlineA error %u
\n
"
,
GetLastError
());
ret
=
GetGlyphOutlineA
(
hdc
,
c
[
i
].
a
,
GGO_METRICS
,
&
gm2
,
0
,
NULL
,
&
mat
);
ok
(
ret
!=
GDI_ERROR
,
"GetGlyphOutlineA error %u
\n
"
,
GetLastError
());
ok
(
gm2
.
gmCellIncX
==
gm
.
gmCellIncX
*
2
||
broken
(
gm2
.
gmCellIncX
==
-
lf
.
lfHeight
),
"expected %d, got %d (%s:%d)
\n
"
,
gm
.
gmCellIncX
*
2
,
gm2
.
gmCellIncX
,
lf
.
lfFaceName
,
lf
.
lfCharSet
);
lf
.
lfItalic
=
FALSE
;
lf
.
lfEscapement
=
lf
.
lfOrientation
=
2700
;
hfont
=
CreateFontIndirect
(
&
lf
);
ok
(
hfont
!=
NULL
,
"CreateFontIndirect error %u
\n
"
,
GetLastError
());
DeleteObject
(
SelectObject
(
hdc
,
hfont
));
ret
=
GetGlyphOutlineA
(
hdc
,
c
[
i
].
a
,
GGO_METRICS
,
&
gm2
,
0
,
NULL
,
&
mat
);
ok
(
ret
!=
GDI_ERROR
,
"GetGlyphOutlineA error %u
\n
"
,
GetLastError
());
ok
(
gm2
.
gmCellIncY
==
-
lf
.
lfHeight
,
"expected %d, got %d (%s:%d)
\n
"
,
-
lf
.
lfHeight
,
gm2
.
gmCellIncY
,
lf
.
lfFaceName
,
lf
.
lfCharSet
);
hfont
=
SelectObject
(
hdc
,
old_hfont
);
DeleteObject
(
hfont
);
}
...
...
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