diff --git a/sys/windows/windsys.c b/sys/windows/windsys.c index af51e9c5b..42115121c 100644 --- a/sys/windows/windsys.c +++ b/sys/windows/windsys.c @@ -543,10 +543,26 @@ winos_ascii_to_wide_str(const unsigned char * src, WCHAR * dst, size_t dstLength return dst; } -WCHAR -winos_ascii_to_wide(const unsigned char c) +void +winos_ascii_to_wide(WCHAR dst[3], UINT32 c) { - return cp437[c]; +#ifdef ENHANCED_SYMBOLS + if (SYMHANDLING(H_UTF8)) { + if (c <= 0xFFFF) { + dst[0] = (WCHAR) c; + dst[1] = L'\0'; + } else { + /* UTF-16 surrogate pair */ + dst[0] = (WCHAR) ((c >> 10) + 0xD7C0); + dst[1] = (WCHAR) ((c & 0x3FF) + 0xDC00); + dst[2] = L'\0'; + } + } else +#endif + { + dst[0] = cp437[c]; + dst[1] = L'\0'; + } } BOOL winos_font_support_cp437(HFONT hFont) diff --git a/sys/windows/winos.h b/sys/windows/winos.h index 55300bda0..132b153e0 100644 --- a/sys/windows/winos.h +++ b/sys/windows/winos.h @@ -12,8 +12,8 @@ extern const WCHAR cp437[256]; WCHAR * winos_ascii_to_wide_str(const unsigned char * src, WCHAR * dst, size_t dstLength); -WCHAR -winos_ascii_to_wide(const unsigned char c); +void +winos_ascii_to_wide(WCHAR dst[3], UINT32 c); BOOL winos_font_support_cp437(HFONT hFont); diff --git a/win/win32/mhmap.c b/win/win32/mhmap.c index 1212395cb..723a0f7ce 100644 --- a/win/win32/mhmap.c +++ b/win/win32/mhmap.c @@ -49,6 +49,7 @@ typedef struct mswin_nethack_map_window { POINT map_orig; /* map origin point */ HFONT hMapFont; /* font for ASCII mode */ + HFONT hMapFontUnicode; /* font for Unicode mode */ boolean bUnicodeFont; /* font supports unicode page 437 */ int tileWidth; /* width of tile in pixels at 96 dpi */ @@ -252,6 +253,12 @@ mswin_map_layout(HWND hWnd, LPSIZE map_size) data->bUnicodeFont = winos_font_support_cp437(data->hMapFont); + // Same as above, but with ANSI_CHARSET for IBM and Unicode modes + lgfnt.lfCharSet = ANSI_CHARSET; + if (data->hMapFontUnicode) + DeleteObject(data->hMapFontUnicode); + data->hMapFontUnicode = CreateFontIndirect(&lgfnt); + // set tile size to match font metrics data->xBackTile = textMetrics.tmAveCharWidth; @@ -626,6 +633,8 @@ MapWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_DESTROY: if (data->hMapFont) DeleteObject(data->hMapFont); + if (data->hMapFontUnicode) + DeleteObject(data->hMapFontUnicode); if (data->hBackBuffer) DeleteBitmap(data->hBackBuffer); if (data->backBufferDC) @@ -911,9 +920,11 @@ paintGlyph(PNHMapWindow data, int i, int j, RECT * rect) { if (data->map[i][j].glyph >= 0) { - char ch; - WCHAR wch; + glyph_info *glyphinfo; + uint32 ch; + WCHAR wch[3]; int color; + uint32 rgbcolor; // unsigned special; // int mgch; HBRUSH back_brush; @@ -925,12 +936,23 @@ paintGlyph(PNHMapWindow data, int i, int j, RECT * rect) FillRect(data->backBufferDC, rect, blackBrush); DeleteObject(blackBrush); - #if (VERSION_MAJOR < 4) && (VERSION_MINOR < 4) && (PATCHLEVEL < 2) - nhglyph2charcolor(data->map[i][j], &ch, &color); - OldFg = SetTextColor(hDC, nhcolor_to_RGB(color)); - #else - ch = (char) data->map[i][j].ttychar; - color = (int) data->map[i][j].gm.sym.color; + glyphinfo = &data->map[i][j]; + ch = glyphinfo->ttychar; + color = (int) glyphinfo->gm.sym.color; + rgbcolor = nhcolor_to_RGB(color); +#ifdef ENHANCED_SYMBOLS + if (SYMHANDLING(H_UTF8) + && glyphinfo->gm.u + && glyphinfo->gm.u->utf8str) { + ch = glyphinfo->gm.u->utf32ch; + if (glyphinfo->gm.u->ucolor != 0) { + rgbcolor = RGB( + (glyphinfo->gm.u->ucolor >> 16) & 0xFF, + (glyphinfo->gm.u->ucolor >> 8) & 0xFF, + (glyphinfo->gm.u->ucolor >> 0) & 0xFF); + } + } +#endif if (((data->map[i][j].gm.glyphflags & MG_PET) && iflags.hilite_pet) || ((data->map[i][j].gm.glyphflags & (MG_DETECT | MG_BW_LAVA)) && iflags.use_inverse)) { @@ -946,21 +968,23 @@ paintGlyph(PNHMapWindow data, int i, int j, RECT * rect) break; default: OldFg = - SetTextColor(data->backBufferDC, nhcolor_to_RGB(color)); + SetTextColor(data->backBufferDC, rgbcolor); } } else { - OldFg = SetTextColor(data->backBufferDC, nhcolor_to_RGB(color)); + OldFg = SetTextColor(data->backBufferDC, rgbcolor); } - #endif - if (data->bUnicodeFont) { - wch = winos_ascii_to_wide(ch); - if (wch == 0x2591 || wch == 0x2592) { + if (data->bUnicodeFont || SYMHANDLING(H_UTF8)) { + winos_ascii_to_wide(wch, ch); + if (wch[0] == 0x2591 || wch[0] == 0x2592) { int intensity = 80; HBRUSH brush = CreateSolidBrush(RGB(intensity, intensity, intensity)); FillRect(data->backBufferDC, rect, brush); DeleteObject(brush); - intensity = (wch == 0x2591 ? 100 : 200); - brush = CreateSolidBrush(RGB(intensity, intensity, intensity)); + intensity = (wch[0] == 0x2591 ? 1 : 2); + brush = CreateSolidBrush(RGB( + GetRValue(rgbcolor)*intensity/2, + GetGValue(rgbcolor)*intensity/2, + GetBValue(rgbcolor)*intensity/2)); RECT smallRect = {0}; smallRect.left = rect->left + 1; smallRect.top = rect->top + 1; @@ -969,12 +993,15 @@ paintGlyph(PNHMapWindow data, int i, int j, RECT * rect) FillRect(data->backBufferDC, &smallRect, brush); DeleteObject(brush); } else { - DrawTextW(data->backBufferDC, &wch, 1, rect, + SelectObject(data->backBufferDC, data->hMapFontUnicode); + DrawTextW(data->backBufferDC, wch, -1, rect, DT_CENTER | DT_VCENTER | DT_NOPREFIX | DT_SINGLELINE); } } else { - DrawTextA(data->backBufferDC, &ch, 1, rect, + char ch8 = (char) ch; + SelectObject(data->backBufferDC, data->hMapFont); + DrawTextA(data->backBufferDC, &ch8, 1, rect, DT_CENTER | DT_VCENTER | DT_NOPREFIX | DT_SINGLELINE); } diff --git a/win/win32/mswproc.c b/win/win32/mswproc.c index 0b409ab06..efc655f12 100644 --- a/win/win32/mswproc.c +++ b/win/win32/mswproc.c @@ -90,6 +90,9 @@ struct window_procs mswin_procs = { | WC_SPLASH_SCREEN | WC_POPUP_DIALOG | WC_MOUSE_SUPPORT, #ifdef STATUS_HILITES WC2_HITPOINTBAR | WC2_FLUSH_STATUS | WC2_RESET_STATUS | WC2_HILITE_STATUS | +#endif +#ifdef ENHANCED_SYMBOLS + WC2_U_UTF8STR | WC2_U_24BITCOLOR | #endif 0L, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */