Skip to content

Commit

Permalink
* Move the "resize nicely with background color" part of the profile …
Browse files Browse the repository at this point in the history
…popout into a util function
  • Loading branch information
iProgramMC committed Jul 20, 2024
1 parent c460dcc commit 200ad6f
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 40 deletions.
51 changes: 11 additions & 40 deletions src/windows/ProfilePopout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -320,47 +320,18 @@ bool ProfilePopout::Layout(HWND hWnd, SIZE& fullSize)
bool hasAlpha = false;
HBITMAP hbm = GetAvatarCache()->GetBitmap(gld->m_avatarlnk, hasAlpha);
if (hbm) {
int pps = GetProfilePictureSize();
hdc = GetDC(hWnd);

// create 3 compatible DCs. Ungodly
HDC hdc1 = CreateCompatibleDC(hdc);
HDC hdc2 = CreateCompatibleDC(hdc);
HDC hdc3 = CreateCompatibleDC(hdc);

// this "hack" bitmap will hold an intermediate: the profile picture but behind a COLOR_3DFACE background.
// This allows us to call StretchBlt with no loss of quality while also looking like it's blended in.
HBITMAP hack = CreateCompatibleBitmap(hdc, pps, pps);
m_hBitmap = CreateCompatibleBitmap(hdc, joinedAtIconSize, joinedAtIconSize);

// select the bitmaps
HGDIOBJ a1 = SelectObject(hdc1, hbm);
HGDIOBJ a2 = SelectObject(hdc2, hack);
HGDIOBJ a3 = SelectObject(hdc3, m_hBitmap);

// into hdc2, we will first draw the background and then alphablend the profile picture if has alpha
RECT rcFull = { 0, 0, pps, pps };
BLENDFUNCTION bf = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
FillRect(hdc2, &rcFull, GetSysColorBrush(COLOR_3DFACE));

if (hasAlpha)
ri::AlphaBlend(hdc2, 0, 0, pps, pps, hdc1, 0, 0, pps, pps, bf);
else
BitBlt(hdc2, 0, 0, pps, pps, hdc1, 0, 0, SRCCOPY);

// now draw from hdc2 into hdc3
int mode = SetStretchBltMode(hdc3, HALFTONE);
StretchBlt(hdc3, 0, 0, joinedAtIconSize, joinedAtIconSize, hdc2, 0, 0, pps, pps, SRCCOPY);
SetStretchBltMode(hdc3, mode);

// cleanup
SelectObject(hdc1, a1);
SelectObject(hdc2, a2);
SelectObject(hdc3, a3);
DeleteDC(hdc1);
DeleteDC(hdc2);
DeleteDC(hdc3);
DeleteObject(hack);
int pps = GetProfilePictureSize();
m_hBitmap = ResizeWithBackgroundColor(
hdc,
hbm,
GetSysColorBrush(COLOR_3DFACE),
hasAlpha,
joinedAtIconSize,
joinedAtIconSize,
pps,
pps
);
ReleaseDC(hWnd, hdc);
ShowWindow(hChild, SW_SHOW);
SendMessage(hChild, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)m_hBitmap);
Expand Down
46 changes: 46 additions & 0 deletions src/windows/WinUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1252,3 +1252,49 @@ void DrawIconInvert(HDC hdc, HICON hIcon, int x, int y, int sizeX, int sizeY, bo
DeleteBitmap(hbm);
DeleteDC(hdcMem);
}

// Resizes a transparent image with a transparent color, without looking bad.
// NOTE: Creates a new bitmap. Make sure to delete the bitmap when done.
HBITMAP ResizeWithBackgroundColor(HDC hdc, HBITMAP hBitmap, HBRUSH backgroundColor, bool bHasAlpha, int newSizeX, int newSizeY, int oldSizeX, int oldSizeY)
{
// create 3 compatible DCs. Ungodly
HDC hdc1 = CreateCompatibleDC(hdc);
HDC hdc2 = CreateCompatibleDC(hdc);
HDC hdc3 = CreateCompatibleDC(hdc);

// this "hack" bitmap will hold an intermediate: the profile picture but behind a COLOR_3DFACE background.
// This allows us to call StretchBlt with no loss of quality while also looking like it's blended in.
HBITMAP hackBitmap = CreateCompatibleBitmap(hdc, oldSizeX, oldSizeY);
HBITMAP newBitmap = CreateCompatibleBitmap(hdc, newSizeX, newSizeY);

// select the bitmaps
HGDIOBJ a1 = SelectObject(hdc1, hBitmap);
HGDIOBJ a2 = SelectObject(hdc2, hackBitmap);
HGDIOBJ a3 = SelectObject(hdc3, newBitmap);

// into hdc2, we will first draw the background and then alphablend the profile picture if has alpha
RECT rcFull = { 0, 0, oldSizeX, oldSizeY };
BLENDFUNCTION bf = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
FillRect(hdc2, &rcFull, backgroundColor);

if (bHasAlpha)
ri::AlphaBlend(hdc2, 0, 0, oldSizeX, oldSizeY, hdc1, 0, 0, oldSizeX, oldSizeY, bf);
else
BitBlt(hdc2, 0, 0, oldSizeX, oldSizeY, hdc1, 0, 0, SRCCOPY);

// now draw from hdc2 into hdc3
int mode = SetStretchBltMode(hdc3, HALFTONE);
StretchBlt(hdc3, 0, 0, newSizeX, newSizeY, hdc2, 0, 0, oldSizeX, oldSizeY, SRCCOPY);
SetStretchBltMode(hdc3, mode);

// cleanup
SelectObject(hdc1, a1);
SelectObject(hdc2, a2);
SelectObject(hdc3, a3);
DeleteDC(hdc1);
DeleteDC(hdc2);
DeleteDC(hdc3);
DeleteObject(hackBitmap);

return newBitmap;
}
1 change: 1 addition & 0 deletions src/windows/WinUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ std::string CutOutURLPath(const std::string& url);
int MessageBoxHooked(HWND hWnd, LPCTSTR title, LPCTSTR caption, int flags, int overID, LPCTSTR overText);
int MessageBoxHooked(HWND hWnd, LPCTSTR title, LPCTSTR caption, int flags, int overCount, const int* overID, const LPCTSTR* overText);
void DrawIconInvert(HDC hdc, HICON hIcon, int x, int y, int sizeX, int sizeY, bool invert);
HBITMAP ResizeWithBackgroundColor(HDC hdc, HBITMAP hBitmap, HBRUSH backgroundColor, bool bHasAlpha, int newSizeX, int newSizeY, int oldSizeX, int oldSizeY);

#ifdef USE_DEBUG_PRINTS
void DbgPrintW(const char* fmt, ...);
Expand Down

0 comments on commit 200ad6f

Please sign in to comment.