Actually, I didn't notice it until I restarted my computer where my news
reader (thunderbird) actually show what the "expected" and "display"
looked like (previously it just displayed as boxed characters). Hmm, it
seems to me that there is a bug in gdi+ that incorrectly show certain
script ('khmer' in this case) to a different wording. (I actually
haven't verify it by creating a native win32 program that directly call
a gdi+ function, but since the Graphics.DrawString() method in .Net just
call the native method in gdi+ library, the possibility is quite high).
I had tried with the WPF version of DrawingContext.DrawText() method,
and it didn't suffer the same problem (which is not a surprise as the
rendering in WPF is through DirectX).
Okay, I actually did a test with a native win32 application (code below)
and yes - there is a problem with gdi+ of DrawString method. At the
moment, I don't know any workaround yet (maybe the OP can post a bug
report to MS Connect) and probably this is a good time for the OP to
migrate to WPF...
#include <windows.h>
#include <objidl.h>
#include <gdiplus.h>
using namespace Gdiplus;
#pragma comment (lib,"Gdiplus.lib")
VOID OnPaint(HDC hdc)
{
Graphics graphics(hdc);
SolidBrush brush(Color(255, 0, 0, 255));
FontFamily fontFamily(L"Khmer UI");
Font font(&fontFamily, 64, FontStyleRegular, UnitPixel);
PointF pointF(10.0f, 20.0f);
graphics.DrawString(L"សួស្ážáž¸", -1, &font, pointF, &brush);
}
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, INT iCmdShow)
{
HWND hWnd;
MSG msg;
WNDCLASS wndClass;
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
// Initialize GDI+.
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
wndClass.style = CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = WndProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hInstance = hInstance;
wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndClass.lpszMenuName = NULL;
wndClass.lpszClassName = TEXT("Test");
RegisterClass(&wndClass);
hWnd = CreateWindow(
TEXT("Test"), // window class name
TEXT("Test"), // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL); // creation parameters
ShowWindow(hWnd, iCmdShow);
UpdateWindow(hWnd);
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
GdiplusShutdown(gdiplusToken);
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
HDC hdc;
PAINTSTRUCT ps;
switch(message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
OnPaint(hdc);
EndPaint(hWnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}