Changeset 44235 in webkit


Ignore:
Timestamp:
May 28, 2009 9:55:04 AM (15 years ago)
Author:
bfulgham@webkit.org
Message:

WebCore:

2009-05-28 Simon Fraser <Simon Fraser>

Reviewed by Oliver Hunt.


https://bugs.webkit.org/show_bug.cgi?id=8736

Tests: fast/borders/border-radius-constraints.html

fast/borders/border-radius-split-inline.html


When the sum of the corner radii on a side exceed the length of the side,
reduce the radii according to CSS 3 rules.


Add RenderStyle::getBorderRadiiForRect() to fetch corner radii, applying
the constraints. Use that for painting borders, box-shadow, clipping replaced
elements

  • platform/graphics/IntSize.h: (WebCore::IntSize::scale): Add a scale method that scales by a float (using C rounding rules, like IntRect::scale()).
  • platform/graphics/Path.cpp: Make the QUARTER const static.
  • rendering/RenderBox.cpp: (WebCore::RenderBox::pushContentsClip): Use getBorderRadiiForRect to fetch border radii.
  • rendering/RenderBoxModelObject.cpp: (WebCore::RenderBoxModelObject::paintFillLayerExtended): Use getBorderRadiiForRect to fetch border radii.

(WebCore::RenderBoxModelObject::paintBorder):
Use getBorderRadiiForRect to fetch border radii, and fix a bug when drawing
borders for split inlines, which used to apply the radii for each segment,
and no longer does.

(WebCore::RenderBoxModelObject::paintBoxShadow):
Use getBorderRadiiForRect to fetch border radii.

  • rendering/RenderReplaced.cpp: (WebCore::RenderReplaced::paint): Use getBorderRadiiForRect to fetch border radii for clipping.
  • rendering/RenderWidget.cpp: (WebCore::RenderWidget::paint): Use getBorderRadiiForRect to fetch border radii for clipping.
  • rendering/style/RenderStyle.h:
  • rendering/style/RenderStyle.cpp: (WebCore::RenderStyle::getBorderRadiiForRect): New bottleneck method to fetch corner radiil given a rect, applying the constraint rules.

LayoutTests:

2009-05-28 Simon Fraser <Simon Fraser>

Reviewed by Oliver Hunt.


https://bugs.webkit.org/show_bug.cgi?id=8736

  • fast/borders/border-radius-constraints.html: Added.
  • platform/mac/fast/borders/border-radius-constraints-expected.checksum: Added.
  • platform/mac/fast/borders/border-radius-constraints-expected.png: Added.
  • platform/mac/fast/borders/border-radius-constraints-expected.txt: Added.


Test that corner radii are constrained according to CSS3 rules.

  • fast/borders/border-radius-huge-assert.html:
  • platform/mac/fast/borders/border-radius-huge-assert-expected.checksum:
  • platform/mac/fast/borders/border-radius-huge-assert-expected.png:
  • platform/mac/fast/borders/border-radius-huge-assert-expected.txt:


Now that we constrain border-radius, update the text of the test, and the
expected result.


  • fast/borders/border-radius-split-inline.html: Added.
  • platform/mac/fast/borders/border-radius-split-inline-expected.checksum: Added.
  • platform/mac/fast/borders/border-radius-split-inline-expected.png: Added.
  • platform/mac/fast/borders/border-radius-split-inline-expected.txt: Added.


New test for border-radius on a split inline.


  • fast/box-shadow/border-radius-big.html:
  • platform/mac/fast/box-shadow/border-radius-big-expected.checksum:
  • platform/mac/fast/box-shadow/border-radius-big-expected.png:
  • platform/mac/fast/box-shadow/border-radius-big-expected.txt:

Now that we constrain border-radius, update the text of the test, and the
expected result.

