gdi32: Implement GetKerningPairs for TrueType fonts.
This commit is contained in:
parent
84a6330690
commit
ce6d4c72ac
|
@ -2514,11 +2514,68 @@ BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
|
||||||
* GetKerningPairsA (GDI32.@)
|
* GetKerningPairsA (GDI32.@)
|
||||||
*/
|
*/
|
||||||
DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
|
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.@)
|
* GetKerningPairsW (GDI32.@)
|
||||||
|
@ -2526,15 +2583,18 @@ DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
|
||||||
DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
|
DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
|
||||||
LPKERNINGPAIR lpKerningPairs )
|
LPKERNINGPAIR lpKerningPairs )
|
||||||
{
|
{
|
||||||
unsigned int i;
|
DC *dc = DC_GetDCPtr(hDC);
|
||||||
FIXME("(%p,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
|
DWORD ret = 0;
|
||||||
|
|
||||||
if(!lpKerningPairs) /* return the number of kerning pairs */
|
TRACE("(%p,%ld,%p)\n", hDC, cPairs, lpKerningPairs);
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (i = 0; i < cPairs; i++)
|
if (!dc) return 0;
|
||||||
lpKerningPairs[i].iKernAmount = 0;
|
|
||||||
return 0;
|
if (dc->gdiFont)
|
||||||
|
ret = WineEngGetKerningPairs(dc->gdiFont, cPairs, lpKerningPairs);
|
||||||
|
|
||||||
|
GDI_ReleaseObj(hDC);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
* FreeType font engine interface
|
* FreeType font engine interface
|
||||||
*
|
*
|
||||||
* Copyright 2001 Huw D M Davies for CodeWeavers.
|
* Copyright 2001 Huw D M Davies for CodeWeavers.
|
||||||
|
* Copyright 2006 Dmitry Timoshkov for CodeWeavers.
|
||||||
*
|
*
|
||||||
* This file contains the WineEng* functions.
|
* 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 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_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_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);
|
static FT_TrueTypeEngineType (*pFT_Get_TrueType_Engine_Type)(FT_Library);
|
||||||
#ifdef HAVE_FREETYPE_FTWINFNT_H
|
#ifdef HAVE_FREETYPE_FTWINFNT_H
|
||||||
MAKE_FUNCPTR(FT_Get_WinFNT_Header);
|
MAKE_FUNCPTR(FT_Get_WinFNT_Header);
|
||||||
|
@ -268,6 +270,8 @@ struct tagGdiFont {
|
||||||
SHORT yMax;
|
SHORT yMax;
|
||||||
SHORT yMin;
|
SHORT yMin;
|
||||||
OUTLINETEXTMETRICW *potm;
|
OUTLINETEXTMETRICW *potm;
|
||||||
|
DWORD total_kern_pairs;
|
||||||
|
KERNINGPAIR *kern_pairs;
|
||||||
FONTSIGNATURE fs;
|
FONTSIGNATURE fs;
|
||||||
GdiFont base_font;
|
GdiFont base_font;
|
||||||
struct list child_fonts;
|
struct list child_fonts;
|
||||||
|
@ -1652,6 +1656,7 @@ BOOL WineEngInit(void)
|
||||||
pFT_Library_Version = wine_dlsym(ft_handle, "FT_Library_Version", NULL, 0);
|
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_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_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);
|
pFT_Get_TrueType_Engine_Type = wine_dlsym(ft_handle, "FT_Get_TrueType_Engine_Type", NULL, 0);
|
||||||
#ifdef HAVE_FREETYPE_FTWINFNT_H
|
#ifdef HAVE_FREETYPE_FTWINFNT_H
|
||||||
pFT_Get_WinFNT_Header = wine_dlsym(ft_handle, "FT_Get_WinFNT_Header", NULL, 0);
|
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->gmsize * sizeof(*ret->gm));
|
||||||
ret->potm = NULL;
|
ret->potm = NULL;
|
||||||
ret->font_desc.matrix.eM11 = ret->font_desc.matrix.eM22 = 1.0;
|
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->hfontlist);
|
||||||
list_init(&ret->child_fonts);
|
list_init(&ret->child_fonts);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1966,6 +1973,7 @@ static void free_font(GdiFont font)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (font->ft_face) pFT_Done_Face(font->ft_face);
|
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->potm);
|
||||||
HeapFree(GetProcessHeap(), 0, font->name);
|
HeapFree(GetProcessHeap(), 0, font->name);
|
||||||
HeapFree(GetProcessHeap(), 0, font->gm);
|
HeapFree(GetProcessHeap(), 0, font->gm);
|
||||||
|
@ -4096,6 +4104,228 @@ BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
|
||||||
return TRUE;
|
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 */
|
#else /* HAVE_FREETYPE */
|
||||||
|
|
||||||
|
@ -4233,4 +4463,10 @@ BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
|
||||||
return TRUE;
|
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 */
|
#endif /* HAVE_FREETYPE */
|
||||||
|
|
|
@ -376,6 +376,7 @@ extern DWORD WineEngGetGlyphIndices(GdiFont font, LPCWSTR lpstr, INT count,
|
||||||
extern DWORD WineEngGetGlyphOutline(GdiFont, UINT glyph, UINT format,
|
extern DWORD WineEngGetGlyphOutline(GdiFont, UINT glyph, UINT format,
|
||||||
LPGLYPHMETRICS, DWORD buflen, LPVOID buf,
|
LPGLYPHMETRICS, DWORD buflen, LPVOID buf,
|
||||||
const MAT2*);
|
const MAT2*);
|
||||||
|
extern DWORD WineEngGetKerningPairs(GdiFont, DWORD, KERNINGPAIR *);
|
||||||
extern BOOL WineEngGetLinkedHFont(DC *dc, WCHAR c, HFONT *new_hfont, UINT *glyph);
|
extern BOOL WineEngGetLinkedHFont(DC *dc, WCHAR c, HFONT *new_hfont, UINT *glyph);
|
||||||
extern UINT WineEngGetOutlineTextMetrics(GdiFont, UINT, LPOUTLINETEXTMETRICW);
|
extern UINT WineEngGetOutlineTextMetrics(GdiFont, UINT, LPOUTLINETEXTMETRICW);
|
||||||
extern UINT WineEngGetTextCharsetInfo(GdiFont font, LPFONTSIGNATURE fs, DWORD flags);
|
extern UINT WineEngGetTextCharsetInfo(GdiFont font, LPFONTSIGNATURE fs, DWORD flags);
|
||||||
|
|
Loading…
Reference in New Issue