diff options
| author | Jonas Kümmerlin <jonas@kuemmerlin.eu> | 2020-05-06 18:04:07 +0200 |
|---|---|---|
| committer | Jonas Kümmerlin <jonas@kuemmerlin.eu> | 2020-05-06 18:04:07 +0200 |
| commit | c77d5b3fbfb455b7db990872be6f4b4490a6ac37 (patch) | |
| tree | c94e9f850f9f61c54b27d8c5e4060864bfe58a5f /alf | |
| parent | 9940644e71cec3eb4905eece652ab5bbfc510f49 (diff) | |
notebook: add tricks for faster rendering
Win10 in particular sucks at stretching a completely white bitmap
Diffstat (limited to 'alf')
| -rw-r--r-- | alf/alfgroupbox.cpp | 9 | ||||
| -rw-r--r-- | alf/alfnotebook.cpp | 95 |
2 files changed, 89 insertions, 15 deletions
diff --git a/alf/alfgroupbox.cpp b/alf/alfgroupbox.cpp index 9786323..5c459dc 100644 --- a/alf/alfgroupbox.cpp +++ b/alf/alfgroupbox.cpp @@ -62,6 +62,15 @@ ALF_GroupBox_PaintFrameUxtheme(ALFGroupBoxPriv *priv, HWND hwnd, HDC dc, RECT *r RECT rc; GetClientRect(hwnd, &rc); + // Skip drawing the border if that is not requested, since stretching that bitmap might be expensive. + // Will happen when a transparent child calls DrawThemeParentBackground. + RECT rcTop = { 0, 0, rc.right-rc.left, priv->layout.containerMargins.top }; + RECT rcLeft = { 0, 0, priv->layout.containerMargins.left, rc.bottom-rc.top }; + RECT rcRight = { rc.right-rc.left-priv->layout.containerMargins.right, 0, rc.right-rc.left, rc.bottom-rc.top }; + RECT rcBottom = { 0, rc.bottom-rc.top-priv->layout.containerMargins.bottom, rc.right-rc.left, rc.bottom-rc.top }; + if (!RectVisible(dc, &rcTop) && !RectVisible(dc, &rcLeft) && !RectVisible(dc, &rcRight) && !RectVisible(dc, &rcBottom)) + return; + rc.top += priv->calculatedLabelSize.cy / 2; HRGN oldClipR = CreateRectRgn(0, 0, 0, 0); diff --git a/alf/alfnotebook.cpp b/alf/alfnotebook.cpp index 73b0c85..ea4517c 100644 --- a/alf/alfnotebook.cpp +++ b/alf/alfnotebook.cpp @@ -15,7 +15,7 @@ TCHAR *_alf_notebookClass = NULL; typedef struct { HWND hwndTabCtrl; HTHEME hTheme; - ALFColor themeTabBgColor; + ALFColor tabPaneBgColor; DWORD flags; int dpi; } ALFNotebookPriv; @@ -31,7 +31,7 @@ ALF_Notebook_CreatePriv(void) { ALFNotebookPriv *priv = ALF_New(ALFNotebookPriv, 1); - priv->themeTabBgColor = ALF_COLOR_SYS(COLOR_BTNFACE); + priv->tabPaneBgColor = ALF_COLOR_SYS(COLOR_BTNFACE); return priv; } @@ -96,11 +96,7 @@ static void ALF_Notebook_SetSingleTabBackground(HWND hwndNotebook, ALFNotebookPriv *priv, HWND panel) { (void)hwndNotebook; - if (priv->hTheme && !(priv->flags & ALF_NOTEBOOK_SOLID_TAB_BACKGROUND)) { - SendMessage(panel, ALF_WM_SETBGCOLOR, 0, (LPARAM)ALF_COLOR_TRANSPARENT); - } else { - SendMessage(panel, ALF_WM_SETBGCOLOR, 0, (LPARAM)priv->themeTabBgColor); - } + SendMessage(panel, ALF_WM_SETBGCOLOR, 0, (LPARAM)priv->tabPaneBgColor); } static void @@ -147,23 +143,88 @@ ALF_Notebook_PropagateDpiChange(HWND hwndNotebook, ALFNotebookPriv *priv, WPARAM } } +static BOOL +ALF_Notebook_CheckSingleColorBits(void *bits, SIZE s, COLORREF *outColor) +{ + int l = s.cx * s.cy; + + DWORD c; + CopyMemory(&c, bits, 4); + c &= 0x00FFFFFF; + + for (int i = 1; i < l; ++i) { + DWORD c2; + CopyMemory(&c2, (char*)bits + i*4, 4); + c2 &= 0x00FFFFFF; + + if (c2 != c) + return FALSE; + } + + *outColor = c; + return TRUE; +} + static void ALF_Notebook_InternalHandleThemeChange(HWND hwndNotebook, ALFNotebookPriv *priv) { ALF_Compat_CloseThemeData(priv->hTheme); priv->hTheme = NULL; + priv->tabPaneBgColor = ALF_COLOR_SYS(COLOR_BTNFACE); + if (ALF_Compat_IsAppThemed()) priv->hTheme = ALF_Compat_OpenThemeData(hwndNotebook, L"Tab"); InvalidateRect(hwndNotebook, NULL, TRUE); ALF_InvalidateLayout(hwndNotebook); - // tab fill color for solid bg color mode - priv->themeTabBgColor = ALF_COLOR_SYS(COLOR_BTNFACE); if (priv->hTheme) { - COLORREF c; - if (SUCCEEDED(ALF_Compat_GetThemeColor(priv->hTheme, TABP_BODY, 0, TMT_FILLCOLORHINT, &c))) { - priv->themeTabBgColor = (ALFColor)c; + if (priv->flags & ALF_NOTEBOOK_SOLID_TAB_BACKGROUND) { + COLORREF c; + if (SUCCEEDED(ALF_Compat_GetThemeColor(priv->hTheme, TABP_BODY, 0, TMT_FILLCOLORHINT, &c))) { + priv->tabPaneBgColor = (ALFColor)c; + } + } else { + priv->tabPaneBgColor = ALF_COLOR_TRANSPARENT; + + // SPEED HACK: check if tab pane background is a single solid color + // Windows 10 really sucks at stretching a completely white bitmap + HDC dcNotebook = GetDC(hwndNotebook); + HDC dcMem = CreateCompatibleDC(dcNotebook); + SIZE s; + if (SUCCEEDED(ALF_Compat_GetThemePartSize(priv->hTheme, dcNotebook, TABP_BODY, 0, NULL, TS_TRUE, &s))) { + BITMAPINFO bi; + ZeroMemory(&bi, sizeof(bi)); + + bi.bmiHeader.biSize = sizeof(bi.bmiHeader); + bi.bmiHeader.biWidth = s.cx; + bi.bmiHeader.biHeight = s.cy; + bi.bmiHeader.biPlanes = 1; + bi.bmiHeader.biBitCount = 32; + bi.bmiHeader.biCompression = BI_RGB; + + void *bits = NULL; + HBITMAP hDib = CreateDIBSection(dcMem, &bi, DIB_RGB_COLORS, &bits, NULL, 0); + if (hDib) { + HBITMAP hbmOld = SelectBitmap(dcMem, hDib); + + RECT r = { 0, 0, s.cx, s.cy }; + if (SUCCEEDED(ALF_Compat_DrawThemeBackground(priv->hTheme, dcMem, TABP_BODY, 0, &r, NULL))) { + GdiFlush(); + + COLORREF c = 0; + if (ALF_Notebook_CheckSingleColorBits(bits, s, &c)) { + priv->tabPaneBgColor = (ALFColor)c; + } + } + + SelectBitmap(dcMem, hbmOld); + DeleteObject(hDib); + } + } + + DeleteDC(dcMem); + ReleaseDC(hwndNotebook, dcNotebook); } } @@ -252,7 +313,11 @@ ALF_Notebook_InternalPaint(HWND hwnd, ALFNotebookPriv *priv, HDC dc, RECT *f) if (r2.right > r.right) r2.right = r.right; - ALF_Compat_DrawThemeBackground(priv->hTheme, dc, TABP_BODY, 0, &r2, NULL); + if (f && r2.left > f->right && r2.right < f->left) + continue; + + if (RectVisible(dc, &r2)) + ALF_Compat_DrawThemeBackground(priv->hTheme, dc, TABP_BODY, 0, &r2, NULL); } } else { // old version - let uxtheme stretch it @@ -421,7 +486,7 @@ ALF__NotebookWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) EndDeferWindowPos(hdwp); if (priv->hTheme - && !(priv->flags & ALF_NOTEBOOK_SOLID_TAB_BACKGROUND) + && priv->tabPaneBgColor == ALF_COLOR_TRANSPARENT && ((oldR.bottom - oldR.top) != (r.bottom - r.top))) { // only needed when height changes, since bg is tiled horizontally HWND panel = ALF_NotebookSelectedPanel(hwnd); @@ -464,7 +529,7 @@ ALF__NotebookWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) priv->flags = (DWORD)lParam; if ((oldFlags & ALF_NOTEBOOK_SOLID_TAB_BACKGROUND) != (priv->flags & ALF_NOTEBOOK_SOLID_TAB_BACKGROUND)) { - ALF_Notebook_SetAllTabBackgrounds(hwnd, priv); + ALF_Notebook_InternalHandleThemeChange(hwnd, priv); } } else if (uMsg == ALF_WM_LYT_GETWDGTFLAGS) { return (LRESULT)ALF_Notebook_GetWidgetFlags(hwnd, priv, (HWND)wParam); |