Location:
trunk
Files:
6 added
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r44232 r44235  
     12009-05-28  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Reviewed by Oliver Hunt.
     4       
     5        https://bugs.webkit.org/show_bug.cgi?id=8736
     6
     7        * fast/borders/border-radius-constraints.html: Added.
     8        * platform/mac/fast/borders/border-radius-constraints-expected.checksum: Added.
     9        * platform/mac/fast/borders/border-radius-constraints-expected.png: Added.
     10        * platform/mac/fast/borders/border-radius-constraints-expected.txt: Added.
     11       
     12        Test that corner radii are constrained according to CSS3 rules.
     13
     14        * fast/borders/border-radius-huge-assert.html:
     15        * platform/mac/fast/borders/border-radius-huge-assert-expected.checksum:
     16        * platform/mac/fast/borders/border-radius-huge-assert-expected.png:
     17        * platform/mac/fast/borders/border-radius-huge-assert-expected.txt:
     18       
     19        Now that we constrain border-radius, update the text of the test, and the
     20        expected result.
     21       
     22        * fast/borders/border-radius-split-inline.html: Added.
     23        * platform/mac/fast/borders/border-radius-split-inline-expected.checksum: Added.
     24        * platform/mac/fast/borders/border-radius-split-inline-expected.png: Added.
     25        * platform/mac/fast/borders/border-radius-split-inline-expected.txt: Added.
     26       
     27        New test for border-radius on a split inline.
     28       
     29        * fast/box-shadow/border-radius-big.html:
     30        * platform/mac/fast/box-shadow/border-radius-big-expected.checksum:
     31        * platform/mac/fast/box-shadow/border-radius-big-expected.png:
     32        * platform/mac/fast/box-shadow/border-radius-big-expected.txt:
     33
     34        Now that we constrain border-radius, update the text of the test, and the
     35        expected result.
     36
    1372009-05-28  Alexey Proskuryakov  <ap@webkit.org>
    238
  • trunk/LayoutTests/fast/borders/border-radius-huge-assert.html

    r18602 r44235  
    44    <style type="text/css">
    55        div { width: 50px; height: 50px; background-color: silver; border: medium solid; margin: 10px 0 10px 0; }
    6         button { -webkit-border-radius:926179103pt; }
    76    </style>
    87</head>
     
    1312    </p>
    1413    <p>
    15         There should be four identical squares below.
     14        There should be three squres and a circle below.
    1615    </p>
    1716    <div></div>
     
    1918    <div style="-webkit-border-radius: 10px 926179103pt;"></div>
    2019    <div style="-webkit-border-radius: 926179103pt;"></div>
     20
    2121</body>
    2222</html>
  • trunk/LayoutTests/fast/box-shadow/border-radius-big.html

    r21601 r44235  
    11<p>
    2     This:
     2    You should see a circle with a shadow above a square with a shadow.
    33</p>
    44<div style="margin: 40px; background: green; -webkit-border-radius: 40px; width: 60px; height: 60px; -webkit-box-shadow: black 10px 10px 0;"></div>
    5 <p>
    6     Should look like this:
    7 </p>
    85<div style="margin: 40px; background: green; width: 60px; height: 60px; -webkit-box-shadow: black 10px 10px 0;"></div>
  • trunk/LayoutTests/platform/mac/fast/borders/border-radius-huge-assert-expected.checksum

    r38008 r44235  
    1 f5bff44ab6407da13ad6505b95aa87a9
     10fe93b32a9f8f4bf1b8be6d24f3a465b
  • trunk/LayoutTests/platform/mac/fast/borders/border-radius-huge-assert-expected.txt

    r30635 r44235  
    1818          text run at (246,18) width 4: "."
    1919      RenderBlock {P} at (0,52) size 784x18
    20         RenderText {#text} at (0,0) size 287x18
    21           text run at (0,0) width 287: "There should be four identical squares below."
     20        RenderText {#text} at (0,0) size 304x18
     21          text run at (0,0) width 304: "There should be three squres and a circle below."
    2222      RenderBlock {DIV} at (0,86) size 56x56 [bgcolor=#C0C0C0] [border: (3px solid #000000)]
    2323      RenderBlock {DIV} at (0,152) size 56x56 [bgcolor=#C0C0C0] [border: (3px solid #000000)]
  • trunk/LayoutTests/platform/mac/fast/box-shadow/border-radius-big-expected.checksum

    r38121 r44235  
    1 b7baf9cc57b84bbf39a6383af77fa9d9
     107983e136e2d173b6c73d17a293e4471
  • trunk/LayoutTests/platform/mac/fast/box-shadow/border-radius-big-expected.txt

    r30635 r44235  
    55    RenderBody {BODY} at (8,8) size 784x552
    66      RenderBlock {P} at (0,0) size 784x18
    7         RenderText {#text} at (0,0) size 32x18
    8           text run at (0,0) width 32: "This:"
     7        RenderText {#text} at (0,0) size 441x18
     8          text run at (0,0) width 441: "You should see a circle with a shadow above a square with a shadow."
    99      RenderBlock {DIV} at (40,58) size 60x60 [bgcolor=#008000]
    10       RenderBlock {P} at (0,158) size 784x18
    11         RenderText {#text} at (0,0) size 134x18
    12           text run at (0,0) width 134: "Should look like this:"
    13       RenderBlock {DIV} at (40,216) size 60x60 [bgcolor=#008000]
     10      RenderBlock {DIV} at (40,158) size 60x60 [bgcolor=#008000]
  • trunk/WebCore/ChangeLog

    r44232 r44235  
     12009-05-28  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Reviewed by Oliver Hunt.
     4       
     5        https://bugs.webkit.org/show_bug.cgi?id=8736
     6
     7        Tests: fast/borders/border-radius-constraints.html
     8               fast/borders/border-radius-split-inline.html
     9               
     10        When the sum of the corner radii on a side exceed the length of the side,
     11        reduce the radii according to CSS 3 rules.
     12       
     13        Add RenderStyle::getBorderRadiiForRect() to fetch corner radii, applying
     14        the constraints. Use that for painting borders, box-shadow, clipping replaced
     15        elements
     16
     17        * platform/graphics/IntSize.h:
     18        (WebCore::IntSize::scale):
     19        Add a scale method that scales by a float (using C rounding rules, like IntRect::scale()).
     20
     21        * platform/graphics/Path.cpp:
     22        Make the QUARTER const static.
     23
     24        * rendering/RenderBox.cpp:
     25        (WebCore::RenderBox::pushContentsClip):
     26        Use getBorderRadiiForRect to fetch border radii.
     27
     28        * rendering/RenderBoxModelObject.cpp:
     29        (WebCore::RenderBoxModelObject::paintFillLayerExtended):
     30        Use getBorderRadiiForRect to fetch border radii.
     31
     32        (WebCore::RenderBoxModelObject::paintBorder):
     33        Use getBorderRadiiForRect to fetch border radii, and fix a bug when drawing
     34        borders for split inlines, which used to apply the radii for each segment,
     35        and no longer does.
     36
     37        (WebCore::RenderBoxModelObject::paintBoxShadow):
     38        Use getBorderRadiiForRect to fetch border radii.
     39
     40        * rendering/RenderReplaced.cpp:
     41        (WebCore::RenderReplaced::paint):
     42        Use getBorderRadiiForRect to fetch border radii for clipping.
     43
     44        * rendering/RenderWidget.cpp:
     45        (WebCore::RenderWidget::paint):
     46        Use getBorderRadiiForRect to fetch border radii for clipping.
     47
     48        * rendering/style/RenderStyle.h:
     49        * rendering/style/RenderStyle.cpp:
     50        (WebCore::RenderStyle::getBorderRadiiForRect):
     51        New bottleneck method to fetch corner radiil given a rect, applying the constraint
     52        rules.
     53
    1542009-05-28  Alexey Proskuryakov  <ap@webkit.org>
    255
  • trunk/WebCore/platform/graphics/IntSize.h

    r38098 r44235  
    7272        m_width += width;
    7373        m_height += height;
     74    }
     75   
     76    void scale(float scale)
     77    {
     78        m_width *= scale;
     79        m_height *= scale;
    7480    }
    7581   
  • trunk/WebCore/platform/graphics/Path.cpp

    r29663 r44235  
    3636#include <wtf/MathExtras.h>
    3737
    38 const float QUARTER = 0.552f; // approximation of control point positions on a bezier
     38static const float QUARTER = 0.552f; // approximation of control point positions on a bezier
    3939                              // to simulate a quarter of a circle.
    4040namespace WebCore {
  • trunk/WebCore/rendering/RenderBox.cpp

    r43662 r44235  
    828828    IntRect clipRect(isControlClip ? controlClipRect(tx, ty) : overflowClipRect(tx, ty));
    829829    paintInfo.context->save();
    830     if (style()->hasBorderRadius())
    831         paintInfo.context->addRoundedRectClip(IntRect(tx, ty, width(), height()), style()->borderTopLeftRadius(),
    832                                               style()->borderTopRightRadius(),
    833                                               style()->borderBottomLeftRadius(),
    834                                               style()->borderBottomRightRadius());
     830    if (style()->hasBorderRadius()) {
     831        IntSize topLeft, topRight, bottomLeft, bottomRight;
     832        IntRect borderRect = IntRect(tx, ty, width(), height());
     833        style()->getBorderRadiiForRect(borderRect, topLeft, topRight, bottomLeft, bottomRight);
     834
     835        paintInfo.context->addRoundedRectClip(borderRect, topLeft, topRight, bottomLeft, bottomRight);
     836    }
     837   
    835838    paintInfo.context->clip(clipRect);
    836839    return true;
  • trunk/WebCore/rendering/RenderBoxModelObject.cpp

    r44096 r44235  
    312312    if (style()->hasBorderRadius() && (includeLeftEdge || includeRightEdge)) {
    313313        context->save();
    314         context->addRoundedRectClip(IntRect(tx, ty, w, h),
    315             includeLeftEdge ? style()->borderTopLeftRadius() : IntSize(),
    316             includeRightEdge ? style()->borderTopRightRadius() : IntSize(),
    317             includeLeftEdge ? style()->borderBottomLeftRadius() : IntSize(),
    318             includeRightEdge ? style()->borderBottomRightRadius() : IntSize());
     314
     315        IntSize topLeft, topRight, bottomLeft, bottomRight;
     316        IntRect borderRect(tx, ty, w, h);
     317        style()->getBorderRadiiForRect(borderRect, topLeft, topRight, bottomLeft, bottomRight);
     318
     319        context->addRoundedRectClip(borderRect, includeLeftEdge ? topLeft : IntSize(),
     320                                                includeRightEdge ? topRight : IntSize(),
     321                                                includeLeftEdge ? bottomLeft : IntSize(),
     322                                                includeRightEdge ? bottomRight : IntSize());
    319323        clippedToBorderRadius = true;
    320324    }
     
    778782    bool renderBottom = bottomStyle > BHIDDEN && !bottomTransparent;
    779783
    780     // Need sufficient width and height to contain border radius curves.  Sanity check our border radii
    781     // and our width/height values to make sure the curves can all fit. If not, then we won't paint
    782     // any border radii.
    783784    bool renderRadii = false;
    784     IntSize topLeft = style->borderTopLeftRadius();
    785     IntSize topRight = style->borderTopRightRadius();
    786     IntSize bottomLeft = style->borderBottomLeftRadius();
    787     IntSize bottomRight = style->borderBottomRightRadius();
    788 
    789     if (style->hasBorderRadius() &&
    790         static_cast<unsigned>(w) >= static_cast<unsigned>(topLeft.width()) + static_cast<unsigned>(topRight.width()) &&
    791         static_cast<unsigned>(w) >= static_cast<unsigned>(bottomLeft.width()) + static_cast<unsigned>(bottomRight.width()) &&
    792         static_cast<unsigned>(h) >= static_cast<unsigned>(topLeft.height()) + static_cast<unsigned>(bottomLeft.height()) &&
    793         static_cast<unsigned>(h) >= static_cast<unsigned>(topRight.height()) + static_cast<unsigned>(bottomRight.height()))
     785    IntSize topLeft, topRight, bottomLeft, bottomRight;
     786
     787    if (style->hasBorderRadius()) {
     788        IntRect borderRect = IntRect(tx, ty, w, h);
     789
     790        IntSize topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius;
     791        style->getBorderRadiiForRect(borderRect, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius);
     792
     793        if (begin) {
     794            topLeft = topLeftRadius;
     795            bottomLeft = bottomLeftRadius;
     796        }
     797        if (end) {
     798            topRight = topRightRadius;
     799            bottomRight = bottomRightRadius;
     800        }
     801
    794802        renderRadii = true;
    795803
    796     // Clip to the rounded rectangle.
    797     if (renderRadii) {
     804        // Clip to the rounded rectangle.
    798805        graphicsContext->save();
    799         graphicsContext->addRoundedRectClip(IntRect(tx, ty, w, h), topLeft, topRight, bottomLeft, bottomRight);
     806        graphicsContext->addRoundedRectClip(borderRect, topLeft, topRight, bottomLeft, bottomRight);
    800807    }
    801808
     
    11271134        context->setShadow(shadowOffset, shadowBlur, shadow->color);
    11281135        if (hasBorderRadius) {
    1129             IntSize topLeft = begin ? s->borderTopLeftRadius() : IntSize();
    1130             IntSize topRight = end ? s->borderTopRightRadius() : IntSize();
    1131             IntSize bottomLeft = begin ? s->borderBottomLeftRadius() : IntSize();
    1132             IntSize bottomRight = end ? s->borderBottomRightRadius() : IntSize();
     1136            IntSize topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius;
     1137            s->getBorderRadiiForRect(rect, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius);
     1138
     1139            IntSize topLeft = begin ? topLeftRadius : IntSize();
     1140            IntSize topRight = end ? topRightRadius : IntSize();
     1141            IntSize bottomLeft = begin ? bottomLeftRadius : IntSize();
     1142            IntSize bottomRight = end ? bottomRightRadius : IntSize();
     1143
    11331144            if (!hasOpaqueBackground)
    11341145                context->clipOutRoundedRect(rect, topLeft, topRight, bottomLeft, bottomRight);
  • trunk/WebCore/rendering/RenderReplaced.cpp

    r41947 r44235  
    132132        // Push a clip if we have a border radius, since we want to round the foreground content that gets painted.
    133133        paintInfo.context->save();
    134         paintInfo.context->addRoundedRectClip(IntRect(tx, ty, width(), height()),
    135                                               style()->borderTopLeftRadius(),
    136                                               style()->borderTopRightRadius(),
    137                                               style()->borderBottomLeftRadius(),
    138                                               style()->borderBottomRightRadius());
     134       
     135        IntSize topLeft, topRight, bottomLeft, bottomRight;
     136        IntRect borderRect = IntRect(tx, ty, width(), height());
     137        style()->getBorderRadiiForRect(borderRect, topLeft, topRight, bottomLeft, bottomRight);
     138
     139        paintInfo.context->addRoundedRectClip(borderRect, topLeft, topRight, bottomLeft, bottomRight);
    139140    }
    140141
  • trunk/WebCore/rendering/RenderWidget.cpp

    r43378 r44235  
    197197        // Push a clip if we have a border radius, since we want to round the foreground content that gets painted.
    198198        paintInfo.context->save();
    199         paintInfo.context->addRoundedRectClip(IntRect(tx, ty, width(), height()),
    200                                               style()->borderTopLeftRadius(),
    201                                               style()->borderTopRightRadius(),
    202                                               style()->borderBottomLeftRadius(),
    203                                               style()->borderBottomRightRadius());
     199       
     200        IntSize topLeft, topRight, bottomLeft, bottomRight;
     201        IntRect borderRect = IntRect(tx, ty, width(), height());
     202        style()->getBorderRadiiForRect(borderRect, topLeft, topRight, bottomLeft, bottomRight);
     203
     204        paintInfo.context->addRoundedRectClip(borderRect, topLeft, topRight, bottomLeft, bottomRight);
    204205    }
    205206
  • trunk/WebCore/rendering/style/RenderStyle.cpp

    r43323 r44235  
    3232#include <wtf/StdLibExtras.h>
    3333#include <algorithm>
     34
     35using namespace std;
    3436
    3537namespace WebCore {
     
    710712}
    711713
     714void RenderStyle::getBorderRadiiForRect(const IntRect& r, IntSize& topLeft, IntSize& topRight, IntSize& bottomLeft, IntSize& bottomRight) const
     715{
     716    topLeft = surround->border.topLeft;
     717    topRight = surround->border.topRight;
     718   
     719    bottomLeft = surround->border.bottomLeft;
     720    bottomRight = surround->border.bottomRight;
     721
     722    // Constrain corner radii using CSS3 rules:
     723    // http://www.w3.org/TR/css3-background/#the-border-radius
     724   
     725    float factor = 1;
     726    unsigned radiiSum;
     727
     728    // top
     729    radiiSum = static_cast<unsigned>(topLeft.width()) + static_cast<unsigned>(topRight.width()); // Casts to avoid integer overflow.
     730    if (radiiSum > static_cast<unsigned>(r.width()))
     731        factor = min(static_cast<float>(r.width()) / radiiSum, factor);
     732
     733    // bottom
     734    radiiSum = static_cast<unsigned>(bottomLeft.width()) + static_cast<unsigned>(bottomRight.width());
     735    if (radiiSum > static_cast<unsigned>(r.width()))
     736        factor = min(static_cast<float>(r.width()) / radiiSum, factor);
     737   
     738    // left
     739    radiiSum = static_cast<unsigned>(topLeft.height()) + static_cast<unsigned>(bottomLeft.height());
     740    if (radiiSum > static_cast<unsigned>(r.height()))
     741        factor = min(static_cast<float>(r.height()) / radiiSum, factor);
     742   
     743    // right
     744    radiiSum = static_cast<unsigned>(topRight.height()) + static_cast<unsigned>(bottomRight.height());
     745    if (radiiSum > static_cast<unsigned>(r.height()))
     746        factor = min(static_cast<float>(r.height()) / radiiSum, factor);
     747   
     748    // Scale all radii by f if necessary.
     749    if (factor < 1) {
     750        // If either radius on a corner becomes zero, reset both radii on that corner.
     751        topLeft.scale(factor);
     752        if (!topLeft.width() || !topLeft.height())
     753            topLeft = IntSize();
     754        topRight.scale(factor);
     755        if (!topRight.width() || !topRight.height())
     756            topRight = IntSize();
     757        bottomLeft.scale(factor);
     758        if (!bottomLeft.width() || !bottomLeft.height())
     759            bottomLeft = IntSize();
     760        bottomRight.scale(factor);
     761        if (!bottomRight.width() || !bottomRight.height())
     762            bottomRight = IntSize();
     763    }
     764}
     765
    712766const CounterDirectiveMap* RenderStyle::counterDirectives() const
    713767{
  • trunk/WebCore/rendering/style/RenderStyle.h

    r43323 r44235  
    760760        setBorderBottomRightRadius(s);
    761761    }
     762   
     763    void getBorderRadiiForRect(const IntRect&, IntSize& topLeft, IntSize& topRight, IntSize& bottomLeft, IntSize& bottomRight) const;
    762764
    763765    void setBorderLeftWidth(unsigned short v) { SET_VAR(surround, border.left.width, v) }
Note: See TracChangeset for help on using the changeset viewer.