Why does the local system of non-Unicode applications make Unicode character-encoded fonts display incorrectly?

I am trying to display Unicode characters from a Wingdings font (this is a Unicode TrueType font that only supports character encoding). It displays correctly on my Win7 / 64 system using the appropriate regional OS settings:

  • Formats: Russian
  • Location: Russia
  • System locale (AKA for non-Unicode applications): English

But if I switch the System language to Russian, Unicode characters with codes> 127 do not display correctly (replaced with boxes).

My application is created using Unicode Charset in Visual Studio, it only calls the Unicode Windows API functions.

I also noted that several Windows applications also incorrectly display such characters with character fonts (Symbol, Wingdings, Webdings, etc.), for example. Notepad, Beyond Compare 3. But WordPad and MS Office are not affected.

The following is a minimal code snippet (purge resources skipped for brevity):

LOGFONTW lf = { 0 };
lf.lfCharSet = SYMBOL_CHARSET;
lf.lfHeight = 50;
wcscpy_s(lf.lfFaceName, L"Wingdings");

HFONT f = CreateFontIndirectW(&lf);

SelectObject(hdc, f);

// First two chars displayed OK, 3rd and 4th aren't (replaced with boxes) if
// Non-Unicode apps language is NOT English.
TextOutW(hdc, 10, 10, L"\x7d\x7e\x81\xfc");

So the question is: why the hell does the language setting for Un-Unicode applications affect Unicode applications?

And what is the correct (and easiest) way to display fonts SYMBOL_CHARSETwithout depending on the OS language system?

+4
source share
2 answers

, Wingdings -Unicode. Unicode, . . @Adrian McCarthy, , .

. : http://www.fileformat.info/info/unicode/font/wingdings : http://www.alanwood.net/demos/wingdings.html

, , ? :

1.

API API ANSI, @user1793036:

TextOutA(hdc, 10, 10, "\x7d\x7e\x81\xfc"); // Displayed correctly!

2.

Unicode F0 ( ) ASCII. Wingdings:

TextOutW(hdc, 10, 10, L"\xf07d\xf07e\xf081\xf0fc"); // Displayed correctly!

, , , . dp4

3. ,

, , ? - , :

void TextOutByGlyphs(HDC hdc, int x, int y, const CStringW& text)
{
   CStringW glyphs;

   GCP_RESULTSW gcpRes = {0};
   gcpRes.lStructSize = sizeof(GCP_RESULTS);
   gcpRes.lpGlyphs = glyphs.GetBuffer(text.GetLength());
   gcpRes.nGlyphs = text.GetLength();

   const DWORD flags = GetFontLanguageInfo(hdc) & FLI_MASK;
   GetCharacterPlacementW(hdc, text.GetString(), text.GetLength(), 0,
     &gcpRes, flags);
   glyphs.ReleaseBuffer(gcpRes.nGlyphs);

   ExtTextOutW(hdc, x, y, ETO_GLYPH_INDEX, NULL, glyphs.GetString(),
      glyphs.GetLength(), NULL);
}

TextOutByGlyphs(hdc, 10, 10, L"\x7d\x7e\x81\xfc"); // Displayed correctly!

GetCharacterPlacementW() . - GetGlyphIndicesW() "" > 127.

+5

, , :

  • Wingdings ( cmap?). ( charmap.exe: Character set .)

  • Unicode , Windows , " -".

  • Windows () 1252, .

  • , Windows () 1251, .

  • '\x81' 1251 U+0403, , , , . , '\xFC' U+044C.

, ExtTextOutW ETO_GLYPH_INDEX, Windows . .

ETO_IGNORELANGUAGE, , , , , , .

+4

Source: https://habr.com/ru/post/1523911/


All Articles