gdi32: Copy TranslateCharsetInfo to text.c.

And use a separated copy in ntgdi functions.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2021-09-01 14:09:04 +02:00 committed by Alexandre Julliard
parent 7da78fd269
commit 00359ebfa0
4 changed files with 123 additions and 58 deletions

View file

@ -196,11 +196,8 @@ typedef struct
LOGFONTW logfont;
} FONTOBJ;
/*
* For TranslateCharsetInfo
*/
#define MAXTCIINDEX 32
static const CHARSETINFO FONT_tci[MAXTCIINDEX] = {
/* for translate_charset_info */
static const CHARSETINFO charset_info[] = {
/* ANSI */
{ ANSI_CHARSET, 1252, {{0,0,0,0},{FS_LATIN1,0}} },
{ EASTEUROPE_CHARSET, 1250, {{0,0,0,0},{FS_LATIN2,0}} },
@ -1432,6 +1429,34 @@ static void load_system_links(void)
}
}
/* see TranslateCharsetInfo */
BOOL translate_charset_info( DWORD *src, CHARSETINFO *cs, DWORD flags )
{
int index = 0;
switch (flags)
{
case TCI_SRCFONTSIG:
while (index < ARRAY_SIZE(charset_info) && !(*src>>index & 0x0001)) index++;
break;
case TCI_SRCCODEPAGE:
while (index < ARRAY_SIZE(charset_info) && PtrToUlong(src) != charset_info[index].ciACP)
index++;
break;
case TCI_SRCCHARSET:
while (index < ARRAY_SIZE(charset_info) &&
PtrToUlong(src) != charset_info[index].ciCharset)
index++;
break;
default:
return FALSE;
}
if (index >= ARRAY_SIZE(charset_info) || charset_info[index].ciCharset == DEFAULT_CHARSET) return FALSE;
*cs = charset_info[index];
return TRUE;
}
/* font matching */
static BOOL can_select_face( const struct gdi_font_face *face, FONTSIGNATURE fs, BOOL can_use_bitmap )
@ -1562,7 +1587,7 @@ static struct gdi_font_face *find_matching_face( const LOGFONTW *lf, CHARSETINFO
BOOL want_vertical = (lf->lfFaceName[0] == '@');
struct gdi_font_face *face;
if (!TranslateCharsetInfo( (DWORD *)(INT_PTR)lf->lfCharSet, csi, TCI_SRCCHARSET ))
if (!translate_charset_info( (DWORD *)(INT_PTR)lf->lfCharSet, csi, TCI_SRCCHARSET ))
{
if (lf->lfCharSet != DEFAULT_CHARSET) FIXME( "Untranslated charset %d\n", lf->lfCharSet );
csi->fs.fsCsb[0] = 0;
@ -1578,7 +1603,7 @@ static struct gdi_font_face *find_matching_face( const LOGFONTW *lf, CHARSETINFO
TRACE( "substituting %s,%d -> %s,%d\n", debugstr_w(lf->lfFaceName), lf->lfCharSet,
debugstr_w(subst), (subst_charset != -1) ? subst_charset : lf->lfCharSet );
if (subst_charset != -1)
TranslateCharsetInfo( (DWORD *)(INT_PTR)subst_charset, csi, TCI_SRCCHARSET );
translate_charset_info( (DWORD *)(INT_PTR)subst_charset, csi, TCI_SRCCHARSET );
*orig_name = lf->lfFaceName;
}
@ -1592,7 +1617,7 @@ static struct gdi_font_face *find_matching_face( const LOGFONTW *lf, CHARSETINFO
if (!csi->fs.fsCsb[0])
{
INT acp = GetACP();
if (!TranslateCharsetInfo( (DWORD *)(INT_PTR)acp, csi, TCI_SRCCODEPAGE ))
if (!translate_charset_info( (DWORD *)(INT_PTR)acp, csi, TCI_SRCCODEPAGE ))
{
FIXME( "TCI failed on codepage %d\n", acp );
csi->fs.fsCsb[0] = 0;
@ -2609,7 +2634,7 @@ static DWORD create_enum_charset_list(DWORD charset, struct enum_charset *list)
CHARSETINFO csi;
int i;
if (TranslateCharsetInfo( ULongToPtr(charset), &csi, TCI_SRCCHARSET ) && csi.fs.fsCsb[0] != 0)
if (translate_charset_info( ULongToPtr(charset), &csi, TCI_SRCCHARSET ) && csi.fs.fsCsb[0] != 0)
{
list->mask = csi.fs.fsCsb[0];
list->charset = csi.ciCharset;
@ -2623,7 +2648,7 @@ static DWORD create_enum_charset_list(DWORD charset, struct enum_charset *list)
/* Set the current codepage's charset as the first element. */
if (!is_complex_script_ansi_cp(acp) &&
TranslateCharsetInfo( (DWORD *)(INT_PTR)acp, &csi, TCI_SRCCODEPAGE ) &&
translate_charset_info( (DWORD *)(INT_PTR)acp, &csi, TCI_SRCCODEPAGE ) &&
csi.fs.fsCsb[0] != 0)
{
list->mask = csi.fs.fsCsb[0];
@ -2640,7 +2665,7 @@ static DWORD create_enum_charset_list(DWORD charset, struct enum_charset *list)
fs.fsCsb[0] = 1u << i;
fs.fsCsb[1] = 0;
if (fs.fsCsb[0] & mask) continue; /* skip, already added. */
if (!TranslateCharsetInfo( fs.fsCsb, &csi, TCI_SRCFONTSIG ))
if (!translate_charset_info( fs.fsCsb, &csi, TCI_SRCFONTSIG ))
continue; /* skip, this is an invalid fsCsb bit. */
list->mask = fs.fsCsb[0];
list->charset = csi.ciCharset;
@ -3605,7 +3630,7 @@ static void get_nearest_charset( const WCHAR *family_name, struct gdi_font_face
int i;
if (TranslateCharsetInfo( (DWORD*)(INT_PTR)GetACP(), csi, TCI_SRCCODEPAGE ))
if (translate_charset_info( (DWORD*)(INT_PTR)GetACP(), csi, TCI_SRCCODEPAGE ))
{
const struct gdi_font_link *font_link;
@ -3618,7 +3643,7 @@ static void get_nearest_charset( const WCHAR *family_name, struct gdi_font_face
DWORD fs0 = 1u << i;
if (face->fs.fsCsb[0] & fs0)
{
if (TranslateCharsetInfo(&fs0, csi, TCI_SRCFONTSIG)) return;
if (translate_charset_info(&fs0, csi, TCI_SRCFONTSIG)) return;
FIXME("TCI failing on %x\n", fs0);
}
}
@ -4200,7 +4225,7 @@ static void update_font_code_page( DC *dc, HANDLE font )
}
/* Hmm, nicely designed api this one! */
if (TranslateCharsetInfo( ULongToPtr(charset), &csi, TCI_SRCCHARSET) )
if (translate_charset_info( ULongToPtr(charset), &csi, TCI_SRCCHARSET) )
dc->attr->font_code_page = csi.ciACP;
else {
switch(charset) {
@ -5733,49 +5758,6 @@ DWORD WINAPI NtGdiGetKerningPairsW( HDC hdc, DWORD count, KERNINGPAIR *kern_pair
return ret;
}
/*************************************************************************
* TranslateCharsetInfo [GDI32.@]
*
* Fills a CHARSETINFO structure for a character set, code page, or
* font. This allows making the correspondence between different labels
* (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
* of the same encoding.
*
* Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
* only one codepage should be set in *lpSrc.
*
* RETURNS
* TRUE on success, FALSE on failure.
*
*/
BOOL WINAPI TranslateCharsetInfo(
LPDWORD lpSrc, /* [in]
if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
if flags == TCI_SRCCHARSET: a character set value
if flags == TCI_SRCCODEPAGE: a code page value
*/
LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
DWORD flags /* [in] determines interpretation of lpSrc */)
{
int index = 0;
switch (flags) {
case TCI_SRCFONTSIG:
while (index < MAXTCIINDEX && !(*lpSrc>>index & 0x0001)) index++;
break;
case TCI_SRCCODEPAGE:
while (index < MAXTCIINDEX && PtrToUlong(lpSrc) != FONT_tci[index].ciACP) index++;
break;
case TCI_SRCCHARSET:
while (index < MAXTCIINDEX && PtrToUlong(lpSrc) != FONT_tci[index].ciCharset) index++;
break;
default:
return FALSE;
}
if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
*lpCs = FONT_tci[index];
return TRUE;
}
/*************************************************************************
* NtGdiGetFontData (win32u.@)
*

View file

@ -452,7 +452,7 @@ static UINT get_default_charset( void )
uACP = GetACP();
csi.ciCharset = ANSI_CHARSET;
if ( !TranslateCharsetInfo( ULongToPtr(uACP), &csi, TCI_SRCCODEPAGE ) )
if ( !translate_charset_info( ULongToPtr(uACP), &csi, TCI_SRCCODEPAGE ) )
{
FIXME( "unhandled codepage %u - use ANSI_CHARSET for default stock objects\n", uACP );
return ANSI_CHARSET;

View file

@ -388,6 +388,7 @@ extern BOOL opentype_enum_full_names( const struct tt_name_v0 *tt_name_v0,
extern BOOL opentype_get_properties( const void *data, size_t size, const struct ttc_sfnt_v1 *ttc_sfnt_v1,
DWORD *version, FONTSIGNATURE *fs, DWORD *ntm_flags ) DECLSPEC_HIDDEN;
extern BOOL translate_charset_info( DWORD *src, CHARSETINFO *cs, DWORD flags ) DECLSPEC_HIDDEN;
/* gdiobj.c */
extern HGDIOBJ alloc_gdi_handle( struct gdi_obj_header *obj, WORD type,

View file

@ -2307,3 +2307,85 @@ HANDLE WINAPI AddFontMemResourceEx( void *ptr, DWORD size, void *dv, DWORD *coun
{
return NtGdiAddFontMemResourceEx( ptr, size, dv, 0, count );
}
static const CHARSETINFO charset_info[] = {
/* ANSI */
{ ANSI_CHARSET, 1252, {{0,0,0,0},{FS_LATIN1,0}} },
{ EASTEUROPE_CHARSET, 1250, {{0,0,0,0},{FS_LATIN2,0}} },
{ RUSSIAN_CHARSET, 1251, {{0,0,0,0},{FS_CYRILLIC,0}} },
{ GREEK_CHARSET, 1253, {{0,0,0,0},{FS_GREEK,0}} },
{ TURKISH_CHARSET, 1254, {{0,0,0,0},{FS_TURKISH,0}} },
{ HEBREW_CHARSET, 1255, {{0,0,0,0},{FS_HEBREW,0}} },
{ ARABIC_CHARSET, 1256, {{0,0,0,0},{FS_ARABIC,0}} },
{ BALTIC_CHARSET, 1257, {{0,0,0,0},{FS_BALTIC,0}} },
{ VIETNAMESE_CHARSET, 1258, {{0,0,0,0},{FS_VIETNAMESE,0}} },
/* reserved by ANSI */
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
/* ANSI and OEM */
{ THAI_CHARSET, 874, {{0,0,0,0},{FS_THAI,0}} },
{ SHIFTJIS_CHARSET, 932, {{0,0,0,0},{FS_JISJAPAN,0}} },
{ GB2312_CHARSET, 936, {{0,0,0,0},{FS_CHINESESIMP,0}} },
{ HANGEUL_CHARSET, 949, {{0,0,0,0},{FS_WANSUNG,0}} },
{ CHINESEBIG5_CHARSET, 950, {{0,0,0,0},{FS_CHINESETRAD,0}} },
{ JOHAB_CHARSET, 1361, {{0,0,0,0},{FS_JOHAB,0}} },
/* reserved for alternate ANSI and OEM */
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
/* reserved for system */
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ SYMBOL_CHARSET, CP_SYMBOL, {{0,0,0,0},{FS_SYMBOL,0}} }
};
/***********************************************************************
* TranslateCharsetInfo (GDI32.@)
*
* Fills a CHARSETINFO structure for a character set, code page, or
* font. This allows making the correspondence between different labels
* (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
* of the same encoding.
*
* Only one codepage will be set in cs->fs. If TCI_SRCFONTSIG is used,
* only one codepage should be set in *src.
*
* if flags == TCI_SRCFONTSIG: src is a pointer to fsCsb of a FONTSIGNATURE
* if flags == TCI_SRCCHARSET: src is a character set value
* if flags == TCI_SRCCODEPAGE: src is a code page value
*/
BOOL WINAPI TranslateCharsetInfo( DWORD *src, CHARSETINFO *cs, DWORD flags )
{
int index = 0;
switch (flags)
{
case TCI_SRCFONTSIG:
while (index < ARRAY_SIZE(charset_info) && !(*src>>index & 0x0001)) index++;
break;
case TCI_SRCCODEPAGE:
while (index < ARRAY_SIZE(charset_info) && PtrToUlong(src) != charset_info[index].ciACP)
index++;
break;
case TCI_SRCCHARSET:
while (index < ARRAY_SIZE(charset_info) &&
PtrToUlong(src) != charset_info[index].ciCharset)
index++;
break;
default:
return FALSE;
}
if (index >= ARRAY_SIZE(charset_info) || charset_info[index].ciCharset == DEFAULT_CHARSET) return FALSE;
*cs = charset_info[index];
return TRUE;
}