Font selection - please review

Shachar Shemesh wine-devel at sun.consumer.org.il
Fri Nov 15 07:25:48 CST 2002


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 at 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).


-------------- next part --------------
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;
 }


More information about the wine-patches mailing list