Vincent Povirk : gdiplus: Use clipping region in alpha_blend_pixels.
Alexandre Julliard
julliard at winehq.org
Wed Nov 28 14:14:04 CST 2012
Module: wine
Branch: master
Commit: 423d50eb3b4edd3140880ed2ccbe9d6ca665dcb5
URL: http://source.winehq.org/git/wine.git/?a=commit;h=423d50eb3b4edd3140880ed2ccbe9d6ca665dcb5
Author: Vincent Povirk <vincent at codeweavers.com>
Date: Tue Nov 27 13:42:07 2012 -0600
gdiplus: Use clipping region in alpha_blend_pixels.
---
dlls/gdiplus/graphics.c | 163 +++++++++++++++++++++++++++++-----------------
1 files changed, 103 insertions(+), 60 deletions(-)
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index f56682b..247b17d 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -359,68 +359,67 @@ static void gdi_alpha_blend(GpGraphics *graphics, INT dst_x, INT dst_y, INT dst_
}
}
+static GpStatus get_clip_hrgn(GpGraphics *graphics, HRGN *hrgn)
+{
+ return GdipGetRegionHRgn(graphics->clip, graphics, hrgn);
+}
+
/* Draw non-premultiplied ARGB data to the given graphics object */
-static GpStatus alpha_blend_pixels(GpGraphics *graphics, INT dst_x, INT dst_y,
+static GpStatus alpha_blend_bmp_pixels(GpGraphics *graphics, INT dst_x, INT dst_y,
const BYTE *src, INT src_width, INT src_height, INT src_stride)
{
- if (graphics->image && graphics->image->type == ImageTypeBitmap)
- {
- GpBitmap *dst_bitmap = (GpBitmap*)graphics->image;
- INT x, y;
+ GpBitmap *dst_bitmap = (GpBitmap*)graphics->image;
+ INT x, y;
- for (x=0; x<src_width; x++)
+ for (x=0; x<src_width; x++)
+ {
+ for (y=0; y<src_height; y++)
{
- for (y=0; y<src_height; y++)
- {
- ARGB dst_color, src_color;
- GdipBitmapGetPixel(dst_bitmap, x+dst_x, y+dst_y, &dst_color);
- src_color = ((ARGB*)(src + src_stride * y))[x];
- GdipBitmapSetPixel(dst_bitmap, x+dst_x, y+dst_y, color_over(dst_color, src_color));
- }
+ ARGB dst_color, src_color;
+ GdipBitmapGetPixel(dst_bitmap, x+dst_x, y+dst_y, &dst_color);
+ src_color = ((ARGB*)(src + src_stride * y))[x];
+ GdipBitmapSetPixel(dst_bitmap, x+dst_x, y+dst_y, color_over(dst_color, src_color));
}
-
- return Ok;
- }
- else if (graphics->image && graphics->image->type == ImageTypeMetafile)
- {
- ERR("This should not be used for metafiles; fix caller\n");
- return NotImplemented;
}
- else
- {
- HDC hdc;
- HBITMAP hbitmap;
- BITMAPINFOHEADER bih;
- BYTE *temp_bits;
-
- hdc = CreateCompatibleDC(0);
-
- bih.biSize = sizeof(BITMAPINFOHEADER);
- bih.biWidth = src_width;
- bih.biHeight = -src_height;
- bih.biPlanes = 1;
- bih.biBitCount = 32;
- bih.biCompression = BI_RGB;
- bih.biSizeImage = 0;
- bih.biXPelsPerMeter = 0;
- bih.biYPelsPerMeter = 0;
- bih.biClrUsed = 0;
- bih.biClrImportant = 0;
-
- hbitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bih, DIB_RGB_COLORS,
- (void**)&temp_bits, NULL, 0);
-
- convert_32bppARGB_to_32bppPARGB(src_width, src_height, temp_bits,
- 4 * src_width, src, src_stride);
-
- SelectObject(hdc, hbitmap);
- gdi_alpha_blend(graphics, dst_x, dst_y, src_width, src_height,
- hdc, 0, 0, src_width, src_height);
- DeleteDC(hdc);
- DeleteObject(hbitmap);
- return Ok;
- }
+ return Ok;
+}
+
+static GpStatus alpha_blend_hdc_pixels(GpGraphics *graphics, INT dst_x, INT dst_y,
+ const BYTE *src, INT src_width, INT src_height, INT src_stride)
+{
+ HDC hdc;
+ HBITMAP hbitmap;
+ BITMAPINFOHEADER bih;
+ BYTE *temp_bits;
+
+ hdc = CreateCompatibleDC(0);
+
+ bih.biSize = sizeof(BITMAPINFOHEADER);
+ bih.biWidth = src_width;
+ bih.biHeight = -src_height;
+ bih.biPlanes = 1;
+ bih.biBitCount = 32;
+ bih.biCompression = BI_RGB;
+ bih.biSizeImage = 0;
+ bih.biXPelsPerMeter = 0;
+ bih.biYPelsPerMeter = 0;
+ bih.biClrUsed = 0;
+ bih.biClrImportant = 0;
+
+ hbitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bih, DIB_RGB_COLORS,
+ (void**)&temp_bits, NULL, 0);
+
+ convert_32bppARGB_to_32bppPARGB(src_width, src_height, temp_bits,
+ 4 * src_width, src, src_stride);
+
+ SelectObject(hdc, hbitmap);
+ gdi_alpha_blend(graphics, dst_x, dst_y, src_width, src_height,
+ hdc, 0, 0, src_width, src_height);
+ DeleteDC(hdc);
+ DeleteObject(hbitmap);
+
+ return Ok;
}
static GpStatus alpha_blend_pixels_hrgn(GpGraphics *graphics, INT dst_x, INT dst_y,
@@ -433,20 +432,44 @@ static GpStatus alpha_blend_pixels_hrgn(GpGraphics *graphics, INT dst_x, INT dst
int i, size;
RGNDATA *rgndata;
RECT *rects;
+ HRGN hrgn, visible_rgn;
+
+ hrgn = CreateRectRgn(dst_x, dst_y, dst_x + src_width, dst_y + src_height);
+ if (!hrgn)
+ return OutOfMemory;
+
+ stat = get_clip_hrgn(graphics, &visible_rgn);
+ if (stat != Ok)
+ {
+ DeleteObject(hrgn);
+ return stat;
+ }
+
+ if (visible_rgn)
+ {
+ CombineRgn(hrgn, hrgn, visible_rgn, RGN_AND);
+ DeleteObject(visible_rgn);
+ }
- size = GetRegionData(hregion, 0, NULL);
+ if (hregion)
+ CombineRgn(hrgn, hrgn, hregion, RGN_AND);
+
+ size = GetRegionData(hrgn, 0, NULL);
rgndata = GdipAlloc(size);
if (!rgndata)
+ {
+ DeleteObject(hrgn);
return OutOfMemory;
+ }
- GetRegionData(hregion, size, rgndata);
+ GetRegionData(hrgn, size, rgndata);
rects = (RECT*)&rgndata->Buffer;
for (i=0; stat == Ok && i<rgndata->rdh.nCount; i++)
{
- stat = alpha_blend_pixels(graphics, rects[i].left, rects[i].top,
+ stat = alpha_blend_bmp_pixels(graphics, rects[i].left, rects[i].top,
&src[(rects[i].left - dst_x) * 4 + (rects[i].top - dst_y) * src_stride],
rects[i].right - rects[i].left, rects[i].bottom - rects[i].top,
src_stride);
@@ -454,6 +477,8 @@ static GpStatus alpha_blend_pixels_hrgn(GpGraphics *graphics, INT dst_x, INT dst
GdipFree(rgndata);
+ DeleteObject(hrgn);
+
return stat;
}
else if (graphics->image && graphics->image->type == ImageTypeMetafile)
@@ -463,21 +488,39 @@ static GpStatus alpha_blend_pixels_hrgn(GpGraphics *graphics, INT dst_x, INT dst
}
else
{
+ HRGN hrgn;
int save;
+ stat = get_clip_hrgn(graphics, &hrgn);
+
+ if (stat != Ok)
+ return stat;
+
save = SaveDC(graphics->hdc);
- ExtSelectClipRgn(graphics->hdc, hregion, RGN_AND);
+ if (hrgn)
+ ExtSelectClipRgn(graphics->hdc, hrgn, RGN_AND);
- stat = alpha_blend_pixels(graphics, dst_x, dst_y, src, src_width,
+ if (hregion)
+ ExtSelectClipRgn(graphics->hdc, hregion, RGN_AND);
+
+ stat = alpha_blend_hdc_pixels(graphics, dst_x, dst_y, src, src_width,
src_height, src_stride);
RestoreDC(graphics->hdc, save);
+ DeleteObject(hrgn);
+
return stat;
}
}
+static GpStatus alpha_blend_pixels(GpGraphics *graphics, INT dst_x, INT dst_y,
+ const BYTE *src, INT src_width, INT src_height, INT src_stride)
+{
+ return alpha_blend_pixels_hrgn(graphics, dst_x, dst_y, src, src_width, src_height, src_stride, NULL);
+}
+
static ARGB blend_colors(ARGB start, ARGB end, REAL position)
{
ARGB result=0;
More information about the wine-cvs
mailing list