mirror of
https://github.com/reactos/reactos.git
synced 2025-01-05 22:12:46 +00:00
[COMCTL32]
- Add DrawShadowText implementation svn path=/trunk/; revision=55578
This commit is contained in:
parent
b226050aa4
commit
4cf1b4adda
2 changed files with 229 additions and 4 deletions
|
@ -1,3 +1,126 @@
|
||||||
|
Index: commctrl.c
|
||||||
|
===================================================================
|
||||||
|
--- commctrl.c (revision 55577)
|
||||||
|
+++ commctrl.c (working copy)
|
||||||
|
@@ -1593,12 +1593,114 @@
|
||||||
|
*
|
||||||
|
* Draw text with shadow.
|
||||||
|
*/
|
||||||
|
-int WINAPI DrawShadowText(HDC hdc, LPCWSTR pszText, UINT cch, RECT *rect, DWORD dwFlags,
|
||||||
|
+int WINAPI DrawShadowText(HDC hdc, LPCWSTR pszText, UINT cch, RECT *prc, DWORD dwFlags,
|
||||||
|
COLORREF crText, COLORREF crShadow, int ixOffset, int iyOffset)
|
||||||
|
{
|
||||||
|
- FIXME("(%p, %s, %d, %p, %d, 0x%08x, 0x%08x, %d, %d): stub\n", hdc, debugstr_w(pszText), cch, rect, dwFlags,
|
||||||
|
- crText, crShadow, ixOffset, iyOffset);
|
||||||
|
- return DrawTextW(hdc, pszText, cch, rect, DT_LEFT);
|
||||||
|
+ COLORREF crOldText;
|
||||||
|
+ RECT rcText;
|
||||||
|
+ INT iRet, x, y, x2, y2;
|
||||||
|
+ BYTE *pBits;
|
||||||
|
+ HBITMAP hbm, hbmOld;
|
||||||
|
+ BITMAPINFO bi;
|
||||||
|
+ HDC hdcMem;
|
||||||
|
+ HFONT hOldFont;
|
||||||
|
+ BLENDFUNCTION bf;
|
||||||
|
+
|
||||||
|
+ /* Create 32 bit DIB section for the shadow */
|
||||||
|
+ ZeroMemory(&bi, sizeof(bi));
|
||||||
|
+ bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
|
||||||
|
+ bi.bmiHeader.biWidth = prc->right - prc->left + 4;
|
||||||
|
+ bi.bmiHeader.biHeight = prc->bottom - prc->top + 5; // bottom-up DIB
|
||||||
|
+ bi.bmiHeader.biPlanes = 1;
|
||||||
|
+ bi.bmiHeader.biBitCount = 32;
|
||||||
|
+ bi.bmiHeader.biCompression = BI_RGB;
|
||||||
|
+ hbm = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (PVOID*)&pBits, NULL, 0);
|
||||||
|
+ if(!hbm)
|
||||||
|
+ {
|
||||||
|
+ ERR("CreateDIBSection failed\n");
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Create memory device context for new DIB section and select it */
|
||||||
|
+ hdcMem = CreateCompatibleDC(hdc);
|
||||||
|
+ if(!hdcMem)
|
||||||
|
+ {
|
||||||
|
+ ERR("CreateCompatibleDC failed\n");
|
||||||
|
+ DeleteObject(hbm);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ hbmOld = (HBITMAP)SelectObject(hdcMem, hbm);
|
||||||
|
+
|
||||||
|
+ /* Draw text on our helper bitmap */
|
||||||
|
+ hOldFont = (HFONT)SelectObject(hdcMem, GetCurrentObject(hdc, OBJ_FONT));
|
||||||
|
+ SetTextColor(hdcMem, RGB(16, 16, 16));
|
||||||
|
+ SetBkColor(hdcMem, RGB(0, 0, 0));
|
||||||
|
+ SetBkMode(hdcMem, TRANSPARENT);
|
||||||
|
+ SetRect(&rcText, 0, 0, prc->right - prc->left, prc->bottom - prc->top);
|
||||||
|
+ DrawTextW(hdcMem, pszText, cch, &rcText, dwFlags);
|
||||||
|
+ SelectObject(hdcMem, hOldFont);
|
||||||
|
+
|
||||||
|
+ /* Flush GDI so data pointed by pBits is valid */
|
||||||
|
+ GdiFlush();
|
||||||
|
+
|
||||||
|
+ /* Set alpha of pixels (forget about colors for now. They will be changed in next loop).
|
||||||
|
+ We copy text image 4*5 times and each time alpha is added */
|
||||||
|
+ for (x = 0; x < bi.bmiHeader.biWidth; ++x)
|
||||||
|
+ for (y = 0; y < bi.bmiHeader.biHeight; ++y)
|
||||||
|
+ {
|
||||||
|
+ BYTE *pDest = &pBits[(y * bi.bmiHeader.biWidth + x) * 4];
|
||||||
|
+ UINT Alpha = 0;
|
||||||
|
+
|
||||||
|
+ for (x2 = x - 4 + 1; x2 <= x; ++x2)
|
||||||
|
+ for (y2 = y; y2 < y + 5; ++y2)
|
||||||
|
+ {
|
||||||
|
+ if (x2 >= 0 && x2 < bi.bmiHeader.biWidth && y2 >= 0 && y2 < bi.bmiHeader.biHeight)
|
||||||
|
+ {
|
||||||
|
+ BYTE *pSrc = &pBits[(y2 * bi.bmiHeader.biWidth + x2) * 4];
|
||||||
|
+ Alpha += pSrc[0];
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (Alpha > 255)
|
||||||
|
+ Alpha = 255;
|
||||||
|
+ pDest[3] = Alpha;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Now set the color of each pixel to shadow color * alpha (see GdiAlphaBlend) */
|
||||||
|
+ for (x = 0; x < bi.bmiHeader.biWidth; ++x)
|
||||||
|
+ for (y = 0; y < bi.bmiHeader.biHeight; ++y)
|
||||||
|
+ {
|
||||||
|
+ BYTE *pDest = &pBits[(y * bi.bmiHeader.biWidth + x) * 4];
|
||||||
|
+ pDest[0] = GetBValue(crShadow) * pDest[3] / 255;
|
||||||
|
+ pDest[1] = GetGValue(crShadow) * pDest[3] / 255;
|
||||||
|
+ pDest[2] = GetRValue(crShadow) * pDest[3] / 255;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Fix ixOffset of the shadow (tested on Win) */
|
||||||
|
+ ixOffset -= 3;
|
||||||
|
+ iyOffset -= 3;
|
||||||
|
+
|
||||||
|
+ /* Alpha blend helper image to destination DC */
|
||||||
|
+ bf.BlendOp = AC_SRC_OVER;
|
||||||
|
+ bf.BlendFlags = 0;
|
||||||
|
+ bf.SourceConstantAlpha = 255;
|
||||||
|
+ bf.AlphaFormat = AC_SRC_ALPHA;
|
||||||
|
+ if (!GdiAlphaBlend(hdc, prc->left + ixOffset, prc->top + iyOffset, bi.bmiHeader.biWidth, bi.bmiHeader.biHeight, hdcMem, 0, 0, bi.bmiHeader.biWidth, bi.bmiHeader.biHeight, bf))
|
||||||
|
+ ERR("GdiAlphaBlend failed: %lu\n", GetLastError());
|
||||||
|
+
|
||||||
|
+ /* Delete the helper bitmap */
|
||||||
|
+ SelectObject(hdcMem, hbmOld);
|
||||||
|
+ DeleteObject(hbm);
|
||||||
|
+ DeleteDC(hdcMem);
|
||||||
|
+
|
||||||
|
+ /* Finally draw the text over shadow */
|
||||||
|
+ crOldText = SetTextColor(hdc, crText);
|
||||||
|
+ SetBkMode(hdc, TRANSPARENT);
|
||||||
|
+ iRet = DrawTextW(hdc, pszText, cch, prc, dwFlags);
|
||||||
|
+ SetTextColor(hdc, crOldText);
|
||||||
|
+
|
||||||
|
+ return iRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
Index: propsheet.c
|
Index: propsheet.c
|
||||||
===================================================================
|
===================================================================
|
||||||
--- propsheet.c (revision 38890)
|
--- propsheet.c (revision 38890)
|
||||||
|
|
|
@ -1593,12 +1593,114 @@ LRESULT WINAPI SetPathWordBreakProc(HWND hwnd, BOOL bSet)
|
||||||
*
|
*
|
||||||
* Draw text with shadow.
|
* Draw text with shadow.
|
||||||
*/
|
*/
|
||||||
int WINAPI DrawShadowText(HDC hdc, LPCWSTR pszText, UINT cch, RECT *rect, DWORD dwFlags,
|
int WINAPI DrawShadowText(HDC hdc, LPCWSTR pszText, UINT cch, RECT *prc, DWORD dwFlags,
|
||||||
COLORREF crText, COLORREF crShadow, int ixOffset, int iyOffset)
|
COLORREF crText, COLORREF crShadow, int ixOffset, int iyOffset)
|
||||||
{
|
{
|
||||||
FIXME("(%p, %s, %d, %p, %d, 0x%08x, 0x%08x, %d, %d): stub\n", hdc, debugstr_w(pszText), cch, rect, dwFlags,
|
COLORREF crOldText;
|
||||||
crText, crShadow, ixOffset, iyOffset);
|
RECT rcText;
|
||||||
return DrawTextW(hdc, pszText, cch, rect, DT_LEFT);
|
INT iRet, x, y, x2, y2;
|
||||||
|
BYTE *pBits;
|
||||||
|
HBITMAP hbm, hbmOld;
|
||||||
|
BITMAPINFO bi;
|
||||||
|
HDC hdcMem;
|
||||||
|
HFONT hOldFont;
|
||||||
|
BLENDFUNCTION bf;
|
||||||
|
|
||||||
|
/* Create 32 bit DIB section for the shadow */
|
||||||
|
ZeroMemory(&bi, sizeof(bi));
|
||||||
|
bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
|
||||||
|
bi.bmiHeader.biWidth = prc->right - prc->left + 4;
|
||||||
|
bi.bmiHeader.biHeight = prc->bottom - prc->top + 5; // bottom-up DIB
|
||||||
|
bi.bmiHeader.biPlanes = 1;
|
||||||
|
bi.bmiHeader.biBitCount = 32;
|
||||||
|
bi.bmiHeader.biCompression = BI_RGB;
|
||||||
|
hbm = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (PVOID*)&pBits, NULL, 0);
|
||||||
|
if(!hbm)
|
||||||
|
{
|
||||||
|
ERR("CreateDIBSection failed\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create memory device context for new DIB section and select it */
|
||||||
|
hdcMem = CreateCompatibleDC(hdc);
|
||||||
|
if(!hdcMem)
|
||||||
|
{
|
||||||
|
ERR("CreateCompatibleDC failed\n");
|
||||||
|
DeleteObject(hbm);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
hbmOld = (HBITMAP)SelectObject(hdcMem, hbm);
|
||||||
|
|
||||||
|
/* Draw text on our helper bitmap */
|
||||||
|
hOldFont = (HFONT)SelectObject(hdcMem, GetCurrentObject(hdc, OBJ_FONT));
|
||||||
|
SetTextColor(hdcMem, RGB(16, 16, 16));
|
||||||
|
SetBkColor(hdcMem, RGB(0, 0, 0));
|
||||||
|
SetBkMode(hdcMem, TRANSPARENT);
|
||||||
|
SetRect(&rcText, 0, 0, prc->right - prc->left, prc->bottom - prc->top);
|
||||||
|
DrawTextW(hdcMem, pszText, cch, &rcText, dwFlags);
|
||||||
|
SelectObject(hdcMem, hOldFont);
|
||||||
|
|
||||||
|
/* Flush GDI so data pointed by pBits is valid */
|
||||||
|
GdiFlush();
|
||||||
|
|
||||||
|
/* Set alpha of pixels (forget about colors for now. They will be changed in next loop).
|
||||||
|
We copy text image 4*5 times and each time alpha is added */
|
||||||
|
for (x = 0; x < bi.bmiHeader.biWidth; ++x)
|
||||||
|
for (y = 0; y < bi.bmiHeader.biHeight; ++y)
|
||||||
|
{
|
||||||
|
BYTE *pDest = &pBits[(y * bi.bmiHeader.biWidth + x) * 4];
|
||||||
|
UINT Alpha = 0;
|
||||||
|
|
||||||
|
for (x2 = x - 4 + 1; x2 <= x; ++x2)
|
||||||
|
for (y2 = y; y2 < y + 5; ++y2)
|
||||||
|
{
|
||||||
|
if (x2 >= 0 && x2 < bi.bmiHeader.biWidth && y2 >= 0 && y2 < bi.bmiHeader.biHeight)
|
||||||
|
{
|
||||||
|
BYTE *pSrc = &pBits[(y2 * bi.bmiHeader.biWidth + x2) * 4];
|
||||||
|
Alpha += pSrc[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Alpha > 255)
|
||||||
|
Alpha = 255;
|
||||||
|
pDest[3] = Alpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now set the color of each pixel to shadow color * alpha (see GdiAlphaBlend) */
|
||||||
|
for (x = 0; x < bi.bmiHeader.biWidth; ++x)
|
||||||
|
for (y = 0; y < bi.bmiHeader.biHeight; ++y)
|
||||||
|
{
|
||||||
|
BYTE *pDest = &pBits[(y * bi.bmiHeader.biWidth + x) * 4];
|
||||||
|
pDest[0] = GetBValue(crShadow) * pDest[3] / 255;
|
||||||
|
pDest[1] = GetGValue(crShadow) * pDest[3] / 255;
|
||||||
|
pDest[2] = GetRValue(crShadow) * pDest[3] / 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fix ixOffset of the shadow (tested on Win) */
|
||||||
|
ixOffset -= 3;
|
||||||
|
iyOffset -= 3;
|
||||||
|
|
||||||
|
/* Alpha blend helper image to destination DC */
|
||||||
|
bf.BlendOp = AC_SRC_OVER;
|
||||||
|
bf.BlendFlags = 0;
|
||||||
|
bf.SourceConstantAlpha = 255;
|
||||||
|
bf.AlphaFormat = AC_SRC_ALPHA;
|
||||||
|
if (!GdiAlphaBlend(hdc, prc->left + ixOffset, prc->top + iyOffset, bi.bmiHeader.biWidth, bi.bmiHeader.biHeight, hdcMem, 0, 0, bi.bmiHeader.biWidth, bi.bmiHeader.biHeight, bf))
|
||||||
|
ERR("GdiAlphaBlend failed: %lu\n", GetLastError());
|
||||||
|
|
||||||
|
/* Delete the helper bitmap */
|
||||||
|
SelectObject(hdcMem, hbmOld);
|
||||||
|
DeleteObject(hbm);
|
||||||
|
DeleteDC(hdcMem);
|
||||||
|
|
||||||
|
/* Finally draw the text over shadow */
|
||||||
|
crOldText = SetTextColor(hdc, crText);
|
||||||
|
SetBkMode(hdc, TRANSPARENT);
|
||||||
|
iRet = DrawTextW(hdc, pszText, cch, prc, dwFlags);
|
||||||
|
SetTextColor(hdc, crOldText);
|
||||||
|
|
||||||
|
return iRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
Loading…
Reference in a new issue