Hi all,
I am thinking of submitting the attached patch. The problem is that I am not comfertable with the location I added it.
As far as I could tell, there is nowhere in the whole of Wine where the selected language is matched with the charset to be used by default. This is what this patch comes to amend.
There is a slight awkwardness that is inherent to the Win32 API, in which, in order to create the default font, you zero out a LOGFONT struct, fill in the struct length, and call "CreateFontIndirect". Looking at the resulting struct, however, reveals that what you have just asked for is a ANSI_CHARSET font. It appears that windows correctly understands that this is an uninitialized LOGFONT, apparently based on the fields tested.
The reason I am not sure this is the correct place, however, is that there seem to be system-wide default fonts, and I'm not 100% sure why, but they are ANSI (read - latin) only. I am willing to delve deeper into that part of the code, but I need to understand it better first. I was wondering whether anyone else on this list is aware of the reasons.
Shachar
License: LGPL Changelog: Shachar Shemesh winecode@sun.consumer.org.il
objects/font.c
* Added a function to convert language to charset. * Added code to select the apropriate charset in case the charset was not specified (DEFAULT_CHARSET or uninitialized LOGFONT).
Index: objects/font.c =================================================================== RCS file: /home/sun/sources/cvs/wine/objects/font.c,v retrieving revision 1.89 diff -u -r1.89 font.c --- objects/font.c 13 Nov 2002 04:13:42 -0000 1.89 +++ objects/font.c 14 Nov 2002 19:49:44 -0000 @@ -41,6 +41,8 @@ static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer ); static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj );
+static BYTE FONT_GetCharsetFromLang( LANGID language ); + static const struct gdi_obj_funcs font_funcs = { FONT_SelectObject, /* pSelectObject */ @@ -317,6 +319,16 @@ { memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
+ /* Make sure the correct font is chosen in case the decision is up to us */ + if( plf->lfCharSet==DEFAULT_CHARSET || + (plf->lfHeight==0 && plf->lfWidth==0 && plf->lfEscapement==0 && + plf->lfCharSet==0 && plf->lfPitchAndFamily==0 && + plf->lfFaceName[0]==0) ) + { + fontPtr->logfont.lfCharSet= + FONT_GetCharsetFromLang( LANGIDFROMLCID(GetUserDefaultLCID())); + } + TRACE("(%ld %ld %ld %ld %x) %s %s %s => %04x\n", plf->lfHeight, plf->lfWidth, plf->lfEscapement, plf->lfOrientation, @@ -2207,4 +2219,69 @@ BOOL WINAPI RemoveFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv ) { return WineEngRemoveFontResourceEx(str, fl, pdv); +} + +/*********************************************************************** + * FONT_GetCharsetFromLang + */ +static BYTE FONT_GetCharsetFromLang( LANGID language ) +{ + switch( PRIMARYLANGID(language) ) + { + /* I am currently unaware of any language that requires SYMBOL + case : + return SYMBOL_CHARSET;*/ + case LANG_JAPANESE: + return SHIFTJIS_CHARSET; + case LANG_KOREAN: + return HANGEUL_CHARSET; + case LANG_CHINESE: + { + switch( SUBLANGID(language) ) + { + case SUBLANG_CHINESE_SIMPLIFIED: + return GB2312_CHARSET; + case SUBLANG_CHINESE_TRADITIONAL: + return CHINESEBIG5_CHARSET; + } + } + case LANG_GREEK: + return GREEK_CHARSET; + case LANG_TURKISH: + return TURKISH_CHARSET; + case LANG_HEBREW: + return HEBREW_CHARSET; + case LANG_ARABIC: + return ARABIC_CHARSET; + case LANG_LATVIAN: + return BALTIC_CHARSET; + case LANG_VIETNAMESE: + return VIETNAMESE_CHARSET; + case LANG_RUSSIAN: + case LANG_BULGARIAN: + /* Byelorussian probably goes under SUBLANG_RUSSIAN_MOLDAVIA */ + case LANG_MACEDONIAN: + case LANG_SERBIAN: + case LANG_UKRAINIAN: + return RUSSIAN_CHARSET; + case LANG_CZECH: + case LANG_HUNGARIAN: + case LANG_POLISH: + case LANG_ROMANIAN: + /* For some reason SERBIAN and CROATIAN has the same value, despite + * seeming to require different encodings. I disabled one at random. + case LANG_CROATIAN: */ + case LANG_SLOVAK: + case LANG_SLOVENIAN: + case LANG_SORBIAN: + return EE_CHARSET; + case LANG_THAI: + return THAI_CHARSET; + /* The JOHAB charset seem to require KOREAN as well. I don't know when + * to use that instead + case LANG_KOREAN: + return JOHAB_CHARSET; */ + } + + return ANSI_CHARSET; }
On Fri, Nov 15, 2002 at 03:25:48PM +0200, Shachar Shemesh wrote:
Hi all,
I am thinking of submitting the attached patch. The problem is that I am not comfertable with the location I added it.
As far as I could tell, there is nowhere in the whole of Wine where the selected language is matched with the charset to be used by default. This is what this patch comes to amend.
There is a slight awkwardness that is inherent to the Win32 API, in which, in order to create the default font, you zero out a LOGFONT struct, fill in the struct length, and call "CreateFontIndirect". Looking at the resulting struct, however, reveals that what you have just asked for is a ANSI_CHARSET font. It appears that windows correctly understands that this is an uninitialized LOGFONT, apparently based on the fields tested.
Hi,
CHARSET_DEFAULT is translated to the charset assosicated with the current ansi codepage in dlls/gdi/freetype.c:WineEngCreateFontInstance(). This of course only works if you're using client side rendered fonts (this becomes easier as of last night as you don't even need a RENDER capable XServer anymore). CreateFontIndirect is definitely the wrong place for these kind of fixups since GetOject on the hfont always returns the original logfont values. If you need to get this working for X11 fonts then you'll have to poke around in graphics/x11drv/xfont.c somewhere...
I hadn't spotted the brokenness of the Win32 API with regard to certain elements of logfont being set to zero giving a DEFAULT_CHARSET font. In fact it turns out that even if lfFaceName[0] != 0 then you still get this behaviour if the name doesn't match an installed fontname. The attached patch should fix this.
Huw.
Huw D M Davies wrote:
Hi,
CHARSET_DEFAULT is translated to the charset assosicated with the current ansi codepage in dlls/gdi/freetype.c:WineEngCreateFontInstance(). This of course only works if you're using client side rendered fonts (this becomes easier as of last night as you don't even need a RENDER capable XServer anymore).
But that only covers some execution paths. I was trying to opt for a more general solution, not a X11 specific one.
CreateFontIndirect is definitely the wrong place for these kind of fixups since GetOject on the hfont always returns the original logfont values. If you need to get this working for X11 fonts then you'll have to poke around in graphics/x11drv/xfont.c somewhere...
Not good enough. See my later explanation.
I hadn't spotted the brokenness of the Win32 API with regard to certain elements of logfont being set to zero giving a DEFAULT_CHARSET font. In fact it turns out that even if lfFaceName[0] != 0 then you still get this behaviour if the name doesn't match an installed fontname. The attached patch should fix this.
It's more than that. It seems almost like WHENEVER a LOGOFNT is sufficiently non-sensical, the default charset is used instead. In my windows testing, if I zeroed everything and requested zero hieght font, I get the DEFAULT_CHARSET. If, leaving everything else zero, I request 10 height font, I get ANS_CHARSET (zero). If I ask for 30, however, I get DEFAULT all over again. Is that wierd or what?
Huw.
I will have to look into that. In my mind at the moment there is the impression that doing that at that late a stage is too late. I am not 100% sure, however, that this impression is correct.
In any case, thanks for the very constructive feedback.
Shachar