.NET Forum / .NET Framework / .NET SDK / September 2007
CultureInfo.NativeName - can it be rendered?
|
|
Thread rating:  |
David Thielen - 29 Aug 2007 22:52 GMT Hi;
How can I determine for a given CultureInfo.NativeName if the fonts are installed on a system to render it?
 Signature thanks - dave david_at_windward_dot_net http://www.windwardreports.com
Cubicle Wars - http://www.windwardreports.com/film.htm
Walter Wang [MSFT] - 30 Aug 2007 11:21 GMT Hi Dave,
This is a quick note to let you know that I am performing research on this issue and will get back to you as soon as possible. I appreciate your patience.
Regards, Walter Wang (wawang@online.microsoft.com, remove 'online.') Microsoft Online Community Support
================================================== When responding to posts, please "Reply to Group" via your newsreader so that others may learn and benefit from your issue. ==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
Walter Wang [MSFT] - 03 Sep 2007 04:25 GMT Hi Dave,
Sorry the delayed reply.
If your objective here is to show all cultures' NativeName in one control(font), then this is not possible since currently no Unicode font could display all Unicode characters.
If your objective is to show one culture's NativeName at a time (for example, in a Label), then you should simply use the default font and it will choose the best suitable font installed on the system to show the content.
In .NET WinForm, SystemFonts.DefaultFont is used to return the default font that applications can use for dialog boxes and forms.
For more information on this, please refer to following document:
http://www.microsoft.com/globaldev/getwr/steps/wrg_font.mspx
To summarize the info in above document: hardcoding a physical font name is not recommended for showing text which is not in the system default locale. Using the virtual font "MS Shell Dlg" is recommended.
Since .NET WinForm's designer now uses only physical fonts, the "MS Shell Dlg" font is not listed. However, simply don't set a control's Font or uses SystemFonts.DefaultFont should do the equivalent.
For an example on this, please refer to CultureExplorer:
http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=B778F F2C-9142-4769-839A-094F51A6F9F4
This is correctly showing each culture's NativeName on it.
Hope this helps.
Regards, Walter Wang (wawang@online.microsoft.com, remove 'online.') Microsoft Online Community Support
================================================== When responding to posts, please "Reply to Group" via your newsreader so that others may learn and benefit from your issue. ==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
David Thielen - 03 Sep 2007 16:38 GMT I use it in a dropdown control to let them pick their locale. If the Asian and bi-di fonts are installed on a computer it works great - each locale is displayed in it's native language.
But if those fonts are not installed, then I get the box characters for the Asian and bi-di locale names.
So I need some way to find out if the font used in the control can display the characters in the string.
 Signature thanks - dave david_at_windward_dot_net http://www.windwardreports.com
Cubicle Wars - http://www.windwardreports.com/film.htm
> Hi Dave, > [quoted text clipped - 43 lines] > > This posting is provided "AS IS" with no warranties, and confers no rights. Walter Wang [MSFT] - 04 Sep 2007 10:38 GMT Hi Dave,
Thanks. Now I understand your question is actually to detect if the CultureInfo.NativeName can be correctly displayed on current system and if not, fallback to show English name for it, right?
I'll do some more consulting and researching for you.
Regards, Walter Wang (wawang@online.microsoft.com, remove 'online.') Microsoft Online Community Support
================================================== When responding to posts, please "Reply to Group" via your newsreader so that others may learn and benefit from your issue. ==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
David Thielen - 04 Sep 2007 15:40 GMT Yes.
THis way if someone in China is using it I want it to display in Han characters instead of English.
 Signature thanks - dave david_at_windward_dot_net http://www.windwardreports.com
