BOOL nulldrv_ModifyWorldTransform( PHYSDEV dev, const XFORM *xform, DWORD mode ) { DC *dc = get_nulldrv_dc( dev ); switch (mode) { case MWT_IDENTITY: dc->xformWorld2Wnd.eM11 = 1.0f; dc->xformWorld2Wnd.eM12 = 0.0f; dc->xformWorld2Wnd.eM21 = 0.0f; dc->xformWorld2Wnd.eM22 = 1.0f; dc->xformWorld2Wnd.eDx = 0.0f; dc->xformWorld2Wnd.eDy = 0.0f; break; case MWT_LEFTMULTIPLY: CombineTransform( &dc->xformWorld2Wnd, xform, &dc->xformWorld2Wnd ); break; case MWT_RIGHTMULTIPLY: CombineTransform( &dc->xformWorld2Wnd, &dc->xformWorld2Wnd, xform ); break; default: return FALSE; } DC_UpdateXforms( dc ); return TRUE; }
void Test_CombineTransform() { XFORM xform1, xform2, xform3; /* Test NULL paramters */ set_xform(&xform1, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0); set_xform(&xform2, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0); SetLastError(ERROR_SUCCESS); ok_int(CombineTransform(&xform3, &xform1, NULL), 0); ok_int(CombineTransform(&xform3, NULL, &xform2), 0); ok_int(CombineTransform(NULL, &xform1, &xform2), 0); ok_int(GetLastError(), ERROR_SUCCESS); /* 2 zero matrices */ set_xform(&xform1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); set_xform(&xform2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); SetLastError(ERROR_SUCCESS); ok_int(CombineTransform(&xform3, &xform1, &xform2), 1); ok_xform(xform3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); ok_int(GetLastError(), ERROR_SUCCESS); /* 2 Identity matrices */ set_xform(&xform1, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0); set_xform(&xform2, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0); SetLastError(ERROR_SUCCESS); ok_int(CombineTransform(&xform3, &xform1, &xform2), 1); ok_xform(xform3, 1.0, 0., 0., 1.0, 0., 0.); ok_int(GetLastError(), ERROR_SUCCESS); /* 2 Identity matrices with offsets */ set_xform(&xform1, 1.0, 0.0, 0.0, 1.0, 20.0, -100.0); set_xform(&xform2, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0); ok_int(CombineTransform(&xform3, &xform1, &xform2), 1); ok_xform(xform3, 1.0, 0., 0., 1.0, 20.0, -100.0); xform2.eDx = -60.0; xform2.eDy = -20; ok_int(CombineTransform(&xform3, &xform1, &xform2), 1); ok_flt(xform3.eDx, -40.0); ok_flt(xform3.eDy, -120.0); /* add some stretching */ xform2.eM11 = 2; xform2.eM22 = 4; ok_int(CombineTransform(&xform3, &xform1, &xform2), 1); ok_xform(xform3, 2.0, 0., 0., 4.0, -20.0, -420.0); /* add some more stretching */ xform1.eM11 = -2.5; xform1.eM22 = 0.5; ok_int(CombineTransform(&xform3, &xform1, &xform2), 1); ok_xform(xform3, -5.0, 0., 0., 2.0, -20.0, -420.0); xform1.eM12 = 2.0; xform1.eM21 = -0.5; ok_int(CombineTransform(&xform3, &xform1, &xform2), 1); ok_xform(xform3, -5.0, 8.0, -1.0, 2.0, -20.0, -420.0); xform2.eM12 = 4.0; xform2.eM21 = 6.5; ok_int(CombineTransform(&xform3, &xform1, &xform2), 1); ok_xform(xform3, 8.0, -2.0, 2.25, 0.0, -670.0, -340.0); set_xform(&xform1, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0); set_xform(&xform2, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0); set_xform(&xform3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); xform1.eDx = (FLOAT)4294967167.999999761; ok(xform1.eDx == 4294967040.0, "float rounding error.\n"); ok_int(CombineTransform(&xform3, &xform1, &xform2), 1); ok_xform(xform3, 1.0, 0.0, 0.0, 1.0, 4294967040.0, 0.0); set_xform(&xform3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); xform1.eDx = (FLOAT)4294967167.999999762; ok(xform1.eDx == 4294967296.0, "float rounding error.\n"); ok_int(CombineTransform(&xform3, &xform1, &xform2), 0); ok_int(GetLastError(), ERROR_SUCCESS); ok_xform(xform3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); xform1.eDx = (FLOAT)-4294967167.999999761; ok(xform1.eDx == -4294967040.0, "float rounding error.\n"); ok_int(CombineTransform(&xform3, &xform1, &xform2), 1); xform1.eDx = (FLOAT)-4294967167.999999762; ok(xform1.eDx == -4294967296.0, "float rounding error.\n"); ok_int(CombineTransform(&xform3, &xform1, &xform2), 0); ok_int(GetLastError(), ERROR_SUCCESS); xform1.eDx = 0; xform1.eDy = (FLOAT)4294967167.999999761; ok(xform1.eDy == 4294967040.0, "float rounding error.\n"); ok_int(CombineTransform(&xform3, &xform1, &xform2), 1); xform2.eDy = 1; ok_int(CombineTransform(&xform3, &xform1, &xform2), 1); ok_flt(xform3.eDy, 4294967040.0); xform1.eDy = (FLOAT)4294967167.999999762; ok(xform1.eDy == 4294967296.0, "float rounding error.\n"); ok_int(CombineTransform(&xform3, &xform1, &xform2), 0); ok_int(GetLastError(), ERROR_SUCCESS); xform1.eDy = (FLOAT)-4294967167.999999761; ok(xform1.eDy == -4294967040.0, "float rounding error.\n"); ok_int(CombineTransform(&xform3, &xform1, &xform2), 1); xform1.eDy = (FLOAT)-4294967167.999999762; ok(xform1.eDy == -4294967296.0, "float rounding error.\n"); ok_int(CombineTransform(&xform3, &xform1, &xform2), 0); ok_int(GetLastError(), ERROR_SUCCESS); xform2.eDy = 10000; ok_int(CombineTransform(&xform3, &xform1, &xform2), 1); set_xform(&xform1, 1000.0, 0.0, 0.0, 0.0, 0.0, 0.0); xform1.eDx = (FLOAT)-4294967167.999999762; xform2.eM11 = 1000.0; ok_int(CombineTransform(&xform3, &xform1, &xform2), 0); ok_int(GetLastError(), ERROR_SUCCESS); xform1.eDx = 100000.0; xform2.eM11 = 100000.0; ok_int(CombineTransform(&xform3, &xform1, &xform2), 0); ok_int(GetLastError(), ERROR_SUCCESS); /* Some undefined values */ set_xform(&xform1, geIND, 0.0, 0.0, geINF, 0.0, 0.0); xform2 = xform1; SetLastError(ERROR_SUCCESS); ok_int(CombineTransform(&xform3, &xform1, &xform2), 1); ok_xform(xform3, geIND, 0.0, 0.0, geINF, 0.0, 0.0); ok_int(GetLastError(), ERROR_SUCCESS); set_xform(&xform2, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0); ok_int(CombineTransform(&xform3, &xform1, &xform2), 1); ok_xform(xform3, geIND, geIND, geINF, geINF, 0.0, 0.0); ok_int(GetLastError(), ERROR_SUCCESS); set_xform(&xform1, (FLOAT)18446743500000000000.0, 0.0, 1.0, 0.0, 0.0, 0.0); xform2 = xform1; ok_int(CombineTransform(&xform3, &xform1, &xform2), 1); ok_flt(xform3.eM11, 340282326356119260000000000000000000000.0); xform1.eM11 = (FLOAT)18446745000000000000.0; ok_int(CombineTransform(&xform3, &xform1, &xform2), 1); ok_flt(xform3.eM11, 340282346638528860000000000000000000000.0); xform1.eM11 = (FLOAT)18446746000000000000.0; ok_int(CombineTransform(&xform3, &xform1, &xform2), 1); ok_long(*(DWORD*)&xform3.eM11, 0x7f800000); /* zero matrix + 1 invalid */ set_xform(&xform1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); set_xform(&xform2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); *(DWORD*)&xform2.eM22 = 0x7f800000; // (0.0F/0.0F) ok_int(CombineTransform(&xform3, &xform1, &xform2), 1); ok_xform(xform3, 0.0, 0.0, 0.0, geIND, 0.0, 0.0); /* zero matrix + 1 invalid */ xform2 = xform1; *(DWORD*)&xform2.eM12 = 0x7f800000; // (0.0F/0.0F) ok_int(CombineTransform(&xform3, &xform1, &xform2), 1); ok_xform(xform3, 0.0, geIND, 0.0, geIND, 0.0, 0.0); /* Some undefined values */ set_xform(&xform1, 0.0, geIND, 0.0, 0.0, 0.0, 0.0); set_xform(&xform2, geIND, 0.0, 0.0, geINF, 0.0, 0.0); ok_int(CombineTransform(&xform3, &xform1, &xform2), 1); ok_xform(xform3, geIND, geIND, geIND, geIND, 0.0, 0.0); }
void Test_CombineTransform_Inval(float eInval, float eOut) { XFORM xform1, xform2, xform3; /* zero matrix / M11 invalid */ set_xform(&xform1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); set_xform(&xform2, eInval, 0.0, 0.0, 0.0, 0.0, 0.0); ok_int(CombineTransform(&xform3, &xform1, &xform2), 1); ok_xform(xform3, eOut, 0.0, 0.0, 0.0, 0.0, 0.0); // -> M21 ok_int(CombineTransform(&xform3, &xform2, &xform1), 1); ok_xform(xform3, eOut, 0.0, 0.0, 0.0, 0.0, 0.0); // -> M12 /* zero matrix / M12 invalid */ set_xform(&xform1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); set_xform(&xform2, 0.0, eInval, 0.0, 0.0, 0.0, 0.0); ok_int(CombineTransform(&xform3, &xform1, &xform2), 1); ok_xform(xform3, 0.0, eOut, 0.0, eOut, 0.0, 0.0); ok_int(CombineTransform(&xform3, &xform2, &xform1), 1); ok_xform(xform3, eOut, eOut, 0.0, 0.0, 0.0, 0.0); /* zero matrix / M21 invalid */ set_xform(&xform1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); set_xform(&xform2, 0.0, 0.0, eInval, 0.0, 0.0, 0.0); ok_int(CombineTransform(&xform3, &xform1, &xform2), 1); ok_xform(xform3, eOut, 0.0, eOut, 0.0, 0.0, 0.0); ok_int(CombineTransform(&xform3, &xform2, &xform1), 1); ok_xform(xform3, 0.0, 0.0, eOut, eOut, 0.0, 0.0); /* zero matrix / M22 invalid */ set_xform(&xform1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); set_xform(&xform2, 0.0, 0.0, 0.0, eInval, 0.0, 0.0); ok_int(CombineTransform(&xform3, &xform1, &xform2), 1); ok_xform(xform3, 0.0, 0.0, 0.0, eOut, 0.0, 0.0); // -> M12 ok_int(CombineTransform(&xform3, &xform2, &xform1), 1); ok_xform(xform3, 0.0, 0.0, 0.0, eOut, 0.0, 0.0); // -> M21 /* zero matrix / M11,M12 invalid */ set_xform(&xform1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); set_xform(&xform2, eInval, eInval, 0.0, 0.0, 0.0, 0.0); ok_int(CombineTransform(&xform3, &xform1, &xform2), 1); ok_xform(xform3, eOut, eOut, eOut, eOut, 0.0, 0.0); ok_int(CombineTransform(&xform3, &xform2, &xform1), 1); ok_xform(xform3, eOut, eOut, 0.0, 0.0, 0.0, 0.0); /* zero matrix / M11,M21 invalid */ set_xform(&xform1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); set_xform(&xform2, eInval, 0.0, eInval, 0.0, 0.0, 0.0); ok_int(CombineTransform(&xform3, &xform1, &xform2), 1); ok_xform(xform3, eOut, 0.0, eOut, 0.0, 0.0, 0.0); ok_int(CombineTransform(&xform3, &xform2, &xform1), 1); ok_xform(xform3, eOut, eOut, eOut, eOut, 0.0, 0.0); /* zero matrix / M11,M22 invalid */ set_xform(&xform1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); set_xform(&xform2, eInval, 0.0, 0.0, eInval, 0.0, 0.0); ok_int(CombineTransform(&xform3, &xform1, &xform2), 1); ok_xform(xform3, eOut, 0.0, 0.0, eOut, 0.0, 0.0); // -> M12, M21 ok_int(CombineTransform(&xform3, &xform2, &xform1), 1); ok_xform(xform3, eOut, 0.0, 0.0, eOut, 0.0, 0.0); /* zero matrix / M12,M21 invalid */ set_xform(&xform1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); set_xform(&xform2, 0.0, eInval, eInval, 0.0, 0.0, 0.0); ok_int(CombineTransform(&xform3, &xform1, &xform2), 1); ok_xform(xform3, eOut, eOut, eOut, eOut, 0.0, 0.0); ok_int(CombineTransform(&xform3, &xform2, &xform1), 1); ok_xform(xform3, eOut, eOut, eOut, eOut, 0.0, 0.0); }
/********************************************************************* * PlgBlt [GDI32.@] * */ BOOL WINAPI PlgBlt( HDC hdcDest, const POINT *lpPoint, HDC hdcSrc, INT nXSrc, INT nYSrc, INT nWidth, INT nHeight, HBITMAP hbmMask, INT xMask, INT yMask) { int oldgMode; /* parallelogram coords */ POINT plg[3]; /* rect coords */ POINT rect[3]; XFORM xf; XFORM SrcXf; XFORM oldDestXf; double det; /* save actual mode, set GM_ADVANCED */ oldgMode = SetGraphicsMode(hdcDest,GM_ADVANCED); if (oldgMode == 0) return FALSE; memcpy(plg,lpPoint,sizeof(POINT)*3); rect[0].x = nXSrc; rect[0].y = nYSrc; rect[1].x = nXSrc + nWidth; rect[1].y = nYSrc; rect[2].x = nXSrc; rect[2].y = nYSrc + nHeight; /* 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) { SetGraphicsMode(hdcDest,oldgMode); return FALSE; } TRACE("hdcSrc=%p %d,%d,%dx%d -> hdcDest=%p %d,%d,%d,%d,%d,%d\n", hdcSrc, nXSrc, nYSrc, nWidth, nHeight, hdcDest, 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; GetWorldTransform(hdcSrc,&SrcXf); CombineTransform(&xf,&xf,&SrcXf); /* save actual dest transform */ GetWorldTransform(hdcDest,&oldDestXf); SetWorldTransform(hdcDest,&xf); /* now destination and source DCs use same coords */ MaskBlt(hdcDest,nXSrc,nYSrc,nWidth,nHeight, hdcSrc, nXSrc,nYSrc, hbmMask,xMask,yMask, SRCCOPY); /* restore dest DC */ SetWorldTransform(hdcDest,&oldDestXf); SetGraphicsMode(hdcDest,oldgMode); return TRUE; }