summaryrefslogtreecommitdiff
path: root/alf
diff options
context:
space:
mode:
authorJonas Kümmerlin <jonas@kuemmerlin.eu>2020-05-06 18:04:07 +0200
committerJonas Kümmerlin <jonas@kuemmerlin.eu>2020-05-06 18:04:07 +0200
commitc77d5b3fbfb455b7db990872be6f4b4490a6ac37 (patch)
treec94e9f850f9f61c54b27d8c5e4060864bfe58a5f /alf
parent9940644e71cec3eb4905eece652ab5bbfc510f49 (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.cpp9
-rw-r--r--alf/alfnotebook.cpp95
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);