RESOLVED FIXED 129726
[CSS Shapes] inset does not properly clamp large corner radii
https://bugs.webkit.org/show_bug.cgi?id=129726
Summary [CSS Shapes] inset does not properly clamp large corner radii
Bem Jones-Bey
Reported 2014-03-04 20:59:27 PST
inset should clamp large corner radii as described in http://www.w3.org/TR/css3-background/#corner-overlap
Attachments
Patch (8.48 KB, patch)
2014-03-05 07:35 PST, Bem Jones-Bey
no flags
Patch (16.46 KB, patch)
2014-03-05 14:50 PST, Bem Jones-Bey
no flags
Patch (10.68 KB, patch)
2014-03-06 09:57 PST, Bem Jones-Bey
no flags
Patch (17.31 KB, patch)
2014-03-06 11:05 PST, Bem Jones-Bey
no flags
Patch (10.78 KB, patch)
2014-03-06 11:37 PST, Bem Jones-Bey
no flags
Bem Jones-Bey
Comment 1 2014-03-05 07:35:54 PST
Bem Jones-Bey
Comment 2 2014-03-05 07:44:20 PST
I did not add any tests for zero radii here because I ran into Bug 129739. I will add tests for that when I fix that.
Dirk Schulze
Comment 3 2014-03-05 11:10:34 PST
Comment on attachment 225882 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=225882&action=review > Source/WebCore/rendering/shapes/Shape.cpp:131 > + float topRadiiExtent = radii.topLeft().width() + radii.topRight().width(); > + float rightRadiiExtent = radii.topRight().height() + radii.bottomRight().height(); > + float bottomRadiiExtent = radii.bottomLeft().width() + radii.bottomRight().width(); > + float leftRadiiExtent = radii.topLeft().height() + radii.bottomLeft().height(); > + > + float topRatio = topRadiiExtent ? (rect.width() / topRadiiExtent) : 1; > + float rightRatio = rightRadiiExtent ? (rect.height() / rightRadiiExtent) : 1; > + float bottomRatio = bottomRadiiExtent ? (rect.width() / bottomRadiiExtent) : 1; > + float leftRatio = leftRadiiExtent ? (rect.height() / leftRadiiExtent) : 1; > + > + float reductionRatio = std::min<float>(topRatio, std::min<float>(rightRatio, std::min<float>(bottomRatio, leftRatio))); > + if (reductionRatio < 1) > + roundedRect.scaleRadii(reductionRatio); Is there anything that can be shared with border-radius?
Bem Jones-Bey
Comment 4 2014-03-05 14:50:45 PST
Bem Jones-Bey
Comment 5 2014-03-05 14:51:33 PST
(In reply to comment #3) > (From update of attachment 225882 [details]) > View in context: https://bugs.webkit.org/attachment.cgi?id=225882&action=review > > > Source/WebCore/rendering/shapes/Shape.cpp:131 > > + float topRadiiExtent = radii.topLeft().width() + radii.topRight().width(); > > + float rightRadiiExtent = radii.topRight().height() + radii.bottomRight().height(); > > + float bottomRadiiExtent = radii.bottomLeft().width() + radii.bottomRight().width(); > > + float leftRadiiExtent = radii.topLeft().height() + radii.bottomLeft().height(); > > + > > + float topRatio = topRadiiExtent ? (rect.width() / topRadiiExtent) : 1; > > + float rightRatio = rightRadiiExtent ? (rect.height() / rightRadiiExtent) : 1; > > + float bottomRatio = bottomRadiiExtent ? (rect.width() / bottomRadiiExtent) : 1; > > + float leftRatio = leftRadiiExtent ? (rect.height() / leftRadiiExtent) : 1; > > + > > + float reductionRatio = std::min<float>(topRatio, std::min<float>(rightRatio, std::min<float>(bottomRatio, leftRatio))); > > + if (reductionRatio < 1) > > + roundedRect.scaleRadii(reductionRatio); > > Is there anything that can be shared with border-radius? Yeah, I should have done that in the first place. The new patch reuses the same function as border-radius.
Dirk Schulze
Comment 6 2014-03-06 01:29:33 PST
Comment on attachment 225917 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=225917&action=review > Source/WebCore/rendering/style/BorderRadiiConstraintScale.h:29 > +template <class Rect, class Radii> > +inline float calcBorderRadiiConstraintScaleFor(const Rect& rect, const Radii& radii) Cause I hate to debugs templates, I am not a huge fan of templates and would like to avoid them as much as possible. For this particular case it seems you just created a template to be able to use the classes Rect and Radii. Isn't there a better way? Also, Can't you just add this to FloatRoundedRect or RoundedRect instead of creating another header?
Bem Jones-Bey
Comment 7 2014-03-06 08:57:22 PST
(In reply to comment #6) > (From update of attachment 225917 [details]) > View in context: https://bugs.webkit.org/attachment.cgi?id=225917&action=review > > > Source/WebCore/rendering/style/BorderRadiiConstraintScale.h:29 > > +template <class Rect, class Radii> > > +inline float calcBorderRadiiConstraintScaleFor(const Rect& rect, const Radii& radii) > > Cause I hate to debugs templates, I am not a huge fan of templates and would like to avoid them as much as possible. For this particular case it seems you just created a template to be able to use the classes Rect and Radii. Isn't there a better way? Also, Can't you just add this to FloatRoundedRect or RoundedRect instead of creating another header? I would unfortunately have to add it to both of them. The shapes geometry code uses floats, and the style and layout code uses LayoutUnits. Converting in the middle of the geometry code to LayoutUnits and then back to floats has caused problems in the past due to the imprecise nature of that conversion. And I don't think we want to be converting to FloatRoundedRect and back every time we need to do this calculation in RenderStyle (or in my fix for Bug 127982, for that matter). I did notice that there is an adjustRadii() call in RoundedRect, but it doesn't do exactly the same calculation as the border radii case, and it looks like it is only used for box shadow (RenderBoxModelObject::paintBoxShadow).
Dirk Schulze
Comment 8 2014-03-06 09:37:30 PST
(In reply to comment #7) > (In reply to comment #6) > > (From update of attachment 225917 [details] [details]) > > View in context: https://bugs.webkit.org/attachment.cgi?id=225917&action=review > > > > > Source/WebCore/rendering/style/BorderRadiiConstraintScale.h:29 > > > +template <class Rect, class Radii> > > > +inline float calcBorderRadiiConstraintScaleFor(const Rect& rect, const Radii& radii) > > > > Cause I hate to debugs templates, I am not a huge fan of templates and would like to avoid them as much as possible. For this particular case it seems you just created a template to be able to use the classes Rect and Radii. Isn't there a better way? Also, Can't you just add this to FloatRoundedRect or RoundedRect instead of creating another header? > > I would unfortunately have to add it to both of them. The shapes geometry code uses floats, and the style and layout code uses LayoutUnits. Converting in the middle of the geometry code to LayoutUnits and then back to floats has caused problems in the past due to the imprecise nature of that conversion. And I don't think we want to be converting to FloatRoundedRect and back every time we need to do this calculation in RenderStyle (or in my fix for Bug 127982, for that matter). > > I did notice that there is an adjustRadii() call in RoundedRect, but it doesn't do exactly the same calculation as the border radii case, and it looks like it is only used for box shadow (RenderBoxModelObject::paintBoxShadow). Is it possible to create two inline functions where one calls the other but does the conversion first?
Bem Jones-Bey
Comment 9 2014-03-06 09:57:34 PST
Bem Jones-Bey
Comment 10 2014-03-06 09:58:55 PST
(In reply to comment #8) > (In reply to comment #7) > > (In reply to comment #6) > > > (From update of attachment 225917 [details] [details] [details]) > > > View in context: https://bugs.webkit.org/attachment.cgi?id=225917&action=review > > > > > > > Source/WebCore/rendering/style/BorderRadiiConstraintScale.h:29 > > > > +template <class Rect, class Radii> > > > > +inline float calcBorderRadiiConstraintScaleFor(const Rect& rect, const Radii& radii) > > > > > > Cause I hate to debugs templates, I am not a huge fan of templates and would like to avoid them as much as possible. For this particular case it seems you just created a template to be able to use the classes Rect and Radii. Isn't there a better way? Also, Can't you just add this to FloatRoundedRect or RoundedRect instead of creating another header? > > > > I would unfortunately have to add it to both of them. The shapes geometry code uses floats, and the style and layout code uses LayoutUnits. Converting in the middle of the geometry code to LayoutUnits and then back to floats has caused problems in the past due to the imprecise nature of that conversion. And I don't think we want to be converting to FloatRoundedRect and back every time we need to do this calculation in RenderStyle (or in my fix for Bug 127982, for that matter). > > > > I did notice that there is an adjustRadii() call in RoundedRect, but it doesn't do exactly the same calculation as the border radii case, and it looks like it is only used for box shadow (RenderBoxModelObject::paintBoxShadow). > > Is it possible to create two inline functions where one calls the other but does the conversion first? I looked into this and discovered that there are some implicit conversions from LayoutRect/RoundedRect -> FloatRect/FloatRoundedRect. So I just changed the signature to take the float varieties, and not have a template. WDYT?
Bem Jones-Bey
Comment 11 2014-03-06 11:05:40 PST
Dirk Schulze
Comment 12 2014-03-06 11:22:55 PST
Comment on attachment 226011 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=226011&action=review > Source/WebCore/rendering/style/BorderRadiiConstraintScale.h:31 > +inline float calcBorderRadiiConstraintScaleFor(const FloatRect& rect, const FloatRoundedRect::Radii& radii) looks nicer already. Do you think we can put that on FloatRoundedRect.h instead of creating a new header file?
Bem Jones-Bey
Comment 13 2014-03-06 11:37:45 PST
Bem Jones-Bey
Comment 14 2014-03-06 11:38:47 PST
(In reply to comment #12) > (From update of attachment 226011 [details]) > View in context: https://bugs.webkit.org/attachment.cgi?id=226011&action=review > > > Source/WebCore/rendering/style/BorderRadiiConstraintScale.h:31 > > +inline float calcBorderRadiiConstraintScaleFor(const FloatRect& rect, const FloatRoundedRect::Radii& radii) > > looks nicer already. Do you think we can put that on FloatRoundedRect.h instead of creating a new header file? Ok, WDYT? (I wish I could make it just take a FloatRoundedRect, but that would require some serious surgery to how RenderStyle does it's thing.)
Dirk Schulze
Comment 15 2014-03-07 02:47:22 PST
Comment on attachment 226019 [details] Patch r=me
WebKit Commit Bot
Comment 16 2014-03-07 08:19:27 PST
Comment on attachment 226019 [details] Patch Clearing flags on attachment: 226019 Committed r165261: <http://trac.webkit.org/changeset/165261>
WebKit Commit Bot
Comment 17 2014-03-07 08:19:30 PST
All reviewed patches have been landed. Closing bug.
Michal Pakula vel Rutka
Comment 18 2014-03-07 08:43:49 PST
WebKit Commit Bot
Comment 19 2014-03-07 09:02:06 PST
Re-opened since this is blocked by bug 129887
Bem Jones-Bey
Comment 20 2014-03-07 09:20:52 PST
The reopen was spurious; a different commit got tangled up with this one, and that's the one that got reverted.
Note You need to log in before you can comment on or make changes to this bug.