Localized font name
Kusanagi Kouichi
slash at ma.neweb.ne.jp
Thu Jul 29 15:32:56 CDT 2004
Changelog
* WineEngCreateFontInstance() and WineEngEnumFonts() accept
localized font name.
* WineEngEnumFonts() passes localized font name to callback
if localized name which matches current locale exists.
-------------- next part --------------
--- dlls/gdi/freetype.c.orig 2004-07-23 04:42:31.000000000 +0900
+++ dlls/gdi/freetype.c 2004-07-30 05:10:26.000000000 +0900
@@ -36,6 +36,7 @@
#include "winerror.h"
#include "winreg.h"
#include "wingdi.h"
+#include "winnls.h"
#include "gdi.h"
#include "gdi_private.h"
#include "wine/unicode.h"
@@ -100,6 +101,8 @@ static void *ft_handle = NULL;
MAKE_FUNCPTR(FT_Vector_Unit);
MAKE_FUNCPTR(FT_Done_Face);
MAKE_FUNCPTR(FT_Get_Char_Index);
+MAKE_FUNCPTR(FT_Get_Sfnt_Name);
+MAKE_FUNCPTR(FT_Get_Sfnt_Name_Count);
MAKE_FUNCPTR(FT_Get_Sfnt_Table);
MAKE_FUNCPTR(FT_Init_FreeType);
MAKE_FUNCPTR(FT_Load_Glyph);
@@ -172,6 +175,7 @@ typedef struct tagFace {
BOOL external; /* TRUE if we should manually add this font to the registry */
struct tagFace *next;
struct tagFamily *family;
+ struct tagName *name;
} Face;
typedef struct tagFamily {
@@ -180,6 +184,13 @@ typedef struct tagFamily {
struct tagFamily *next;
} Family;
+typedef struct tagName {
+ WORD lang;
+ WCHAR *FamilyName;
+ WCHAR *StyleName;
+ struct tagName *next;
+} Name;
+
typedef struct {
GLYPHMETRICS gm;
INT adv; /* These three hold to widths of the unrotated chars */
@@ -192,6 +203,7 @@ struct tagGdiFont {
FT_Face ft_face;
XFORM xform;
LPWSTR name;
+ LPWSTR style_name;
int charset;
BOOL fake_italic;
BOOL fake_bold;
@@ -493,6 +505,93 @@ static BOOL AddFontFileToList(const char
(*insertface)->font_version = pHeader ? pHeader->Font_Revision : 0;
(*insertface)->family = *pfamily;
(*insertface)->external = (flags & ADDFONT_EXTERNAL_FONT) ? TRUE : FALSE;
+ (*insertface)->name = NULL;
+
+ for (i = pFT_Get_Sfnt_Name_Count(ft_face); i-- > 0;)
+ {
+ FT_SfntName name;
+ Name *pname;
+ WCHAR *str;
+ int j;
+ UINT codepage;
+
+ if (pFT_Get_Sfnt_Name(ft_face, i, &name) ||
+ name.platform_id != 3 ||
+ (name.name_id != 1 && name.name_id != 2))
+ {
+ continue;
+ }
+
+ for (pname = (*insertface)->name; pname != NULL; pname = pname->next)
+ {
+ if (pname->lang == name.language_id)
+ {
+ break;
+ }
+ }
+ if (pname == NULL)
+ {
+ pname = HeapAlloc(GetProcessHeap(), 0, sizeof (Name));
+ if (pname == NULL)
+ {
+ continue;
+ }
+ pname->lang = name.language_id;
+ pname->FamilyName = FamilyW;
+ pname->StyleName = StyleW;
+ pname->next = (*insertface)->name;
+ (*insertface)->name = pname;
+ }
+
+ switch (name.encoding_id)
+ {
+ case 1:
+ len = name.string_len / 2;
+ str = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof (WCHAR));
+ if (str == NULL)
+ {
+ continue;
+ }
+ for (j = 0; j < len; ++j)
+ {
+ str[j] = *name.string++ * 256;
+ str[j] += *name.string++;
+ }
+ break;
+ case 2:
+ codepage = 932;
+ goto conv;
+ case 3:
+ codepage = 936;
+ goto conv;
+ case 4:
+ codepage = 950;
+ goto conv;
+ case 5:
+ codepage = 949;
+ conv:
+ len = MultiByteToWideChar(codepage, 0, name.string, name.string_len, NULL, 0);
+ str = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof (WCHAR));
+ if (str == NULL)
+ {
+ continue;
+ }
+ MultiByteToWideChar(codepage, 0, name.string, name.string_len, str, len);
+ break;
+ default:
+ continue;
+ }
+ str[len] = '\0';
+
+ if (name.name_id == 1)
+ {
+ pname->FamilyName = str;
+ }
+ else
+ {
+ pname->StyleName = str;
+ }
+ }
if(FT_IS_SCALABLE(ft_face)) {
memset(&(*insertface)->size, 0, sizeof((*insertface)->size));
@@ -604,15 +703,6 @@ static void DumpSubstList(void)
return;
}
-static LPWSTR strdupW(LPWSTR p)
-{
- LPWSTR ret;
- DWORD len = (strlenW(p) + 1) * sizeof(WCHAR);
- ret = HeapAlloc(GetProcessHeap(), 0, len);
- memcpy(ret, p, len);
- return ret;
-}
-
static void split_subst_info(NameCs *nc, LPSTR str)
{
CHAR *p = strrchr(str, ',');
@@ -1053,6 +1143,8 @@ BOOL WineEngInit(void)
LOAD_FUNCPTR(FT_Vector_Unit)
LOAD_FUNCPTR(FT_Done_Face)
LOAD_FUNCPTR(FT_Get_Char_Index)
+ LOAD_FUNCPTR(FT_Get_Sfnt_Name)
+ LOAD_FUNCPTR(FT_Get_Sfnt_Name_Count)
LOAD_FUNCPTR(FT_Get_Sfnt_Table)
LOAD_FUNCPTR(FT_Init_FreeType)
LOAD_FUNCPTR(FT_Load_Glyph)
@@ -1339,7 +1431,6 @@ static void free_font(GdiFont font)
{
if (font->ft_face) pFT_Done_Face(font->ft_face);
if (font->potm) HeapFree(GetProcessHeap(), 0, font->potm);
- if (font->name) HeapFree(GetProcessHeap(), 0, font->name);
HeapFree(GetProcessHeap(), 0, font->gm);
HeapFree(GetProcessHeap(), 0, font);
}
@@ -1507,6 +1598,9 @@ GdiFont WineEngCreateFontInstance(DC *dc
BOOL bd, it, can_use_bitmap;
LOGFONTW lf;
CHARSETINFO csi;
+ WORD lang;
+ WCHAR *family_name;
+ Name *name;
if (!GetObjectW( hfont, sizeof(lf), &lf )) return NULL;
can_use_bitmap = GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_RA_ABLE;
@@ -1555,6 +1649,7 @@ GdiFont WineEngCreateFontInstance(DC *dc
}
}
+ lang = LANGIDFROMLCID(GetThreadLocale());
if(lf.lfFaceName[0] != '\0') {
FontSubst *psub;
for(psub = substlist; psub; psub = psub->next)
@@ -1575,7 +1670,17 @@ GdiFont WineEngCreateFontInstance(DC *dc
or if that's unavailable the first charset that the font supports.
*/
for(family = FontList; family; family = family->next) {
- if(!strcmpiW(family->FamilyName, lf.lfFaceName))
+ family_name = family->FamilyName;
+ for (name = family->FirstFace->name; name != NULL; name = name->next)
+ {
+ if (name->lang == lang)
+ {
+ family_name = name->FamilyName;
+ break;
+ }
+ }
+ if (!strcmpiW(family_name, lf.lfFaceName) ||
+ !strcmpiW(family->FamilyName, lf.lfFaceName))
if((csi.fs.fsCsb[0] & family->FirstFace->fs.fsCsb[0]) || !csi.fs.fsCsb[0])
if(family->FirstFace->scalable || can_use_bitmap)
break;
@@ -1695,7 +1800,17 @@ GdiFont WineEngCreateFontInstance(DC *dc
}
ret->orientation = lf.lfOrientation;
- ret->name = strdupW(family->FamilyName);
+ ret->name = face->family->FamilyName;
+ ret->style_name = face->StyleName;
+ for (name = face->name; name != NULL; name = name->next)
+ {
+ if (name->lang == lang)
+ {
+ ret->name = name->FamilyName;
+ ret->style_name = name->StyleName;
+ break;
+ }
+ }
ret->underline = lf.lfUnderline ? 0xff : 0;
ret->strikeout = lf.lfStrikeOut ? 0xff : 0;
@@ -1761,6 +1876,8 @@ BOOL WineEngDestroyFontInstance(HFONT ha
static void GetEnumStructs(Face *face, LPENUMLOGFONTEXW pelf,
NEWTEXTMETRICEXW *pntm, LPDWORD ptype)
{
+ WORD lang;
+ Name *name;
OUTLINETEXTMETRICW *potm = NULL;
UINT size;
TEXTMETRICW tm, *ptm;
@@ -1781,7 +1898,18 @@ static void GetEnumStructs(Face *face, L
return;
}
- font->name = strdupW(face->family->FamilyName);
+ lang = LANGIDFROMLCID(GetThreadLocale());
+ font->name = face->family->FamilyName;
+ font->style_name = face->StyleName;
+ for (name = face->name; name != NULL; name = name->next)
+ {
+ if (name->lang == lang)
+ {
+ font->name = name->FamilyName;
+ font->style_name = name->StyleName;
+ break;
+ }
+ }
memset(&pelf->elfLogFont, 0, sizeof(LOGFONTW));
@@ -1891,41 +2019,43 @@ DWORD WineEngEnumFonts(LPLOGFONTW plf, F
plf = &lf;
}
for(family = FontList; family; family = family->next) {
- if(!strcmpiW(plf->lfFaceName, family->FamilyName)) {
- for(face = family->FirstFace; face; face = face->next) {
- GetEnumStructs(face, &elf, &ntm, &type);
- for(i = 0; i < 32; i++) {
- if(!face->scalable && face->fs.fsCsb[0] == 0) { /* OEM bitmap */
- elf.elfLogFont.lfCharSet = ntm.ntmTm.tmCharSet = OEM_CHARSET;
- strcpyW(elf.elfScript, OEM_DOSW);
- i = 32; /* break out of loop */
- } else if(!(face->fs.fsCsb[0] & (1L << i)))
- continue;
- else {
- fs.fsCsb[0] = 1L << i;
- fs.fsCsb[1] = 0;
- if(!TranslateCharsetInfo(fs.fsCsb, &csi,
- TCI_SRCFONTSIG))
- csi.ciCharset = DEFAULT_CHARSET;
- if(i == 31) csi.ciCharset = SYMBOL_CHARSET;
- if(csi.ciCharset != DEFAULT_CHARSET) {
- elf.elfLogFont.lfCharSet =
- ntm.ntmTm.tmCharSet = csi.ciCharset;
- if(ElfScriptsW[i])
- strcpyW(elf.elfScript, ElfScriptsW[i]);
- else
- FIXME("Unknown elfscript for bit %d\n", i);
- }
- }
- TRACE("enuming face %s full %s style %s charset %d type %ld script %s it %d weight %ld ntmflags %08lx\n",
- debugstr_w(elf.elfLogFont.lfFaceName),
- debugstr_w(elf.elfFullName), debugstr_w(elf.elfStyle),
- csi.ciCharset, type, debugstr_w(elf.elfScript),
- elf.elfLogFont.lfItalic, elf.elfLogFont.lfWeight,
- ntm.ntmTm.ntmFlags);
- ret = proc(&elf.elfLogFont, (TEXTMETRICW *)&ntm, type, lparam);
- if(!ret) goto end;
+ for(face = family->FirstFace; face; face = face->next) {
+ GetEnumStructs(face, &elf, &ntm, &type);
+ if (strcmpiW(plf->lfFaceName, elf.elfLogFont.lfFaceName) &&
+ strcmpiW(plf->lfFaceName, family->FamilyName)) {
+ break;
+ }
+ for(i = 0; i < 32; i++) {
+ if(!face->scalable && face->fs.fsCsb[0] == 0) { /* OEM bitmap */
+ elf.elfLogFont.lfCharSet = ntm.ntmTm.tmCharSet = OEM_CHARSET;
+ strcpyW(elf.elfScript, OEM_DOSW);
+ i = 32; /* break out of loop */
+ } else if(!(face->fs.fsCsb[0] & (1L << i)))
+ continue;
+ else {
+ fs.fsCsb[0] = 1L << i;
+ fs.fsCsb[1] = 0;
+ if(!TranslateCharsetInfo(fs.fsCsb, &csi,
+ TCI_SRCFONTSIG))
+ csi.ciCharset = DEFAULT_CHARSET;
+ if(i == 31) csi.ciCharset = SYMBOL_CHARSET;
+ if(csi.ciCharset != DEFAULT_CHARSET) {
+ elf.elfLogFont.lfCharSet =
+ ntm.ntmTm.tmCharSet = csi.ciCharset;
+ if(ElfScriptsW[i])
+ strcpyW(elf.elfScript, ElfScriptsW[i]);
+ else
+ FIXME("Unknown elfscript for bit %d\n", i);
+ }
}
+ TRACE("enuming face %s full %s style %s charset %d type %ld script %s it %d weight %ld ntmflags %08lx\n",
+ debugstr_w(elf.elfLogFont.lfFaceName),
+ debugstr_w(elf.elfFullName), debugstr_w(elf.elfStyle),
+ csi.ciCharset, type, debugstr_w(elf.elfScript),
+ elf.elfLogFont.lfItalic, elf.elfLogFont.lfWeight,
+ ntm.ntmTm.ntmFlags);
+ ret = proc(&elf.elfLogFont, (TEXTMETRICW *)&ntm, type, lparam);
+ if(!ret) goto end;
}
}
}
@@ -2555,7 +2685,6 @@ UINT WineEngGetOutlineTextMetrics(GdiFon
TT_HoriHeader *pHori;
TT_Postscript *pPost;
FT_Fixed x_scale, y_scale;
- WCHAR *family_nameW, *style_nameW;
static const WCHAR spaceW[] = {' ', '\0'};
char *cp;
INT ascent, descent;
@@ -2571,19 +2700,9 @@ UINT WineEngGetOutlineTextMetrics(GdiFon
return font->potm->otmSize;
}
-
needed = sizeof(*potm);
-
lenfam = (strlenW(font->name) + 1) * sizeof(WCHAR);
- family_nameW = strdupW(font->name);
-
- lensty = MultiByteToWideChar(CP_ACP, 0, ft_face->style_name, -1, NULL, 0)
- * sizeof(WCHAR);
- style_nameW = HeapAlloc(GetProcessHeap(), 0, lensty);
- MultiByteToWideChar(CP_ACP, 0, ft_face->style_name, -1,
- style_nameW, lensty);
-
- /* These names should be read from the TT name table */
+ lensty = (strlenW(font->style_name) + 1) * sizeof(WCHAR);
/* length of otmpFamilyName */
needed += lenfam;
@@ -2761,32 +2880,29 @@ UINT WineEngGetOutlineTextMetrics(GdiFon
/* otmp* members should clearly have type ptrdiff_t, but M$ knows best */
cp = (char*)font->potm + sizeof(*font->potm);
font->potm->otmpFamilyName = (LPSTR)(cp - (char*)font->potm);
- strcpyW((WCHAR*)cp, family_nameW);
+ strcpyW((WCHAR*)cp, font->name);
cp += lenfam;
font->potm->otmpStyleName = (LPSTR)(cp - (char*)font->potm);
- strcpyW((WCHAR*)cp, style_nameW);
+ strcpyW((WCHAR*)cp, font->style_name);
cp += lensty;
font->potm->otmpFaceName = (LPSTR)(cp - (char*)font->potm);
- strcpyW((WCHAR*)cp, family_nameW);
+ strcpyW((WCHAR*)cp, font->name);
if(strcasecmp(ft_face->style_name, "regular")) {
strcatW((WCHAR*)cp, spaceW);
- strcatW((WCHAR*)cp, style_nameW);
+ strcatW((WCHAR*)cp, font->style_name);
cp += lenfam + lensty;
} else
cp += lenfam;
font->potm->otmpFullName = (LPSTR)(cp - (char*)font->potm);
- strcpyW((WCHAR*)cp, family_nameW);
+ strcpyW((WCHAR*)cp, font->name);
strcatW((WCHAR*)cp, spaceW);
- strcatW((WCHAR*)cp, style_nameW);
+ strcatW((WCHAR*)cp, font->style_name);
ret = needed;
if(potm && needed <= cbSize)
memcpy(potm, font->potm, font->potm->otmSize);
end:
- HeapFree(GetProcessHeap(), 0, style_nameW);
- HeapFree(GetProcessHeap(), 0, family_nameW);
-
return ret;
}
More information about the wine-patches
mailing list