Changeset 84341 in webkit


Ignore:
Timestamp:
Apr 19, 2011 10:13:32 PM (13 years ago)
Author:
Simon Fraser
Message:

2011-04-19 Simon Fraser <Simon Fraser>

Reviewed by Dan Bernstein.

background color of elements with border-radius shows around outer edge of border at corners
https://bugs.webkit.org/show_bug.cgi?id=21819

When drawing a background followed by a border with the same rounded
clip, some border color leaks out because of antialiasing.

Fix this by using two different strategies depending on the colors.
If the border is opaque on all sides, we can inset the background by
a device pixel. If not, then we have to draw the unclipped background
and border into a transparency layer, and then clip that.

A futher possible solution is mentioned in a comment in
determineBackgroundBleedAvoidance() but not yet implemented.

Also don't try to paint shadows with zero offset, spread and blur.

Test: fast/backgrounds/background-leakage.html,

fast/backgrounds/background-leakage-transforms.html

  • rendering/RenderBoxModelObject.h: Add a BackgroundBleedAvoidance enum with a value for each strategy.
  • rendering/RenderBoxModelObject.cpp: (WebCore::RenderBoxModelObject::paintFillLayerExtended): Pass BackgroundBleedAvoidance, bail early if the border rect is empty. If using the transparency layer solution, don't bother to clip to the rounded rect for the background. If the strategy is to shrink the background, do that. (WebCore::BorderEdge::BorderEdge): (WebCore::BorderEdge::obscuresBackgroundEdge): Helper method to determine if this border side will totally obscured by the border edge, allowing us to inset it. (WebCore::RenderBoxModelObject::paintOneBorderSide): Pass BackgroundBleedAvoidance through. (WebCore::RenderBoxModelObject::paintBorderSides): Ditto. (WebCore::RenderBoxModelObject::paintTranslucentBorderSides): Ditto. (WebCore::RenderBoxModelObject::paintBorder): Fill BorderEdges using getBorderEdgeInfo now. Don't clip to the rounded border if we are using the transparency layer solution. (WebCore::RenderBoxModelObject::drawBoxSideFromPath): Pass bleedAvoidance through, and use it for double borders. (WebCore::RenderBoxModelObject::getBorderEdgeInfo): Helper to fill in the BorderEdge array. (WebCore::RenderBoxModelObject::borderObscuresBackgroundEdge): Used to determine if we can use the background shrinkage solution. (WebCore::RenderBoxModelObject::paintBoxShadow): Don't paint shadows that should not be visible.
  • rendering/RenderBox.h:
  • rendering/RenderBox.cpp: (WebCore::RenderBox::paintRootBoxFillLayers): Pass BackgroundBleedNone for the root box.

(WebCore::RenderBox::determineBackgroundBleedAvoidance):
Determine which bleed strategy we can use.

(WebCore::RenderBox::paintBoxDecorationsWithSize):
Based on the bleedAvoidance, make a transparency layer
which will be clipped to the rounded border outside edge,
and pass bleedAvoidance to the background and border-painting
methods.
(WebCore::RenderBox::paintMaskImages):
Use BackgroundBleedNone.
(WebCore::RenderBox::paintFillLayers):
(WebCore::RenderBox::paintFillLayer):
Pass bleedAvoidance through.

  • rendering/InlineFlowBox.cpp: (WebCore::InlineFlowBox::paintFillLayer): (WebCore::InlineFlowBox::paintBoxDecorations): Pass BackgroundBleedNone. At some point we may want to do the right thing for split inlines.
  • rendering/RenderFieldset.cpp: (WebCore::RenderFieldset::paintBoxDecorations):
  • rendering/RenderTableCell.cpp: (WebCore::RenderTableCell::paintBackgroundsBehindCell): Pass BackgroundBleedNone.
