FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect) { // It is not enough just to round to pixels in device space. The rotation part of the // affine transform matrix to device space can mess with this conversion if we have a // rotating image like the hands of the world clock widget. We just need the scale, so // we get the affine transform matrix and extract the scale. CGAffineTransform deviceMatrix = CGContextGetUserSpaceToDeviceSpaceTransform(platformContext()); float deviceScaleX = sqrtf(deviceMatrix.a * deviceMatrix.a + deviceMatrix.b * deviceMatrix.b); float deviceScaleY = sqrtf(deviceMatrix.c * deviceMatrix.c + deviceMatrix.d * deviceMatrix.d); CGPoint deviceOrigin = CGPointMake(rect.x() * deviceScaleX, rect.y() * deviceScaleY); CGPoint deviceLowerRight = CGPointMake((rect.x() + rect.width()) * deviceScaleX, (rect.y() + rect.height()) * deviceScaleY); deviceOrigin.x = roundf(deviceOrigin.x); deviceOrigin.y = roundf(deviceOrigin.y); deviceLowerRight.x = roundf(deviceLowerRight.x); deviceLowerRight.y = roundf(deviceLowerRight.y); // Don't let the height or width round to 0 unless either was originally 0 if (deviceOrigin.y == deviceLowerRight.y && rect.height() != 0) deviceLowerRight.y += 1; if (deviceOrigin.x == deviceLowerRight.x && rect.width() != 0) deviceLowerRight.x += 1; FloatPoint roundedOrigin = FloatPoint(deviceOrigin.x / deviceScaleX, deviceOrigin.y / deviceScaleY); FloatPoint roundedLowerRight = FloatPoint(deviceLowerRight.x / deviceScaleX, deviceLowerRight.y / deviceScaleY); return FloatRect(roundedOrigin, roundedLowerRight - roundedOrigin); }
oop CGContextGetUserSpaceToDeviceSpaceTransform_wrap(CGContextRef c) { CGAffineTransform ctm = CGContextGetUserSpaceToDeviceSpaceTransform(c); objVectorOop r = Memory->objVectorObj->cloneSize(6); r->obj_at_put(0, as_floatOop(ctm.a ), false); r->obj_at_put(1, as_floatOop(ctm.b ), false); r->obj_at_put(2, as_floatOop(ctm.c ), false); r->obj_at_put(3, as_floatOop(ctm.d ), false); r->obj_at_put(4, as_floatOop(ctm.tx), false); r->obj_at_put(5, as_floatOop(ctm.ty), false); return r; }