mirror of
https://github.com/WinampDesktop/winamp.git
synced 2024-09-24 15:54:12 +00:00
277 lines
5.5 KiB
C++
277 lines
5.5 KiB
C++
|
#include "main.h"
|
||
|
#include "./backBuffer.h"
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
BackBuffer_Initialize(BackBuffer *self, HWND hwnd)
|
||
|
{
|
||
|
if (NULL == self)
|
||
|
return FALSE;
|
||
|
|
||
|
ZeroMemory(self, sizeof(BackBuffer));
|
||
|
|
||
|
self->hwnd = hwnd;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
BackBuffer_Uninitialize(BackBuffer *self)
|
||
|
{
|
||
|
BackBuffer_Reset(self);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
BackBuffer_Reset(BackBuffer *self)
|
||
|
{
|
||
|
if (NULL == self)
|
||
|
return;
|
||
|
|
||
|
if (NULL != self->hdc)
|
||
|
{
|
||
|
if (NULL != self->previous)
|
||
|
SelectBitmap(self->hdc, self->previous);
|
||
|
|
||
|
DeleteDC(self->hdc);
|
||
|
}
|
||
|
|
||
|
if (NULL != self->bitmap)
|
||
|
{
|
||
|
DeleteObject(self->bitmap);
|
||
|
}
|
||
|
|
||
|
ZeroMemory(self, sizeof(BackBuffer));
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
BackBuffer_EnsureSize(BackBuffer *self, long width, long height)
|
||
|
{
|
||
|
return BackBuffer_EnsureSizeEx(self, width, height, width, height);
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
BackBuffer_EnsureSizeEx(BackBuffer *self, long width, long height, long allocWidth, long allocHeight)
|
||
|
{
|
||
|
BOOL result;
|
||
|
HDC windowDC;
|
||
|
HBITMAP bitmap;
|
||
|
long bitmapWidth, bitmapHeight;
|
||
|
|
||
|
if (NULL == self)
|
||
|
return FALSE;
|
||
|
|
||
|
if (width < 0)
|
||
|
width = 0;
|
||
|
|
||
|
if (height < 0)
|
||
|
height = 0;
|
||
|
|
||
|
if (NULL != self->bitmap)
|
||
|
{
|
||
|
BITMAP bitmapInfo;
|
||
|
if (sizeof(bitmapInfo) == GetObject(self->bitmap, sizeof(bitmapInfo), &bitmapInfo))
|
||
|
{
|
||
|
if (bitmapInfo.bmWidth >= width && bitmapInfo.bmHeight >= height)
|
||
|
return TRUE;
|
||
|
|
||
|
bitmapWidth = bitmapInfo.bmWidth;
|
||
|
bitmapHeight = bitmapInfo.bmHeight;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bitmapWidth = 0;
|
||
|
bitmapHeight = 0;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bitmapWidth = 0;
|
||
|
bitmapHeight = 0;
|
||
|
}
|
||
|
|
||
|
result = FALSE;
|
||
|
bitmap = NULL;
|
||
|
|
||
|
windowDC = GetDCEx(self->hwnd, NULL, DCX_CACHE | DCX_NORESETATTRS);
|
||
|
if(NULL != windowDC)
|
||
|
{
|
||
|
if (allocWidth < width)
|
||
|
allocWidth = width;
|
||
|
|
||
|
if (allocWidth < bitmapWidth)
|
||
|
allocWidth = bitmapWidth;
|
||
|
|
||
|
if (allocHeight < height)
|
||
|
allocHeight = height;
|
||
|
|
||
|
if (allocHeight < bitmapHeight)
|
||
|
allocHeight = bitmapHeight;
|
||
|
|
||
|
bitmap = CreateCompatibleBitmap(windowDC, allocWidth, allocHeight);
|
||
|
ReleaseDC(self->hwnd, windowDC);
|
||
|
}
|
||
|
|
||
|
if (NULL != bitmap)
|
||
|
{
|
||
|
if (NULL != self->hdc)
|
||
|
SelectBitmap(self->hdc, bitmap);
|
||
|
|
||
|
if (NULL != self->bitmap)
|
||
|
DeleteObject(self->bitmap);
|
||
|
|
||
|
self->bitmap = bitmap;
|
||
|
result = TRUE;
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
HDC
|
||
|
BackBuffer_GetDC(BackBuffer *self)
|
||
|
{
|
||
|
if (NULL == self)
|
||
|
return FALSE;
|
||
|
|
||
|
if (NULL == self->hdc)
|
||
|
{
|
||
|
HDC windowDC;
|
||
|
windowDC = GetDCEx(self->hwnd, NULL, DCX_CACHE | DCX_NORESETATTRS);
|
||
|
if (NULL != windowDC)
|
||
|
{
|
||
|
self->hdc = CreateCompatibleDC(windowDC);
|
||
|
ReleaseDC(self->hwnd, windowDC);
|
||
|
|
||
|
if (NULL != self->hdc)
|
||
|
{
|
||
|
if (NULL != self->bitmap)
|
||
|
self->previous = SelectBitmap(self->hdc, self->bitmap);
|
||
|
else
|
||
|
self->previous = GetCurrentBitmap(self->hdc);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return self->hdc;
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
BackBuffer_Copy(BackBuffer *self, HDC hdc, long x, long y, long width, long height)
|
||
|
{
|
||
|
HDC sourceDC;
|
||
|
|
||
|
if (NULL == self || NULL == self->bitmap)
|
||
|
return FALSE;
|
||
|
|
||
|
sourceDC = BackBuffer_GetDC(self);
|
||
|
if (NULL == sourceDC)
|
||
|
return FALSE;
|
||
|
|
||
|
return BitBlt(hdc, x, y, width, height, sourceDC, 0, 0, SRCCOPY);
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
BackBuffer_DrawTextEx(BackBuffer *self, HDC hdc, const wchar_t *string,
|
||
|
int length, RECT *rect, unsigned int format,
|
||
|
HFONT font, COLORREF backColor, COLORREF textColor, int backMode)
|
||
|
{
|
||
|
BOOL result = FALSE;
|
||
|
RECT bufferRect;
|
||
|
|
||
|
if (NULL == hdc || NULL == rect)
|
||
|
return FALSE;
|
||
|
|
||
|
SetRect(&bufferRect, 0, 0, RECTWIDTH(*rect), RECTHEIGHT(*rect));
|
||
|
|
||
|
if (NULL != self &&
|
||
|
FALSE != BackBuffer_EnsureSize(self, bufferRect.right, bufferRect.bottom))
|
||
|
{
|
||
|
HDC bufferDC = BackBuffer_GetDC(self);
|
||
|
if (NULL != bufferDC)
|
||
|
{
|
||
|
HFONT prevFont;
|
||
|
prevFont = SelectFont(bufferDC, font);
|
||
|
SetTextColor(bufferDC, textColor);
|
||
|
SetBkColor(bufferDC, backColor);
|
||
|
SetBkMode(bufferDC, backMode);
|
||
|
|
||
|
if (OPAQUE == backMode)
|
||
|
ExtTextOut(bufferDC, 0, 0, ETO_OPAQUE, &bufferRect, NULL, 0, NULL);
|
||
|
|
||
|
if (FALSE != DrawText(bufferDC, string, length, &bufferRect, format))
|
||
|
{
|
||
|
result = BackBuffer_Copy(self, hdc, rect->left, rect->top,
|
||
|
bufferRect.right, bufferRect.bottom);
|
||
|
}
|
||
|
|
||
|
SelectFont(bufferDC, prevFont);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
if (FALSE == result)
|
||
|
{
|
||
|
HFONT prevFont;
|
||
|
COLORREF prevBackColor, prevTextColor;
|
||
|
int prevBkMode;
|
||
|
|
||
|
prevFont = SelectFont(hdc, font);
|
||
|
prevTextColor = SetTextColor(hdc, textColor);
|
||
|
prevBackColor = SetBkColor(hdc, backColor);
|
||
|
prevBkMode= SetBkMode(hdc, backMode);
|
||
|
|
||
|
result = DrawText(hdc, string, length, rect, format);
|
||
|
|
||
|
SelectFont(hdc, prevFont);
|
||
|
SetTextColor(hdc, prevTextColor);
|
||
|
SetBkColor(hdc, prevBackColor);
|
||
|
SetBkMode(hdc, prevBkMode);
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
BackBuffer_DrawText(BackBuffer *self, HDC hdc, const wchar_t *string,
|
||
|
int length, RECT *rect, unsigned int format)
|
||
|
{
|
||
|
BOOL result = FALSE;
|
||
|
RECT bufferRect;
|
||
|
|
||
|
if (NULL == hdc || NULL == rect)
|
||
|
return FALSE;
|
||
|
|
||
|
SetRect(&bufferRect, 0, 0, RECTWIDTH(*rect), RECTHEIGHT(*rect));
|
||
|
|
||
|
if (NULL != self &&
|
||
|
FALSE != BackBuffer_EnsureSize(self, bufferRect.right, bufferRect.bottom))
|
||
|
{
|
||
|
HDC bufferDC = BackBuffer_GetDC(self);
|
||
|
if (NULL != bufferDC)
|
||
|
{
|
||
|
HFONT prevFont;
|
||
|
int backMode;
|
||
|
prevFont = SelectFont(bufferDC, GetCurrentFont(hdc));
|
||
|
SetTextColor(bufferDC, GetTextColor(hdc));
|
||
|
SetBkColor(bufferDC, GetBkColor(hdc));
|
||
|
backMode = GetBkMode(hdc);
|
||
|
SetBkMode(bufferDC, backMode);
|
||
|
|
||
|
if (OPAQUE == backMode)
|
||
|
ExtTextOut(bufferDC, 0, 0, ETO_OPAQUE, &bufferRect, NULL, 0, NULL);
|
||
|
|
||
|
if (FALSE != DrawText(bufferDC, string, length, &bufferRect, format))
|
||
|
{
|
||
|
result = BackBuffer_Copy(self, hdc, rect->left, rect->top,
|
||
|
bufferRect.right, bufferRect.bottom);
|
||
|
}
|
||
|
|
||
|
SelectFont(bufferDC, prevFont);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (FALSE == result)
|
||
|
result = DrawText(hdc, string, length, rect, format);
|
||
|
|
||
|
return result;
|
||
|
}
|