Add Unicode support to the map

This commit is contained in:
Ray Chason
2022-10-16 21:42:18 -04:00
parent f5111a7fb7
commit 426ef4d8d2
4 changed files with 69 additions and 23 deletions

View File

@@ -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)

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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 */