Changeset 169309 in webkit


Ignore:
Timestamp:
May 24, 2014 7:50:42 AM (10 years ago)
Author:
Alan Bujtas
Message:

Subpixel rendering: Non-compositing transforms with subpixel coordinates paint to wrong position.
https://bugs.webkit.org/show_bug.cgi?id=133184
<rdar://problem/16745606>

Reviewed by Simon Fraser.

Snapping relative negative coordinate values should produce the same position as if they were
positive absolute coordinates.
When a child box gets positioned off of its containers towards top/left, its relative coordinates
become negative. Pixel snapping those negative values should produce the same
final painting position as if the child box was fixed positioned with positive coordinates.
Since halfway values always round away from zero, negative and positive halfway values
produce opposite rounding direction.
This patch ensures that negative halfway values round to the direction as if they were positive.

Source/WebCore:
Test: fast/layers/hidpi-floor-negative-coordinate-values-to-maintain-rounding-direction.html

  • platform/LayoutUnit.h:

(WebCore::roundToDevicePixel):

  • rendering/RenderLayer.cpp:

(WebCore::RenderLayer::paintLayerByApplyingTransform):

LayoutTests:

  • fast/layers/hidpi-floor-negative-coordinate-values-to-maintain-rounding-direction-expected.html: Added.
  • fast/layers/hidpi-floor-negative-coordinate-values-to-maintain-rounding-direction.html: Added.
Location:
trunk
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r169308 r169309  
     12014-05-24  Zalan Bujtas  <zalan@apple.com>
     2
     3        Subpixel rendering: Non-compositing transforms with subpixel coordinates paint to wrong position.
     4        https://bugs.webkit.org/show_bug.cgi?id=133184
     5        <rdar://problem/16745606>
     6
     7        Reviewed by Simon Fraser.
     8
     9        Snapping relative negative coordinate values should produce the same position as if they were
     10        positive absolute coordinates.
     11        When a child box gets positioned off of its containers towards top/left, its relative coordinates
     12        become negative. Pixel snapping those negative values should produce the same
     13        final painting position as if the child box was fixed positioned with positive coordinates.
     14        Since halfway values always round away from zero, negative and positive halfway values
     15        produce opposite rounding direction.
     16        This patch ensures that negative halfway values round to the direction as if they were positive. 
     17
     18        * fast/layers/hidpi-floor-negative-coordinate-values-to-maintain-rounding-direction-expected.html: Added.
     19        * fast/layers/hidpi-floor-negative-coordinate-values-to-maintain-rounding-direction.html: Added.
     20
    1212014-05-24  Frédéric Wang  <fred.wang@free.fr>
    222
  • trunk/Source/WebCore/ChangeLog

    r169305 r169309  
     12014-05-24  Zalan Bujtas  <zalan@apple.com>
     2
     3        Subpixel rendering: Non-compositing transforms with subpixel coordinates paint to wrong position.
     4        https://bugs.webkit.org/show_bug.cgi?id=133184
     5        <rdar://problem/16745606>
     6
     7        Reviewed by Simon Fraser.
     8
     9        Snapping relative negative coordinate values should produce the same position as if they were
     10        positive absolute coordinates.
     11        When a child box gets positioned off of its containers towards top/left, its relative coordinates
     12        become negative. Pixel snapping those negative values should produce the same
     13        final painting position as if the child box was fixed positioned with positive coordinates.
     14        Since halfway values always round away from zero, negative and positive halfway values
     15        produce opposite rounding direction.
     16        This patch ensures that negative halfway values round to the direction as if they were positive. 
     17
     18        Test: fast/layers/hidpi-floor-negative-coordinate-values-to-maintain-rounding-direction.html
     19
     20        * platform/LayoutUnit.h:
     21        (WebCore::roundToDevicePixel):
     22        * rendering/RenderLayer.cpp:
     23        (WebCore::RenderLayer::paintLayerByApplyingTransform):
     24
    1252014-05-24  Frédéric Wang  <fred.wang@free.fr>
    226
  • trunk/Source/WebCore/platform/LayoutUnit.h

    r168528 r169309  
    936936}
    937937
    938 inline float roundToDevicePixel(LayoutUnit value, float pixelSnappingFactor, bool needsDirectionalRounding = false)
    939 {
    940     return roundf(((value.rawValue() - (needsDirectionalRounding ? LayoutUnit::epsilon() / 2.0f : 0)) * pixelSnappingFactor) / kEffectiveFixedPointDenominator) / pixelSnappingFactor;
     938inline float roundToDevicePixel(LayoutUnit value, const float pixelSnappingFactor, bool needsDirectionalRounding = false)
     939{
     940    auto roundInternal = [&] (float valueToRound) { return roundf((valueToRound * pixelSnappingFactor) / kEffectiveFixedPointDenominator) / pixelSnappingFactor; };
     941
     942    float adjustedValue = value.rawValue() - (needsDirectionalRounding ? LayoutUnit::epsilon() / 2.0f : 0);
     943    if (adjustedValue >= 0)
     944        return roundInternal(adjustedValue);
     945
     946    // This adjusts directional rounding on negative halfway values. It produces the same direction for both negative and positive values.
     947    // It helps snapping relative negative coordinates to the same position as if they were positive absolute coordinates.
     948    float translateOrigin = fabsf(adjustedValue - LayoutUnit::fromPixel(1));
     949    return roundInternal(adjustedValue + (translateOrigin * kEffectiveFixedPointDenominator)) - translateOrigin;
    941950}
    942951
  • trunk/Source/WebCore/rendering/RenderLayer.cpp

    r169045 r169309  
    41364136    offsetFromParent.moveBy(translationOffset);
    41374137    TransformationMatrix transform(renderableTransform(paintingInfo.paintBehavior));
    4138     FloatPoint devicePixelFlooredOffsetFromParent = flooredForPainting(offsetFromParent, deviceScaleFactor);
     4138    FloatPoint devicePixelSnappedOffsetFromParent = roundedForPainting(offsetFromParent, deviceScaleFactor);
    41394139    // Translate the graphics context to the snapping position to avoid off-device-pixel positing.
    4140     transform.translateRight(devicePixelFlooredOffsetFromParent.x(), devicePixelFlooredOffsetFromParent.y());
     4140    transform.translateRight(devicePixelSnappedOffsetFromParent.x(), devicePixelSnappedOffsetFromParent.y());
    41414141    // We handle accumulated subpixels through nested layers here. Since the context gets translated to device pixels,
    41424142    // all we need to do is add the delta to the accumulated pixels coming from ancestor layers. With deep nesting of subpixel positioned
    41434143    // boxes, this could grow to a relatively large number, but the translateRight() balances it.
    4144     FloatSize delta = offsetFromParent - devicePixelFlooredOffsetFromParent;
     4144    FloatSize delta = offsetFromParent - devicePixelSnappedOffsetFromParent;
    41454145    LayoutSize adjustedSubPixelAccumulation = paintingInfo.subPixelAccumulation + LayoutSize(delta);
    41464146    // Apply the transform.
Note: See TracChangeset for help on using the changeset viewer.