From 00359ebfa0d4a86aac024f4067a82bb5725c94b4 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Wed, 1 Sep 2021 14:09:04 +0200 Subject: [PATCH] gdi32: Copy TranslateCharsetInfo to text.c. And use a separated copy in ntgdi functions. Signed-off-by: Jacek Caban Signed-off-by: Huw Davies Signed-off-by: Alexandre Julliard --- dlls/gdi32/font.c | 96 ++++++++++++++++---------------------- dlls/gdi32/gdiobj.c | 2 +- dlls/gdi32/ntgdi_private.h | 1 + dlls/gdi32/text.c | 82 ++++++++++++++++++++++++++++++++ 4 files changed, 123 insertions(+), 58 deletions(-) diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c index c5641cd4653..1bbab661c95 100644 --- a/dlls/gdi32/font.c +++ b/dlls/gdi32/font.c @@ -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.@) * diff --git a/dlls/gdi32/gdiobj.c b/dlls/gdi32/gdiobj.c index 2937cdcf48f..1294401f15b 100644 --- a/dlls/gdi32/gdiobj.c +++ b/dlls/gdi32/gdiobj.c @@ -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; diff --git a/dlls/gdi32/ntgdi_private.h b/dlls/gdi32/ntgdi_private.h index 103e06628d7..1463726d200 100644 --- a/dlls/gdi32/ntgdi_private.h +++ b/dlls/gdi32/ntgdi_private.h @@ -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, diff --git a/dlls/gdi32/text.c b/dlls/gdi32/text.c index d1f7050e21a..c54dfac0a42 100644 --- a/dlls/gdi32/text.c +++ b/dlls/gdi32/text.c @@ -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; +}