gdiplus: Implement partially transparent solid fill brushes.
This commit is contained in:
parent
122af07a30
commit
60167dfb74
|
@ -46,13 +46,19 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone)
|
|||
|
||||
switch(brush->bt){
|
||||
case BrushTypeSolidColor:
|
||||
{
|
||||
GpSolidFill *fill;
|
||||
*clone = GdipAlloc(sizeof(GpSolidFill));
|
||||
if (!*clone) return OutOfMemory;
|
||||
|
||||
fill = (GpSolidFill*)*clone;
|
||||
|
||||
memcpy(*clone, brush, sizeof(GpSolidFill));
|
||||
|
||||
(*clone)->gdibrush = CreateBrushIndirect(&(*clone)->lb);
|
||||
fill->bmp = ARGB2BMP(fill->color);
|
||||
break;
|
||||
}
|
||||
case BrushTypeHatchFill:
|
||||
*clone = GdipAlloc(sizeof(GpHatch));
|
||||
if (!*clone) return OutOfMemory;
|
||||
|
@ -560,6 +566,7 @@ GpStatus WINGDIPAPI GdipCreateSolidFill(ARGB color, GpSolidFill **sf)
|
|||
(*sf)->brush.gdibrush = CreateSolidBrush(col);
|
||||
(*sf)->brush.bt = BrushTypeSolidColor;
|
||||
(*sf)->color = color;
|
||||
(*sf)->bmp = ARGB2BMP(color);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
@ -842,6 +849,8 @@ GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush *brush)
|
|||
GdipFree(((GpPathGradient*) brush)->blendpos);
|
||||
break;
|
||||
case BrushTypeSolidColor:
|
||||
if (((GpSolidFill*)brush)->bmp)
|
||||
DeleteObject(((GpSolidFill*)brush)->bmp);
|
||||
break;
|
||||
case BrushTypeLinearGradient:
|
||||
GdipFree(((GpLineGradient*)brush)->blendfac);
|
||||
|
|
|
@ -258,6 +258,42 @@ COLORREF ARGB2COLORREF(ARGB color)
|
|||
((color & 0xff0000) >> 16);
|
||||
}
|
||||
|
||||
HBITMAP ARGB2BMP(ARGB color)
|
||||
{
|
||||
HDC hdc;
|
||||
BITMAPINFO bi;
|
||||
HBITMAP result;
|
||||
RGBQUAD *bits;
|
||||
int alpha;
|
||||
|
||||
if ((color & 0xff000000) == 0xff000000) return 0;
|
||||
|
||||
hdc = CreateCompatibleDC(NULL);
|
||||
|
||||
bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
|
||||
bi.bmiHeader.biWidth = 1;
|
||||
bi.bmiHeader.biHeight = 1;
|
||||
bi.bmiHeader.biPlanes = 1;
|
||||
bi.bmiHeader.biBitCount = 32;
|
||||
bi.bmiHeader.biCompression = BI_RGB;
|
||||
bi.bmiHeader.biSizeImage = 0;
|
||||
bi.bmiHeader.biXPelsPerMeter = 0;
|
||||
bi.bmiHeader.biYPelsPerMeter = 0;
|
||||
bi.bmiHeader.biClrUsed = 0;
|
||||
bi.bmiHeader.biClrImportant = 0;
|
||||
|
||||
result = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void*)&bits, NULL, 0);
|
||||
|
||||
bits[0].rgbReserved = alpha = (color>>24)&0xff;
|
||||
bits[0].rgbRed = ((color>>16)&0xff)*alpha/255;
|
||||
bits[0].rgbGreen = ((color>>8)&0xff)*alpha/255;
|
||||
bits[0].rgbBlue = (color&0xff)*alpha/255;
|
||||
|
||||
DeleteDC(hdc);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Like atan2, but puts angle in correct quadrant if dx is 0. */
|
||||
REAL gdiplus_atan2(REAL dy, REAL dx)
|
||||
{
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#define TENSION_CONST (0.3)
|
||||
|
||||
COLORREF ARGB2COLORREF(ARGB color);
|
||||
HBITMAP ARGB2BMP(ARGB color);
|
||||
extern INT arc2polybezier(GpPointF * points, REAL x1, REAL y1, REAL x2, REAL y2,
|
||||
REAL startAngle, REAL sweepAngle);
|
||||
extern REAL gdiplus_atan2(REAL dy, REAL dx);
|
||||
|
@ -126,6 +127,7 @@ struct GpHatch{
|
|||
struct GpSolidFill{
|
||||
GpBrush brush;
|
||||
ARGB color;
|
||||
HBITMAP bmp;
|
||||
};
|
||||
|
||||
struct GpPathGradient{
|
||||
|
|
|
@ -346,6 +346,40 @@ static void brush_fill_path(GpGraphics *graphics, GpBrush* brush)
|
|||
}
|
||||
break;
|
||||
}
|
||||
case BrushTypeSolidColor:
|
||||
{
|
||||
GpSolidFill *fill = (GpSolidFill*)brush;
|
||||
if (fill->bmp)
|
||||
{
|
||||
RECT rc;
|
||||
/* partially transparent fill */
|
||||
|
||||
SelectClipPath(graphics->hdc, RGN_AND);
|
||||
if (GetClipBox(graphics->hdc, &rc) != NULLREGION)
|
||||
{
|
||||
HDC hdc = CreateCompatibleDC(NULL);
|
||||
HBITMAP oldbmp;
|
||||
BLENDFUNCTION bf;
|
||||
|
||||
if (!hdc) break;
|
||||
|
||||
oldbmp = SelectObject(hdc, fill->bmp);
|
||||
|
||||
bf.BlendOp = AC_SRC_OVER;
|
||||
bf.BlendFlags = 0;
|
||||
bf.SourceConstantAlpha = 255;
|
||||
bf.AlphaFormat = AC_SRC_ALPHA;
|
||||
|
||||
GdiAlphaBlend(graphics->hdc, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, hdc, 0, 0, 1, 1, bf);
|
||||
|
||||
SelectObject(hdc, oldbmp);
|
||||
DeleteDC(hdc);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
/* else fall through */
|
||||
}
|
||||
default:
|
||||
SelectObject(graphics->hdc, brush->gdibrush);
|
||||
FillPath(graphics->hdc);
|
||||
|
|
Loading…
Reference in New Issue