Location:
trunk
Files:
4 added
87 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r84339 r84341  
     12011-04-19  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Reviewed by Dan Bernstein.
     4
     5        background color of elements with border-radius shows around outer edge of border at corners
     6        https://bugs.webkit.org/show_bug.cgi?id=21819
     7
     8        * fast/backgrounds/background-leakage-transforms.html: Added.
     9        * platform/mac/fast/backgrounds/background-leakage-expected.checksum:
     10        * platform/mac/fast/backgrounds/background-leakage-expected.png:
     11        * platform/mac/fast/backgrounds/background-leakage-transforms-expected.checksum: Added.
     12        * platform/mac/fast/backgrounds/background-leakage-transforms-expected.png: Added.
     13        * platform/mac/fast/backgrounds/background-leakage-transforms-expected.txt: Added.
     14        * platform/mac/fast/borders/border-radius-circle-expected.checksum:
     15        * platform/mac/fast/borders/border-radius-circle-expected.png:
     16        * platform/mac/fast/borders/border-radius-huge-assert-expected.checksum:
     17        * platform/mac/fast/borders/border-radius-huge-assert-expected.png:
     18        * platform/mac/fast/borders/border-radius-wide-border-01-expected.checksum:
     19        * platform/mac/fast/borders/border-radius-wide-border-01-expected.png:
     20        * platform/mac/fast/borders/borderRadiusAllStylesAllCorners-expected.checksum:
     21        * platform/mac/fast/borders/borderRadiusAllStylesAllCorners-expected.png:
     22        * platform/mac/fast/borders/borderRadiusArcs01-expected.checksum:
     23        * platform/mac/fast/borders/borderRadiusArcs01-expected.png:
     24        * platform/mac/fast/borders/borderRadiusDashed01-expected.checksum:
     25        * platform/mac/fast/borders/borderRadiusDashed01-expected.png:
     26        * platform/mac/fast/borders/borderRadiusDashed02-expected.checksum:
     27        * platform/mac/fast/borders/borderRadiusDashed02-expected.png:
     28        * platform/mac/fast/borders/borderRadiusDashed03-expected.checksum:
     29        * platform/mac/fast/borders/borderRadiusDashed03-expected.png:
     30        * platform/mac/fast/borders/borderRadiusDotted01-expected.checksum:
     31        * platform/mac/fast/borders/borderRadiusDotted01-expected.png:
     32        * platform/mac/fast/borders/borderRadiusDotted02-expected.checksum:
     33        * platform/mac/fast/borders/borderRadiusDotted02-expected.png:
     34        * platform/mac/fast/borders/borderRadiusDotted03-expected.checksum:
     35        * platform/mac/fast/borders/borderRadiusDotted03-expected.png:
     36        * platform/mac/fast/borders/borderRadiusDouble01-expected.checksum:
     37        * platform/mac/fast/borders/borderRadiusDouble01-expected.png:
     38        * platform/mac/fast/borders/borderRadiusDouble02-expected.checksum:
     39        * platform/mac/fast/borders/borderRadiusDouble02-expected.png:
     40        * platform/mac/fast/borders/borderRadiusDouble03-expected.checksum:
     41        * platform/mac/fast/borders/borderRadiusDouble03-expected.png:
     42        * platform/mac/fast/borders/borderRadiusGroove01-expected.checksum:
     43        * platform/mac/fast/borders/borderRadiusGroove01-expected.png:
     44        * platform/mac/fast/borders/borderRadiusGroove02-expected.checksum:
     45        * platform/mac/fast/borders/borderRadiusGroove02-expected.png:
     46        * platform/mac/fast/borders/borderRadiusInset01-expected.checksum:
     47        * platform/mac/fast/borders/borderRadiusInset01-expected.png:
     48        * platform/mac/fast/borders/borderRadiusInvalidColor-expected.checksum:
     49        * platform/mac/fast/borders/borderRadiusInvalidColor-expected.png:
     50        * platform/mac/fast/borders/borderRadiusOutset01-expected.checksum:
     51        * platform/mac/fast/borders/borderRadiusOutset01-expected.png:
     52        * platform/mac/fast/borders/borderRadiusRidge01-expected.checksum:
     53        * platform/mac/fast/borders/borderRadiusRidge01-expected.png:
     54        * platform/mac/fast/borders/borderRadiusSolid01-expected.checksum:
     55        * platform/mac/fast/borders/borderRadiusSolid01-expected.png:
     56        * platform/mac/fast/borders/borderRadiusSolid02-expected.checksum:
     57        * platform/mac/fast/borders/borderRadiusSolid02-expected.png:
     58        * platform/mac/fast/borders/borderRadiusSolid03-expected.checksum:
     59        * platform/mac/fast/borders/borderRadiusSolid03-expected.png:
     60        * platform/mac/fast/box-shadow/inset-expected.checksum:
     61        * platform/mac/fast/box-shadow/inset-expected.png:
     62        * platform/mac/fast/box-shadow/inset-with-extraordinary-radii-and-border-expected.checksum:
     63        * platform/mac/fast/box-shadow/inset-with-extraordinary-radii-and-border-expected.png:
     64        * platform/mac/fast/forms/basic-selects-expected.checksum:
     65        * platform/mac/fast/forms/basic-selects-expected.png:
     66        * platform/mac/fast/forms/menulist-clip-expected.checksum:
     67        * platform/mac/fast/forms/menulist-clip-expected.png:
     68        * platform/mac/fast/forms/menulist-narrow-width-expected.checksum:
     69        * platform/mac/fast/forms/menulist-narrow-width-expected.png:
     70        * platform/mac/fast/forms/menulist-option-wrap-expected.checksum:
     71        * platform/mac/fast/forms/menulist-option-wrap-expected.png:
     72        * platform/mac/fast/forms/menulist-restrict-line-height-expected.checksum:
     73        * platform/mac/fast/forms/menulist-restrict-line-height-expected.png:
     74        * platform/mac/fast/forms/menulist-separator-painting-expected.checksum:
     75        * platform/mac/fast/forms/menulist-separator-painting-expected.png:
     76        * platform/mac/fast/forms/menulist-style-color-expected.checksum:
     77        * platform/mac/fast/forms/menulist-style-color-expected.png:
     78        * platform/mac/fast/forms/select-baseline-expected.checksum:
     79        * platform/mac/fast/forms/select-baseline-expected.png:
     80        * platform/mac/fast/forms/select-empty-option-height-expected.checksum:
     81        * platform/mac/fast/forms/select-empty-option-height-expected.png:
     82        * platform/mac/fast/forms/select-style-expected.checksum:
     83        * platform/mac/fast/forms/select-style-expected.png:
     84        * platform/mac/fast/overflow/border-radius-clipping-expected.checksum:
     85        * platform/mac/fast/overflow/border-radius-clipping-expected.png:
     86        * platform/mac/fast/repaint/border-radius-repaint-expected.checksum:
     87        * platform/mac/fast/repaint/border-radius-repaint-expected.png:
     88        * platform/mac/fast/repaint/control-clip-expected.checksum:
     89        * platform/mac/fast/repaint/control-clip-expected.png:
     90
    1912011-04-19  Dirk Pranke  <dpranke@chromium.org>
    292
  • trunk/LayoutTests/platform/mac/fast/backgrounds/background-leakage-expected.checksum

    r84327 r84341  
    1 55dbe59355ab4ee1a81a875ffaea89e4
     172b37b86b3b818766aeb5fd1ceca215c
  • trunk/LayoutTests/platform/mac/fast/borders/border-radius-circle-expected.checksum

    r84273 r84341  
    1 de435721aa54f1ecb9beefa605021fc6
     1c1c6d542746da7c0d3f86ade842d8757
  • trunk/LayoutTests/platform/mac/fast/borders/border-radius-huge-assert-expected.checksum

    r84273 r84341  
    1 17c5f317e15e62b2332a24969dac3523
     119972f6044a8b134372796b9e4bf558c
  • trunk/LayoutTests/platform/mac/fast/borders/border-radius-wide-border-01-expected.checksum

    r62200 r84341  
    1 550e70b25479d1ae378a57ae84435cf9
     1259df2d1f1c76e94445c037e970c8619
  • trunk/LayoutTests/platform/mac/fast/borders/borderRadiusAllStylesAllCorners-expected.checksum

    r84273 r84341  
    1 e8baa4426989be3a6fa5617a886cae1d
     18fface99e9eba92d8922c63e643888ea
  • trunk/LayoutTests/platform/mac/fast/borders/borderRadiusArcs01-expected.checksum

    r63864 r84341  
    1 968c93833340f79aa9c49692f3dc0827
     1e0a3036616677958b8522c0ed374b8db
  • trunk/LayoutTests/platform/mac/fast/borders/borderRadiusDashed01-expected.checksum

    r63864 r84341  
    1 f704755acc058a44c5b751cf2086340b
     1c6f09f1c92925cce3d3a711698f763b2
  • trunk/LayoutTests/platform/mac/fast/borders/borderRadiusDashed02-expected.checksum

    r63864 r84341  
    1 9b11881bd405bee0ce2f01529a87aa5c
     1928c49ca91a09cb209c5a26aeb04340c
  • trunk/LayoutTests/platform/mac/fast/borders/borderRadiusDashed03-expected.checksum

    r63864 r84341  
    1 e17538efde12ef7448417e746c3d2558
     194535c26bc45718ae7295e04655bd278
  • trunk/LayoutTests/platform/mac/fast/borders/borderRadiusDotted01-expected.checksum

    r62035 r84341  
    1 41dee88f9b630d383cb1415b6b774d97
     1ca33c7bb6a5080c22896634b3ffb5706
  • trunk/LayoutTests/platform/mac/fast/borders/borderRadiusDotted02-expected.checksum

    r63864 r84341  
    1 0a0d0eea89522d8f77061afeac74fccf
     145aabaed8e9adc028694139bd5939812
  • trunk/LayoutTests/platform/mac/fast/borders/borderRadiusDotted03-expected.checksum

    r63864 r84341  
    1 c426077d1e7bbf827382d9975897f9b7
     14d0539ffc3874d5618aa0e628de9d253
  • trunk/LayoutTests/platform/mac/fast/borders/borderRadiusDouble01-expected.checksum

    r63864 r84341  
    1 885eda56b7a4efc54aedbc36532e28d5
     196c1358a9d3ca2f8e409d5a2a40d6d51
  • trunk/LayoutTests/platform/mac/fast/borders/borderRadiusDouble02-expected.checksum

    r63864 r84341  
    1 573d36242a243c1eaac4542f2c01515f
     194bb67465c20bedefde52e0500219473
  • trunk/LayoutTests/platform/mac/fast/borders/borderRadiusDouble03-expected.checksum

    r63864 r84341  
    1 8d73c009ce0a74f53880bf0e539f5402
     190a175abec5579656cfe2b095b023699
  • trunk/LayoutTests/platform/mac/fast/borders/borderRadiusGroove01-expected.checksum

    r63864 r84341  
    1 58139b6dec68d5a94f3935a0bf4c19c6
     1677e1558fe1425adf4202afde380ee7d
  • trunk/LayoutTests/platform/mac/fast/borders/borderRadiusGroove02-expected.checksum

    r63864 r84341  
    1 4b5f38a94a4d0b931db413be72f04c94
     15df1a00c1201362d193829d1385a53ec
  • trunk/LayoutTests/platform/mac/fast/borders/borderRadiusInset01-expected.checksum

    r63864 r84341  
    1 ec77767e4c7cb598960be42882f8484a
     19586fd38aee973e8966d280ee9290033
  • trunk/LayoutTests/platform/mac/fast/borders/borderRadiusInvalidColor-expected.checksum

    r84273 r84341  
    1 b44ecacc58efb306297b0c02e931b8f3
     1933054a1ddf336cb3708ce9c683f50e8
  • trunk/LayoutTests/platform/mac/fast/borders/borderRadiusOutset01-expected.checksum

    r63864 r84341  
    1 c86bb840151e3305763a8ec316e03318
     1e56a3090fabaf825ee52a9487167f878
  • trunk/LayoutTests/platform/mac/fast/borders/borderRadiusRidge01-expected.checksum

    r63864 r84341  
    1 67cc243ea897d8da7e99a060715bf2c4
     1ef917018d14057c78756d8f68d678be9
  • trunk/LayoutTests/platform/mac/fast/borders/borderRadiusSolid01-expected.checksum

    r84273 r84341  
    1 0f711ca8d3036d8751f0f5ef52fac2bd
     178896f0bfccd174b54ca2e449859954e
  • trunk/LayoutTests/platform/mac/fast/borders/borderRadiusSolid02-expected.checksum

    r84273 r84341  
    1 2d4439965d61592fd46702cba67230bf
     108ffa4d40dab7ca782cbd6792b750642
  • trunk/LayoutTests/platform/mac/fast/borders/borderRadiusSolid03-expected.checksum

    r84273 r84341  
    1 700112dc0f13cdf7eb1f544ab30e422c
     11d7fbc6a46be559d77dd55b23a99380f
  • trunk/LayoutTests/platform/mac/fast/box-shadow/inset-expected.checksum

    r84327 r84341  
    1 148b87d8c1c983a51eb13ed14dfe3981
     13a81fa1a4637004d2c01d01f90e58ca9
  • trunk/LayoutTests/platform/mac/fast/box-shadow/inset-with-extraordinary-radii-and-border-expected.checksum

    r84327 r84341  
    1 ec78c0685b5d32ff8c661bdeae3a6d4f
     10b99597ebf5c710ad4ce26b0dedee73a
  • trunk/LayoutTests/platform/mac/fast/forms/basic-selects-expected.checksum

    r84327 r84341  
    1 f6a4d0d8403f4b8c72b3f6eb6792601c
     1523cafd614a95b7ae70c6e3a8d9cea30
  • trunk/LayoutTests/platform/mac/fast/forms/menulist-clip-expected.checksum

    r84327 r84341  
    1 a66f62c487a504263dd23816d30c1b7c
     12360329aaf19a9ac47855f071e020089
  • trunk/LayoutTests/platform/mac/fast/forms/menulist-narrow-width-expected.checksum

    r84327 r84341  
    1 d1afe5a05b049f6c38b3ad92ee3063a6
     1c586ef5ca76eccd85d219d40ccf838ed
  • trunk/LayoutTests/platform/mac/fast/forms/menulist-option-wrap-expected.checksum

    r84327 r84341  
    1 c71de50784558dcadfd2acd2222e62ea
     1755a60c939bab694392a67cc8e1de95d
  • trunk/LayoutTests/platform/mac/fast/forms/menulist-restrict-line-height-expected.checksum

    r84327 r84341  
    1 40280d636919b5d9039967f11da98933
     124177abe5661f6ab91b9bd0f02939fd0
  • trunk/LayoutTests/platform/mac/fast/forms/menulist-separator-painting-expected.checksum

    r84327 r84341  
    1 494c714b6bc0d045b8fd36c12dd4bb8a
     10f3d661ca28ae24d1d0cf3f7ceb75271
  • trunk/LayoutTests/platform/mac/fast/forms/menulist-style-color-expected.checksum

    r84327 r84341  
    1 f369e1718d9f7075d1c6a74f36df3ae0
     1c64b240169b24bfab1610d977d842087
  • trunk/LayoutTests/platform/mac/fast/forms/select-baseline-expected.checksum

    r84327 r84341  
    1 80c17148eb6427f266100488225d1268
     14b0435055b843a892a28328564e11d28
  • trunk/LayoutTests/platform/mac/fast/forms/select-empty-option-height-expected.checksum

    r84327 r84341  
    1 b1d9082dee72cf0c53fdd89fb63ffd63
     1788d0cd40211826ec7979a899d660094
  • trunk/LayoutTests/platform/mac/fast/forms/select-style-expected.checksum

    r84327 r84341  
    1 48a3cab308291de930dc282008ef62d0
     10765dfc84133011df8c57e1dd30b1156
  • trunk/LayoutTests/platform/mac/fast/overflow/border-radius-clipping-expected.checksum

    r84327 r84341  
    1 dda2c146af2f11bfd6970c776580d9dc
     13e7122d7554ec5046c2e39639d9d1a78
  • trunk/LayoutTests/platform/mac/fast/repaint/border-radius-repaint-expected.checksum

    r84327 r84341  
    1 c8dfb371750f5450ff39d2d2cd9221a4
     1aa2cf3eebd43b6de5fe1cce9467fcb1f
  • trunk/LayoutTests/platform/mac/fast/repaint/control-clip-expected.checksum

    r84327 r84341  
    1 16f15e540ea0069460029a029e5cc101
     1222573f6871e48de6a366723cf84ef1a
  • trunk/Source/WebCore/ChangeLog

    r84340 r84341  
     12011-04-19  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Reviewed by Dan Bernstein.
     4
     5        background color of elements with border-radius shows around outer edge of border at corners
     6        https://bugs.webkit.org/show_bug.cgi?id=21819
     7       
     8        When drawing a background followed by a border with the same rounded
     9        clip, some border color leaks out because of antialiasing.
     10       
     11        Fix this by using two different strategies depending on the colors.
     12        If the border is opaque on all sides, we can inset the background by
     13        a device pixel. If not, then we have to draw the unclipped background
     14        and border into a transparency layer, and then clip that.
     15       
     16        A futher possible solution is mentioned in a comment in
     17        determineBackgroundBleedAvoidance() but not yet implemented.
     18       
     19        Also don't try to paint shadows with zero offset, spread and blur.
     20
     21        Test: fast/backgrounds/background-leakage.html,
     22              fast/backgrounds/background-leakage-transforms.html
     23
     24        * rendering/RenderBoxModelObject.h:
     25        Add a BackgroundBleedAvoidance enum with a value for each
     26        strategy.
     27        * rendering/RenderBoxModelObject.cpp:
     28        (WebCore::RenderBoxModelObject::paintFillLayerExtended):
     29        Pass BackgroundBleedAvoidance, bail early if the border rect is empty.
     30        If using the transparency layer solution, don't bother to clip
     31        to the rounded rect for the background. If the strategy is to
     32        shrink the background, do that.
     33        (WebCore::BorderEdge::BorderEdge):
     34        (WebCore::BorderEdge::obscuresBackgroundEdge):
     35        Helper method to determine if this border side will totally
     36        obscured by the border edge, allowing us to inset it.
     37        (WebCore::RenderBoxModelObject::paintOneBorderSide):
     38        Pass BackgroundBleedAvoidance through.
     39        (WebCore::RenderBoxModelObject::paintBorderSides):
     40        Ditto.
     41        (WebCore::RenderBoxModelObject::paintTranslucentBorderSides):
     42        Ditto.
     43        (WebCore::RenderBoxModelObject::paintBorder):
     44        Fill BorderEdges using getBorderEdgeInfo now.
     45        Don't clip to the rounded border if we are using the
     46        transparency layer solution.
     47        (WebCore::RenderBoxModelObject::drawBoxSideFromPath):
     48        Pass bleedAvoidance through, and use it for double borders.
     49        (WebCore::RenderBoxModelObject::getBorderEdgeInfo):
     50        Helper to fill in the BorderEdge array.
     51        (WebCore::RenderBoxModelObject::borderObscuresBackgroundEdge):
     52        Used to determine if we can use the background shrinkage solution.
     53        (WebCore::RenderBoxModelObject::paintBoxShadow):
     54        Don't paint shadows that should not be visible.
     55
     56        * rendering/RenderBox.h:
     57        * rendering/RenderBox.cpp:
     58        (WebCore::RenderBox::paintRootBoxFillLayers):
     59        Pass BackgroundBleedNone for the root box.
     60       
     61        (WebCore::RenderBox::determineBackgroundBleedAvoidance):
     62        Determine which bleed strategy we can use.
     63       
     64        (WebCore::RenderBox::paintBoxDecorationsWithSize):
     65        Based on the bleedAvoidance, make a transparency layer
     66        which will be clipped to the rounded border outside edge,
     67        and pass bleedAvoidance to the background and border-painting
     68        methods.       
     69        (WebCore::RenderBox::paintMaskImages):
     70        Use BackgroundBleedNone.
     71        (WebCore::RenderBox::paintFillLayers):
     72        (WebCore::RenderBox::paintFillLayer):
     73        Pass bleedAvoidance through.
     74
     75        * rendering/InlineFlowBox.cpp:
     76        (WebCore::InlineFlowBox::paintFillLayer):
     77        (WebCore::InlineFlowBox::paintBoxDecorations):
     78        Pass BackgroundBleedNone. At some point we may want to do the right
     79        thing for split inlines.
     80
     81        * rendering/RenderFieldset.cpp:
     82        (WebCore::RenderFieldset::paintBoxDecorations):
     83        * rendering/RenderTableCell.cpp:
     84        (WebCore::RenderTableCell::paintBackgroundsBehindCell):
     85        Pass BackgroundBleedNone.
     86
    1872011-04-19  Yuta Kitamura  <yutak@chromium.org>
    288
  • trunk/Source/WebCore/rendering/InlineFlowBox.cpp

    r84283 r84341  
    10301030    bool hasFillImage = img && img->canRender(renderer()->style()->effectiveZoom());
    10311031    if ((!hasFillImage && !renderer()->style()->hasBorderRadius()) || (!prevLineBox() && !nextLineBox()) || !parent())
    1032         boxModelObject()->paintFillLayerExtended(paintInfo, c, fillLayer, tx, ty, w, h, this, w, h, op);
     1032        boxModelObject()->paintFillLayerExtended(paintInfo, c, fillLayer, tx, ty, w, h, BackgroundBleedNone, this, w, h, op);
    10331033    else {
    10341034        // We have a fill image that spans multiple lines.
     
    10591059        paintInfo.context->save();
    10601060        paintInfo.context->clip(IntRect(tx, ty, width(), height()));
    1061         boxModelObject()->paintFillLayerExtended(paintInfo, c, fillLayer, stripX, stripY, stripWidth, stripHeight, this, w, h, op);
     1061        boxModelObject()->paintFillLayerExtended(paintInfo, c, fillLayer, stripX, stripY, stripWidth, stripHeight, BackgroundBleedNone, this, w, h, op);
    10621062        paintInfo.context->restore();
    10631063    }
     
    11281128            // cases only a single call to draw is required.
    11291129            if (!hasBorderImage || (!prevLineBox() && !nextLineBox()))
    1130                 boxModelObject()->paintBorder(context, tx, ty, w, h, renderer()->style(), includeLogicalLeftEdge(), includeLogicalRightEdge());
     1130                boxModelObject()->paintBorder(context, tx, ty, w, h, renderer()->style(), BackgroundBleedNone, includeLogicalLeftEdge(), includeLogicalRightEdge());
    11311131            else {
    11321132                // We have a border image that spans multiple lines.
  • trunk/Source/WebCore/rendering/RenderBox.cpp

    r84283 r84341  
    804804    // The background of the box generated by the root element covers the entire canvas, so just use
    805805    // the RenderView's docTop/Left/Width/Height accessors.
    806     paintFillLayers(paintInfo, bgColor, bgLayer, view()->docLeft(), view()->docTop(), view()->docWidth(), view()->docHeight(), CompositeSourceOver, bodyObject);
     806    paintFillLayers(paintInfo, bgColor, bgLayer, view()->docLeft(), view()->docTop(), view()->docWidth(), view()->docHeight(), BackgroundBleedNone, CompositeSourceOver, bodyObject);
    807807}
    808808
     
    812812        return;
    813813    return paintBoxDecorationsWithSize(paintInfo, tx, ty, width(), height());
     814}
     815
     816BackgroundBleedAvoidance RenderBox::determineBackgroundBleedAvoidance(GraphicsContext* context) const
     817{
     818    if (context->paintingDisabled())
     819        return BackgroundBleedNone;
     820
     821    const RenderStyle* style = this->style();
     822
     823    if (!style->hasBackground() || !style->hasBorder() || !style->hasBorderRadius())
     824        return BackgroundBleedNone;
     825
     826    AffineTransform ctm = context->getCTM();
     827    FloatSize contextScaling(ctm.xScale(), ctm.yScale());
     828    if (borderObscuresBackgroundEdge(contextScaling))
     829        return BackgroundBleedShrinkBackground;
     830   
     831    // FIXME: there is one more strategy possible, for opaque backgrounds and
     832    // translucent borders. In that case we could avoid using a transparency layer,
     833    // and paint the border first, and then paint the background clipped to the
     834    // inside of the border.
     835
     836    return BackgroundBleedUseTransparencyLayer;
    814837}
    815838
     
    824847    paintBoxShadow(paintInfo.context, tx, ty, width, height, style(), Normal);
    825848
     849    BackgroundBleedAvoidance bleedAvoidance = determineBackgroundBleedAvoidance(paintInfo.context);
     850    if (bleedAvoidance == BackgroundBleedUseTransparencyLayer) {
     851        // To avoid the background color bleeding out behind the border, we'll render background and border
     852        // into a transparency layer, and then clip that in one go (which requires setting up the clip before
     853        // beginning the layer).
     854        RoundedIntRect border = style()->getRoundedBorderFor(IntRect(tx, ty, width, height));
     855        paintInfo.context->save();
     856        paintInfo.context->addRoundedRectClip(border);
     857        paintInfo.context->beginTransparencyLayer(1);
     858    }
     859   
    826860    // If we have a native theme appearance, paint that before painting our background.
    827861    // The theme will tell us whether or not we should also paint the CSS background.
     
    833867            // The <body> only paints its background if the root element has defined a background
    834868            // independent of the body.
    835             paintFillLayers(paintInfo, style()->visitedDependentColor(CSSPropertyBackgroundColor), style()->backgroundLayers(), tx, ty, width, height);
     869            paintFillLayers(paintInfo, style()->visitedDependentColor(CSSPropertyBackgroundColor), style()->backgroundLayers(), tx, ty, width, height, bleedAvoidance);
    836870        }
    837871        if (style()->hasAppearance())
     
    842876    // The theme will tell us whether or not we should also paint the CSS border.
    843877    if ((!style()->hasAppearance() || (!themePainted && theme()->paintBorderOnly(this, paintInfo, IntRect(tx, ty, width, height)))) && style()->hasBorder())
    844         paintBorder(paintInfo.context, tx, ty, width, height, style());
     878        paintBorder(paintInfo.context, tx, ty, width, height, style(), bleedAvoidance);
     879
     880    if (bleedAvoidance == BackgroundBleedUseTransparencyLayer) {
     881        paintInfo.context->endTransparencyLayer();
     882        paintInfo.context->restore();
     883    }
    845884}
    846885
     
    918957
    919958    if (allMaskImagesLoaded) {
    920         paintFillLayers(paintInfo, Color(), style()->maskLayers(), tx, ty, w, h, compositeOp);
     959        paintFillLayers(paintInfo, Color(), style()->maskLayers(), tx, ty, w, h, BackgroundBleedNone, compositeOp);
    921960        paintNinePieceImage(paintInfo.context, tx, ty, w, h, style(), style()->maskBoxImage(), compositeOp);
    922961    }
     
    945984}
    946985
    947 void RenderBox::paintFillLayers(const PaintInfo& paintInfo, const Color& c, const FillLayer* fillLayer, int tx, int ty, int width, int height, CompositeOperator op, RenderObject* backgroundObject)
     986void RenderBox::paintFillLayers(const PaintInfo& paintInfo, const Color& c, const FillLayer* fillLayer, int tx, int ty, int width, int height,
     987    BackgroundBleedAvoidance bleedAvoidance, CompositeOperator op, RenderObject* backgroundObject)
    948988{
    949989    if (!fillLayer)
    950990        return;
    951991
    952     paintFillLayers(paintInfo, c, fillLayer->next(), tx, ty, width, height, op, backgroundObject);
    953     paintFillLayer(paintInfo, c, fillLayer, tx, ty, width, height, op, backgroundObject);
    954 }
    955 
    956 void RenderBox::paintFillLayer(const PaintInfo& paintInfo, const Color& c, const FillLayer* fillLayer, int tx, int ty, int width, int height, CompositeOperator op, RenderObject* backgroundObject)
    957 {
    958     paintFillLayerExtended(paintInfo, c, fillLayer, tx, ty, width, height, 0, 0, 0, op, backgroundObject);
     992    paintFillLayers(paintInfo, c, fillLayer->next(), tx, ty, width, height, bleedAvoidance, op, backgroundObject);
     993    paintFillLayer(paintInfo, c, fillLayer, tx, ty, width, height, bleedAvoidance, op, backgroundObject);
     994}
     995
     996void RenderBox::paintFillLayer(const PaintInfo& paintInfo, const Color& c, const FillLayer* fillLayer, int tx, int ty, int width, int height,
     997    BackgroundBleedAvoidance bleedAvoidance, CompositeOperator op, RenderObject* backgroundObject)
     998{
     999    paintFillLayerExtended(paintInfo, c, fillLayer, tx, ty, width, height, bleedAvoidance, 0, 0, 0, op, backgroundObject);
    9591000}
    9601001
  • trunk/Source/WebCore/rendering/RenderBox.h

    r83221 r84341  
    406406    virtual void updateBoxModelInfoFromStyle();
    407407
    408     void paintFillLayer(const PaintInfo&, const Color&, const FillLayer*, int tx, int ty, int width, int height, CompositeOperator op, RenderObject* backgroundObject);
    409     void paintFillLayers(const PaintInfo&, const Color&, const FillLayer*, int tx, int ty, int width, int height, CompositeOperator = CompositeSourceOver, RenderObject* backgroundObject = 0);
     408    void paintFillLayer(const PaintInfo&, const Color&, const FillLayer*, int tx, int ty, int width, int height, BackgroundBleedAvoidance, CompositeOperator, RenderObject* backgroundObject);
     409    void paintFillLayers(const PaintInfo&, const Color&, const FillLayer*, int tx, int ty, int width, int height, BackgroundBleedAvoidance = BackgroundBleedNone, CompositeOperator = CompositeSourceOver, RenderObject* backgroundObject = 0);
    410410
    411411    void paintBoxDecorationsWithSize(PaintInfo&, int tx, int ty, int width, int height);
     
    453453    virtual void computePreferredLogicalWidths() { setPreferredLogicalWidthsDirty(false); }
    454454
     455    BackgroundBleedAvoidance determineBackgroundBleedAvoidance(GraphicsContext*) const;
     456
    455457private:
    456458    // The width/height of the contents + borders + padding.  The x/y location is relative to our container (which is not always our parent).
  • trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp

    r84283 r84341  
    573573
    574574void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, const Color& color, const FillLayer* bgLayer, int tx, int ty, int w, int h,
    575     InlineFlowBox* box, int inlineBoxWidth, int inlineBoxHeight, CompositeOperator op, RenderObject* backgroundObject)
     575    BackgroundBleedAvoidance bleedAvoidance, InlineFlowBox* box, int inlineBoxWidth, int inlineBoxHeight, CompositeOperator op, RenderObject* backgroundObject)
    576576{
    577577    GraphicsContext* context = paintInfo.context;
    578578    if (context->paintingDisabled())
     579        return;
     580
     581    IntRect borderRect(tx, ty, w, h);
     582    if (borderRect.isEmpty())
    579583        return;
    580584
     
    613617            return;
    614618
    615         IntRect borderRect(tx, ty, w, h);
    616         if (borderRect.isEmpty())
    617             return;
    618 
    619         if (hasRoundedBorder) {
    620             RoundedIntRect border = getBackgroundRoundedRect(borderRect, box, inlineBoxWidth, inlineBoxHeight, includeLeftEdge, includeRightEdge);
     619        if (hasRoundedBorder && bleedAvoidance != BackgroundBleedUseTransparencyLayer) {
     620            IntRect roundedBorder = borderRect;
     621            if (bleedAvoidance == BackgroundBleedShrinkBackground) {
     622                // We need to shrink the border by one device pixel on each side.
     623                AffineTransform ctm = context->getCTM();
     624                FloatSize contextScale(ctm.xScale(), ctm.yScale());
     625                roundedBorder.inflateX(-ceilf(1.0f / contextScale.width()));
     626                roundedBorder.inflateY(-ceilf(1.0f / contextScale.height()));
     627            }
     628            RoundedIntRect border = getBackgroundRoundedRect(roundedBorder, box, inlineBoxWidth, inlineBoxHeight, includeLeftEdge, includeRightEdge);
    621629            context->fillRoundedRect(border, bgColor, style()->colorSpace());
    622630        } else
     
    627635
    628636    bool clippedToBorderRadius = false;
    629     if (hasRoundedBorder) {
    630         IntRect borderRect(tx, ty, w, h);
    631 
    632         if (borderRect.isEmpty())
    633             return;
    634 
     637    if (hasRoundedBorder && bleedAvoidance != BackgroundBleedUseTransparencyLayer) {
    635638        context->save();
    636 
    637639        RoundedIntRect border = getBackgroundRoundedRect(borderRect, box, inlineBoxWidth, inlineBoxHeight, includeLeftEdge, includeRightEdge);
    638640        context->addRoundedRectClip(border);
     
    10351037}
    10361038
    1037 #if HAVE(PATH_BASED_BORDER_RADIUS_DRAWING)
    1038 static bool borderWillArcInnerEdge(const IntSize& firstRadius, const IntSize& secondRadius)
    1039 {
    1040     return !firstRadius.isZero() || !secondRadius.isZero();
    1041 }
    1042 
    1043 enum BorderEdgeFlag {
    1044     TopBorderEdge = 1 << BSTop,
    1045     RightBorderEdge = 1 << BSRight,
    1046     BottomBorderEdge = 1 << BSBottom,
    1047     LeftBorderEdge = 1 << BSLeft,
    1048     AllBorderEdges = TopBorderEdge | BottomBorderEdge | LeftBorderEdge | RightBorderEdge
    1049 };
    1050 
    1051 static inline BorderEdgeFlag edgeFlagForSide(BoxSide side)
    1052 {
    1053     return static_cast<BorderEdgeFlag>(1 << side);
    1054 }
    1055 
    1056 static inline bool includesEdge(BorderEdgeFlags flags, BoxSide side)
    1057 {
    1058     return flags & edgeFlagForSide(side);
    1059 }
    1060 
    10611039class BorderEdge {
    10621040public:
    1063     BorderEdge(int edgeWidth, const Color& edgeColor, EBorderStyle edgeStyle, bool edgeIsTransparent, bool edgeIsPresent)
     1041    BorderEdge(int edgeWidth, const Color& edgeColor, EBorderStyle edgeStyle, bool edgeIsTransparent, bool edgeIsPresent = true)
    10641042        : width(edgeWidth)
    10651043        , color(edgeColor)
     
    10721050    }
    10731051   
     1052    BorderEdge()
     1053        : width(0)
     1054        , style(BHIDDEN)
     1055        , isTransparent(false)
     1056        , isPresent(false)
     1057    {
     1058    }
     1059   
    10741060    bool hasVisibleColorAndStyle() const { return style > BHIDDEN && !isTransparent; }
    10751061    bool shouldRender() const { return isPresent && hasVisibleColorAndStyle(); }
    10761062    bool presentButInvisible() const { return usedWidth() && !hasVisibleColorAndStyle(); }
     1063    bool obscuresBackgroundEdge(float scale) const
     1064    {
     1065        if (!isPresent || isTransparent || width < (2 * scale) || color.hasAlpha() || style == BHIDDEN)
     1066            return false;
     1067
     1068        if (style == DOTTED || style == DASHED)
     1069            return false;
     1070
     1071        if (style == DOUBLE)
     1072            return width >= 5 * scale; // The outer band needs to be >= 2px wide at unit scale.
     1073
     1074        return true;
     1075    }
    10771076
    10781077    int usedWidth() const { return isPresent ? width : 0; }
     
    10991098};
    11001099
     1100#if HAVE(PATH_BASED_BORDER_RADIUS_DRAWING)
     1101static bool borderWillArcInnerEdge(const IntSize& firstRadius, const IntSize& secondRadius)
     1102{
     1103    return !firstRadius.isZero() || !secondRadius.isZero();
     1104}
     1105
     1106enum BorderEdgeFlag {
     1107    TopBorderEdge = 1 << BSTop,
     1108    RightBorderEdge = 1 << BSRight,
     1109    BottomBorderEdge = 1 << BSBottom,
     1110    LeftBorderEdge = 1 << BSLeft,
     1111    AllBorderEdges = TopBorderEdge | BottomBorderEdge | LeftBorderEdge | RightBorderEdge
     1112};
     1113
     1114static inline BorderEdgeFlag edgeFlagForSide(BoxSide side)
     1115{
     1116    return static_cast<BorderEdgeFlag>(1 << side);
     1117}
     1118
     1119static inline bool includesEdge(BorderEdgeFlags flags, BoxSide side)
     1120{
     1121    return flags & edgeFlagForSide(side);
     1122}
     1123
    11011124inline bool edgesShareColor(const BorderEdge& firstEdge, const BorderEdge& secondEdge)
    11021125{
     
    12081231void RenderBoxModelObject::paintOneBorderSide(GraphicsContext* graphicsContext, const RenderStyle* style, const RoundedIntRect& outerBorder, const RoundedIntRect& innerBorder,
    12091232    const IntRect& sideRect, BoxSide side, BoxSide adjacentSide1, BoxSide adjacentSide2, const BorderEdge edges[], const Path* path,
    1210     bool includeLogicalLeftEdge, bool includeLogicalRightEdge, bool antialias, const Color* overrideColor)
     1233    BackgroundBleedAvoidance bleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge, bool antialias, const Color* overrideColor)
    12111234{
    12121235    const BorderEdge& edgeToRender = edges[side];
     
    12261249        clipBorderSidePolygon(graphicsContext, outerBorder, innerBorder, side, adjacentSide1StylesMatch, adjacentSide2StylesMatch);
    12271250        float thickness = max(max(edgeToRender.width, adjacentEdge1.width), adjacentEdge2.width);
    1228         drawBoxSideFromPath(graphicsContext, outerBorder.rect(), *path, edges, edgeToRender.width, thickness, side, style, colorToPaint, edgeToRender.style, includeLogicalLeftEdge, includeLogicalRightEdge);
     1251        drawBoxSideFromPath(graphicsContext, outerBorder.rect(), *path, edges, edgeToRender.width, thickness, side, style,
     1252            colorToPaint, edgeToRender.style, bleedAvoidance, includeLogicalLeftEdge, includeLogicalRightEdge);
    12291253        graphicsContext->restore();
    12301254    } else {
     
    12491273
    12501274void RenderBoxModelObject::paintBorderSides(GraphicsContext* graphicsContext, const RenderStyle* style, const RoundedIntRect& outerBorder, const RoundedIntRect& innerBorder,
    1251                                             const BorderEdge edges[], BorderEdgeFlags edgeSet, bool includeLogicalLeftEdge, bool includeLogicalRightEdge, bool antialias, const Color* overrideColor)
     1275                                            const BorderEdge edges[], BorderEdgeFlags edgeSet, BackgroundBleedAvoidance bleedAvoidance,
     1276                                            bool includeLogicalLeftEdge, bool includeLogicalRightEdge, bool antialias, const Color* overrideColor)
    12521277{
    12531278    bool renderRadii = outerBorder.isRounded();
     
    12621287
    12631288        bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSTop].style) || borderWillArcInnerEdge(innerBorder.radii().topLeft(), innerBorder.radii().topRight()));
    1264         paintOneBorderSide(graphicsContext, style, outerBorder, innerBorder, sideRect, BSTop, BSLeft, BSRight, edges, usePath ? &roundedPath : 0, includeLogicalLeftEdge, includeLogicalRightEdge, antialias, overrideColor);
     1289        paintOneBorderSide(graphicsContext, style, outerBorder, innerBorder, sideRect, BSTop, BSLeft, BSRight, edges, usePath ? &roundedPath : 0, bleedAvoidance, includeLogicalLeftEdge, includeLogicalRightEdge, antialias, overrideColor);
    12651290    }
    12661291
     
    12701295
    12711296        bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSBottom].style) || borderWillArcInnerEdge(innerBorder.radii().bottomLeft(), innerBorder.radii().bottomRight()));
    1272         paintOneBorderSide(graphicsContext, style, outerBorder, innerBorder, sideRect, BSBottom, BSLeft, BSRight, edges, usePath ? &roundedPath : 0, includeLogicalLeftEdge, includeLogicalRightEdge, antialias, overrideColor);
     1297        paintOneBorderSide(graphicsContext, style, outerBorder, innerBorder, sideRect, BSBottom, BSLeft, BSRight, edges, usePath ? &roundedPath : 0, bleedAvoidance, includeLogicalLeftEdge, includeLogicalRightEdge, antialias, overrideColor);
    12731298    }
    12741299
     
    12781303
    12791304        bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSLeft].style) || borderWillArcInnerEdge(innerBorder.radii().bottomLeft(), innerBorder.radii().topLeft()));
    1280         paintOneBorderSide(graphicsContext, style, outerBorder, innerBorder, sideRect, BSLeft, BSTop, BSBottom, edges, usePath ? &roundedPath : 0, includeLogicalLeftEdge, includeLogicalRightEdge, antialias, overrideColor);
     1305        paintOneBorderSide(graphicsContext, style, outerBorder, innerBorder, sideRect, BSLeft, BSTop, BSBottom, edges, usePath ? &roundedPath : 0, bleedAvoidance, includeLogicalLeftEdge, includeLogicalRightEdge, antialias, overrideColor);
    12811306    }
    12821307
     
    12861311
    12871312        bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSRight].style) || borderWillArcInnerEdge(innerBorder.radii().bottomRight(), innerBorder.radii().topRight()));
    1288         paintOneBorderSide(graphicsContext, style, outerBorder, innerBorder, sideRect, BSRight, BSTop, BSBottom, edges, usePath ? &roundedPath : 0, includeLogicalLeftEdge, includeLogicalRightEdge, antialias, overrideColor);
     1313        paintOneBorderSide(graphicsContext, style, outerBorder, innerBorder, sideRect, BSRight, BSTop, BSBottom, edges, usePath ? &roundedPath : 0, bleedAvoidance, includeLogicalLeftEdge, includeLogicalRightEdge, antialias, overrideColor);
    12891314    }
    12901315}
    12911316
    12921317void RenderBoxModelObject::paintTranslucentBorderSides(GraphicsContext* graphicsContext, const RenderStyle* style, const RoundedIntRect& outerBorder, const RoundedIntRect& innerBorder,
    1293                                                        const BorderEdge edges[], bool includeLogicalLeftEdge, bool includeLogicalRightEdge, bool antialias)
     1318                                                       const BorderEdge edges[], BackgroundBleedAvoidance bleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge, bool antialias)
    12941319{
    12951320    BorderEdgeFlags edgesToDraw = AllBorderEdges;
     
    13211346        }
    13221347
    1323         paintBorderSides(graphicsContext, style, outerBorder, innerBorder, edges, commonColorEdgeSet, includeLogicalLeftEdge, includeLogicalRightEdge, antialias, &commonColor);
     1348        paintBorderSides(graphicsContext, style, outerBorder, innerBorder, edges, commonColorEdgeSet, bleedAvoidance, includeLogicalLeftEdge, includeLogicalRightEdge, antialias, &commonColor);
    13241349           
    13251350        if (useTransparencyLayer)
     
    13311356
    13321357void RenderBoxModelObject::paintBorder(GraphicsContext* graphicsContext, int tx, int ty, int w, int h,
    1333                                        const RenderStyle* style, bool includeLogicalLeftEdge, bool includeLogicalRightEdge)
    1334 {
     1358                                       const RenderStyle* style, BackgroundBleedAvoidance bleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge)
     1359{
     1360    // border-image is not affected by border-radius.
    13351361    if (paintNinePieceImage(graphicsContext, tx, ty, w, h, style, style->borderImage()))
    13361362        return;
     
    13391365        return;
    13401366
    1341     bool horizontal = style->isHorizontalWritingMode();
    1342 
    1343     BorderEdge edges[4] = {
    1344         // BSTop
    1345         BorderEdge(style->borderTopWidth(),
    1346                     style->visitedDependentColor(CSSPropertyBorderTopColor),
    1347                     style->borderTopStyle(),
    1348                     style->borderTopIsTransparent(),
    1349                     horizontal || includeLogicalLeftEdge),
    1350         // BSRight
    1351         BorderEdge(style->borderRightWidth(),
    1352                     style->visitedDependentColor(CSSPropertyBorderRightColor),
    1353                     style->borderRightStyle(),
    1354                     style->borderRightIsTransparent(),
    1355                     !horizontal || includeLogicalRightEdge),
    1356         // BSBottom
    1357         BorderEdge(style->borderBottomWidth(),
    1358                     style->visitedDependentColor(CSSPropertyBorderBottomColor),
    1359                     style->borderBottomStyle(),
    1360                     style->borderBottomIsTransparent(),
    1361                     horizontal || includeLogicalRightEdge),
    1362         // BSLeft
    1363         BorderEdge(style->borderLeftWidth(),
    1364                     style->visitedDependentColor(CSSPropertyBorderLeftColor),
    1365                     style->borderLeftStyle(),
    1366                     style->borderLeftIsTransparent(),
    1367                     !horizontal || includeLogicalLeftEdge)
    1368     };
     1367    BorderEdge edges[4];
     1368    getBorderEdgeInfo(edges, includeLogicalLeftEdge, includeLogicalRightEdge);
    13691369
    13701370    IntRect borderRect(tx, ty, w, h);
     
    14101410            Path path;
    14111411           
    1412             // FIXME: Path should take a RoundedIntRect directly.
    1413             if (outerBorder.isRounded())
     1412            if (outerBorder.isRounded() && bleedAvoidance != BackgroundBleedUseTransparencyLayer)
    14141413                path.addRoundedRect(outerBorder);
    14151414            else
     
    14251424            graphicsContext->fillPath(path);
    14261425        } else
    1427             paintBorderSides(graphicsContext, style, outerBorder, innerBorder, edges, AllBorderEdges, includeLogicalLeftEdge, includeLogicalRightEdge, antialias);
     1426            paintBorderSides(graphicsContext, style, outerBorder, innerBorder, edges, AllBorderEdges, bleedAvoidance, includeLogicalLeftEdge, includeLogicalRightEdge, antialias);
    14281427   
    14291428        return;
     
    14331432        // Clip to the inner and outer radii rects.
    14341433        graphicsContext->save();
    1435         graphicsContext->addRoundedRectClip(outerBorder);
     1434        if (bleedAvoidance != BackgroundBleedUseTransparencyLayer)
     1435            graphicsContext->addRoundedRectClip(outerBorder);
    14361436        graphicsContext->clipOutRoundedRect(innerBorder);
    14371437    }
    14381438
    14391439    if (haveAlphaColor)
    1440         paintTranslucentBorderSides(graphicsContext, style, outerBorder, innerBorder, edges, includeLogicalLeftEdge, includeLogicalRightEdge, antialias);
     1440        paintTranslucentBorderSides(graphicsContext, style, outerBorder, innerBorder, edges, bleedAvoidance, includeLogicalLeftEdge, includeLogicalRightEdge, antialias);
    14411441    else
    1442         paintBorderSides(graphicsContext, style, outerBorder, innerBorder, edges, AllBorderEdges, includeLogicalLeftEdge, includeLogicalRightEdge, antialias);
     1442        paintBorderSides(graphicsContext, style, outerBorder, innerBorder, edges, AllBorderEdges, bleedAvoidance, includeLogicalLeftEdge, includeLogicalRightEdge, antialias);
    14431443
    14441444    if (outerBorder.isRounded())
     
    14481448void RenderBoxModelObject::drawBoxSideFromPath(GraphicsContext* graphicsContext, const IntRect& borderRect, const Path& borderPath, const BorderEdge edges[],
    14491449                                    float thickness, float drawThickness, BoxSide side, const RenderStyle* style,
    1450                                     Color color, EBorderStyle borderStyle, bool includeLogicalLeftEdge, bool includeLogicalRightEdge)
     1450                                    Color color, EBorderStyle borderStyle, BackgroundBleedAvoidance bleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge)
    14511451{
    14521452    if (thickness <= 0)
     
    15271527       
    15281528        graphicsContext->addRoundedRectClip(innerClip);
    1529         drawBoxSideFromPath(graphicsContext, borderRect, borderPath, edges, thickness, drawThickness, side, style, color, SOLID, includeLogicalLeftEdge, includeLogicalRightEdge);
     1529        drawBoxSideFromPath(graphicsContext, borderRect, borderPath, edges, thickness, drawThickness, side, style, color, SOLID, bleedAvoidance, includeLogicalLeftEdge, includeLogicalRightEdge);
    15301530        graphicsContext->restore();
    15311531
    15321532        // Draw outer border line
    15331533        graphicsContext->save();
    1534        
    1535         RoundedIntRect outerClip = style->getRoundedInnerBorderFor(borderRect,
     1534
     1535        IntRect outerRect = borderRect;
     1536        if (bleedAvoidance == BackgroundBleedUseTransparencyLayer) {
     1537            outerRect.inflate(1);
     1538            ++outerBorderTopWidth;
     1539            ++outerBorderBottomWidth;
     1540            ++outerBorderLeftWidth;
     1541            ++outerBorderRightWidth;
     1542        }
     1543           
     1544        RoundedIntRect outerClip = style->getRoundedInnerBorderFor(outerRect,
    15361545            outerBorderTopWidth, outerBorderBottomWidth, outerBorderLeftWidth, outerBorderRightWidth,
    15371546            includeLogicalLeftEdge, includeLogicalRightEdge);
    1538        
    15391547        graphicsContext->clipOutRoundedRect(outerClip);
    1540         drawBoxSideFromPath(graphicsContext, borderRect, borderPath, edges, thickness, drawThickness, side, style, color, SOLID, includeLogicalLeftEdge, includeLogicalRightEdge);
     1548        drawBoxSideFromPath(graphicsContext, borderRect, borderPath, edges, thickness, drawThickness, side, style, color, SOLID, bleedAvoidance, includeLogicalLeftEdge, includeLogicalRightEdge);
    15411549        graphicsContext->restore();
    15421550        return;
     
    15561564       
    15571565        // Paint full border
    1558         drawBoxSideFromPath(graphicsContext, borderRect, borderPath, edges, thickness, drawThickness, side, style, color, s1, includeLogicalLeftEdge, includeLogicalRightEdge);
     1566        drawBoxSideFromPath(graphicsContext, borderRect, borderPath, edges, thickness, drawThickness, side, style, color, s1, bleedAvoidance, includeLogicalLeftEdge, includeLogicalRightEdge);
    15591567
    15601568        // Paint inner only
     
    15711579
    15721580        graphicsContext->addRoundedRectClip(clipRect);
    1573         drawBoxSideFromPath(graphicsContext, borderRect, borderPath, edges, thickness, drawThickness, side, style, color, s2, includeLogicalLeftEdge, includeLogicalRightEdge);
     1581        drawBoxSideFromPath(graphicsContext, borderRect, borderPath, edges, thickness, drawThickness, side, style, color, s2, bleedAvoidance, includeLogicalLeftEdge, includeLogicalRightEdge);
    15741582        graphicsContext->restore();
    15751583        return;
     
    15931601#else
    15941602void RenderBoxModelObject::paintBorder(GraphicsContext* graphicsContext, int tx, int ty, int w, int h,
    1595                                        const RenderStyle* style, bool includeLogicalLeftEdge, bool includeLogicalRightEdge)
     1603                                       const RenderStyle* style, BackgroundBleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge)
    15961604{
    15971605    // FIXME: This old version of paintBorder should be removed when all ports implement
     
    20472055}
    20482056
     2057void RenderBoxModelObject::getBorderEdgeInfo(BorderEdge edges[], bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const
     2058{
     2059    const RenderStyle* style = this->style();
     2060    bool horizontal = style->isHorizontalWritingMode();
     2061
     2062    edges[BSTop] = BorderEdge(style->borderTopWidth(),
     2063        style->visitedDependentColor(CSSPropertyBorderTopColor),
     2064        style->borderTopStyle(),
     2065        style->borderTopIsTransparent(),
     2066        horizontal || includeLogicalLeftEdge);
     2067
     2068    edges[BSRight] = BorderEdge(style->borderRightWidth(),
     2069        style->visitedDependentColor(CSSPropertyBorderRightColor),
     2070        style->borderRightStyle(),
     2071        style->borderRightIsTransparent(),
     2072        !horizontal || includeLogicalRightEdge);
     2073
     2074    edges[BSBottom] = BorderEdge(style->borderBottomWidth(),
     2075        style->visitedDependentColor(CSSPropertyBorderBottomColor),
     2076        style->borderBottomStyle(),
     2077        style->borderBottomIsTransparent(),
     2078        horizontal || includeLogicalRightEdge);
     2079
     2080    edges[BSLeft] = BorderEdge(style->borderLeftWidth(),
     2081        style->visitedDependentColor(CSSPropertyBorderLeftColor),
     2082        style->borderLeftStyle(),
     2083        style->borderLeftIsTransparent(),
     2084        !horizontal || includeLogicalLeftEdge);
     2085}
     2086
     2087bool RenderBoxModelObject::borderObscuresBackgroundEdge(const FloatSize& contextScale) const
     2088{
     2089    BorderEdge edges[4];
     2090    getBorderEdgeInfo(edges);
     2091
     2092    for (int i = BSTop; i <= BSLeft; ++i) {
     2093        const BorderEdge& currEdge = edges[i];
     2094        // FIXME: for vertical text
     2095        float axisScale = (i == BSTop || i == BSBottom) ? contextScale.height() : contextScale.width();
     2096        if (!currEdge.obscuresBackgroundEdge(axisScale))
     2097            return false;
     2098    }
     2099
     2100    return true;
     2101}
     2102
    20492103static inline IntRect areaCastingShadowInHole(const IntRect& holeRect, int shadowBlur, int shadowSpread, const IntSize& shadowOffset)
    20502104{
     
    20832137        int shadowBlur = shadow->blur();
    20842138        int shadowSpread = shadow->spread();
     2139       
     2140        if (shadowOffset.isZero() && !shadowBlur && !shadowSpread)
     2141            continue;
     2142       
    20852143        const Color& shadowColor = shadow->color();
    20862144
  • trunk/Source/WebCore/rendering/RenderBoxModelObject.h

    r84283 r84341  
    3434enum LineDirectionMode { HorizontalLine, VerticalLine };
    3535typedef unsigned BorderEdgeFlags;
     36
     37enum BackgroundBleedAvoidance {
     38    BackgroundBleedNone,
     39    BackgroundBleedShrinkBackground,
     40    BackgroundBleedUseTransparencyLayer
     41};
    3642
    3743// This class is the base for all objects that adhere to the CSS box model as described
     
    113119    virtual void childBecameNonInline(RenderObject* /*child*/) { }
    114120
    115     void paintBorder(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true);
     121    void paintBorder(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*, BackgroundBleedAvoidance = BackgroundBleedNone, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true);
    116122    bool paintNinePieceImage(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*, const NinePieceImage&, CompositeOperator = CompositeSourceOver);
    117123    void paintBoxShadow(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*, ShadowStyle, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true);
    118     void paintFillLayerExtended(const PaintInfo&, const Color&, const FillLayer*, int tx, int ty, int width, int height, InlineFlowBox* = 0, int inlineBoxWidth = 0, int inlineBoxHeight = 0, CompositeOperator = CompositeSourceOver, RenderObject* backgroundObject = 0);
     124    void paintFillLayerExtended(const PaintInfo&, const Color&, const FillLayer*, int tx, int ty, int width, int height, BackgroundBleedAvoidance, InlineFlowBox* = 0, int inlineBoxWidth = 0, int inlineBoxHeight = 0, CompositeOperator = CompositeSourceOver, RenderObject* backgroundObject = 0);
    119125   
    120126    // Overridden by subclasses to determine line height and baseline position.
     
    130136protected:
    131137    void calculateBackgroundImageGeometry(const FillLayer*, int tx, int ty, int w, int h, IntRect& destRect, IntPoint& phase, IntSize& tileSize);
     138    void getBorderEdgeInfo(class BorderEdge[], bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true) const;
     139    bool borderObscuresBackgroundEdge(const FloatSize& contextScale) const;
    132140
    133141    bool shouldPaintAtLowQuality(GraphicsContext*, Image*, const void*, const IntSize&);
     
    135143    RenderBoxModelObject* continuation() const;
    136144    void setContinuation(RenderBoxModelObject*);
    137    
     145
    138146private:
    139147    virtual bool isBoxModelObject() const { return true; }
     
    148156    void paintOneBorderSide(GraphicsContext*, const RenderStyle*, const RoundedIntRect& outerBorder, const RoundedIntRect& innerBorder,
    149157                                const IntRect& sideRect, BoxSide, BoxSide adjacentSide1, BoxSide adjacentSide2, const class BorderEdge[],
    150                                 const Path*, bool includeLogicalLeftEdge, bool includeLogicalRightEdge, bool antialias, const Color* overrideColor = 0);
     158                                const Path*, BackgroundBleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge, bool antialias, const Color* overrideColor = 0);
    151159    void paintTranslucentBorderSides(GraphicsContext*, const RenderStyle*, const RoundedIntRect& outerBorder, const RoundedIntRect& innerBorder,
    152                           const class BorderEdge[], bool includeLogicalLeftEdge, bool includeLogicalRightEdge, bool antialias = false);
     160                          const class BorderEdge[], BackgroundBleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge, bool antialias = false);
    153161    void paintBorderSides(GraphicsContext*, const RenderStyle*, const RoundedIntRect& outerBorder, const RoundedIntRect& innerBorder,
    154                           const class BorderEdge[], BorderEdgeFlags, bool includeLogicalLeftEdge, bool includeLogicalRightEdge, bool antialias = false, const Color* overrideColor = 0);
     162                          const class BorderEdge[], BorderEdgeFlags, BackgroundBleedAvoidance,
     163                          bool includeLogicalLeftEdge, bool includeLogicalRightEdge, bool antialias = false, const Color* overrideColor = 0);
    155164    void drawBoxSideFromPath(GraphicsContext*, const IntRect&, const Path&, const class BorderEdge[],
    156165                            float thickness, float drawThickness, BoxSide, const RenderStyle*,
    157                             Color, EBorderStyle, bool includeLogicalLeftEdge, bool includeLogicalRightEdge);
     166                            Color, EBorderStyle, BackgroundBleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge);
    158167
    159168    friend class RenderView;
  • trunk/Source/WebCore/rendering/RenderFieldset.cpp

    r75837 r84341  
    178178    }
    179179
    180     paintBorder(paintInfo.context, tx, ty, w, h, style(), true, true);
     180    paintBorder(paintInfo.context, tx, ty, w, h, style());
    181181
    182182    graphicsContext->restore();
  • trunk/Source/WebCore/rendering/RenderTableCell.cpp

    r81747 r84341  
    995995            paintInfo.context->clip(clipRect);
    996996        }
    997         paintFillLayers(paintInfo, c, bgLayer, tx, ty, w, h, CompositeSourceOver, backgroundObject);
     997        paintFillLayers(paintInfo, c, bgLayer, tx, ty, w, h, BackgroundBleedNone, CompositeSourceOver, backgroundObject);
    998998        if (shouldClip)
    999999            paintInfo.context->restore();
Note: See TracChangeset for help on using the changeset viewer.