Cubicle Wars - http://www.windwardreports.com/film.htm
> Hi Dave, > [quoted text clipped - 14 lines] > > This posting is provided "AS IS" with no warranties, and confers no rights. Walter Wang [MSFT] - 06 Sep 2007 07:24 GMT Hi Dave,
Please refer to following blog:
#Sorting It All Out : WYSIWYG font dropdowns http://blogs.msdn.com/michkap/archive/2006/06/28/649791.aspx <quote> So, the real question here is even simpler: "How can one determine if a font supports the characters in a string?"
The easiest way is via the GetGlyphIndices function, which has in the initial description:
The GetGlyphIndices function translates a string into an array of glyph indices. The function can be used to determine whether a glyph exists in a font.
So you can pass the name you were going to use to the function (making sure to pass the GGI_MARK_NONEXISTING_GLYPHS flag), and then look at the glyph indices for the 0xffff marker.
If it shows up for any of the characters, then you know you should use some other font. </quote>
In summary, you use the default font for the ComboBox, then iterate all NativeName to see if the text could be displayed. If not, then you use english name to display the CultureInfo.
Regards, Walter Wang (wawang@online.microsoft.com, remove 'online.') Microsoft Online Community Support
================================================== When responding to posts, please "Reply to Group" via your newsreader so that others may learn and benefit from your issue. ==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
David Thielen - 06 Sep 2007 18:00 GMT perfect - thanks
 Signature thanks - dave david_at_windward_dot_net http://www.windwardreports.com
Cubicle Wars - http://www.windwardreports.com/film.htm
> Hi Dave, > [quoted text clipped - 35 lines] > > This posting is provided "AS IS" with no warranties, and confers no rights. David Thielen - 09 Sep 2007 23:36 GMT Hi;
I'm hitting 2 problems with this.
1) It returns all 0's for all Asian languages (it does return correctly for Hebrew & Arabic). I have the Far-East fonts installed and they display fine - but I get all 0's for them.
2) The code "CultureInfo.CreateSpecificCulture(ci.IetfLanguageTag)" throws an exception for Chinese - both traditional & simplified. For every other language it returns a CultureInfo. I assume this is because of the PRC/Taiwan issue? Is there a good way to handle this other than hard-coding for those 2 cases?
 Signature thanks - dave david_at_windward_dot_net http://www.windwardreports.com
Cubicle Wars - http://www.windwardreports.com/film.htm
> Hi Dave, > [quoted text clipped - 35 lines] > > This posting is provided "AS IS" with no warranties, and confers no rights. Walter Wang [MSFT] - 12 Sep 2007 01:28 GMT Hi Dave,
According to documentation of CultureInfo.IetfLanguageTag:
------ The format of an IETF language tag is similar to the culture name returned by the Name property, but does not identify a culture uniquely. That is, different cultures share the same IETF language tag if those cultures have identical linguistic characteristics. ------
Which exact value is the ci.IetfLanguageTag that you're passing to CultureInfo.CreateSpecificCulture()?
By the way, I'm not sure if you have looked at the source code of the sample CultureExplorer I mentioned previously: if you're using CultureInfo.GetCultures(type), then I think you can don't need to create individual CultureInfo again? For example, if you use CultureTypes.InstalledWin32Cultures, this will return all CultureInfoes that are installed locally.
What's the system default locale?
Would you please post or send me the code that you're using? Preferably a smaller but complete project. Thanks.
Regards, Walter Wang (wawang@online.microsoft.com, remove 'online.') Microsoft Online Community Support
================================================== When responding to posts, please "Reply to Group" via your newsreader so that others may learn and benefit from your issue. ==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
David Thielen - 25 Sep 2007 22:06 GMT Please take a look at http://www.windwardreports.com/temp/CultureInfo.zip - on my system, which does have all the far east fonts loaded and on which those fonts display ok, it says it cannot display them.
And for the culture neutral enum, it does not like Chinese - neither simplified or traditional.
 Signature thanks - dave david_at_windward_dot_net http://www.windwardreports.com
