gdiplus: Add a software implementation of GdipFillRegion.
This commit is contained in:
parent
6acffba564
commit
60cd477342
|
@ -487,6 +487,36 @@ static void brush_fill_path(GpGraphics *graphics, GpBrush* brush)
|
|||
}
|
||||
}
|
||||
|
||||
static INT brush_can_fill_pixels(GpBrush *brush)
|
||||
{
|
||||
switch (brush->bt)
|
||||
{
|
||||
case BrushTypeSolidColor:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static GpStatus brush_fill_pixels(GpGraphics *graphics, GpBrush *brush,
|
||||
DWORD *argb_pixels, GpRect *fill_area, UINT cdwStride)
|
||||
{
|
||||
switch (brush->bt)
|
||||
{
|
||||
case BrushTypeSolidColor:
|
||||
{
|
||||
int x, y;
|
||||
GpSolidFill *fill = (GpSolidFill*)brush;
|
||||
for (x=0; x<fill_area->Width; x++)
|
||||
for (y=0; y<fill_area->Height; y++)
|
||||
argb_pixels[x + y*cdwStride] = fill->color;
|
||||
return Ok;
|
||||
}
|
||||
default:
|
||||
return NotImplemented;
|
||||
}
|
||||
}
|
||||
|
||||
/* GdipDrawPie/GdipFillPie helper function */
|
||||
static void draw_pie(GpGraphics *graphics, REAL x, REAL y, REAL width,
|
||||
REAL height, REAL startAngle, REAL sweepAngle)
|
||||
|
@ -3321,13 +3351,122 @@ static GpStatus GDI32_GdipFillRegion(GpGraphics* graphics, GpBrush* brush,
|
|||
return Ok;
|
||||
}
|
||||
|
||||
static GpStatus SOFTWARE_GdipFillRegion(GpGraphics *graphics, GpBrush *brush,
|
||||
GpRegion* region)
|
||||
{
|
||||
GpStatus stat;
|
||||
GpRegion *temp_region;
|
||||
GpMatrix *world_to_device, *identity;
|
||||
GpRectF graphics_bounds;
|
||||
UINT scans_count, i;
|
||||
INT dummy;
|
||||
GpRect *scans;
|
||||
DWORD *pixel_data;
|
||||
|
||||
if (!brush_can_fill_pixels(brush))
|
||||
return NotImplemented;
|
||||
|
||||
stat = get_graphics_bounds(graphics, &graphics_bounds);
|
||||
|
||||
if (stat == Ok)
|
||||
stat = GdipCloneRegion(region, &temp_region);
|
||||
|
||||
if (stat == Ok)
|
||||
{
|
||||
stat = get_graphics_transform(graphics, CoordinateSpaceDevice,
|
||||
CoordinateSpaceWorld, &world_to_device);
|
||||
|
||||
if (stat == Ok)
|
||||
{
|
||||
stat = GdipTransformRegion(temp_region, world_to_device);
|
||||
|
||||
GdipDeleteMatrix(world_to_device);
|
||||
}
|
||||
|
||||
if (stat == Ok)
|
||||
stat = GdipCombineRegionRect(temp_region, &graphics_bounds, CombineModeIntersect);
|
||||
|
||||
if (stat == Ok)
|
||||
stat = GdipCreateMatrix(&identity);
|
||||
|
||||
if (stat == Ok)
|
||||
{
|
||||
stat = GdipGetRegionScansCount(temp_region, &scans_count, identity);
|
||||
|
||||
if (stat == Ok && scans_count != 0)
|
||||
{
|
||||
scans = GdipAlloc(sizeof(*scans) * scans_count);
|
||||
if (!scans)
|
||||
stat = OutOfMemory;
|
||||
|
||||
if (stat == Ok)
|
||||
{
|
||||
stat = GdipGetRegionScansI(temp_region, scans, &dummy, identity);
|
||||
|
||||
if (stat != Ok)
|
||||
GdipFree(scans);
|
||||
}
|
||||
}
|
||||
|
||||
GdipDeleteMatrix(identity);
|
||||
}
|
||||
|
||||
GdipDeleteRegion(temp_region);
|
||||
}
|
||||
|
||||
if (stat == Ok && scans_count == 0)
|
||||
return Ok;
|
||||
|
||||
if (stat == Ok)
|
||||
{
|
||||
UINT max_size=0;
|
||||
|
||||
for (i=0; i<scans_count; i++)
|
||||
{
|
||||
UINT size = scans[i].Width * scans[i].Height;
|
||||
|
||||
if (size > max_size)
|
||||
max_size = size;
|
||||
}
|
||||
|
||||
pixel_data = GdipAlloc(sizeof(*pixel_data) * max_size);
|
||||
if (!pixel_data)
|
||||
stat = OutOfMemory;
|
||||
|
||||
if (stat == Ok)
|
||||
{
|
||||
for (i=0; i<scans_count; i++)
|
||||
{
|
||||
stat = brush_fill_pixels(graphics, brush, pixel_data, &scans[i],
|
||||
scans[i].Width);
|
||||
|
||||
if (stat == Ok)
|
||||
{
|
||||
stat = alpha_blend_pixels(graphics, scans[i].X, scans[i].Y,
|
||||
(BYTE*)pixel_data, scans[i].Width, scans[i].Height,
|
||||
scans[i].Width * 4);
|
||||
}
|
||||
|
||||
if (stat != Ok)
|
||||
break;
|
||||
}
|
||||
|
||||
GdipFree(pixel_data);
|
||||
}
|
||||
|
||||
GdipFree(scans);
|
||||
}
|
||||
|
||||
return stat;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* GdipFillRegion [GDIPLUS.@]
|
||||
*/
|
||||
GpStatus WINGDIPAPI GdipFillRegion(GpGraphics* graphics, GpBrush* brush,
|
||||
GpRegion* region)
|
||||
{
|
||||
GpStatus stat;
|
||||
GpStatus stat = NotImplemented;
|
||||
|
||||
TRACE("(%p, %p, %p)\n", graphics, brush, region);
|
||||
|
||||
|
@ -3337,11 +3476,18 @@ GpStatus WINGDIPAPI GdipFillRegion(GpGraphics* graphics, GpBrush* brush,
|
|||
if(graphics->busy)
|
||||
return ObjectBusy;
|
||||
|
||||
if (!graphics->image)
|
||||
stat = GDI32_GdipFillRegion(graphics, brush, region);
|
||||
|
||||
if (stat == NotImplemented)
|
||||
stat = SOFTWARE_GdipFillRegion(graphics, brush, region);
|
||||
|
||||
if (stat == NotImplemented && graphics->image)
|
||||
stat = GDI32_GdipFillRegion(graphics, brush, region);
|
||||
|
||||
if (stat == NotImplemented)
|
||||
{
|
||||
FIXME("partially implemented\n");
|
||||
FIXME("not implemented for brushtype %i\n", brush->bt);
|
||||
stat = Ok;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue