gdiplus: Use AlphaBlend for 32-bit images with alpha channels.
This commit is contained in:
parent
7fdc0208e8
commit
895c6d8e1e
|
@ -399,6 +399,25 @@ BOOL lengthen_path(GpPath *path, INT len)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void convert_32bppARGB_to_32bppPARGB(UINT width, UINT height,
|
||||||
|
BYTE *dst_bits, INT dst_stride, const BYTE *src_bits, INT src_stride)
|
||||||
|
{
|
||||||
|
UINT x, y;
|
||||||
|
for (y=0; y<height; y++)
|
||||||
|
{
|
||||||
|
const BYTE *src=src_bits+y*src_stride;
|
||||||
|
BYTE *dst=dst_bits+y*dst_stride;
|
||||||
|
for (x=0; x<width; x++)
|
||||||
|
{
|
||||||
|
BYTE alpha=src[3];
|
||||||
|
*dst++ = *src++ * alpha / 255;
|
||||||
|
*dst++ = *src++ * alpha / 255;
|
||||||
|
*dst++ = *src++ * alpha / 255;
|
||||||
|
*dst++ = *src++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* recursive deletion of GpRegion nodes */
|
/* recursive deletion of GpRegion nodes */
|
||||||
inline void delete_element(region_element* element)
|
inline void delete_element(region_element* element)
|
||||||
{
|
{
|
||||||
|
|
|
@ -80,6 +80,9 @@ static inline REAL deg2rad(REAL degrees)
|
||||||
|
|
||||||
extern const char *debugstr_rectf(CONST RectF* rc);
|
extern const char *debugstr_rectf(CONST RectF* rc);
|
||||||
|
|
||||||
|
extern void convert_32bppARGB_to_32bppPARGB(UINT width, UINT height,
|
||||||
|
BYTE *dst_bits, INT dst_stride, const BYTE *src_bits, INT src_stride);
|
||||||
|
|
||||||
struct GpPen{
|
struct GpPen{
|
||||||
UINT style;
|
UINT style;
|
||||||
GpUnit unit;
|
GpUnit unit;
|
||||||
|
|
|
@ -1877,8 +1877,8 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
|
||||||
{
|
{
|
||||||
HDC hdc;
|
HDC hdc;
|
||||||
GpBitmap* bitmap = (GpBitmap*)image;
|
GpBitmap* bitmap = (GpBitmap*)image;
|
||||||
int bm_is_selected;
|
int temp_hdc=0, temp_bitmap=0;
|
||||||
HBITMAP old_hbm=NULL;
|
HBITMAP hbitmap, old_hbm=NULL;
|
||||||
|
|
||||||
if (srcUnit == UnitInch)
|
if (srcUnit == UnitInch)
|
||||||
dx = dy = 96.0; /* FIXME: use the image resolution */
|
dx = dy = 96.0; /* FIXME: use the image resolution */
|
||||||
|
@ -1887,24 +1887,73 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
|
||||||
else
|
else
|
||||||
return NotImplemented;
|
return NotImplemented;
|
||||||
|
|
||||||
hdc = bitmap->hdc;
|
if (bitmap->format == PixelFormat32bppARGB)
|
||||||
bm_is_selected = (hdc != 0);
|
|
||||||
|
|
||||||
if (!bm_is_selected)
|
|
||||||
{
|
{
|
||||||
|
BITMAPINFOHEADER bih;
|
||||||
|
BYTE *temp_bits;
|
||||||
|
|
||||||
|
/* we need a bitmap with premultiplied alpha */
|
||||||
hdc = CreateCompatibleDC(0);
|
hdc = CreateCompatibleDC(0);
|
||||||
old_hbm = SelectObject(hdc, bitmap->hbitmap);
|
temp_hdc = 1;
|
||||||
|
temp_bitmap = 1;
|
||||||
|
|
||||||
|
bih.biSize = sizeof(BITMAPINFOHEADER);
|
||||||
|
bih.biWidth = bitmap->width;
|
||||||
|
bih.biHeight = -bitmap->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(bitmap->width, bitmap->height,
|
||||||
|
temp_bits, bitmap->width*4, bitmap->bits, bitmap->stride);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hbitmap = bitmap->hbitmap;
|
||||||
|
hdc = bitmap->hdc;
|
||||||
|
temp_hdc = (hdc == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: maybe alpha blend depending on the format */
|
if (temp_hdc)
|
||||||
StretchBlt(graphics->hdc, pti[0].x, pti[0].y, pti[1].x-pti[0].x, pti[2].y-pti[0].y,
|
{
|
||||||
hdc, srcx*dx, srcy*dy, srcwidth*dx, srcheight*dy, SRCCOPY);
|
if (!hdc) hdc = CreateCompatibleDC(0);
|
||||||
|
old_hbm = SelectObject(hdc, hbitmap);
|
||||||
|
}
|
||||||
|
|
||||||
if (!bm_is_selected)
|
if (bitmap->format == PixelFormat32bppARGB || bitmap->format == PixelFormat32bppPARGB)
|
||||||
|
{
|
||||||
|
BLENDFUNCTION bf;
|
||||||
|
|
||||||
|
bf.BlendOp = AC_SRC_OVER;
|
||||||
|
bf.BlendFlags = 0;
|
||||||
|
bf.SourceConstantAlpha = 255;
|
||||||
|
bf.AlphaFormat = AC_SRC_ALPHA;
|
||||||
|
|
||||||
|
GdiAlphaBlend(graphics->hdc, pti[0].x, pti[0].y, pti[1].x-pti[0].x, pti[2].y-pti[0].y,
|
||||||
|
hdc, srcx*dx, srcy*dy, srcwidth*dx, srcheight*dy, bf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StretchBlt(graphics->hdc, pti[0].x, pti[0].y, pti[1].x-pti[0].x, pti[2].y-pti[0].y,
|
||||||
|
hdc, srcx*dx, srcy*dy, srcwidth*dx, srcheight*dy, SRCCOPY);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (temp_hdc)
|
||||||
{
|
{
|
||||||
SelectObject(hdc, old_hbm);
|
SelectObject(hdc, old_hbm);
|
||||||
DeleteDC(hdc);
|
DeleteDC(hdc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (temp_bitmap)
|
||||||
|
DeleteObject(hbitmap);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue