Improve accuracy of destination coordinates in generic StretchBlit() implementation

It's not possible to map the scaled integer coordinates to the exact
destination location. The inaccuracy can be (mostly) avoided by shifting
the DC origin instead. Also fixes handling of non-zero logical origin.

See #18129
This commit is contained in:
Paul Cornett
2018-05-05 11:45:54 -07:00
parent 2e8516c5fe
commit 41a920cf72

View File

@@ -581,15 +581,34 @@ wxDCImpl::DoStretchBlit(wxCoord xdest, wxCoord ydest,
double xscale = (double)srcWidth/dstWidth,
yscale = (double)srcHeight/dstHeight;
// Shift origin to avoid imprecision of integer destination coordinates
const int deviceOriginX = m_deviceOriginX;
const int deviceOriginY = m_deviceOriginY;
const int deviceLocalOriginX = m_deviceLocalOriginX;
const int deviceLocalOriginY = m_deviceLocalOriginY;
const int logicalOriginX = m_logicalOriginX;
const int logicalOriginY = m_logicalOriginY;
m_deviceOriginX = LogicalToDeviceX(xdest);
m_deviceOriginY = LogicalToDeviceY(ydest);
m_deviceLocalOriginX = 0;
m_deviceLocalOriginY = 0;
m_logicalOriginX = 0;
m_logicalOriginY = 0;
double xscaleOld, yscaleOld;
GetUserScale(&xscaleOld, &yscaleOld);
SetUserScale(xscaleOld/xscale, yscaleOld/yscale);
bool rc = DoBlit(wxCoord(xdest*xscale), wxCoord(ydest*yscale),
wxCoord(dstWidth*xscale), wxCoord(dstHeight*yscale),
bool rc = DoBlit(0, 0, srcWidth, srcHeight,
source,
xsrc, ysrc, rop, useMask, xsrcMask, ysrcMask);
m_deviceOriginX = deviceOriginX;
m_deviceOriginY = deviceOriginY;
m_deviceLocalOriginX = deviceLocalOriginX;
m_deviceLocalOriginY = deviceLocalOriginY;
m_logicalOriginX = logicalOriginX;
m_logicalOriginY = logicalOriginY;
SetUserScale(xscaleOld, yscaleOld);
return rc;