Commit ab12be68 authored by Piotr Caban's avatar Piotr Caban Committed by Alexandre Julliard

wineps: Handle EMR_STRETCHBLT record in spool files.

parent 83f0862b
......@@ -137,6 +137,133 @@ static inline INT GDI_ROUND(double val)
return (int)floor(val + 0.5);
}
static void translate(RECT *rect, const XFORM *xform)
{
double x, y;
x = rect->left;
y = rect->top;
rect->left = GDI_ROUND(x * xform->eM11 + y * xform->eM21 + xform->eDx);
rect->top = GDI_ROUND(x * xform->eM12 + y * xform->eM22 + xform->eDy);
x = rect->right;
y = rect->bottom;
rect->right = GDI_ROUND(x * xform->eM11 + y * xform->eM21 + xform->eDx);
rect->bottom = GDI_ROUND(x * xform->eM12 + y * xform->eM22 + xform->eDy);
}
static inline void get_bounding_rect(RECT *rect, int x, int y, int width, int height)
{
rect->left = x;
rect->right = x + width;
rect->top = y;
rect->bottom = y + height;
if (rect->left > rect->right)
{
int tmp = rect->left;
rect->left = rect->right + 1;
rect->right = tmp + 1;
}
if (rect->top > rect->bottom)
{
int tmp = rect->top;
rect->top = rect->bottom + 1;
rect->bottom = tmp + 1;
}
}
static void get_vis_rectangles(HDC hdc, struct bitblt_coords *dst,
const XFORM *xform, DWORD width, DWORD height, struct bitblt_coords *src)
{
RECT rect;
rect.left = dst->log_x;
rect.top = dst->log_y;
rect.right = dst->log_x + dst->log_width;
rect.bottom = dst->log_y + dst->log_height;
LPtoDP(hdc, (POINT *)&rect, 2);
dst->x = rect.left;
dst->y = rect.top;
dst->width = rect.right - rect.left;
dst->height = rect.bottom - rect.top;
if (dst->layout & LAYOUT_RTL && dst->layout & LAYOUT_BITMAPORIENTATIONPRESERVED)
{
dst->x += dst->width;
dst->width = -dst->width;
}
get_bounding_rect(&rect, dst->x, dst->y, dst->width, dst->height);
dst->visrect = rect;
if (!src) return;
rect.left = src->log_x;
rect.top = src->log_y;
rect.right = src->log_x + src->log_width;
rect.bottom = src->log_y + src->log_height;
translate(&rect, xform);
src->x = rect.left;
src->y = rect.top;
src->width = rect.right - rect.left;
src->height = rect.bottom - rect.top;
get_bounding_rect( &rect, src->x, src->y, src->width, src->height );
src->visrect = rect;
}
static int stretch_blt(PHYSDEV dev, const EMRSTRETCHBLT *blt,
const BITMAPINFO *bi, const BYTE *src_bits)
{
char dst_buffer[FIELD_OFFSET(BITMAPINFO, bmiColors[256])];
BITMAPINFO *dst_info = (BITMAPINFO *)dst_buffer;
struct bitblt_coords src, dst;
struct gdi_image_bits bits;
DWORD err;
dst.log_x = blt->xDest;
dst.log_y = blt->yDest;
dst.log_width = blt->cxDest;
dst.log_height = blt->cyDest;
dst.layout = GetLayout(dev->hdc);
if (blt->dwRop & NOMIRRORBITMAP)
dst.layout |= LAYOUT_BITMAPORIENTATIONPRESERVED;
if (!blt->cbBmiSrc)
{
get_vis_rectangles(dev->hdc, &dst, NULL, 0, 0, NULL);
return PSDRV_PatBlt(dev, &dst, blt->dwRop);
}
src.log_x = blt->xSrc;
src.log_y = blt->ySrc;
src.log_width = blt->cxSrc;
src.log_height = blt->cySrc;
src.layout = 0;
get_vis_rectangles(dev->hdc, &dst, &blt->xformSrc,
bi->bmiHeader.biWidth, bi->bmiHeader.biHeight, &src);
memcpy(dst_info, bi, blt->cbBmiSrc);
memset(&bits, 0, sizeof(bits));
bits.ptr = (BYTE *)src_bits;
err = PSDRV_PutImage(dev, 0, dst_info, &bits, &src, &dst, blt->dwRop);
if (err == ERROR_BAD_FORMAT)
{
HDC hdc = CreateCompatibleDC(NULL);
HBITMAP bitmap;
bits.is_copy = TRUE;
bitmap = CreateDIBSection(hdc, dst_info, DIB_RGB_COLORS, &bits.ptr, NULL, 0);
SetDIBits(hdc, bitmap, 0, bi->bmiHeader.biHeight, src_bits, bi, blt->iUsageSrc);
err = PSDRV_PutImage(dev, 0, dst_info, &bits, &src, &dst, blt->dwRop);
DeleteObject(bitmap);
DeleteObject(hdc);
}
if (err != ERROR_SUCCESS)
FIXME("PutImage returned %ld\n", err);
return !err;
}
static int WINAPI hmf_proc(HDC hdc, HANDLETABLE *htable,
const ENHMETARECORD *rec, int n, LPARAM arg)
{
......@@ -366,6 +493,14 @@ static int WINAPI hmf_proc(HDC hdc, HANDLETABLE *htable,
DeleteObject(rgn);
return ret;
}
case EMR_STRETCHBLT:
{
const EMRSTRETCHBLT *p = (const EMRSTRETCHBLT *)rec;
const BITMAPINFO *bi = (const BITMAPINFO *)((BYTE *)p + p->offBmiSrc);
const BYTE *src_bits = (BYTE *)p + p->offBitsSrc;
return stretch_blt(&data->pdev->dev, p, bi, src_bits);
}
case EMR_POLYBEZIER16:
{
const EMRPOLYBEZIER16 *p = (const EMRPOLYBEZIER16 *)rec;
......
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