Cubicle Wars - http://www.windwardreports.com/film.htm
> Hi Dave, > [quoted text clipped - 32 lines] > > This posting is provided "AS IS" with no warranties, and confers no rights. Walter Wang [MSFT] - 27 Sep 2007 13:38 GMT Hi Dave,
This is a quick note to let you know that I am performing research on this issue and will get back to you as soon as possible. I appreciate your patience.
Regards, Walter Wang (wawang@online.microsoft.com, remove 'online.') Microsoft Online Community Support
================================================== When responding to posts, please "Reply to Group" via your newsreader so that others may learn and benefit from your issue. ==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
Walter Wang [MSFT] - 28 Sep 2007 05:44 GMT Hi Dave,
I believe it's related to the font created in .NET code doesn't correctly fallback to other fonts properly.
I've created a win32 DLL to do the call and it seems working correctly:
// File FontUtil.cpp // cl /LD /D "_UNICODE" /D "UNICODE" user32.lib kernel32.lib gdi32.lib #define _WIN32_WINNT 0x0500 #include <windows.h> #include <tchar.h>
#define FONTUTIL_EXPORTS
#ifdef FONTUTIL_EXPORTS #define FONTUTIL_API __declspec(dllexport) #else #define FONTUTIL_API __declspec(dllimport) #endif
extern "C" { FONTUTIL_API BOOL IsFontInstalled(LPCTSTR szFontName); FONTUTIL_API BOOL IsCharactersAvailableInFont(LPCTSTR szFontName, LPCTSTR characters); }
static int CALLBACK EnumFontFamProc(CONST ENUMLOGFONT *lpelf, CONST NEWTEXTMETRIC *lpntm, DWORD FontType, LPARAM lParam ) { *((BOOL*)lParam) = TRUE; return 0; }
BOOL IsFontInstalled(LPCTSTR szFontName) { BOOL bIsInstalled = FALSE; HDC hDC = GetDC(NULL); EnumFontFamilies(hDC, szFontName, (FONTENUMPROC) EnumFontFamProc, (LPARAM) &bIsInstalled); ReleaseDC(NULL, hDC); return bIsInstalled; }
BOOL IsCharactersAvailableInFont(LPCTSTR szFontName, LPCTSTR characters) { HDC hdc; HFONT hFontOld; HFONT hFontNew; BOOL bResult = TRUE;
hFontNew = CreateFont(0, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, szFontName); if (hFontNew == NULL) return FALSE;
hdc = GetDC(NULL); hFontOld = (HFONT) SelectObject(hdc, hFontNew);
int count = _tcslen(characters); WORD* indices = new WORD[count]; DWORD dwRet = GetGlyphIndices(hdc, characters, count, &indices[0], GGI_MARK_NONEXISTING_GLYPHS); if (dwRet == GDI_ERROR) { bResult = FALSE; } else { for (int i = 0; i < count; i++) { if (indices[i] == 0xffff) { bResult = FALSE; break; } } }
SelectObject(hdc, hFontOld); DeleteObject(hFontNew); ReleaseDC(NULL, hdc);
return bResult; }
Save above code as "FontUtil.cpp", open a VS2005 environment command prompt, run command:
cl /LD /D "_UNICODE" /D "UNICODE" FontUtil.cpp user32.lib kernel32.lib gdi32.lib
This will generate FontUtil.dll.
In your .NET, use following code to check if a CultureInfo.NativeName can be displayed in Font "MS Shell Dlg", which is a virtual font name when you use default font in WinForm:
[DllImport(@"FontUtil.dll", CharSet=CharSet.Unicode)] static extern bool IsCharactersAvailableInFont(string fontName, string text);
[DllImport(@"FontUtil.dll", CharSet = CharSet.Unicode)] static extern bool IsFontInstalled(string fontName);
static void Main(string[] args) { Console.WriteLine(IsFontInstalled("Berlin Sans FB Demi")); foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.AllCultures)) { if (!IsCharactersAvailableInFont("MS Shell Dlg", ci.NativeName)) { Console.WriteLine(ci.Name); } } }
Regards, Walter Wang (wawang@online.microsoft.com, remove 'online.') Microsoft Online Community Support
================================================== When responding to posts, please "Reply to Group" via your newsreader so that others may learn and benefit from your issue. ==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
Walter Wang [MSFT] - 28 Sep 2007 05:49 GMT minor fix to the CPP code:
delete indices; // add this return bResult; }
David Thielen - 28 Sep 2007 17:32 GMT Hi;
I really really appreciate you creating this. However, we presently are 100% managed code and this isn't important enough to add unmanaged code to our app - so we'll have to live with it writing the far east names in English.
 Signature thanks - dave david_at_windward_dot_net http://www.windwardreports.com
Cubicle Wars - http://www.windwardreports.com/film.htm
> Hi Dave, > [quoted text clipped - 123 lines] > > This posting is provided "AS IS" with no warranties, and confers no rights.
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|