Module: wine Branch: master Commit: 93c5adbf9273199e3e98e7eab634eca7fda608e7 URL: https://gitlab.winehq.org/wine/wine/-/commit/93c5adbf9273199e3e98e7eab634eca...
Author: Piotr Caban piotr@codeweavers.com Date: Thu Apr 6 20:11:08 2023 +0200
wineps: Handle EMR_PLGBLT record in spool files.
---
dlls/wineps.drv/printproc.c | 103 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+)
diff --git a/dlls/wineps.drv/printproc.c b/dlls/wineps.drv/printproc.c index 1f94e4782b9..399e8a8c212 100644 --- a/dlls/wineps.drv/printproc.c +++ b/dlls/wineps.drv/printproc.c @@ -527,6 +527,103 @@ static int mask_blt(PHYSDEV dev, const EMRMASKBLT *p, const BITMAPINFO *src_bi, return TRUE; }
+static void combine_transform(XFORM *result, const XFORM *xform1, const XFORM *xform2) +{ + XFORM r; + + /* Create the result in a temporary XFORM, since result may be + * equal to xform1 or xform2 */ + r.eM11 = xform1->eM11 * xform2->eM11 + xform1->eM12 * xform2->eM21; + r.eM12 = xform1->eM11 * xform2->eM12 + xform1->eM12 * xform2->eM22; + r.eM21 = xform1->eM21 * xform2->eM11 + xform1->eM22 * xform2->eM21; + r.eM22 = xform1->eM21 * xform2->eM12 + xform1->eM22 * xform2->eM22; + r.eDx = xform1->eDx * xform2->eM11 + xform1->eDy * xform2->eM21 + xform2->eDx; + r.eDy = xform1->eDx * xform2->eM12 + xform1->eDy * xform2->eM22 + xform2->eDy; + + *result = r; +} + +static int plg_blt(PHYSDEV dev, const EMRPLGBLT *p) +{ + const BITMAPINFO *src_bi, *mask_bi; + const BYTE *src_bits, *mask_bits; + XFORM xf, xform_dest; + EMRMASKBLT maskblt; + /* rect coords */ + POINT rect[3]; + /* parallelogram coords */ + POINT plg[3]; + double det; + + memcpy(plg, p->aptlDest, sizeof(plg)); + rect[0].x = p->xSrc; + rect[0].y = p->ySrc; + rect[1].x = p->xSrc + p->cxSrc; + rect[1].y = p->ySrc; + rect[2].x = p->xSrc; + rect[2].y = p->ySrc + p->cySrc; + /* calc XFORM matrix to transform hdcDest -> hdcSrc (parallelogram to rectangle) */ + /* determinant */ + det = rect[1].x*(rect[2].y - rect[0].y) - rect[2].x*(rect[1].y - rect[0].y) - rect[0].x*(rect[2].y - rect[1].y); + + if (fabs(det) < 1e-5) + return TRUE; + + TRACE("%ld,%ld,%ldx%ld -> %ld,%ld,%ld,%ld,%ld,%ld\n", p->xSrc, p->ySrc, p->cxSrc, p->cySrc, + plg[0].x, plg[0].y, plg[1].x, plg[1].y, plg[2].x, plg[2].y); + + /* X components */ + xf.eM11 = (plg[1].x*(rect[2].y - rect[0].y) - plg[2].x*(rect[1].y - rect[0].y) - plg[0].x*(rect[2].y - rect[1].y)) / det; + xf.eM21 = (rect[1].x*(plg[2].x - plg[0].x) - rect[2].x*(plg[1].x - plg[0].x) - rect[0].x*(plg[2].x - plg[1].x)) / det; + xf.eDx = (rect[0].x*(rect[1].y*plg[2].x - rect[2].y*plg[1].x) - + rect[1].x*(rect[0].y*plg[2].x - rect[2].y*plg[0].x) + + rect[2].x*(rect[0].y*plg[1].x - rect[1].y*plg[0].x) + ) / det; + + /* Y components */ + xf.eM12 = (plg[1].y*(rect[2].y - rect[0].y) - plg[2].y*(rect[1].y - rect[0].y) - plg[0].y*(rect[2].y - rect[1].y)) / det; + xf.eM22 = (rect[1].x*(plg[2].y - plg[0].y) - rect[2].x*(plg[1].y - plg[0].y) - rect[0].x*(plg[2].y - plg[1].y)) / det; + xf.eDy = (rect[0].x*(rect[1].y*plg[2].y - rect[2].y*plg[1].y) - + rect[1].x*(rect[0].y*plg[2].y - rect[2].y*plg[0].y) + + rect[2].x*(rect[0].y*plg[1].y - rect[1].y*plg[0].y) + ) / det; + + combine_transform(&xf, &xf, &p->xformSrc); + + GetTransform(dev->hdc, 0x203, &xform_dest); + SetWorldTransform(dev->hdc, &xf); + /* now destination and source DCs use same coords */ + maskblt.rclBounds = p->rclBounds; + maskblt.xDest = p->xSrc; + maskblt.yDest = p->ySrc; + maskblt.cxDest = p->cxSrc; + maskblt.cyDest = p->cySrc; + maskblt.dwRop = SRCCOPY; + maskblt.xSrc = p->xSrc; + maskblt.ySrc = p->ySrc; + maskblt.xformSrc = p->xformSrc; + maskblt.crBkColorSrc = p->crBkColorSrc; + maskblt.iUsageSrc = p->iUsageSrc; + maskblt.offBmiSrc = 0; + maskblt.cbBmiSrc = p->cbBmiSrc; + maskblt.offBitsSrc = 0; + maskblt.cbBitsSrc = p->cbBitsSrc; + maskblt.xMask = p->xMask; + maskblt.yMask = p->yMask; + maskblt.iUsageMask = p->iUsageMask; + maskblt.offBmiMask = 0; + maskblt.cbBmiMask = p->cbBmiMask; + maskblt.offBitsMask = 0; + maskblt.cbBitsMask = p->cbBitsMask; + src_bi = (const BITMAPINFO *)((BYTE *)p + p->offBmiSrc); + src_bits = (BYTE *)p + p->offBitsSrc; + mask_bi = (const BITMAPINFO *)((BYTE *)p + p->offBmiMask); + mask_bits = (BYTE *)p + p->offBitsMask; + mask_blt(dev, &maskblt, src_bi, src_bits, mask_bi, mask_bits); + SetWorldTransform(dev->hdc, &xform_dest); + return TRUE; +} + static int WINAPI hmf_proc(HDC hdc, HANDLETABLE *htable, const ENHMETARECORD *rec, int n, LPARAM arg) { @@ -802,6 +899,12 @@ static int WINAPI hmf_proc(HDC hdc, HANDLETABLE *htable,
return mask_blt(&data->pdev->dev, p, src_bi, src_bits, mask_bi, mask_bits); } + case EMR_PLGBLT: + { + const EMRPLGBLT *p = (const EMRPLGBLT *)rec; + + return plg_blt(&data->pdev->dev, p); + } case EMR_POLYBEZIER16: { const EMRPOLYBEZIER16 *p = (const EMRPOLYBEZIER16 *)rec;