From: Bart House Date: Sun, 2 Dec 2018 21:25:03 +0000 (-0800) Subject: NetHackW status hilite support improved to include support for attributes. X-Git-Tag: nmake-explicit-path~95 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0f679b3109113fcb784de3dd16cb69a60090a828;p=nethack NetHackW status hilite support improved to include support for attributes. --- diff --git a/win/win32/mhfont.c b/win/win32/mhfont.c index e8296cc8d..9f00df770 100644 --- a/win/win32/mhfont.c +++ b/win/win32/mhfont.c @@ -8,14 +8,10 @@ #include "winos.h" #include "mhfont.h" +/* font table - 64 fonts ought to be enough */ #define MAXFONTS 64 -/* font table - 64 fonts ought to be enough */ -static struct font_table_entry { - int code; - HFONT hFont; - BOOL supportsUnicode; -} font_table[MAXFONTS]; +static cached_font font_table[MAXFONTS]; static int font_table_size = 0; HFONT version_splash_font; @@ -66,7 +62,7 @@ mswin_font_supports_unicode(HFONT hFont) /* create font based on window type, charater attributes and window device context */ -HGDIOBJ +cached_font * mswin_get_font(int win_type, int attr, HDC hdc, BOOL replace) { HFONT fnt = NULL; @@ -88,7 +84,7 @@ mswin_get_font(int win_type, int attr, HDC hdc, BOOL replace) break; if (!replace && font_index < font_table_size) - return font_table[font_index].hFont; + return &font_table[font_index]; switch (win_type) { case NHW_STATUS: @@ -102,7 +98,7 @@ mswin_get_font(int win_type, int attr, HDC hdc, BOOL replace) lgfnt.lfWeight = (attr == ATR_BOLD) ? FW_BOLD : FW_NORMAL; // font weight lgfnt.lfItalic = FALSE; // italic attribute option - lgfnt.lfUnderline = FALSE; // underline attribute option + lgfnt.lfUnderline = (attr == ATR_ULINE); // underline attribute option lgfnt.lfStrikeOut = FALSE; // strikeout attribute option lgfnt.lfCharSet = mswin_charset(); // character set identifier lgfnt.lfOutPrecision = OUT_DEFAULT_PRECIS; // output precision @@ -214,7 +210,15 @@ mswin_get_font(int win_type, int attr, HDC hdc, BOOL replace) font_table[font_index].hFont = fnt; font_table[font_index].supportsUnicode = winos_font_support_cp437(fnt); - return fnt; + HGDIOBJ savedFont = SelectObject(hdc, fnt); + SIZE size; + GetTextExtentPoint32A(hdc, " ", 1, &size); + SelectObject(hdc, savedFont); + + font_table[font_index].height = size.cy; + font_table[font_index].width = size.cx; + + return &font_table[font_index]; } UINT diff --git a/win/win32/mhfont.h b/win/win32/mhfont.h index 76e651215..1e472b080 100644 --- a/win/win32/mhfont.h +++ b/win/win32/mhfont.h @@ -9,8 +9,16 @@ #include "winMS.h" +typedef struct cached_font { + int code; + HFONT hFont; + BOOL supportsUnicode; + int width; + int height; +} cached_font; + BOOL mswin_font_supports_unicode(HFONT hFont); -HGDIOBJ mswin_get_font(int win_type, int attr, HDC hdc, BOOL replace); +cached_font * mswin_get_font(int win_type, int attr, HDC hdc, BOOL replace); void mswin_init_splashfonts(HWND hWnd); void mswin_destroy_splashfonts(void); UINT mswin_charset(void); diff --git a/win/win32/mhmenu.c b/win/win32/mhmenu.c index d35c5ef2e..5e38d0235 100644 --- a/win/win32/mhmenu.c +++ b/win/win32/mhmenu.c @@ -297,8 +297,9 @@ MenuWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) data); /* set font for the text cotrol */ + cached_font * font = mswin_get_font(NHW_MENU, ATR_NONE, hdc, FALSE); SendMessage(control, WM_SETFONT, - (WPARAM) mswin_get_font(NHW_MENU, ATR_NONE, hdc, FALSE), + (WPARAM) font->hFont, (LPARAM) 0); ReleaseDC(control, hdc); @@ -564,8 +565,8 @@ onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) /* calculate dimensions of the added line of text */ hdc = GetDC(text_view); - saveFont = - SelectObject(hdc, mswin_get_font(NHW_MENU, ATR_NONE, hdc, FALSE)); + cached_font * font = mswin_get_font(NHW_MENU, ATR_NONE, hdc, FALSE); + saveFont = SelectObject(hdc, font->hFont); SetRect(&text_rt, 0, 0, 0, 0); DrawTextA(hdc, msg_data->text, strlen(msg_data->text), &text_rt, DT_CALCRECT | DT_TOP | DT_LEFT | DT_NOPREFIX @@ -629,8 +630,8 @@ onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) /* calculate tabstop size */ hDC = GetDC(hWnd); - saveFont = SelectObject( - hDC, mswin_get_font(NHW_MENU, msg_data->attr, hDC, FALSE)); + cached_font * font = mswin_get_font(NHW_MENU, msg_data->attr, hDC, FALSE); + saveFont = SelectObject(hDC, font->hFont); GetTextMetrics(hDC, &tm); p1 = data->menu.items[new_item].str; p = strchr(data->menu.items[new_item].str, '\t'); @@ -936,8 +937,8 @@ onMeasureItem(HWND hWnd, WPARAM wParam, LPARAM lParam) GetClientRect(GetMenuControl(hWnd), &list_rect); hdc = GetDC(GetMenuControl(hWnd)); - saveFont = - SelectObject(hdc, mswin_get_font(NHW_MENU, ATR_INVERSE, hdc, FALSE)); + cached_font * font = mswin_get_font(NHW_MENU, ATR_INVERSE, hdc, FALSE); + saveFont = SelectObject(hdc, font->hFont); GetTextMetrics(hdc, &tm); /* Set the height of the list box items to max height of the individual @@ -1000,8 +1001,8 @@ onDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam) item = &data->menu.items[lpdis->itemID]; tileDC = CreateCompatibleDC(lpdis->hDC); - saveFont = SelectObject( - lpdis->hDC, mswin_get_font(NHW_MENU, item->attr, lpdis->hDC, FALSE)); + cached_font * font = mswin_get_font(NHW_MENU, item->attr, lpdis->hDC, FALSE); + saveFont = SelectObject(lpdis->hDC, font->hFont); NewBg = menu_bg_brush ? menu_bg_color : (COLORREF) GetSysColor(DEFAULT_COLOR_BG_MENU); OldBg = SetBkColor(lpdis->hDC, NewBg); @@ -1050,8 +1051,8 @@ onDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam) if (iflags.use_menu_color && (menucolr = get_menu_coloring(item->str, &color, &attr))) { - SelectObject(lpdis->hDC, - mswin_get_font(NHW_MENU, attr, lpdis->hDC, FALSE)); + cached_font * menu_font = mswin_get_font(NHW_MENU, attr, lpdis->hDC, FALSE); + SelectObject(lpdis->hDC, menu_font->hFont); if (color != NO_COLOR) SetTextColor(lpdis->hDC, nhcolor_to_RGB(color)); } @@ -1165,8 +1166,10 @@ onDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam) data->menu.items[lpdis->itemID].count); } - SelectObject(lpdis->hDC, mswin_get_font(NHW_MENU, ATR_BLINK, - lpdis->hDC, FALSE)); + /* TOOD: add blinking for blink text */ + + cached_font * blink_font = mswin_get_font(NHW_MENU, ATR_BLINK, lpdis->hDC, FALSE); + SelectObject(lpdis->hDC, blink_font->hFont); /* calculate text rectangle */ SetRect(&drawRect, client_rt.left, lpdis->rcItem.top, diff --git a/win/win32/mhmsgwnd.c b/win/win32/mhmsgwnd.c index febe88143..505b40f36 100644 --- a/win/win32/mhmsgwnd.c +++ b/win/win32/mhmsgwnd.c @@ -635,9 +635,9 @@ onPaint(HWND hWnd) draw_rt.top = y - data->yChar; draw_rt.bottom = y; - oldFont = SelectObject( - hdc, mswin_get_font(NHW_MESSAGE, data->window_text[i].attr, - hdc, FALSE)); + cached_font * font = mswin_get_font(NHW_MESSAGE, + data->window_text[i].attr, hdc, FALSE); + oldFont = SelectObject(hdc, font->hFont); /* convert to UNICODE stripping newline */ strcpy(tmptext, data->window_text[i].text); @@ -746,8 +746,8 @@ mswin_message_window_size(HWND hWnd, LPSIZE sz) /* -- Calculate the font size -- */ /* Get the handle to the client area's device context. */ hdc = GetDC(hWnd); - saveFont = - SelectObject(hdc, mswin_get_font(NHW_MESSAGE, ATR_NONE, hdc, FALSE)); + cached_font * font = mswin_get_font(NHW_MESSAGE, ATR_NONE, hdc, FALSE); + saveFont = SelectObject(hdc, font->hFont); /* Extract font dimensions from the text metrics. */ GetTextMetrics(hdc, &tm); @@ -813,10 +813,9 @@ can_append_text(HWND hWnd, int attr, const char *text) strcat(tmptext, MORE); hdc = GetDC(hWnd); - saveFont = SelectObject( - hdc, - mswin_get_font(NHW_MESSAGE, data->window_text[MSG_LINES - 1].attr, - hdc, FALSE)); + cached_font * font = mswin_get_font(NHW_MESSAGE, + data->window_text[MSG_LINES - 1].attr, hdc, FALSE); + saveFont = SelectObject(hdc, font->hFont); GetClientRect(hWnd, &draw_rt); draw_rt.left += LINE_PADDING_LEFT(data); draw_rt.right -= LINE_PADDING_RIGHT(data); @@ -860,17 +859,16 @@ more_prompt_check(HWND hWnd) remaining_height = client_rt.bottom - client_rt.top; hdc = GetDC(hWnd); - saveFont = - SelectObject(hdc, mswin_get_font(NHW_MESSAGE, ATR_NONE, hdc, FALSE)); + cached_font * font = mswin_get_font(NHW_MESSAGE, ATR_NONE, hdc, FALSE); + saveFont = SelectObject(hdc, font->hFont); for (i = 0; i < data->lines_not_seen; i++) { /* we only need width for the DrawText */ SetRect(&draw_rt, client_rt.left + LINE_PADDING_LEFT(data), client_rt.top, client_rt.right - LINE_PADDING_RIGHT(data), client_rt.top); - SelectObject(hdc, - mswin_get_font(NHW_MESSAGE, - data->window_text[MSG_LINES - i - 1].attr, - hdc, FALSE)); + font = mswin_get_font(NHW_MESSAGE, + data->window_text[MSG_LINES - i - 1].attr, hdc, FALSE); + SelectObject(hdc, font->hFont); strcpy(tmptext, data->window_text[MSG_LINES - i - 1].text); strip_newline(tmptext); diff --git a/win/win32/mhrip.c b/win/win32/mhrip.c index ed826704b..79ad05342 100644 --- a/win/win32/mhrip.c +++ b/win/win32/mhrip.c @@ -69,7 +69,6 @@ mswin_display_RIP_window(HWND hWnd) RECT riprt; RECT clientrect; RECT textrect; - HDC hdc; HFONT OldFont; MonitorInfo monitorInfo; @@ -98,8 +97,8 @@ mswin_display_RIP_window(HWND hWnd) textrect.left += data->x; textrect.right -= data->x; if (data->window_text) { - hdc = GetDC(hWnd); - OldFont = SelectObject(hdc, mswin_get_font(NHW_TEXT, 0, hdc, FALSE)); + HDC hdc = GetDC(hWnd); + OldFont = SelectObject(hdc, mswin_get_font(NHW_TEXT, 0, hdc, FALSE)->hFont); DrawText(hdc, data->window_text, strlen(data->window_text), &textrect, DT_LEFT | DT_NOPREFIX | DT_CALCRECT); SelectObject(hdc, OldFont); @@ -144,21 +143,18 @@ mswin_display_RIP_window(HWND hWnd) INT_PTR CALLBACK NHRIPWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - HDC hdc; - PNHRIPWindow data; - - data = (PNHRIPWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA); + PNHRIPWindow data = (PNHRIPWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA); switch (message) { - case WM_INITDIALOG: + case WM_INITDIALOG: { + HDC hdc = GetDC(hWnd); + cached_font * font = mswin_get_font(NHW_TEXT, ATR_NONE, hdc, FALSE); + /* set text control font */ - hdc = GetDC(hWnd); - SendMessage(hWnd, WM_SETFONT, - (WPARAM) mswin_get_font(NHW_TEXT, ATR_NONE, hdc, FALSE), - 0); + SendMessage(hWnd, WM_SETFONT, (WPARAM)font->hFont, 0); ReleaseDC(hWnd, hdc); SetFocus(GetDlgItem(hWnd, IDOK)); - return FALSE; + } break; case WM_MSNH_COMMAND: onMSNHCommand(hWnd, wParam, lParam); @@ -172,9 +168,10 @@ NHRIPWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) HANDLE OldBitmap; PAINTSTRUCT ps; HFONT OldFont; + HDC hdc = BeginPaint(hWnd, &ps); + cached_font * font = mswin_get_font(NHW_TEXT, ATR_NONE, hdc, FALSE); - hdc = BeginPaint(hWnd, &ps); - OldFont = SelectObject(hdc, mswin_get_font(NHW_TEXT, 0, hdc, FALSE)); + OldFont = SelectObject(hdc, font->hFont); hdcBitmap = CreateCompatibleDC(hdc); SetBkMode(hdc, TRANSPARENT); GetClientRect(hWnd, &clientrect); diff --git a/win/win32/mhsplash.c b/win/win32/mhsplash.c index 0b0e313cd..734e44bb3 100644 --- a/win/win32/mhsplash.c +++ b/win/win32/mhsplash.c @@ -170,21 +170,18 @@ mswin_display_splash_window(BOOL show_ver) INT_PTR CALLBACK NHSplashWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - HDC hdc; - UNREFERENCED_PARAMETER(lParam); switch (message) { - case WM_INITDIALOG: + case WM_INITDIALOG: { + HDC hdc = GetDC(hWnd); + cached_font * font = mswin_get_font(NHW_TEXT, ATR_NONE, hdc, FALSE); /* set text control font */ - hdc = GetDC(hWnd); - SendMessage(hWnd, WM_SETFONT, - (WPARAM) mswin_get_font(NHW_TEXT, ATR_NONE, hdc, FALSE), - 0); + SendMessage(hWnd, WM_SETFONT, (WPARAM)font->hFont, 0); ReleaseDC(hWnd, hdc); SetFocus(GetDlgItem(hWnd, IDOK)); - return FALSE; + } break; case WM_PAINT: { char VersionString[BUFSZ]; @@ -196,7 +193,7 @@ NHSplashWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) SplashData *splashData = (SplashData *) GetWindowLongPtr(hWnd, GWLP_USERDATA); - hdc = BeginPaint(hWnd, &ps); + HDC hdc = BeginPaint(hWnd, &ps); /* Show splash graphic */ hdcBitmap = CreateCompatibleDC(hdc); diff --git a/win/win32/mhstatus.c b/win/win32/mhstatus.c index 57c70b436..b9175a04e 100644 --- a/win/win32/mhstatus.c +++ b/win/win32/mhstatus.c @@ -9,8 +9,15 @@ #include "mhmsg.h" #include "mhfont.h" +#ifndef STATUS_HILITES +#error STATUS_HILITES not defined +#endif + #define MAXWINDOWTEXT BUFSZ +#define STATUS_BLINK_INTERVAL 500 // milliseconds + + extern COLORREF nhcolor_to_RGB(int c); /* from mhmap */ typedef struct back_buffer { @@ -65,6 +72,8 @@ typedef struct mswin_nethack_status_window { char window_text[NHSW_LINES][MAXWINDOWTEXT + 1]; mswin_status_lines * status_lines; back_buffer_t back_buffer; + boolean blink_state; /* true = invert blink text */ + boolean has_blink_fields; /* true if one or more has blink attriubte */ } NHStatusWindow, *PNHStatusWindow; @@ -135,6 +144,9 @@ mswin_init_status_window() status_fg_brush = CreateSolidBrush(status_fg_color); } + /* set cursor blink timer */ + SetTimer(ret, 0, STATUS_BLINK_INTERVAL, NULL); + return ret; } @@ -183,28 +195,23 @@ StatusWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) case MSNH_MSG_GETTEXT: { PMSNHMsgGetText msg_data = (PMSNHMsgGetText) lParam; -#ifdef STATUS_HILITES msg_data->buffer[0] = '\0'; + size_t space_remaining = msg_data->max_size; for (int line = 0; line < NHSW_LINES; line++) { mswin_status_line *status_line = data->status_lines[line].lines; for (int i = 0; i < status_line->status_strings.count; i++) { mswin_status_string * status_string = status_line->status_strings.status_strings[i]; - strncat(msg_data->buffer, status_string->str, - msg_data->max_size - strlen(msg_data->buffer)); + if (status_string->space_in_front) { + strncat(msg_data->buffer, " ", space_remaining); + space_remaining = msg_data->max_size - strlen(msg_data->buffer); + } + strncat(msg_data->buffer, status_string->str, space_remaining); + space_remaining = msg_data->max_size - strlen(msg_data->buffer); } - strncat(msg_data->buffer, "\r\n", - msg_data->max_size - strlen(msg_data->buffer)); + strncat(msg_data->buffer, "\r\n", space_remaining); + space_remaining = msg_data->max_size - strlen(msg_data->buffer); } - -#else - strncpy(msg_data->buffer, data->window_text[0], - msg_data->max_size); - strncat(msg_data->buffer, "\r\n", - msg_data->max_size - strlen(msg_data->buffer)); - strncat(msg_data->buffer, data->window_text[1], - msg_data->max_size - strlen(msg_data->buffer)); -#endif } break; case MSNH_MSG_UPDATE_STATUS: { @@ -245,22 +252,25 @@ StatusWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) SetFocus(GetNHApp()->hMainWnd); break; + case WM_TIMER: + data->blink_state = !data->blink_state; + if (data->has_blink_fields) + InvalidateRect(hWnd, NULL, TRUE); + break; + default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } -#ifdef STATUS_HILITES static LRESULT onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam) { SIZE sz; - HGDIOBJ normalFont, boldFont; WCHAR wbuf[BUFSZ]; RECT rt; PAINTSTRUCT ps; - HDC hdc; PNHStatusWindow data; int width, height; RECT clear_rect; @@ -276,12 +286,7 @@ onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam) back_buffer_size(&data->back_buffer, width, height); - hdc = data->back_buffer.hdc; - - normalFont = mswin_get_font(NHW_STATUS, ATR_NONE, hdc, FALSE); - boldFont = mswin_get_font(NHW_STATUS, ATR_BOLD, hdc, FALSE); - - SelectObject(hdc, normalFont); + HDC hdc = data->back_buffer.hdc; SetBkColor(hdc, status_bg_color); SetTextColor(hdc, status_fg_color); @@ -301,6 +306,8 @@ onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam) return 0; } + data->has_blink_fields = FALSE; + for (int line = 0; line < NHSW_LINES; line++) { LONG left = rt.left; LONG cy = 0; @@ -312,15 +319,13 @@ onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam) mswin_status_string * status_string = status_line->status_strings.status_strings[i]; int clr, atr; int fntatr = ATR_NONE; - HGDIOBJ fnt; COLORREF nFg, nBg; if (status_string->str == NULL || status_string->str[0] == '\0') continue; - - clr = status_string->color & 0x00ff; - atr = (status_string->color & 0xff00) >> 8; + clr = status_string->color; + atr = status_string->attribute; const char *str = status_string->str; @@ -332,25 +337,46 @@ onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam) fntatr = ATR_INVERSE; else if (atr & HL_ULINE) fntatr = ATR_ULINE; - else if (atr & HL_BLINK) - fntatr = ATR_BLINK; + else if (atr & HL_BLINK) { + data->has_blink_fields = TRUE; + if (data->blink_state) { + fntatr = ATR_INVERSE; + atr |= HL_INVERSE; + } + } else if (atr & HL_DIM) fntatr = ATR_DIM; - fnt = mswin_get_font(NHW_STATUS, fntatr, hdc, FALSE); + cached_font * fnt = mswin_get_font(NHW_STATUS, fntatr, hdc, FALSE); - BOOL useUnicode = mswin_font_supports_unicode(fnt); + BOOL useUnicode = fnt->supportsUnicode; winos_ascii_to_wide_str(str, wbuf, SIZE(wbuf)); nFg = (clr == NO_COLOR ? status_fg_color : ((clr >= 0 && clr < CLR_MAX) ? nhcolor_to_RGB(clr) : status_fg_color)); + + if (atr & HL_DIM) { + /* make a dim representation - this can produce color shift */ + float redReduction = 0.5f; + float greenReduction = 0.5f; + float blueReduction = 0.25f; + uchar red = (uchar) (GetRValue(nFg) * (1.0f - redReduction)); + uchar green = (uchar) (GetGValue(nFg) * (1.0f - greenReduction)); + uchar blue = (uchar) (GetBValue(nFg) * (1.0f - blueReduction)); + nFg = RGB(red, green, blue); + } + nBg = status_bg_color; + if (status_string->space_in_front) + rt.left += fnt->width; + sz.cy = -1; if (status_string->draw_bar && iflags.wc2_hitpointbar) { + /* NOTE: we current don't support bar attributes */ /* when we are drawing bar we need to look at the hp status * field to get the correct percentage and color */ @@ -359,11 +385,10 @@ onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam) RECT barrect; /* prepare for drawing */ - SelectObject(hdc, fnt); + SelectObject(hdc, fnt->hFont); SetBkMode(hdc, OPAQUE); SetBkColor(hdc, status_bg_color); - /* SetTextColor(hdc, nhcolor_to_RGB(hpbar_color)); */ - SetTextColor(hdc, status_fg_color); + SetTextColor(hdc, status_fg_color); if (useUnicode) { /* get bounding rectangle */ @@ -409,7 +434,7 @@ onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam) } /* prepare for drawing */ - SelectObject(hdc, fnt); + SelectObject(hdc, fnt->hFont); SetBkMode(hdc, OPAQUE); SetBkColor(hdc, nBg); SetTextColor(hdc, nFg); @@ -444,70 +469,24 @@ onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam) return 0; } -#else -static LRESULT -onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam) -{ - int i; - SIZE sz; - HGDIOBJ oldFont; - TCHAR wbuf[BUFSZ]; - COLORREF OldBg, OldFg; - RECT rt; - PAINTSTRUCT ps; - HDC hdc; - PNHStatusWindow data; - - data = (PNHStatusWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA); - - hdc = BeginPaint(hWnd, &ps); - GetClientRect(hWnd, &rt); - - oldFont = - SelectObject(hdc, mswin_get_font(NHW_STATUS, ATR_NONE, hdc, FALSE)); - - OldBg = SetBkColor(hdc, status_bg_brush ? status_bg_color - : (COLORREF) GetSysColor( - DEFAULT_COLOR_BG_STATUS)); - OldFg = SetTextColor(hdc, status_fg_brush ? status_fg_color - : (COLORREF) GetSysColor( - DEFAULT_COLOR_FG_STATUS)); - - for (i = 0; i < NHSW_LINES; i++) { - int wlen = strlen(data->window_text[i]); - NH_A2W(data->window_text[i], wbuf, SIZE(wbuf)); - GetTextExtentPoint32(hdc, wbuf, wlen, &sz); - DrawText(hdc, wbuf, wlen, &rt, DT_LEFT | DT_END_ELLIPSIS); - rt.top += sz.cy; - } - - SelectObject(hdc, oldFont); - SetTextColor(hdc, OldFg); - SetBkColor(hdc, OldBg); - EndPaint(hWnd, &ps); - - return 0; -} -#endif /* !STATUS_HILITES */ void mswin_status_window_size(HWND hWnd, LPSIZE sz) { - TEXTMETRIC tm; - HGDIOBJ saveFont; - HDC hdc; - PNHStatusWindow data; RECT rt; - SIZE text_sz; GetClientRect(hWnd, &rt); - data = (PNHStatusWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA); + PNHStatusWindow data = (PNHStatusWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA); if (data) { - hdc = GetDC(hWnd); - saveFont = SelectObject( - hdc, mswin_get_font(NHW_STATUS, ATR_NONE, hdc, FALSE)); + HDC hdc = GetDC(hWnd); + cached_font * font = mswin_get_font(NHW_STATUS, ATR_NONE, hdc, FALSE); + HGDIOBJ saveFont = SelectObject(hdc, font->hFont); + + SIZE text_sz; GetTextExtentPoint32(hdc, _T("W"), 1, &text_sz); + + TEXTMETRIC tm; GetTextMetrics(hdc, &tm); rt.bottom = rt.top + text_sz.cy * NHSW_LINES; diff --git a/win/win32/mhstatus.h b/win/win32/mhstatus.h index 1f0d75d26..d7239d580 100644 --- a/win/win32/mhstatus.h +++ b/win/win32/mhstatus.h @@ -34,10 +34,13 @@ static const int fieldcounts[NHSW_LINES] = { SIZE(fieldorder1) - 1, SIZE(fieldor * to represent what needs to be rendered. */ typedef struct mswin_status_string { const char * str; /* ascii string to be displayed */ - int color; /* string text color */ - boolean draw_bar; + boolean space_in_front; /* render with a space in front of string */ + int color; /* string text color index */ + int attribute; /* string text attributes */ + boolean draw_bar; /* draw a percentage bar */ int bar_percent; /* a percentage to indicate; 100 will draw no percentage bar */ int bar_color; /* color index of percentage bar */ + int bar_attribute; /* attributes of percentage bar */ } mswin_status_string; typedef struct mswin_status_strings @@ -51,9 +54,11 @@ typedef struct mswin_status_field { boolean enabled; // whether the field is enabled const char * name; // name of status field const char * format; // format of field + boolean space_in_front; // add a space in front of the field int percent; int color; + int attribute; char string[BUFSZ]; } mswin_status_field; diff --git a/win/win32/mhtext.c b/win/win32/mhtext.c index 626e46e2b..8c1c2b32f 100644 --- a/win/win32/mhtext.c +++ b/win/win32/mhtext.c @@ -84,38 +84,35 @@ mswin_display_text_window(HWND hWnd) INT_PTR CALLBACK NHTextWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - HWND control; - HDC hdc; - PNHTextWindow data; - TCHAR title[MAX_LOADSTRING]; + PNHTextWindow data = (PNHTextWindow)GetWindowLongPtr(hWnd, GWLP_USERDATA); - data = (PNHTextWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA); switch (message) { - case WM_INITDIALOG: + case WM_INITDIALOG: { + HWND control = GetDlgItem(hWnd, IDC_TEXT_CONTROL); + HDC hdc = GetDC(control); + cached_font * font = mswin_get_font(NHW_TEXT, ATR_NONE, hdc, FALSE); /* set text control font */ - control = GetDlgItem(hWnd, IDC_TEXT_CONTROL); + if (!control) { panic("cannot get text view window"); } - hdc = GetDC(control); - SendMessage(control, WM_SETFONT, - (WPARAM) mswin_get_font(NHW_TEXT, ATR_NONE, hdc, FALSE), - 0); + SendMessage(control, WM_SETFONT, (WPARAM) font->hFont, 0); ReleaseDC(control, hdc); /* subclass edit control */ editControlWndProc = - (WNDPROC) GetWindowLongPtr(control, GWLP_WNDPROC); - SetWindowLongPtr(control, GWLP_WNDPROC, (LONG_PTR) NHEditHookWndProc); + (WNDPROC)GetWindowLongPtr(control, GWLP_WNDPROC); + SetWindowLongPtr(control, GWLP_WNDPROC, (LONG_PTR)NHEditHookWndProc); SetFocus(control); /* Even though the dialog has no caption, you can still set the title which shows on Alt-Tab */ + TCHAR title[MAX_LOADSTRING]; LoadString(GetNHApp()->hApp, IDS_APP_TITLE, title, MAX_LOADSTRING); SetWindowText(hWnd, title); - return FALSE; + } break; case WM_MSNH_COMMAND: onMSNHCommand(hWnd, wParam, lParam); diff --git a/win/win32/mswproc.c b/win/win32/mswproc.c index 74a4cd3c6..cadfb1f97 100644 --- a/win/win32/mswproc.c +++ b/win/win32/mswproc.c @@ -1913,16 +1913,13 @@ mswin_outrip(winid wid, int how, time_t when) void mswin_preference_update(const char *pref) { - HDC hdc; - int i; - if (stricmp(pref, "font_menu") == 0 || stricmp(pref, "font_size_menu") == 0) { if (iflags.wc_fontsiz_menu < NHFONT_SIZE_MIN || iflags.wc_fontsiz_menu > NHFONT_SIZE_MAX) iflags.wc_fontsiz_menu = NHFONT_DEFAULT_SIZE; - hdc = GetDC(GetNHApp()->hMainWnd); + HDC hdc = GetDC(GetNHApp()->hMainWnd); mswin_get_font(NHW_MENU, ATR_NONE, hdc, TRUE); mswin_get_font(NHW_MENU, ATR_BOLD, hdc, TRUE); mswin_get_font(NHW_MENU, ATR_DIM, hdc, TRUE); @@ -1941,7 +1938,7 @@ mswin_preference_update(const char *pref) || iflags.wc_fontsiz_status > NHFONT_SIZE_MAX) iflags.wc_fontsiz_status = NHFONT_DEFAULT_SIZE; - hdc = GetDC(GetNHApp()->hMainWnd); + HDC hdc = GetDC(GetNHApp()->hMainWnd); mswin_get_font(NHW_STATUS, ATR_NONE, hdc, TRUE); mswin_get_font(NHW_STATUS, ATR_BOLD, hdc, TRUE); mswin_get_font(NHW_STATUS, ATR_DIM, hdc, TRUE); @@ -1950,7 +1947,7 @@ mswin_preference_update(const char *pref) mswin_get_font(NHW_STATUS, ATR_INVERSE, hdc, TRUE); ReleaseDC(GetNHApp()->hMainWnd, hdc); - for (i = 1; i < MAXWINDOWS; i++) { + for (int i = 1; i < MAXWINDOWS; i++) { if (GetNHApp()->windowlist[i].type == NHW_STATUS && GetNHApp()->windowlist[i].win != NULL) { InvalidateRect(GetNHApp()->windowlist[i].win, NULL, TRUE); @@ -1966,7 +1963,7 @@ mswin_preference_update(const char *pref) || iflags.wc_fontsiz_message > NHFONT_SIZE_MAX) iflags.wc_fontsiz_message = NHFONT_DEFAULT_SIZE; - hdc = GetDC(GetNHApp()->hMainWnd); + HDC hdc = GetDC(GetNHApp()->hMainWnd); mswin_get_font(NHW_MESSAGE, ATR_NONE, hdc, TRUE); mswin_get_font(NHW_MESSAGE, ATR_BOLD, hdc, TRUE); mswin_get_font(NHW_MESSAGE, ATR_DIM, hdc, TRUE); @@ -1986,7 +1983,7 @@ mswin_preference_update(const char *pref) || iflags.wc_fontsiz_text > NHFONT_SIZE_MAX) iflags.wc_fontsiz_text = NHFONT_DEFAULT_SIZE; - hdc = GetDC(GetNHApp()->hMainWnd); + HDC hdc = GetDC(GetNHApp()->hMainWnd); mswin_get_font(NHW_TEXT, ATR_NONE, hdc, TRUE); mswin_get_font(NHW_TEXT, ATR_BOLD, hdc, TRUE); mswin_get_font(NHW_TEXT, ATR_DIM, hdc, TRUE); @@ -2772,19 +2769,19 @@ static mswin_status_string _condition_strings[BL_MASK_BITS]; static mswin_status_field _status_fields[MAXBLSTATS]; static mswin_condition_field _condition_fields[BL_MASK_BITS] = { - { BL_MASK_STONE, " Stone" }, - { BL_MASK_SLIME, " Slime" }, - { BL_MASK_STRNGL, " Strngl" }, - { BL_MASK_FOODPOIS, " FoodPois" }, - { BL_MASK_TERMILL, " TermIll" }, - { BL_MASK_BLIND, " Blind" }, - { BL_MASK_DEAF, " Deaf" }, - { BL_MASK_STUN, " Stun" }, - { BL_MASK_CONF, " Conf" }, - { BL_MASK_HALLU, " Hallu" }, - { BL_MASK_LEV, " Lev" }, - { BL_MASK_FLY, " Fly" }, - { BL_MASK_RIDE, " Ride" } + { BL_MASK_STONE, "Stone" }, + { BL_MASK_SLIME, "Slime" }, + { BL_MASK_STRNGL, "Strngl" }, + { BL_MASK_FOODPOIS, "FoodPois" }, + { BL_MASK_TERMILL, "TermIll" }, + { BL_MASK_BLIND, "Blind" }, + { BL_MASK_DEAF, "Deaf" }, + { BL_MASK_STUN, "Stun" }, + { BL_MASK_CONF, "Conf" }, + { BL_MASK_HALLU, "Hallu" }, + { BL_MASK_LEV, "Lev" }, + { BL_MASK_FLY, "Fly" }, + { BL_MASK_RIDE, "Ride" } }; @@ -2915,10 +2912,13 @@ mswin_status_enablefield(int fieldidx, const char *nm, const char *fmt, if (field != NULL) { field->format = fmt; + field->space_in_front = (fmt[0] == ' '); + if (field->space_in_front) field->format++; field->name = nm; field->enabled = enable; string->str = (field->enabled ? field->string : NULL); + string->space_in_front = field->space_in_front; if (field->field_index == BL_CONDITION) string->str = NULL; @@ -2943,6 +2943,22 @@ unsigned long *bmarray; return NO_COLOR; } +static int +mswin_condattr(bm, bmarray) +long bm; +unsigned long *bmarray; +{ + if (bm && bmarray) { + if (bm & bmarray[HL_ATTCLR_DIM]) return HL_DIM; + if (bm & bmarray[HL_ATTCLR_BLINK]) return HL_BLINK; + if (bm & bmarray[HL_ATTCLR_ULINE]) return HL_ULINE; + if (bm & bmarray[HL_ATTCLR_INVERSE]) return HL_INVERSE; + if (bm & bmarray[HL_ATTCLR_BOLD]) return HL_BOLD; + } + + return HL_NONE; +} + /* status_update(int fldindex, genericptr_t ptr, int chg, int percent, int color, unsigned long *colormasks) @@ -2984,11 +3000,12 @@ status_update(int fldindex, genericptr_t ptr, int chg, int percent, int color, u have to skip past ':' in passed "ptr" for the BL_GOLD case. -- color is the color that the NetHack core is telling you to use to display the text. - -- colormasks is a pointer to a set of CLR_MAX unsigned longs - telling you which fields should be displayed in each color. + -- condmasks is a pointer to a set of BL_ATTCLR_MAX unsigned + longs telling which conditions should be displayed in each + color and attriubte. */ void -mswin_status_update(int idx, genericptr_t ptr, int chg, int percent, int color, unsigned long *colormasks) +mswin_status_update(int idx, genericptr_t ptr, int chg, int percent, int color, unsigned long *condmasks) { long cond, *condptr = (long *) ptr; char *text = (char *) ptr; @@ -2996,7 +3013,7 @@ mswin_status_update(int idx, genericptr_t ptr, int chg, int percent, int color, int ocolor, ochar; unsigned ospecial; - logDebug("mswin_status_update(%d, %p, %d, %d, %x, %p)\n", idx, ptr, chg, percent, color, colormasks); + logDebug("mswin_status_update(%d, %p, %d, %d, %x, %p)\n", idx, ptr, chg, percent, color, condmasks); #if 0 // TODO: this code was dead ... do we need to respond to these updates? switch (idx) { @@ -3024,9 +3041,8 @@ mswin_status_update(int idx, genericptr_t ptr, int chg, int percent, int color, return; } - // TODO: is color actualy color and attribute OR not? - status_field->color = color & 0xff; - status_string->color = color & 0xff; + status_field->color = status_string->color = color & 0xff; + status_field->attribute = status_string->attribute = (color >> 8) & 0xff; switch (idx) { case BL_CONDITION: { @@ -3041,7 +3057,9 @@ mswin_status_update(int idx, genericptr_t ptr, int chg, int percent, int color, if (condition_field->mask & cond) { status_string->str = condition_field->name; - status_string->color = mswin_condcolor(condition_field->mask, colormasks); + status_string->space_in_front = TRUE; + status_string->color = mswin_condcolor(condition_field->mask, condmasks); + status_string->attribute = mswin_condattr(condition_field->mask, condmasks); } else status_string->str = NULL; @@ -3077,7 +3095,8 @@ mswin_status_update(int idx, genericptr_t ptr, int chg, int percent, int color, if (idx == BL_HP) { mswin_status_string * title_string = &_status_strings[BL_TITLE]; - title_string->bar_color = color; + title_string->bar_color = color & 0xff; + title_string->bar_attribute = (color >> 8) & 0xff; title_string->bar_percent = percent; }