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
ce6d4c72
Commit
ce6d4c72
authored
Sep 21, 2006
by
Dmitry Timoshkov
Committed by
Alexandre Julliard
Sep 26, 2006
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gdi32: Implement GetKerningPairs for TrueType fonts.
parent
84a63306
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
307 additions
and
10 deletions
+307
-10
font.c
dlls/gdi/font.c
+70
-10
freetype.c
dlls/gdi/freetype.c
+236
-0
gdi_private.h
dlls/gdi/gdi_private.h
+1
-0
No files found.
dlls/gdi/font.c
View file @
ce6d4c72
...
...
@@ -2514,11 +2514,68 @@ BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
* GetKerningPairsA (GDI32.@)
*/
DWORD
WINAPI
GetKerningPairsA
(
HDC
hDC
,
DWORD
cPairs
,
LPKERNINGPAIR
lpKerningPairs
)
LPKERNINGPAIR
kern_pairA
)
{
return
GetKerningPairsW
(
hDC
,
cPairs
,
lpKerningPairs
);
}
INT
charset
;
CHARSETINFO
csi
;
CPINFO
cpi
;
DWORD
i
,
total_kern_pairs
,
kern_pairs_copied
=
0
;
KERNINGPAIR
*
kern_pairW
;
if
(
!
cPairs
&&
kern_pairA
)
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
0
;
}
charset
=
GetTextCharset
(
hDC
);
if
(
!
TranslateCharsetInfo
((
DWORD
*
)
charset
,
&
csi
,
TCI_SRCCHARSET
))
{
FIXME
(
"Can't find codepage for charset %d
\n
"
,
charset
);
return
0
;
}
if
(
!
GetCPInfo
(
csi
.
ciACP
,
&
cpi
))
{
FIXME
(
"Can't find codepage %u info
\n
"
,
csi
.
ciACP
);
return
0
;
}
TRACE
(
"charset %d => codepage %u
\n
"
,
charset
,
csi
.
ciACP
);
total_kern_pairs
=
GetKerningPairsW
(
hDC
,
0
,
NULL
);
if
(
!
total_kern_pairs
)
return
0
;
kern_pairW
=
HeapAlloc
(
GetProcessHeap
(),
0
,
total_kern_pairs
*
sizeof
(
*
kern_pairW
));
GetKerningPairsW
(
hDC
,
total_kern_pairs
,
kern_pairW
);
for
(
i
=
0
;
i
<
total_kern_pairs
;
i
++
)
{
char
first
,
second
;
if
(
!
WideCharToMultiByte
(
csi
.
ciACP
,
0
,
&
kern_pairW
[
i
].
wFirst
,
1
,
&
first
,
1
,
NULL
,
NULL
))
continue
;
if
(
!
WideCharToMultiByte
(
csi
.
ciACP
,
0
,
&
kern_pairW
[
i
].
wSecond
,
1
,
&
second
,
1
,
NULL
,
NULL
))
continue
;
if
(
first
==
cpi
.
DefaultChar
[
0
]
||
second
==
cpi
.
DefaultChar
[
0
])
continue
;
if
(
kern_pairA
)
{
if
(
kern_pairs_copied
>=
cPairs
)
break
;
kern_pairA
->
wFirst
=
(
BYTE
)
first
;
kern_pairA
->
wSecond
=
(
BYTE
)
second
;
kern_pairA
->
iKernAmount
=
kern_pairW
[
i
].
iKernAmount
;
kern_pairA
++
;
}
kern_pairs_copied
++
;
}
HeapFree
(
GetProcessHeap
(),
0
,
kern_pairW
);
return
kern_pairs_copied
;
}
/*************************************************************************
* GetKerningPairsW (GDI32.@)
...
...
@@ -2526,15 +2583,18 @@ DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
DWORD
WINAPI
GetKerningPairsW
(
HDC
hDC
,
DWORD
cPairs
,
LPKERNINGPAIR
lpKerningPairs
)
{
unsigned
int
i
;
FIXME
(
"(%p,%ld,%p): almost empty stub!
\n
"
,
hDC
,
cPairs
,
lpKerningPairs
)
;
DC
*
dc
=
DC_GetDCPtr
(
hDC
)
;
DWORD
ret
=
0
;
if
(
!
lpKerningPairs
)
/* return the number of kerning pairs */
return
0
;
TRACE
(
"(%p,%ld,%p)
\n
"
,
hDC
,
cPairs
,
lpKerningPairs
);
for
(
i
=
0
;
i
<
cPairs
;
i
++
)
lpKerningPairs
[
i
].
iKernAmount
=
0
;
return
0
;
if
(
!
dc
)
return
0
;
if
(
dc
->
gdiFont
)
ret
=
WineEngGetKerningPairs
(
dc
->
gdiFont
,
cPairs
,
lpKerningPairs
);
GDI_ReleaseObj
(
hDC
);
return
ret
;
}
/*************************************************************************
...
...
dlls/gdi/freetype.c
View file @
ce6d4c72
...
...
@@ -2,6 +2,7 @@
* FreeType font engine interface
*
* Copyright 2001 Huw D M Davies for CodeWeavers.
* Copyright 2006 Dmitry Timoshkov for CodeWeavers.
*
* This file contains the WineEng* functions.
*
...
...
@@ -134,6 +135,7 @@ MAKE_FUNCPTR(FT_Vector_Transform);
static
void
(
*
pFT_Library_Version
)(
FT_Library
,
FT_Int
*
,
FT_Int
*
,
FT_Int
*
);
static
FT_Error
(
*
pFT_Load_Sfnt_Table
)(
FT_Face
,
FT_ULong
,
FT_Long
,
FT_Byte
*
,
FT_ULong
*
);
static
FT_ULong
(
*
pFT_Get_First_Char
)(
FT_Face
,
FT_UInt
*
);
static
FT_ULong
(
*
pFT_Get_Next_Char
)(
FT_Face
,
FT_ULong
,
FT_UInt
*
);
static
FT_TrueTypeEngineType
(
*
pFT_Get_TrueType_Engine_Type
)(
FT_Library
);
#ifdef HAVE_FREETYPE_FTWINFNT_H
MAKE_FUNCPTR
(
FT_Get_WinFNT_Header
);
...
...
@@ -268,6 +270,8 @@ struct tagGdiFont {
SHORT
yMax
;
SHORT
yMin
;
OUTLINETEXTMETRICW
*
potm
;
DWORD
total_kern_pairs
;
KERNINGPAIR
*
kern_pairs
;
FONTSIGNATURE
fs
;
GdiFont
base_font
;
struct
list
child_fonts
;
...
...
@@ -1652,6 +1656,7 @@ BOOL WineEngInit(void)
pFT_Library_Version
=
wine_dlsym
(
ft_handle
,
"FT_Library_Version"
,
NULL
,
0
);
pFT_Load_Sfnt_Table
=
wine_dlsym
(
ft_handle
,
"FT_Load_Sfnt_Table"
,
NULL
,
0
);
pFT_Get_First_Char
=
wine_dlsym
(
ft_handle
,
"FT_Get_First_Char"
,
NULL
,
0
);
pFT_Get_Next_Char
=
wine_dlsym
(
ft_handle
,
"FT_Get_Next_Char"
,
NULL
,
0
);
pFT_Get_TrueType_Engine_Type
=
wine_dlsym
(
ft_handle
,
"FT_Get_TrueType_Engine_Type"
,
NULL
,
0
);
#ifdef HAVE_FREETYPE_FTWINFNT_H
pFT_Get_WinFNT_Header
=
wine_dlsym
(
ft_handle
,
"FT_Get_WinFNT_Header"
,
NULL
,
0
);
...
...
@@ -1938,6 +1943,8 @@ static GdiFont alloc_font(void)
ret
->
gmsize
*
sizeof
(
*
ret
->
gm
));
ret
->
potm
=
NULL
;
ret
->
font_desc
.
matrix
.
eM11
=
ret
->
font_desc
.
matrix
.
eM22
=
1
.
0
;
ret
->
total_kern_pairs
=
(
DWORD
)
-
1
;
ret
->
kern_pairs
=
NULL
;
list_init
(
&
ret
->
hfontlist
);
list_init
(
&
ret
->
child_fonts
);
return
ret
;
...
...
@@ -1966,6 +1973,7 @@ static void free_font(GdiFont font)
}
if
(
font
->
ft_face
)
pFT_Done_Face
(
font
->
ft_face
);
HeapFree
(
GetProcessHeap
(),
0
,
font
->
kern_pairs
);
HeapFree
(
GetProcessHeap
(),
0
,
font
->
potm
);
HeapFree
(
GetProcessHeap
(),
0
,
font
->
name
);
HeapFree
(
GetProcessHeap
(),
0
,
font
->
gm
);
...
...
@@ -4096,6 +4104,228 @@ BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
return
TRUE
;
}
/*************************************************************************
* Kerning support for TrueType fonts
*/
#define MS_KERN_TAG MS_MAKE_TAG('k', 'e', 'r', 'n')
struct
TT_kern_table
{
USHORT
version
;
USHORT
nTables
;
};
struct
TT_kern_subtable
{
USHORT
version
;
USHORT
length
;
union
{
USHORT
word
;
struct
{
USHORT
horizontal
:
1
;
USHORT
minimum
:
1
;
USHORT
cross_stream
:
1
;
USHORT
override
:
1
;
USHORT
reserved1
:
4
;
USHORT
format
:
8
;
}
bits
;
}
coverage
;
};
struct
TT_format0_kern_subtable
{
USHORT
nPairs
;
USHORT
searchRange
;
USHORT
entrySelector
;
USHORT
rangeShift
;
};
struct
TT_kern_pair
{
USHORT
left
;
USHORT
right
;
short
value
;
};
static
DWORD
parse_format0_kern_subtable
(
GdiFont
font
,
const
struct
TT_format0_kern_subtable
*
tt_f0_ks
,
const
USHORT
*
glyph_to_char
,
KERNINGPAIR
*
kern_pair
,
DWORD
cPairs
)
{
USHORT
i
,
nPairs
;
const
struct
TT_kern_pair
*
tt_kern_pair
;
TRACE
(
"font height %ld, units_per_EM %d
\n
"
,
font
->
ppem
,
font
->
ft_face
->
units_per_EM
);
nPairs
=
GET_BE_WORD
(
tt_f0_ks
->
nPairs
);
TRACE
(
"nPairs %u, searchRange %u, entrySelector %u, rangeShift %u
\n
"
,
nPairs
,
GET_BE_WORD
(
tt_f0_ks
->
searchRange
),
GET_BE_WORD
(
tt_f0_ks
->
entrySelector
),
GET_BE_WORD
(
tt_f0_ks
->
rangeShift
));
if
(
!
kern_pair
||
!
cPairs
)
return
nPairs
;
tt_kern_pair
=
(
const
struct
TT_kern_pair
*
)(
tt_f0_ks
+
1
);
nPairs
=
min
(
nPairs
,
cPairs
);
for
(
i
=
0
;
i
<
nPairs
;
i
++
)
{
kern_pair
->
wFirst
=
glyph_to_char
[
GET_BE_WORD
(
tt_kern_pair
[
i
].
left
)];
kern_pair
->
wSecond
=
glyph_to_char
[
GET_BE_WORD
(
tt_kern_pair
[
i
].
right
)];
kern_pair
->
iKernAmount
=
MulDiv
((
short
)
GET_BE_WORD
(
tt_kern_pair
[
i
].
value
),
font
->
ppem
,
font
->
ft_face
->
units_per_EM
);
TRACE
(
"left %u right %u value %d
\n
"
,
kern_pair
->
wFirst
,
kern_pair
->
wSecond
,
kern_pair
->
iKernAmount
);
kern_pair
++
;
}
TRACE
(
"copied %u entries
\n
"
,
nPairs
);
return
nPairs
;
}
DWORD
WineEngGetKerningPairs
(
GdiFont
font
,
DWORD
cPairs
,
KERNINGPAIR
*
kern_pair
)
{
DWORD
length
;
void
*
buf
;
const
struct
TT_kern_table
*
tt_kern_table
;
const
struct
TT_kern_subtable
*
tt_kern_subtable
;
USHORT
i
,
nTables
;
USHORT
*
glyph_to_char
;
if
(
font
->
total_kern_pairs
!=
(
DWORD
)
-
1
)
{
if
(
cPairs
&&
kern_pair
)
{
cPairs
=
min
(
cPairs
,
font
->
total_kern_pairs
);
memcpy
(
kern_pair
,
font
->
kern_pairs
,
cPairs
*
sizeof
(
*
kern_pair
));
return
cPairs
;
}
return
font
->
total_kern_pairs
;
}
font
->
total_kern_pairs
=
0
;
length
=
WineEngGetFontData
(
font
,
MS_KERN_TAG
,
0
,
NULL
,
0
);
if
(
length
==
GDI_ERROR
)
{
TRACE
(
"no kerning data in the font
\n
"
);
return
0
;
}
buf
=
HeapAlloc
(
GetProcessHeap
(),
0
,
length
);
if
(
!
buf
)
{
WARN
(
"Out of memory
\n
"
);
return
0
;
}
WineEngGetFontData
(
font
,
MS_KERN_TAG
,
0
,
buf
,
length
);
/* build a glyph index to char code map */
glyph_to_char
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
USHORT
)
*
65536
);
if
(
!
glyph_to_char
)
{
WARN
(
"Out of memory allocating a glyph index to char code map
\n
"
);
HeapFree
(
GetProcessHeap
(),
0
,
buf
);
return
0
;
}
if
(
font
->
ft_face
->
charmap
->
encoding
==
FT_ENCODING_UNICODE
&&
pFT_Get_First_Char
)
{
FT_UInt
glyph_code
;
FT_ULong
char_code
;
glyph_code
=
0
;
char_code
=
pFT_Get_First_Char
(
font
->
ft_face
,
&
glyph_code
);
TRACE
(
"face encoding FT_ENCODING_UNICODE, number of glyphs %ld, first glyph %u, first char %lu
\n
"
,
font
->
ft_face
->
num_glyphs
,
glyph_code
,
char_code
);
while
(
glyph_code
)
{
/*TRACE("Char %04lX -> Index %u%s\n", char_code, glyph_code, glyph_to_char[glyph_code] ? " !" : "" );*/
/* FIXME: This doesn't match what Windows does: it does some fancy
* things with duplicate glyph index to char code mappings, while
* we just avoid overriding existing entries.
*/
if
(
glyph_code
<=
65535
&&
!
glyph_to_char
[
glyph_code
])
glyph_to_char
[
glyph_code
]
=
(
USHORT
)
char_code
;
char_code
=
pFT_Get_Next_Char
(
font
->
ft_face
,
char_code
,
&
glyph_code
);
}
}
else
{
ULONG
n
;
FIXME
(
"encoding %u not supported
\n
"
,
font
->
ft_face
->
charmap
->
encoding
);
for
(
n
=
0
;
n
<=
65535
;
n
++
)
glyph_to_char
[
n
]
=
(
USHORT
)
n
;
}
tt_kern_table
=
buf
;
nTables
=
GET_BE_WORD
(
tt_kern_table
->
nTables
);
TRACE
(
"version %u, nTables %u
\n
"
,
GET_BE_WORD
(
tt_kern_table
->
version
),
nTables
);
tt_kern_subtable
=
(
const
struct
TT_kern_subtable
*
)(
tt_kern_table
+
1
);
for
(
i
=
0
;
i
<
nTables
;
i
++
)
{
struct
TT_kern_subtable
tt_kern_subtable_copy
;
tt_kern_subtable_copy
.
version
=
GET_BE_WORD
(
tt_kern_subtable
->
version
);
tt_kern_subtable_copy
.
length
=
GET_BE_WORD
(
tt_kern_subtable
->
length
);
tt_kern_subtable_copy
.
coverage
.
word
=
GET_BE_WORD
(
tt_kern_subtable
->
coverage
.
word
);
TRACE
(
"version %u, length %u, coverage %u, subtable format %u
\n
"
,
tt_kern_subtable_copy
.
version
,
tt_kern_subtable_copy
.
length
,
tt_kern_subtable_copy
.
coverage
.
word
,
tt_kern_subtable_copy
.
coverage
.
bits
.
format
);
/* According to the TrueType specification this is the only format
* that will be properly interpreted by Windows and OS/2
*/
if
(
tt_kern_subtable_copy
.
coverage
.
bits
.
format
==
0
)
{
DWORD
new_chunk
,
old_total
=
font
->
total_kern_pairs
;
new_chunk
=
parse_format0_kern_subtable
(
font
,
(
const
struct
TT_format0_kern_subtable
*
)(
tt_kern_subtable
+
1
),
glyph_to_char
,
NULL
,
0
);
font
->
total_kern_pairs
+=
new_chunk
;
if
(
!
font
->
kern_pairs
)
font
->
kern_pairs
=
HeapAlloc
(
GetProcessHeap
(),
0
,
font
->
total_kern_pairs
*
sizeof
(
*
font
->
kern_pairs
));
else
font
->
kern_pairs
=
HeapReAlloc
(
GetProcessHeap
(),
0
,
font
->
kern_pairs
,
font
->
total_kern_pairs
*
sizeof
(
*
font
->
kern_pairs
));
parse_format0_kern_subtable
(
font
,
(
const
struct
TT_format0_kern_subtable
*
)(
tt_kern_subtable
+
1
),
glyph_to_char
,
font
->
kern_pairs
+
old_total
,
new_chunk
);
}
else
TRACE
(
"skipping kerning table format %u
\n
"
,
tt_kern_subtable_copy
.
coverage
.
bits
.
format
);
tt_kern_subtable
=
(
const
struct
TT_kern_subtable
*
)((
const
char
*
)
tt_kern_subtable
+
tt_kern_subtable_copy
.
length
);
}
HeapFree
(
GetProcessHeap
(),
0
,
glyph_to_char
);
HeapFree
(
GetProcessHeap
(),
0
,
buf
);
if
(
cPairs
&&
kern_pair
)
{
cPairs
=
min
(
cPairs
,
font
->
total_kern_pairs
);
memcpy
(
kern_pair
,
font
->
kern_pairs
,
cPairs
*
sizeof
(
*
kern_pair
));
return
cPairs
;
}
return
font
->
total_kern_pairs
;
}
#else
/* HAVE_FREETYPE */
...
...
@@ -4233,4 +4463,10 @@ BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
return
TRUE
;
}
DWORD
WineEngGetKerningPairs
(
GdiFont
font
,
DWORD
cPairs
,
KERNINGPAIR
*
kern_pair
)
{
ERR
(
"called but we don't have FreeType
\n
"
);
return
0
;
}
#endif
/* HAVE_FREETYPE */
dlls/gdi/gdi_private.h
View file @
ce6d4c72
...
...
@@ -376,6 +376,7 @@ extern DWORD WineEngGetGlyphIndices(GdiFont font, LPCWSTR lpstr, INT count,
extern
DWORD
WineEngGetGlyphOutline
(
GdiFont
,
UINT
glyph
,
UINT
format
,
LPGLYPHMETRICS
,
DWORD
buflen
,
LPVOID
buf
,
const
MAT2
*
);
extern
DWORD
WineEngGetKerningPairs
(
GdiFont
,
DWORD
,
KERNINGPAIR
*
);
extern
BOOL
WineEngGetLinkedHFont
(
DC
*
dc
,
WCHAR
c
,
HFONT
*
new_hfont
,
UINT
*
glyph
);
extern
UINT
WineEngGetOutlineTextMetrics
(
GdiFont
,
UINT
,
LPOUTLINETEXTMETRICW
);
extern
UINT
WineEngGetTextCharsetInfo
(
GdiFont
font
,
LPFONTSIGNATURE
fs
,
DWORD
flags
);
...
...
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