Commit 60167dfb authored by Vincent Povirk's avatar Vincent Povirk Committed by Alexandre Julliard

gdiplus: Implement partially transparent solid fill brushes.

parent 122af07a
...@@ -46,13 +46,19 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone) ...@@ -46,13 +46,19 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone)
switch(brush->bt){ switch(brush->bt){
case BrushTypeSolidColor: case BrushTypeSolidColor:
{
GpSolidFill *fill;
*clone = GdipAlloc(sizeof(GpSolidFill)); *clone = GdipAlloc(sizeof(GpSolidFill));
if (!*clone) return OutOfMemory; if (!*clone) return OutOfMemory;
fill = (GpSolidFill*)*clone;
memcpy(*clone, brush, sizeof(GpSolidFill)); memcpy(*clone, brush, sizeof(GpSolidFill));
(*clone)->gdibrush = CreateBrushIndirect(&(*clone)->lb); (*clone)->gdibrush = CreateBrushIndirect(&(*clone)->lb);
fill->bmp = ARGB2BMP(fill->color);
break; break;
}
case BrushTypeHatchFill: case BrushTypeHatchFill:
*clone = GdipAlloc(sizeof(GpHatch)); *clone = GdipAlloc(sizeof(GpHatch));
if (!*clone) return OutOfMemory; if (!*clone) return OutOfMemory;
...@@ -560,6 +566,7 @@ GpStatus WINGDIPAPI GdipCreateSolidFill(ARGB color, GpSolidFill **sf) ...@@ -560,6 +566,7 @@ GpStatus WINGDIPAPI GdipCreateSolidFill(ARGB color, GpSolidFill **sf)
(*sf)->brush.gdibrush = CreateSolidBrush(col); (*sf)->brush.gdibrush = CreateSolidBrush(col);
(*sf)->brush.bt = BrushTypeSolidColor; (*sf)->brush.bt = BrushTypeSolidColor;
(*sf)->color = color; (*sf)->color = color;
(*sf)->bmp = ARGB2BMP(color);
return Ok; return Ok;
} }
...@@ -842,6 +849,8 @@ GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush *brush) ...@@ -842,6 +849,8 @@ GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush *brush)
GdipFree(((GpPathGradient*) brush)->blendpos); GdipFree(((GpPathGradient*) brush)->blendpos);
break; break;
case BrushTypeSolidColor: case BrushTypeSolidColor:
if (((GpSolidFill*)brush)->bmp)
DeleteObject(((GpSolidFill*)brush)->bmp);
break; break;
case BrushTypeLinearGradient: case BrushTypeLinearGradient:
GdipFree(((GpLineGradient*)brush)->blendfac); GdipFree(((GpLineGradient*)brush)->blendfac);
......
...@@ -258,6 +258,42 @@ COLORREF ARGB2COLORREF(ARGB color) ...@@ -258,6 +258,42 @@ COLORREF ARGB2COLORREF(ARGB color)
((color & 0xff0000) >> 16); ((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. */ /* Like atan2, but puts angle in correct quadrant if dx is 0. */
REAL gdiplus_atan2(REAL dy, REAL dx) REAL gdiplus_atan2(REAL dy, REAL dx)
{ {
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#define TENSION_CONST (0.3) #define TENSION_CONST (0.3)
COLORREF ARGB2COLORREF(ARGB color); COLORREF ARGB2COLORREF(ARGB color);
HBITMAP ARGB2BMP(ARGB color);
extern INT arc2polybezier(GpPointF * points, REAL x1, REAL y1, REAL x2, REAL y2, extern INT arc2polybezier(GpPointF * points, REAL x1, REAL y1, REAL x2, REAL y2,
REAL startAngle, REAL sweepAngle); REAL startAngle, REAL sweepAngle);
extern REAL gdiplus_atan2(REAL dy, REAL dx); extern REAL gdiplus_atan2(REAL dy, REAL dx);
...@@ -126,6 +127,7 @@ struct GpHatch{ ...@@ -126,6 +127,7 @@ struct GpHatch{
struct GpSolidFill{ struct GpSolidFill{
GpBrush brush; GpBrush brush;
ARGB color; ARGB color;
HBITMAP bmp;
}; };
struct GpPathGradient{ struct GpPathGradient{
......
...@@ -346,6 +346,40 @@ static void brush_fill_path(GpGraphics *graphics, GpBrush* brush) ...@@ -346,6 +346,40 @@ static void brush_fill_path(GpGraphics *graphics, GpBrush* brush)
} }
break; 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: default:
SelectObject(graphics->hdc, brush->gdibrush); SelectObject(graphics->hdc, brush->gdibrush);
FillPath(graphics->hdc); FillPath(graphics->hdc);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment