Changeset 15470

Show
Ignore:
Timestamp:
07/16/06 17:25:56 (2 years ago)
Author:
bdakin
Message:

Reviewed by Maciej.

Fix for <rdar://problem/4616595> REGRESSION: Problems with world
clock widget clock hand motion on 9A211 + 4604574

The second hand on the widget was jiggling because the rotation was
messing up the use of the affine transformation matrix while
rounding to pixel boundaries in device space. We are mainly
concerned with rounding to pixel boundaries with the scale in mind,
so this patch extracts the scale to device space from the matrix,
and rounds to pixel boundaries using only the scale. This doesn't
seem like it is a perfect solution, but it definitely solves the
immediate problem. We will probably need to re-address what should
happen to avoid pixel cracks with rotations at non-integral scale
factors.

  • platform/cg/GraphicsContextCG.cpp: (WebCore::GraphicsContext::roundToDevicePixels):
Location:
trunk/WebCore
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r15461 r15470  
     12006-07-16  Beth Dakin  <bdakin@apple.com> 
     2 
     3        Reviewed by Maciej. 
     4 
     5        Fix for <rdar://problem/4616595> REGRESSION: Problems with world  
     6        clock widget clock hand motion on 9A211 + 4604574 
     7 
     8        The second hand on the widget was jiggling because the rotation was  
     9        messing up the use of the affine transformation matrix while  
     10        rounding to pixel boundaries in device space. We are mainly  
     11        concerned with rounding to pixel boundaries with the scale in mind,  
     12        so this patch extracts the scale to device space from the matrix,  
     13        and rounds to pixel boundaries using only the scale. This doesn't  
     14        seem like it is a perfect solution, but it definitely solves the  
     15        immediate problem. We will probably need to re-address what should  
     16        happen to avoid pixel cracks with rotations at non-integral scale  
     17        factors.  
     18 
     19        * platform/cg/GraphicsContextCG.cpp: 
     20        (WebCore::GraphicsContext::roundToDevicePixels): 
     21 
    1222006-07-15  Darin Adler  <darin@apple.com> 
    223 
  • trunk/WebCore/platform/cg/GraphicsContextCG.cpp

    r14918 r15470  
    637637FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect) 
    638638{ 
    639     // It's important to separately transform the two corners, as transforming the whole rect 
    640     // will grab bounding boxes, and so will enlarge the rect when there is any rotation or skew 
    641     // in the current transform 
    642     CGPoint deviceOrigin = CGContextConvertPointToDeviceSpace(platformContext(), rect.location()); 
    643     CGPoint deviceLowerRight = CGContextConvertPointToDeviceSpace(platformContext(), rect.location() + rect.size()); 
     639    // It is not enough just to round to pixels in device space. The rotation part of the  
     640    // affine transform matrix to device space can mess with this conversion if we have a 
     641    // rotating image like the hands of the world clock widget. We just need the scale, so  
     642    // we get the affine transform matrix and extract the scale. 
     643    CGAffineTransform deviceMatrix = CGContextGetUserSpaceToDeviceSpaceTransform(platformContext()); 
     644    float deviceScaleX = sqrtf(deviceMatrix.a * deviceMatrix.a + deviceMatrix.b * deviceMatrix.b); 
     645    float deviceScaleY = sqrtf(deviceMatrix.c * deviceMatrix.c + deviceMatrix.d * deviceMatrix.d); 
     646 
     647    CGPoint deviceOrigin = CGPointMake(rect.x() * deviceScaleX, rect.y() * deviceScaleY); 
     648    CGPoint deviceLowerRight = CGPointMake((rect.x() + rect.width()) * deviceScaleX, 
     649        (rect.y() + rect.height()) * deviceScaleY); 
    644650 
    645651    deviceOrigin.x = roundf(deviceOrigin.x); 
     
    653659    if (deviceOrigin.x == deviceLowerRight.x && rect.width() != 0) 
    654660        deviceLowerRight.x += 1; 
    655      
    656     FloatPoint roundedOrigin = CGContextConvertPointToUserSpace(platformContext(), deviceOrigin); 
    657     FloatPoint roundedLowerRight = CGContextConvertPointToUserSpace(platformContext(), deviceLowerRight); 
    658  
     661 
     662    FloatPoint roundedOrigin = FloatPoint(deviceOrigin.x / deviceScaleX, deviceOrigin.y / deviceScaleY); 
     663    FloatPoint roundedLowerRight = FloatPoint(deviceLowerRight.x / deviceScaleX, deviceLowerRight.y / deviceScaleY); 
    659664    return FloatRect(roundedOrigin, roundedLowerRight - roundedOrigin); 
    660665}