Changeset 185916 in webkit


Ignore:
Timestamp:
Jun 24, 2015, 10:53:44 AM (10 years ago)
Author:
Alan Bujtas
Message:

Subpixel rendering: roundToDevicePixel() snaps to wrong value.
https://bugs.webkit.org/show_bug.cgi?id=146273
rdar://problem/18509840

Reviewed by Simon Fraser.

Due to the floating point approximate representation, we can't always produce
the correct snap value. This patch addresses the issue by removing redundant kFixedPointDenominator multiplication
and by changing the rounding in roundToDevicePixel() from float to double.

Source/WebCore:

API test is added.

  • platform/LayoutUnit.h:

(WebCore::roundToDevicePixel):

Tools:

  • TestWebKitAPI/Tests/WebCore/LayoutUnit.cpp:

(TestWebKitAPI::TEST):

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r185914 r185916  
     12015-06-24  Zalan Bujtas  <zalan@apple.com>
     2
     3        Subpixel rendering: roundToDevicePixel() snaps to wrong value.
     4        https://bugs.webkit.org/show_bug.cgi?id=146273
     5        rdar://problem/18509840
     6
     7        Reviewed by Simon Fraser.
     8
     9        Due to the floating point approximate representation, we can't always produce
     10        the correct snap value. This patch addresses the issue by removing redundant kFixedPointDenominator multiplication
     11        and by changing the rounding in roundToDevicePixel() from float to double.
     12
     13        API test is added.
     14
     15        * platform/LayoutUnit.h:
     16        (WebCore::roundToDevicePixel):
     17
    1182015-06-23  Matt Rajca  <mrajca@apple.com>
    219
  • trunk/Source/WebCore/platform/LayoutUnit.h

    r183169 r185916  
    875875inline float roundToDevicePixel(LayoutUnit value, const float pixelSnappingFactor, bool needsDirectionalRounding = false)
    876876{
    877     auto roundInternal = [&] (float valueToRound) { return roundf((valueToRound * pixelSnappingFactor) / kFixedPointDenominator) / pixelSnappingFactor; };
    878 
    879     float adjustedValue = value.rawValue() - (needsDirectionalRounding ? LayoutUnit::epsilon() / 2.0f : 0);
    880     if (adjustedValue >= 0)
    881         return roundInternal(adjustedValue);
     877    double valueToRound = value.toDouble();
     878    if (needsDirectionalRounding)
     879        valueToRound -= LayoutUnit::epsilon() / (2 * kFixedPointDenominator);
     880
     881    if (valueToRound >= 0)
     882        return round(valueToRound * pixelSnappingFactor) / pixelSnappingFactor;
    882883
    883884    // This adjusts directional rounding on negative halfway values. It produces the same direction for both negative and positive values.
     885    // Instead of rounding negative halfway cases away from zero, we translate them to positive values before rounding.
    884886    // It helps snapping relative negative coordinates to the same position as if they were positive absolute coordinates.
    885     float translateOrigin = fabsf(adjustedValue - LayoutUnit::fromPixel(1));
    886     return roundInternal(adjustedValue + (translateOrigin * kFixedPointDenominator)) - translateOrigin;
     887    unsigned translateOrigin = -value.rawValue();
     888    return (round((valueToRound + translateOrigin) * pixelSnappingFactor) / pixelSnappingFactor) - translateOrigin;
    887889}
    888890
  • trunk/Tools/ChangeLog

    r185915 r185916  
     12015-06-24  Zalan Bujtas  <zalan@apple.com>
     2
     3        Subpixel rendering: roundToDevicePixel() snaps to wrong value.
     4        https://bugs.webkit.org/show_bug.cgi?id=146273
     5        rdar://problem/18509840
     6
     7        Reviewed by Simon Fraser.
     8
     9        Due to the floating point approximate representation, we can't always produce
     10        the correct snap value. This patch addresses the issue by removing redundant kFixedPointDenominator multiplication
     11        and by changing the rounding in roundToDevicePixel() from float to double.
     12
     13        * TestWebKitAPI/Tests/WebCore/LayoutUnit.cpp:
     14        (TestWebKitAPI::TEST):
     15
    1162015-06-24  Brady Eidson  <beidson@apple.com>
    217
  • trunk/Tools/TestWebKitAPI/Tests/WebCore/LayoutUnit.cpp

    r177845 r185916  
    232232}
    233233
     234TEST(WebCoreLayoutUnit, LayoutUnitPixelSnapping)
     235{
     236    for (int i = -100000; i <= 100000; ++i) {
     237        ASSERT_EQ(roundToDevicePixel(LayoutUnit(i), 1), i);
     238        ASSERT_EQ(roundToDevicePixel(LayoutUnit(i), 2), i);
     239        ASSERT_EQ(roundToDevicePixel(LayoutUnit(i), 3), i);
     240    }
     241
     242    for (float i = -10000; i < 0; i = i + 0.5)
     243        ASSERT_FLOAT_EQ(roundToDevicePixel(LayoutUnit(i), 2), i);
     244
     245    for (float i = -10000.25; i < 0; i = i + 0.5)
     246        ASSERT_FLOAT_EQ(roundToDevicePixel(LayoutUnit(i), 2), i + 0.25);
     247}
    234248
    235249} // namespace TestWebKitAPI
Note: See TracChangeset for help on using the changeset viewer.