📄 gradient.cpp
字号:
{
// Gradient color percent
percent = 1 - (double)i / (double)(offset);
// Gradient color
red = (unsigned char)(GetRValue(sColor)*percent) + (unsigned char)(GetRValue(eColor)*(1-percent));
green = (unsigned char)(GetGValue(sColor)*percent) + (unsigned char)(GetGValue(eColor)*(1-percent));
blue = (unsigned char)(GetBValue(sColor)*percent) + (unsigned char)(GetBValue(eColor)*(1-percent));
if (bGamma)
{
red = (unsigned char)(pow((double)red/255.0, gamma) * 255);
green = (unsigned char)(pow((double)green/255.0, gamma) * 255);
blue = (unsigned char)(pow((double)blue/255.0, gamma) * 255);
}
color = RGB(red, green, blue);
// Gradient
rect.left = lpRect->left + 1;
rect.top = lpRect->top + (c-1)*offset + i + 1;
if (rect.top >= lpRect->bottom-2)
rect.top = lpRect->bottom-2;
rect.right = lpRect->right - 1;
rect.bottom = rect.top + 1;
hBrush = CreateSolidBrush(color);
FillRect(hDC, &rect, hBrush);
DeleteObject(hBrush);
}
if (offset*(numColors-1) < height)
{
rect.left = lpRect->left + 1;
rect.top = lpRect->bottom - (height-offset*(numColors-1));
rect.right = lpRect->right - 1;
rect.bottom = lpRect->bottom - 1;
hBrush = CreateSolidBrush(colors[numColors-1]);
FillRect(hDC, &rect, hBrush);
DeleteObject(hBrush);
}
}
}
void CGradient::MulticolorRadialGradient(HDC hDC, LPRECT lpRect, COLORREF colors[], int numColors, BOOL bCircle, BOOL bGamma, double gamma)
{
if (numColors < 2)
return;
else if (numColors == 2)
{
RadialGradient(hDC, lpRect, colors[0], colors[1], bCircle, bGamma);
return;
}
// Gradient params
int width = lpRect->right - lpRect->left - 1;
int height = lpRect->bottom - lpRect->top - 1;
int size = (width < height) ? width : height;
// Fill background
HBRUSH hBrush = CreateSolidBrush(colors[0]);
RECT fillRect = {lpRect->left+1, lpRect->top+1, lpRect->right-1, lpRect->bottom-1};
FillRect(hDC, &fillRect, hBrush);
DeleteObject(hBrush);
HBRUSH hOldBrush = (HBRUSH)SelectObject(hDC, (HBRUSH)GetStockObject(HOLLOW_BRUSH));
int offset = size / numColors;
int offset1 = width / numColors;
int offset2 = height / numColors;
POINT pointStart, pointEnd;
HPEN hPen = NULL;
HPEN hOldPen = NULL;
for (int c=numColors-1; c>0; c--)
{
COLORREF sColor = colors[numColors-c];
COLORREF eColor = colors[numColors-c-1];
if (!bCircle)
{
// Start and end points
pointStart.x = (lpRect->left + lpRect->right - c*offset1)/2 + 1;
pointStart.y = (lpRect->top + lpRect->bottom - c*offset2)/2 + 1;
pointEnd.x = (lpRect->left + lpRect->right + c*offset1)/2 - 1;
pointEnd.y = (lpRect->top + lpRect->bottom + c*offset2)/2 - 1;
hOldPen = (HPEN)SelectObject(hDC, CreatePen(PS_SOLID, 1, sColor));
hOldBrush = (HBRUSH)SelectObject(hDC, CreateSolidBrush(sColor));
Ellipse(hDC, pointStart.x, pointStart.y, pointEnd.x, pointEnd.y);
SelectObject(hDC, hOldBrush);
SelectObject(hDC, hOldPen);
}
// Draw gradient
double percent;
unsigned char red, green, blue;
COLORREF color;
for (int i=0; i<=offset/2; i++)
{
// Gradient color percent
percent = 1 - (double)i / (double)(offset/2);
// Gradient color
red = (unsigned char)(GetRValue(sColor)*percent) + (unsigned char)(GetRValue(eColor)*(1-percent));
green = (unsigned char)(GetGValue(sColor)*percent) + (unsigned char)(GetGValue(eColor)*(1-percent));
blue = (unsigned char)(GetBValue(sColor)*percent) + (unsigned char)(GetBValue(eColor)*(1-percent));
if (bGamma)
{
red = (unsigned char)(pow((double)red/255.0, gamma) * 255);
green = (unsigned char)(pow((double)green/255.0, gamma) * 255);
blue = (unsigned char)(pow((double)blue/255.0, gamma) * 255);
}
color = RGB(red, green, blue);
if (bCircle)
{
// Start and end points
pointStart.x = (lpRect->left + lpRect->right - (c-1)*offset)/2 - i + 2;
pointStart.y = (lpRect->top + lpRect->bottom - (c-1)*offset)/2 - i + 2;
pointEnd.x = (lpRect->left + lpRect->right + (c-1)*offset)/2 + i - 2;
pointEnd.y = (lpRect->top + lpRect->bottom + (c-1)*offset)/2 + i - 2;
}
else
{
// Start and end points
pointStart.x = (lpRect->left + lpRect->right - c*offset1)/2 - i + 2;
pointStart.y = (lpRect->top + lpRect->bottom - c*offset2)/2 - i + 2;
pointEnd.x = (lpRect->left + lpRect->right + c*offset1)/2 + i - 2;
pointEnd.y = (lpRect->top + lpRect->bottom + c*offset2)/2 + i - 2;
}
// Gradient
hPen = CreatePen(PS_SOLID, 2, color);
hOldPen = (HPEN)SelectObject(hDC, hPen);
Ellipse(hDC, pointStart.x, pointStart.y, pointEnd.x, pointEnd.y);
SelectObject(hDC, hOldPen);
DeleteObject(hPen);
}
}
SelectObject(hDC, hOldBrush);
}
void CGradient::HorizontalGradient(HDC hDC, HRGN hRgn, COLORREF sColor, COLORREF eColor, BOOL bGamma, double gamma)
{
RECT rgnRect;
GetRgnBox(hRgn, &rgnRect);
// Gradient params
int width = rgnRect.right - rgnRect.left - 1;
int height = rgnRect.bottom - rgnRect.top - 1;
// Draw gradient
HBRUSH hBrush = NULL;
double percent;
unsigned char red, green, blue;
COLORREF color;
int startY, endY;
RECT rect;
bool foundStart, foundEnd;
for (int i=0; i<width; i++)
{
// Gradient color percent
percent = 1 - (double)i / (double)(width);
// Gradient color
red = (unsigned char)(GetRValue(sColor)*percent) + (unsigned char)(GetRValue(eColor)*(1-percent));
green = (unsigned char)(GetGValue(sColor)*percent) + (unsigned char)(GetGValue(eColor)*(1-percent));
blue = (unsigned char)(GetBValue(sColor)*percent) + (unsigned char)(GetBValue(eColor)*(1-percent));
if (bGamma)
{
red = (unsigned char)(pow((double)red/255.0, gamma) * 255);
green = (unsigned char)(pow((double)green/255.0, gamma) * 255);
blue = (unsigned char)(pow((double)blue/255.0, gamma) * 255);
}
color = RGB(red, green, blue);
endY = rgnRect.top;
while (endY<=rgnRect.bottom)
{
foundStart = foundEnd = false;
// Top offset
startY = endY;
while (startY<=rgnRect.bottom)
{
if ( PtInRegion(hRgn, rgnRect.left+i, startY) )
{
foundStart = true;
break;
}
else
startY++;
}
// Bottom offset
endY = startY;
while (endY<=rgnRect.bottom)
{
if ( !PtInRegion(hRgn, rgnRect.left+i, endY) )
{
foundEnd = true;
break;
}
else
endY++;
}
if (foundStart && foundEnd)
{
// Gradient rectangle
rect.left = rgnRect.left + i;
rect.top = startY;
rect.right = rect.left + 1;
rect.bottom = endY;
hBrush = CreateSolidBrush(color);
FillRect(hDC, &rect, hBrush);
DeleteObject(hBrush);
}
}
}
}
void CGradient::VerticalGradient(HDC hDC, HRGN hRgn, COLORREF sColor, COLORREF eColor, BOOL bGamma, double gamma)
{
RECT rgnRect;
GetRgnBox(hRgn, &rgnRect);
// Gradient params
int width = rgnRect.right - rgnRect.left - 1;
int height = rgnRect.bottom - rgnRect.top - 1;
// Draw gradient
HBRUSH hBrush = NULL;
double percent;
unsigned char red, green, blue;
COLORREF color;
int startX, endX;
RECT rect;
bool foundStart, foundEnd;
for (int i=0; i<height; i++)
{
// Gradient color percent
percent = 1 - (double)i / (double)(height);
// Gradient color
red = (unsigned char)(GetRValue(sColor)*percent) + (unsigned char)(GetRValue(eColor)*(1-percent));
green = (unsigned char)(GetGValue(sColor)*percent) + (unsigned char)(GetGValue(eColor)*(1-percent));
blue = (unsigned char)(GetBValue(sColor)*percent) + (unsigned char)(GetBValue(eColor)*(1-percent));
if (bGamma)
{
red = (unsigned char)(pow((double)red/255.0, gamma) * 255);
green = (unsigned char)(pow((double)green/255.0, gamma) * 255);
blue = (unsigned char)(pow((double)blue/255.0, gamma) * 255);
}
color = RGB(red, green, blue);
endX = rgnRect.left;
while (endX<=rgnRect.right)
{
foundStart = foundEnd = false;
// Left offset
startX = endX;
while (startX<=rgnRect.right)
{
if ( PtInRegion(hRgn, startX, rgnRect.top+i) )
{
foundStart = true;
break;
}
startX++;
}
// Right offset
endX = startX;
while (endX<=rgnRect.right)
{
if ( !PtInRegion(hRgn, endX, rgnRect.top+i) )
{
foundEnd = true;
break;
}
endX++;
}
if (foundStart && foundEnd)
{
// Gradient rectangle
rect.left = startX;
rect.top = rgnRect.top + i;
rect.right = endX;
rect.bottom = rect.top + 1;
hBrush = CreateSolidBrush(color);
FillRect(hDC, &rect, hBrush);
DeleteObject(hBrush);
}
}
}
}
void CGradient::MulticolorHorizontalGradient(HDC hDC, HRGN hRgn, COLORREF colors[], int numColors, BOOL bGamma, double gamma)
{
if (numColors < 2)
return;
RECT rgnRect;
GetRgnBox(hRgn, &rgnRect);
// Gradient params
int width = rgnRect.right - rgnRect.left - 1;
int height = rgnRect.bottom - rgnRect.top - 1;
int offset = width / (numColors-1);
for (int c=1; c<numColors; c++)
{
COLORREF sColor = colors[c-1];
COLORREF eColor = colors[c];
// Draw gradient
HBRUSH hBrush = NULL;
double percent;
unsigned char red, green, blue;
COLORREF color;
int startY, endY;
RECT rect;
bool foundStart, foundEnd;
for (int i=0; i<=offset; i++)
{
// Gradient color percent
percent = 1 - (double)i / (double)(offset);
// Gradient color
red = (unsigned char)(GetRValue(sColor)*percent) + (unsigned char)(GetRValue(eColor)*(1-percent));
green = (unsigned char)(GetGValue(sColor)*percent) + (unsigned char)(GetGValue(eColor)*(1-percent));
blue = (unsigned char)(GetBValue(sColor)*percent) + (unsigned char)(GetBValue(eColor)*(1-percent));
if (bGamma)
{
red = (unsigned char)(pow((double)red/255.0, gamma) * 255);
green = (unsigned char)(pow((double)green/255.0, gamma) * 255);
blue = (unsigned char)(pow((double)blue/255.0, gamma) * 255);
}
color = RGB(red, green, blue);
endY = rgnRect.top;
while (endY<=rgnRect.bottom)
{
foundStart = foundEnd = false;
// Top offset
startY = endY;
while (startY<=rgnRect.bottom)
{
if ( PtInRegion(hRgn, rgnRect.left+(c-1)*offset+i, startY) )
{
foundStart = true;
break;
}
startY++;
}
// Bottom offset
endY = startY;
while (endY<=rgnRect.bottom)
{
if ( !PtInRegion(hRgn, rgnRect.left+(c-1)*offset+i, endY) )
{
foundEnd = true;
break;
}
endY++;
}
if (foundStart && foundEnd)
{
// Gradient rectangle
rect.left = rgnRect.left + (c-1)*offset + i;
rect.top = startY;
rect.right = rect.left + 1;
rect.bottom = endY;
hBrush = CreateSolidBrush(color);
FillRect(hDC, &rect, hBrush);
DeleteObject(hBrush);
}
}
}
}
}
void CGradient::MulticolorVerticalGradient(HDC hDC, HRGN hRgn, COLORREF colors[], int numColors, BOOL bGamma, double gamma)
{
if (numColors < 2)
return;
RECT rgnRect;
GetRgnBox(hRgn, &rgnRect);
// Gradient params
int width = rgnRect.right - rgnRect.left - 1;
int height = rgnRect.bottom - rgnRect.top - 1;
int offset = height / (numColors-1);
for (int c=1; c<numColors; c++)
{
COLORREF sColor = colors[c-1];
COLORREF eColor = colors[c];
int step = (int)(((double)offset/2)/255);
if ( step == 0 )
step = 1;
// Draw gradient
HBRUSH hBrush = NULL;
HPEN hPen = NULL;
HPEN hOldPen = NULL;
double percent;
unsigned char red, green, blue;
COLORREF color;
int startX, endX;
RECT rect;
bool foundStart, foundEnd;
for (int i=0; i<offset; i++)
{
// Gradient color percent
percent = 1 - (double)i / (double)(offset);
// Gradient color
red = (unsigned char)(GetRValue(sColor)*percent) + (unsigned char)(GetRValue(eColor)*(1-percent));
green = (unsigned char)(GetGValue(sColor)*percent) + (unsigned char)(GetGValue(eColor)*(1-percent));
blue = (unsigned char)(GetBValue(sColor)*percent) + (unsigned char)(GetBValue(eColor)*(1-percent));
if (bGamma)
{
red = (unsigned char)(pow((double)red/255.0, gamma) * 255);
green = (unsigned char)(pow((double)green/255.0, gamma) * 255);
blue = (unsigned char)(pow((double)blue/255.0, gamma) * 255);
}
color = RGB(red, green, blue);
endX = rgnRect.left;
while (endX<=rgnRect.right)
{
foundStart = foundEnd = false;
// Left offset
startX = endX;
while (startX<=rgnRect.right)
{
if ( PtInRegion(hRgn, startX, rgnRect.top+(c-1)*offset+i) )
{
foundStart = true;
break;
}
startX++;
}
// Right offset
endX = startX;
while (endX<=rgnRect.right)
{
if ( !PtInRegion(hRgn, endX, rgnRect.top+(c-1)*offset+i) )
{
foundEnd = true;
break;
}
endX++;
}
if (foundStart && foundEnd)
{
// Gradient rectangle
rect.left = startX;
rect.top = rgnRect.top + (c-1)*offset + i;
rect.right = endX;
rect.bottom = rect.top + 1;
hBrush = CreateSolidBrush(color);
FillRect(hDC, &rect, hBrush);
DeleteObject(hBrush);
}
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -