WaldB
WaldB

Reputation: 1261

Why is the character `0x62A` printed with the "Calibri" font, but the character `0x660E` isn't?

The Calibri font doesn't have neither one of the characters, 0x062A and 0x660E, but the first character gets printed using some other font. However, the character 0x660E shows as an invalid char code. Why TextOut() doesn't substitute the font to print this last character, the same it did with the character code 0x062A ?

If I replace the Calibri font by Arial, the result is the same.

Edit : also I want to call your attention to this sentence, which can be found here http://msdn.microsoft.com/en-us/goglobal/bb688134.aspx : "The Windows core fonts (Times New Roman, Courier New, Arial, Microsoft Sans Serif, and Tahoma) contain Latin, Hebrew, Arabic, Greek, and Cyrillic scripts but do not contain East Asian script characters. They link to fonts that do." Well I've tried my code with all those fonts and the results were exactly the same : the character 0x660E is rendered invalid.

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, UINT wParam, LONG lParam)
{
    static HFONT s_hFont;   

    switch( message )
    {
        case WM_CREATE:
        {
            LOGFONT lf;
            memset(&lf, 0, sizeof(LOGFONT));
            lf.lfHeight = -MulDiv(20, 96, 72);
            lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
            wcscpy_s(lf.lfFaceName, LF_FACESIZE, L"Calibri");

            if( !(s_hFont = CreateFontIndirect(&lf)) ) return -1;
        }
        break;

        case WM_PAINT:
        {
            PAINTSTRUCT ps;
            BeginPaint(hwnd, &ps);
            s_hFont = (HFONT)SelectObject(ps.hdc, s_hFont);

            wchar_t wchar1 = 0x062A;                //  Arabic character
            TextOut(ps.hdc, 10, 10, &wchar1, 1);

            wchar_t wchar2 = 0x660E;                //  Japanese character
            TextOut(ps.hdc, 10, 50, &wchar2, 1);

            s_hFont = (HFONT)SelectObject(ps.hdc, s_hFont);
            EndPaint(hwnd, &ps);
        }
        break;


        case WM_DESTROY:
        DeleteObject(s_hFont);
        PostQuitMessage(0);
        break;

        default:

        return DefWindowProc(hwnd, message, wParam, lParam);
    }
    return 0L ;
}

Screen shot from the output

enter image description here

Upvotes: 3

Views: 1359

Answers (2)

Adrian McCarthy
Adrian McCarthy

Reputation: 48022

The Windows core fonts (Times New Roman, Courier New, Arial, Microsoft Sans Serif, and Tahoma) contain Latin, Hebrew, Arabic, Greek, and Cyrillic scripts but do not contain East Asian script characters. They link to fonts that do.

And, indeed they do link to fonts with CJK support, but that doesn't mean you have those fonts installed. You didn't specify which version of Windows. On older versions (e.g., XP and maybe Vista) if you install a "western" edition, you don't get good CJK font support unless you explicitly ask Windows to install the necessary fonts and tables.

There's a control panel application (Regional Settings?) that lets you indicate you want more complete international character support. It will require your installation media to be present, and it will install more fonts and update tables related to these additional characters. It might even update the font linking registry keys.

Upvotes: 0

arx
arx

Reputation: 16904

I doubt you'll get a very good answer because font linking isn't terribly well documented and nobody really cares about it (for reasons I'll explain).

Michael Kaplan wrote a short series of articles on the subject: Font substitution and linking parts 1, 2 and 3. And there's an MSDN article.

As Michael Kaplan points out, font linking depends on the current system locale and can also be edited on any system. You can't rely on it.

Thus any application that cares about handling multilingual text will use MLang or Uniscribe or some other library to ensure good results.

Most applications don't need this level of international support. Handling the user's own script is usually enough, and Windows mostly does this for you. For example, my Japanese users want to enter Japanese text; they don't care if Urdu doesn't work on their computers. And vice versa for users in Pakistan.

In summary, if you don't care about supporting more than the user's script, use Windows defaults. If you do care, use a library for your text output. Don't rely on font linking.

Upvotes: 3

Related Questions