RESOLVED FIXED 81057
Fix rounding and usage of LayoutUnits in RenderBoxModelObject
https://bugs.webkit.org/show_bug.cgi?id=81057
Summary Fix rounding and usage of LayoutUnits in RenderBoxModelObject
Emil A Eklund
Reported 2012-03-13 16:41:20 PDT
LayoutUnits and ints are currently used interchangeably in RenderBoxModelObject, specifically in background and border image calculations.
Attachments
Patch (10.16 KB, patch)
2012-03-13 16:50 PDT, Emil A Eklund
no flags
Patch (10.41 KB, patch)
2012-03-15 14:57 PDT, Emil A Eklund
no flags
Emil A Eklund
Comment 1 2012-03-13 16:50:13 PDT
Emil A Eklund
Comment 2 2012-03-14 14:55:10 PDT
Ping?
Julien Chaffraix
Comment 3 2012-03-14 20:30:23 PDT
Comment on attachment 131750 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=131750&action=review > Source/WebCore/rendering/RenderBoxModelObject.cpp:1084 > + IntRect alignedRect = pixelSnappedIntRect(paintRect); It should be named alignedPaintRect. Maybe even better: snappedPaintRect? > Source/WebCore/rendering/RenderBoxModelObject.cpp:1127 > + positioningAreaSize = IntSize(alignedRect.width() - left - right, alignedRect.height() - top - bottom); Is it possible that we would want to snap after doing the subtractions as all the directions are LayoutUnits? Or is it better to be coherent with the width / height snapping above? > Source/WebCore/rendering/RenderBoxModelObject.cpp:1142 > + geometry.setPhaseX(geometry.tileSize().width() ? layoutMod(geometry.tileSize().width() - (xPosition + left), geometry.tileSize().width()) : zeroLayoutUnit); BackgroundImageGeometry::setPhaseX takes an |int| not a LayoutUnit. AFAICT we want to keep the integer there as we are manipulating a replaced element. Is this really what we want to do here? > Source/WebCore/rendering/RenderBoxModelObject.cpp:1148 > + geometry.setPhaseY(geometry.tileSize().height() ? layoutMod(geometry.tileSize().height() - (yPosition + top), geometry.tileSize().height()) : zeroLayoutUnit); Ditto.
Emil A Eklund
Comment 4 2012-03-15 14:57:50 PDT
Emil A Eklund
Comment 5 2012-03-15 15:00:58 PDT
Thanks for your thorough review Julien! (In reply to comment #3) > (From update of attachment 131750 [details]) > View in context: https://bugs.webkit.org/attachment.cgi?id=131750&action=review > > > Source/WebCore/rendering/RenderBoxModelObject.cpp:1084 > > + IntRect alignedRect = pixelSnappedIntRect(paintRect); > > It should be named alignedPaintRect. Maybe even better: snappedPaintRect? Renamed to snappedPaintRect > > > Source/WebCore/rendering/RenderBoxModelObject.cpp:1127 > > + positioningAreaSize = IntSize(alignedRect.width() - left - right, alignedRect.height() - top - bottom); > > Is it possible that we would want to snap after doing the subtractions as all the directions are LayoutUnits? Or is it better to be coherent with the width / height snapping above? Good idea, the padding values could have subpixel precision and would be floored otherwise. Changed to snap after subtracting the padding/border. > > > Source/WebCore/rendering/RenderBoxModelObject.cpp:1142 > > + geometry.setPhaseX(geometry.tileSize().width() ? layoutMod(geometry.tileSize().width() - (xPosition + left), geometry.tileSize().width()) : zeroLayoutUnit); > > BackgroundImageGeometry::setPhaseX takes an |int| not a LayoutUnit. AFAICT we want to keep the integer there as we are manipulating a replaced element. Is this really what we want to do here? Changed this to use integers throughout.
Julien Chaffraix
Comment 6 2012-03-15 16:06:06 PDT
Comment on attachment 132126 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=132126&action=review > Source/WebCore/rendering/RenderBoxModelObject.cpp:1144 > - geometry.setPhaseX(geometry.tileSize().width() ? layoutMod(geometry.tileSize().width() - (xPosition + left), geometry.tileSize().width()) : LayoutUnit(0)); > + geometry.setPhaseX(geometry.tileSize().width() ? geometry.tileSize().width() - (xPosition + left) % geometry.tileSize().width() : 0); Those 2 lines are not equivalent due to % being of higher priority that -. It's sad that our tests are not catching that. Extra points if you can find a test to catch that regression. > Source/WebCore/rendering/RenderBoxModelObject.cpp:1150 > + geometry.setPhaseY(geometry.tileSize().height() ? geometry.tileSize().height() - (yPosition + top) % geometry.tileSize().height() : 0); Ditto.
Emil A Eklund
Comment 7 2012-03-15 17:03:07 PDT
(In reply to comment #6) > (From update of attachment 132126 [details]) > View in context: https://bugs.webkit.org/attachment.cgi?id=132126&action=review > > > Source/WebCore/rendering/RenderBoxModelObject.cpp:1144 > > - geometry.setPhaseX(geometry.tileSize().width() ? layoutMod(geometry.tileSize().width() - (xPosition + left), geometry.tileSize().width()) : LayoutUnit(0)); > > + geometry.setPhaseX(geometry.tileSize().width() ? geometry.tileSize().width() - (xPosition + left) % geometry.tileSize().width() : 0); > > Those 2 lines are not equivalent due to % being of higher priority that -. It's sad that our tests are not catching that. Extra points if you can find a test to catch that regression. > > > Source/WebCore/rendering/RenderBoxModelObject.cpp:1150 > > + geometry.setPhaseY(geometry.tileSize().height() ? geometry.tileSize().height() - (yPosition + top) % geometry.tileSize().height() : 0); > > Ditto. Good catch but this actually restores the code to the exact same state as it was before we changed it to use LayoutUnits. Which means that this been broken for the last seven months (!). http://trac.webkit.org/browser/trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp?rev=92529#L932
Levi Weintraub
Comment 8 2012-03-15 17:04:27 PDT
Comment on attachment 132126 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=132126&action=review >>> Source/WebCore/rendering/RenderBoxModelObject.cpp:1144 >>> + geometry.setPhaseX(geometry.tileSize().width() ? geometry.tileSize().width() - (xPosition + left) % geometry.tileSize().width() : 0); >> >> Those 2 lines are not equivalent due to % being of higher priority that -. It's sad that our tests are not catching that. Extra points if you can find a test to catch that regression. > > Good catch but this actually restores the code to the exact same state as it was before we changed it to use LayoutUnits. Which means that this been broken for the last seven months (!). > > http://trac.webkit.org/browser/trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp?rev=92529#L932 This seems difficult to believe...!
Emil A Eklund
Comment 9 2012-03-15 22:52:04 PDT
Having looked into this in detail it turns out to be quite interesting, the way this is computed means that the two calculations will produce different numbers in cases where the background offset is larger than the size of the image. This isn't very common in the wild but is certainly valid. However it turns out that this doesn't effect the visual representation at all as it will be off by the full width (or height) of the image, resulting in the same offset and thus the same rendering.
Julien Chaffraix
Comment 10 2012-03-16 12:47:20 PDT
Comment on attachment 132126 [details] Patch > However it turns out that this doesn't effect the visual representation at all as it will be off by the full width (or height) of the image, resulting in the same offset and thus the same rendering. OK... Could you file about a bug about this craziness / the fact that calculateBackgroundImageGeometry code should definitely be made less error-prone?
Emil A Eklund
Comment 11 2012-03-16 13:35:11 PDT
Filed bug 81396 to track the calculateBackgroundImageGeometry crazies.
WebKit Review Bot
Comment 12 2012-03-16 14:30:26 PDT
Comment on attachment 132126 [details] Patch Clearing flags on attachment: 132126 Committed r111066: <http://trac.webkit.org/changeset/111066>
WebKit Review Bot
Comment 13 2012-03-16 14:30:32 PDT
All reviewed patches have been landed. Closing bug.
Note You need to log in before you can comment on or make changes to this bug.