Changeset 159337 in webkit


Ignore:
Timestamp:
Nov 15, 2013 7:34:21 AM (10 years ago)
Author:
stavila@adobe.com
Message:

[CSS Regions] Implement visual overflow for first & last regions
https://bugs.webkit.org/show_bug.cgi?id=118665

Source/WebCore:

In order to properly propagate the visual overflow of elements flowed inside regions,
the responsiblity of painting and hit-testing content inside flow threads has been
moved to the flow thread layer's level.
Each region keeps the associated overflow with each box in the RenderBoxRegionInfo
structure, including one for the flow thread itself. This data is used during
painting and hit-testing.

Reviewed by David Hyatt.

Tests: fast/regions/overflow-first-and-last-regions-in-container-hidden.html

fast/regions/overflow-first-and-last-regions.html
fast/regions/overflow-nested-regions.html
fast/regions/overflow-region-float.html
fast/regions/overflow-region-inline.html
fast/regions/overflow-region-transform.html

  • rendering/InlineFlowBox.cpp:

(WebCore::InlineFlowBox::setLayoutOverflow):
(WebCore::InlineFlowBox::setVisualOverflow):

  • rendering/InlineFlowBox.h:
  • rendering/RenderBlock.cpp:

(WebCore::RenderBlock::addOverflowFromChildren):
(WebCore::RenderBlock::paint):
(WebCore::RenderBlock::paintObject):
(WebCore::RenderBlock::estimateRegionRangeForBoxChild):
(WebCore::RenderBlock::updateRegionRangeForBoxChild):

  • rendering/RenderBlockFlow.cpp:

(WebCore::RenderBlockFlow::hasNextPage):
(WebCore::RenderBlockFlow::relayoutForPagination):

  • rendering/RenderBlockLineLayout.cpp:

(WebCore::RenderBlockFlow::positionNewFloatOnLine):

  • rendering/RenderBox.cpp:

(WebCore::RenderBox::borderBoxRectInRegion):
(WebCore::RenderBox::computeRectForRepaint):
(WebCore::RenderBox::addLayoutOverflow):
(WebCore::RenderBox::addVisualOverflow):
(WebCore::RenderBox::isUnsplittableForPagination):
(WebCore::RenderBox::overflowRectForPaintRejection):

  • rendering/RenderBox.h:

(WebCore::RenderBox::canHaveOutsideRegionRange):

  • rendering/RenderBoxModelObject.cpp:

(WebCore::RenderBoxModelObject::paintMaskForTextFillBox):
(WebCore::RenderBoxModelObject::paintFillLayerExtended):

  • rendering/RenderBoxModelObject.h:
  • rendering/RenderBoxRegionInfo.h:

(WebCore::RenderBoxRegionInfo::createOverflow):

  • rendering/RenderFlowThread.cpp:

(WebCore::RenderFlowThread::objectShouldPaintInFlowRegion):
(WebCore::RenderFlowThread::mapFromLocalToFlowThread):
(WebCore::RenderFlowThread::mapFromFlowThreadToLocal):
(WebCore::RenderFlowThread::decorationsClipRectForBoxInRegion):
(WebCore::RenderFlowThread::flipForWritingModeLocalCoordinates):
(WebCore::RenderFlowThread::addRegionsOverflowFromChild):
(WebCore::RenderFlowThread::addRegionsVisualOverflow):
(WebCore::CurrentRenderFlowThreadMaintainer::CurrentRenderFlowThreadMaintainer):

  • rendering/RenderFlowThread.h:
  • rendering/RenderLayer.cpp:

(WebCore::RenderLayer::updateLayerPositions):
(WebCore::expandClipRectForRegionAndReflection):
(WebCore::expandClipRectForDescendantsAndReflection):
(WebCore::RenderLayer::paintLayer):
(WebCore::RenderLayer::paintLayerContents):
(WebCore::RenderLayer::updatePaintingInfoForFragments):
(WebCore::RenderLayer::paintForegroundForFragments):
(WebCore::RenderLayer::hitTest):
(WebCore::RenderLayer::hitTestLayer):
(WebCore::RenderLayer::mapLayerClipRectsToFragmentationLayer):
(WebCore::RenderLayer::calculateClipRects):
(WebCore::RenderLayer::parentClipRects):
(WebCore::RenderLayer::calculateRects):
(WebCore::RenderLayer::intersectsDamageRect):
(WebCore::RenderLayer::updateDescendantsLayerListsIfNeeded):
(WebCore::RenderLayer::repaintIncludingDescendants):
(WebCore::RenderLayer::paintNamedFlowThreadInsideRegion):
(WebCore::RenderLayer::paintFlowThreadIfRegion):
(WebCore::RenderLayer::hitTestFlowThreadIfRegion):

  • rendering/RenderLayer.h:

(WebCore::ClipRect::inflateX):
(WebCore::ClipRect::inflateY):
(WebCore::ClipRect::inflate):

  • rendering/RenderLayerCompositor.cpp:

(WebCore::RenderLayerCompositor::computeCompositingRequirements):

  • rendering/RenderListItem.cpp:

(WebCore::RenderListItem::addOverflowFromChildren):

  • rendering/RenderMultiColumnSet.cpp:

(WebCore::RenderMultiColumnSet::flowThreadPortionOverflowRect):
(WebCore::RenderMultiColumnSet::repaintFlowThreadContent):

  • rendering/RenderMultiColumnSet.h:
  • rendering/RenderNamedFlowFragment.cpp:

(WebCore::RenderNamedFlowFragment::createStyle):
(WebCore::RenderNamedFlowFragment::namedFlowThread):

  • rendering/RenderNamedFlowFragment.h:
  • rendering/RenderOverflow.h:
  • rendering/RenderRegion.cpp:

(WebCore::RenderRegion::flowThreadPortionOverflowRect):
(WebCore::RenderRegion::flowThreadPortionLocation):
(WebCore::RenderRegion::regionContainerLayer):
(WebCore::RenderRegion::overflowRectForFlowThreadPortion):
(WebCore::RenderRegion::computeOverflowFromFlowThread):
(WebCore::RenderRegion::repaintFlowThreadContent):
(WebCore::RenderRegion::repaintFlowThreadContentRectangle):
(WebCore::RenderRegion::insertedIntoTree):
(WebCore::RenderRegion::ensureOverflowForBox):
(WebCore::RenderRegion::rectFlowPortionForBox):
(WebCore::RenderRegion::addLayoutOverflowForBox):
(WebCore::RenderRegion::addVisualOverflowForBox):
(WebCore::RenderRegion::layoutOverflowRectForBox):
(WebCore::RenderRegion::visualOverflowRectForBox):
(WebCore::RenderRegion::visualOverflowRectForBoxForPropagation):

  • rendering/RenderRegion.h:
  • rendering/RenderReplaced.cpp:

(WebCore::RenderReplaced::shouldPaint):

  • rendering/RootInlineBox.cpp:

(WebCore::RootInlineBox::paint):

LayoutTests:

Rebased some tests due to regions layers changes.
Updated some tests to increase clarity. Some of them were only passing because two
regions were close together and the fact that an element was being painted
inside the wrong region was not visible. Floats are now also unsplittable.

  • bottom-overflow-out-of-first-region
  • float-pushed-width-change-2
  • float-pushed-width-change
  • webkit-flow-float-unable-to-push

Changed top-overflow-out-of-second-region to reftest.

Added new tests for testing the visual overflow in different situations
(transformed, inline, opacity, floating).

Reviewed by David Hyatt.

  • fast/regions/bottom-overflow-out-of-first-region-expected.html:
  • fast/regions/bottom-overflow-out-of-first-region.html:
  • fast/regions/counters/extract-ordered-lists-in-regions-explicit-counters-005-expected.html:
  • fast/regions/counters/extract-ordered-lists-in-regions-explicit-counters-005.html:
  • fast/regions/element-in-named-flow-absolute-from-fixed-expected.txt:
  • fast/regions/element-in-named-flow-fixed-from-absolute-expected.txt:
  • fast/regions/element-inflow-fixed-from-outflow-static-expected.txt:
  • fast/regions/element-outflow-static-from-inflow-fixed-expected.txt:
  • fast/regions/float-pushed-width-change-2-expected.html:
  • fast/regions/float-pushed-width-change-2.html:
  • fast/regions/float-pushed-width-change-expected.html:
  • fast/regions/float-pushed-width-change.html:
  • fast/regions/layers/dynamic-layer-added-with-no-layout-expected.txt: Added.
  • fast/regions/layers/dynamic-layer-removed-with-no-layout-expected.txt: Added.
  • fast/regions/layers/regions-promoted-to-layers-expected.txt: Added.
  • fast/regions/layers/regions-promoted-to-layers-horizontal-bt-expected.txt: Added.
  • fast/regions/layers/regions-promoted-to-layers-vertical-lr-expected.txt: Added.
  • fast/regions/layers/regions-promoted-to-layers-vertical-rl-expected.txt: Added.
  • fast/regions/outline-sides-in-region-expected.html:
  • fast/regions/outline-sides-in-region.html:
  • fast/regions/overflow-first-and-last-regions-expected.html: Added.
  • fast/regions/overflow-first-and-last-regions-in-container-hidden-expected.html: Added.
  • fast/regions/overflow-first-and-last-regions-in-container-hidden.html: Added.
  • fast/regions/overflow-first-and-last-regions.html: Added.
  • fast/regions/overflow-last-region-expected.html: Removed.
  • fast/regions/overflow-last-region.html: Removed.
  • fast/regions/overflow-nested-regions-expected.html: Added.
  • fast/regions/overflow-nested-regions.html: Added.
  • fast/regions/overflow-region-float-expected.html: Added.
  • fast/regions/overflow-region-float.html: Added.
  • fast/regions/overflow-region-inline-expected.html: Added.
  • fast/regions/overflow-region-inline.html: Added.
  • fast/regions/overflow-region-transform-expected.html: Added.
  • fast/regions/overflow-region-transform.html: Added.
  • fast/regions/overflow-scrollable-rotated-fragment-expected.html:
  • fast/regions/overflow-scrollable-rotated-fragment.html:
  • fast/regions/top-overflow-out-of-second-region-expected.html: Copied from LayoutTests/fast/regions/top-overflow-out-of-second-region.html.
  • fast/regions/top-overflow-out-of-second-region.html:
  • fast/regions/webkit-flow-float-unable-to-push-expected.html:
  • fast/regions/webkit-flow-float-unable-to-push.html:
  • platform/gtk/fast/regions/text-region-split-vertical-rl-expected.txt: Removed.
  • platform/mac-wk2/TestExpectations:
  • platform/mac/fast/regions/top-overflow-out-of-second-region-expected.png: Removed.
  • platform/mac/fast/regions/top-overflow-out-of-second-region-expected.txt: Removed.
Location:
trunk
Files:
18 added
5 deleted
49 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r159336 r159337  
     12013-11-15  Radu Stavila  <stavila@adobe.com>
     2
     3        [CSS Regions] Implement visual overflow for first & last regions
     4        https://bugs.webkit.org/show_bug.cgi?id=118665
     5
     6        Rebased some tests due to regions layers changes.
     7        Updated some tests to increase clarity. Some of them were only passing because two
     8        regions were close together and the fact that an element was being painted
     9        inside the wrong region was not visible. Floats are now also unsplittable.
     10                - bottom-overflow-out-of-first-region
     11                - float-pushed-width-change-2
     12                - float-pushed-width-change
     13                - webkit-flow-float-unable-to-push
     14
     15        Changed top-overflow-out-of-second-region to reftest.
     16
     17        Added new tests for testing the visual overflow in different situations
     18        (transformed, inline, opacity, floating).
     19
     20        Reviewed by David Hyatt.
     21
     22        * fast/regions/bottom-overflow-out-of-first-region-expected.html:
     23        * fast/regions/bottom-overflow-out-of-first-region.html:
     24        * fast/regions/counters/extract-ordered-lists-in-regions-explicit-counters-005-expected.html:
     25        * fast/regions/counters/extract-ordered-lists-in-regions-explicit-counters-005.html:
     26        * fast/regions/element-in-named-flow-absolute-from-fixed-expected.txt:
     27        * fast/regions/element-in-named-flow-fixed-from-absolute-expected.txt:
     28        * fast/regions/element-inflow-fixed-from-outflow-static-expected.txt:
     29        * fast/regions/element-outflow-static-from-inflow-fixed-expected.txt:
     30        * fast/regions/float-pushed-width-change-2-expected.html:
     31        * fast/regions/float-pushed-width-change-2.html:
     32        * fast/regions/float-pushed-width-change-expected.html:
     33        * fast/regions/float-pushed-width-change.html:
     34        * fast/regions/layers/dynamic-layer-added-with-no-layout-expected.txt: Added.
     35        * fast/regions/layers/dynamic-layer-removed-with-no-layout-expected.txt: Added.
     36        * fast/regions/layers/regions-promoted-to-layers-expected.txt: Added.
     37        * fast/regions/layers/regions-promoted-to-layers-horizontal-bt-expected.txt: Added.
     38        * fast/regions/layers/regions-promoted-to-layers-vertical-lr-expected.txt: Added.
     39        * fast/regions/layers/regions-promoted-to-layers-vertical-rl-expected.txt: Added.
     40        * fast/regions/outline-sides-in-region-expected.html:
     41        * fast/regions/outline-sides-in-region.html:
     42        * fast/regions/overflow-first-and-last-regions-expected.html: Added.
     43        * fast/regions/overflow-first-and-last-regions-in-container-hidden-expected.html: Added.
     44        * fast/regions/overflow-first-and-last-regions-in-container-hidden.html: Added.
     45        * fast/regions/overflow-first-and-last-regions.html: Added.
     46        * fast/regions/overflow-last-region-expected.html: Removed.
     47        * fast/regions/overflow-last-region.html: Removed.
     48        * fast/regions/overflow-nested-regions-expected.html: Added.
     49        * fast/regions/overflow-nested-regions.html: Added.
     50        * fast/regions/overflow-region-float-expected.html: Added.
     51        * fast/regions/overflow-region-float.html: Added.
     52        * fast/regions/overflow-region-inline-expected.html: Added.
     53        * fast/regions/overflow-region-inline.html: Added.
     54        * fast/regions/overflow-region-transform-expected.html: Added.
     55        * fast/regions/overflow-region-transform.html: Added.
     56        * fast/regions/overflow-scrollable-rotated-fragment-expected.html:
     57        * fast/regions/overflow-scrollable-rotated-fragment.html:
     58        * fast/regions/top-overflow-out-of-second-region-expected.html: Copied from LayoutTests/fast/regions/top-overflow-out-of-second-region.html.
     59        * fast/regions/top-overflow-out-of-second-region.html:
     60        * fast/regions/webkit-flow-float-unable-to-push-expected.html:
     61        * fast/regions/webkit-flow-float-unable-to-push.html:
     62        * platform/gtk/fast/regions/text-region-split-vertical-rl-expected.txt: Removed.
     63        * platform/mac-wk2/TestExpectations:
     64        * platform/mac/fast/regions/top-overflow-out-of-second-region-expected.png: Removed.
     65        * platform/mac/fast/regions/top-overflow-out-of-second-region-expected.txt: Removed.
     66
    1672013-11-15  Michał Pakuła vel Rutka  <m.pakula@samsung.com>
    268
  • trunk/LayoutTests/fast/regions/bottom-overflow-out-of-first-region-expected.html

    r138446 r159337  
    55            body { font: 16px/1.25 monospace; }
    66
    7             #region1, #region2 { border: 1px solid black; }
     7            #region1, #region2 { border: 1px solid red; }
    88
    99            #region1 {
    1010                width: 412px;
    11                 height: 210px;
     11                height: 140px;
    1212            }
    1313
     
    1515                width: 300px;
    1616                height: 150px;
     17                position: relative;
     18                left: 100px;
     19                top: 50px;
    1720            }
    1821
     
    2326            #first-box {
    2427                border: 1px solid blue;
    25                 height:200px;
     28                height:125px;
    2629            }
    2730
     
    2932                margin: auto;
    3033                border: 1px solid green;
    31                 border-bottom: 0px;
    3234                width: 75%;
    33                 height: 203px;
    3435            }
    3536
    36             #second-box-2 {
    37                 border: 1px solid green;
    38                 border-top: 0px;
    39                 width: 300px;
    40                 margin-left: 55px;
    41             }
    42 
    43             #p1, #p2, #p3 {
     37            #p1, #p2 {
    4438                margin: 0;
    4539            }
     
    4741    </head>
    4842    <body>
    49         <p>In the test case below, the green block's width should not vary and should use the first region to determine its width. It is overflowing downwards out of the blue block, and so the portion that overflows should continue to use the blue block's containing block width. The blue block does not exist in region two, so using some hypothetical made-up width is incorrect. The overflow should be spilling out of the top of region one and be painted in region two.</p>
     43        <p>In the test case below, the green block should not be fragmented into the second region. It is overflowing downwards out of the first region because its parent (the blue block) is only flowed inside the first region.</p>
    5044        <div id="region1">
    5145            <div id="content">
     
    5953        </div>
    6054        <div id="region2">
    61             <div id="second-box-2">
    62                 <p id="p3">These lines should all fit to the width of the block in the first region and spill out of the bottom of the first region.</p>
    63             </div>
    6455        </div>
    6556    </body>
  • trunk/LayoutTests/fast/regions/bottom-overflow-out-of-first-region.html

    r138446 r159337  
    1212            #first-box {
    1313                border: 1px solid blue;
    14                 height:200px;
     14                height:125px;
    1515            }
    1616
     
    2222
    2323            #region1, #region2 {
    24                 border: 1px solid black;
     24                border: 1px solid red;
    2525                -webkit-flow-from: flow1;
    2626            }
     
    2828            #region1 {
    2929                width: 412px;
    30                 height: 210px;
     30                height: 140px;
    3131            }
    3232
     
    3434                width: 300px;
    3535                height: 150px;
     36                position: relative;
     37                left: 100px;
     38                top: 50px;
    3639            }
    37             #p1, #p2, #p3 {
     40            #p1, #p2 {
    3841                margin: 0;
    3942            }
     
    4144    </head>
    4245    <body>
    43         <p>In the test case below, the green block's width should not vary and should use the first region to determine its width. It is overflowing downwards out of the blue block, and so the portion that overflows should continue to use the blue block's containing block width. The blue block does not exist in region two, so using some hypothetical made-up width is incorrect. The overflow should be spilling out of the top of region one and be painted in region two.</p>
     46        <p>In the test case below, the green block should not be fragmented into the second region. It is overflowing downwards out of the first region because its parent (the blue block) is only flowed inside the first region.</p>
    4447        <div id="content">
    4548            <div id="first-box">
     
    4750                    <p id="p1">These lines should all fit to the width of the block in the first region and spill out of the bottom of the first region.</p>
    4851                    <p id="p2">These lines should all fit to the width of the block in the first region and spill out of the bottom of the first region.</p>
    49                     <p id="p3">These lines should all fit to the width of the block in the first region and spill out of the bottom of the first region.</p>
    5052                </div>
    5153            </div>
  • trunk/LayoutTests/fast/regions/counters/extract-ordered-lists-in-regions-explicit-counters-005-expected.html

    r148878 r159337  
    7171        </style>
    7272    </head>
    73     <body>
     73    <body style="-webkit-font-smoothing: none;">
    7474        <p>This test passes if you see two gray rectangles, as described below. All numbering should be aligned to the right margin of the rectangles.</p>
    7575        <p>The first rectangle contains two numbered lists. The <strong>first list</strong> has three items and is numbered using bold roman numerals, starting at 1 (I). After the first item there's a numbered sublist; it is indented and has four items, numbered using decimal numbers preceded by an ellipsis (&hellip;), starting at 1. After the last item in this sublist there's a single item numbered list; the numbering is blue and uses three levels of numbering: roman, decimal and with latin letters, respectively; numbering starts with I.4-a. The <strong>second list</strong> has two items and uses the same blue, three-level numbering, that starts at I.3-a this time.</p>
  • trunk/LayoutTests/fast/regions/counters/extract-ordered-lists-in-regions-explicit-counters-005.html

    r148878 r159337  
    7878        </style>
    7979    </head>
    80     <body>
     80    <body style="-webkit-font-smoothing: none;">
    8181        <p>This test passes if you see two gray rectangles, as described below. All numbering should be aligned to the right margin of the rectangles.</p>
    8282        <p>The first rectangle contains two numbered lists. The <strong>first list</strong> has three items and is numbered using bold roman numerals, starting at 1 (I). After the first item there's a numbered sublist; it is indented and has four items, numbered using decimal numbers preceded by an ellipsis (&hellip;), starting at 1. After the last item in this sublist there's a single item numbered list; the numbering is blue and uses three levels of numbering: roman, decimal and with latin letters, respectively; numbering starts with I.4-a. The <strong>second list</strong> has two items and uses the same blue, three-level numbering, that starts at I.3-a this time.</p>
  • trunk/LayoutTests/fast/regions/element-in-named-flow-absolute-from-fixed-expected.txt

    r157567 r159337  
    11(repaint rects
    22  (rect 50 100 50 50)
     3  (rect 100 100 200 200)
     4  (rect 150 200 50 50)
    35  (rect 150 200 50 50)
    46)
  • trunk/LayoutTests/fast/regions/element-in-named-flow-fixed-from-absolute-expected.txt

    r157567 r159337  
    11(repaint rects
    22  (rect 150 200 50 50)
     3  (rect 100 100 200 200)
     4  (rect 50 100 50 50)
    35  (rect 50 100 50 50)
    46)
  • trunk/LayoutTests/fast/regions/element-inflow-fixed-from-outflow-static-expected.txt

    r157567 r159337  
    11(repaint rects
    22  (rect 300 300 50 50)
     3  (rect 100 100 200 200)
     4  (rect 50 100 50 50)
    35  (rect 50 100 50 50)
    46)
  • trunk/LayoutTests/fast/regions/element-outflow-static-from-inflow-fixed-expected.txt

    r157567 r159337  
    22  (rect 50 100 50 50)
    33  (rect 300 300 50 50)
     4  (rect 100 100 200 200)
    45)
    56
  • trunk/LayoutTests/fast/regions/float-pushed-width-change-2-expected.html

    r154281 r159337  
    77        position:absolute;
    88        width: 150px;
    9         height: 102px;
     9        height: 100px;
    1010        background-color:green;
    11         z-index:-1;
    1211    }
    1312   
     
    3534        padding-left:5px;
    3635        padding-right:5px;
     36        margin-left: 100px;
     37        margin-top: 50px;
    3738    }
    3839   
    3940    #region3 {
    40         width: 385px;
    41         height: 80px;
     41        width: 390px;
     42        height: 85px;
    4243        padding-left:5px;
    43         padding-right:10px;
    44         padding-bottom:10px;
     44        padding-right:5px;
     45        padding-bottom:5px;
     46        margin-left: 50px;
     47        margin-top: 50px;
    4548    }
    4649   
  • trunk/LayoutTests/fast/regions/float-pushed-width-change-2.html

    r154281 r159337  
    3535        width: 400px;
    3636        height: 90px;
     37        margin-left: 100px;
     38        margin-top: 50px;
    3739    }
    3840   
     
    4042        width: 400px;
    4143        height: 90px;
     44        margin-left: 50px;
     45        margin-top: 50px;
    4246    }
    4347
  • trunk/LayoutTests/fast/regions/float-pushed-width-change-expected.html

    r154281 r159337  
    22
    33 <style>
     4
     5    #content {
     6        padding: 5px;
     7        border: 1px solid red;
     8    }
    49   
    510    #float1 {
    611        float: left;
    7         position:absolute;
    812        width: 150px;
    9         height: 102px;
     13        height: 100px;
    1014        background-color:green;
    11         z-index:-1;
    1215    }
    1316   
    1417    #float2 {
    15         margin-top: 30px;
    16         margin-left: -30px;
    17         float:left;
     18        float:right;
    1819        width:200px;
    1920        height:30px;
     
    2324    #region1, #region2, #region3 {
    2425        border: 1px solid black;
     26        margin: 10px;
    2527    }
    2628 
    2729    #region1 {
    28         width: 170px;
    29         height: 80px;
    30         padding: 5px;
     30        margin-left: 30px;
     31        width: 180px;
     32        height: 90px;
    3133    }
    3234   
    3335    #region2 {
    34         width: 390px;
    35         height: 89px;
    36         padding-top:1px;
    37         padding-left:5px;
    38         padding-right:5px;
     36        margin-top: 80px;
     37        width: 400px;
     38        height: 90px;
    3939    }
    40    
    41     #region3 {
    42         width: 385px;
    43         height: 80px;
    44         padding-left:5px;
    45         padding-right:10px;
    46         padding-bottom:10px;
    47     }
    48        
     40
    4941        p.flow1 {
    5042                clear:both;
     
    5850</style>
    5951
    60 <p>In the example below, the green float should be at the top of the first region and on the left. It should spill into region two.
    61 The orange float should be right aligned under the green float because their containing block is flown only in the first region</p>
     52<p>In the example below, the green float should be at the top of the first region and on the left. It should overflow the first region.
     53The orange float should be right aligned under the green float and should overflow the first region because their containing block (red border) is flowed only in the first region.</p>
     54<p>No content should be displayed in the second region.</p>
    6255
    6356<div id="region1">
    64      <p><img id="float1"></p>
     57    <div id="content">
     58        <img id="float1"><img id="float2">
     59    </div>
    6560</div>
    66 <div id="region2">
    67     <img id="float2">
    68     <p class="flow1">This line of text should not get out of the region.</p>
    69 </div>
    70 <div id="region3">
    71 <p class="flow2">This line of text should not get out of the region. This line of text should not get out of the region.</p>
    72 <p>This line of text should not get out of the region.</p>
    73 </div>
     61<div id="region2"></div>
    7462
  • trunk/LayoutTests/fast/regions/float-pushed-width-change.html

    r154281 r159337  
    66        -webkit-flow-into: flow1;
    77        padding: 5px;
     8        border: 1px solid red;
    89    }
    910 
     
    1920        width:200px;
    2021        height:30px;
    21         background-color:orange
     22        background-color:orange;
    2223    }
    2324
    2425    #region1, #region2, #region3 {
     26        margin: 10px;
    2527        border: 1px solid black;
    2628        -webkit-flow-from: flow1;
     
    2830
    2931    #region1 {
     32        margin-left: 30px;
    3033        width: 180px;
    3134        height: 90px;
     
    3336   
    3437    #region2 {
    35         width: 400px;
    36         height: 90px;
    37     }
    38    
    39     #region3 {
     38        margin-top: 80px;
    4039        width: 400px;
    4140        height: 90px;
     
    4342</style>
    4443
    45 <p>In the example below, the green float should be at the top of the first region and on the left. It should spill into region two.
    46 The orange float should be right aligned under the green float because their containing block is flown only in the first region</p>
     44<p>In the example below, the green float should be at the top of the first region and on the left. It should overflow the first region.
     45The orange float should be right aligned under the green float and should overflow the first region because their containing block (red border) is flowed only in the first region.</p>
     46<p>No content should be displayed in the second region.</p>
    4747
    4848<div id="content">
    4949    <div id="first-box">
    5050        <div id="second-box">
    51             <p><img id="float1"><img id="float2"><p/>
    52             <p>This line of text should not get out of the region.</p>
    53             <p>This line of text should not get out of the region. This line of text should not get out of the region.</p>
    54             <p>This line of text should not get out of the region.</p>
    55            
     51            <img id="float1"><img id="float2">
    5652        </div>
    5753    </div>
     
    6157    <div id="region1"></div>
    6258    <div id="region2"></div>
    63     <div id="region3"></div>
    6459</div>
  • trunk/LayoutTests/fast/regions/outline-sides-in-region-expected.html

    r102830 r159337  
    22<style type="text/css">
    33       
    4         h1{
     4        h1 {
    55                outline: 5px solid yellow;
     6                margin-top: 0px;
    67        }
    78       
    8         div{
     9        div {
    910                width:200px;
    10                 height:200px;                   
     11                height:100px;
     12                margin-bottom: 20px;
    1113        }
    1214</style>
    1315<body>
    14         <div>
     16        <div style="border: 1px solid red">
     17                <div>
     18                        <h1>&nbsp;</h1>
     19                </div>
     20        </div>
     21        <div style="border: 1px solid red; overflow: hidden;">
    1522                <div>
    1623                        <h1>&nbsp;</h1>
  • trunk/LayoutTests/fast/regions/outline-sides-in-region.html

    r102830 r159337  
    22<style type="text/css">
    33       
    4         h1{
     4        h1 {
    55                outline: 5px solid yellow;
    6         }
    7        
    8         #source > h1 {
    96                margin-top: 0;
    107        }
     
    1310                -webkit-flow-into: body;
    1411        }
     12
     13        #source_clipped {
     14                -webkit-flow-into: body_clipped;
     15        }
    1516       
    1617        #region{
    1718                -webkit-flow-from: body;
     19                border: 1px solid red;
    1820        }
    19         div{
     21
     22        #region_clipped {
     23                -webkit-flow-from: body_clipped;
     24                border: 1px solid red;
     25                overflow: hidden;
     26        }
     27        div {
    2028                width:200px;
    21                 height:200px;                   
     29                height:100px;
     30                margin-bottom: 20px;
    2231        }
    2332</style>
    2433<body>
    25         <div id="source">
     34        <div id="source" class="source">
     35                <h1>&nbsp;</h1>
     36        </div>
     37
     38        <div id="source_clipped" class="source">
    2639                <h1>&nbsp;</h1>
    2740        </div>
    2841       
    2942        <div id="region"></div>
     43        <div id="region_clipped"></div>
     44
    3045        <div>
    3146                <h1>&nbsp;</h1>
  • trunk/LayoutTests/fast/regions/overflow-scrollable-rotated-fragment-expected.html

    r155026 r159337  
    33    <head>
    44        <style>
    5             .no_overflow { margin: 2px; -webkit-transform: rotate(-25deg);}
     5            .no_overflow { margin: 2px; -webkit-transform: rotate(-90deg);}
    66
    77            #region1, #region2 { height: 100px; }
  • trunk/LayoutTests/fast/regions/overflow-scrollable-rotated-fragment.html

    r155026 r159337  
    77            }
    88
    9             .no_overflow { margin: 2px; -webkit-transform: rotate(-25deg);}
     9            .no_overflow { margin: 2px; -webkit-transform: rotate(-90deg); }
    1010
    1111            #region1, #region2 { -webkit-flow-from: flow; height: 100px; }
  • trunk/LayoutTests/fast/regions/top-overflow-out-of-second-region-expected.html

    r159336 r159337  
    33 <style>
    44    #content {
    5         -webkit-flow-into: flow1;
    65        text-align: justify;
    76        padding: 5px;
     7        margin-top: -105px;
    88    }
    99   
     
    1919    }
    2020   
    21     #region1, #region2, #region3 {
    22         border: 1px solid black;
    23         -webkit-flow-from: flow1;
     21    #region1, #region2 {
     22        border: 1px solid red;
    2423    }
    2524
     
    3231        width: 400px;
    3332        height: 200px;
    34     }
    35 
    36     #region3 {
    37         width: 0px;
    38         height: 0px;
     33        margin-left: 300px;
     34        margin-top: 50px;
    3935    }
    4036</style>
     
    4743The overflow should be spilling out of the top of region two and be painted in region one.
    4844
    49 <div id="content">
    50     <div id="first-box">
    51         <div id="second-box">
    52             <p>These lines should all fit to the width of the block in the second region and spill out of the top of the second
    53             region.</P>
    54              <p>These lines should all fit to the width of the block in the second region and spill out of the top of the second
    55             region.</P>
     45
     46
     47<div id="container">
     48    <div id="region1"></div>
     49    <div id="region2">
     50        <div id="content">
     51            <div id="first-box">
     52                <div id="second-box">
     53                    <p>These lines should all fit to the width of the block in the second region and spill out of the top of the second
     54                    region.</P>
     55                     <p>These lines should all fit to the width of the block in the second region and spill out of the top of the second
     56                    region.</P>
     57                </div>
     58            </div>
    5659        </div>
    5760    </div>
    5861</div>
    59 
    60 <div id="container">
    61     <div id="region1"></div>
    62     <div id="region2"></div>
    63     <div id="region3"></div>
    64 </div>
  • trunk/LayoutTests/fast/regions/top-overflow-out-of-second-region.html

    r128155 r159337  
    1919    }
    2020   
    21     #region1, #region2, #region3 {
    22         border: 1px solid black;
     21    #region1, #region2 {
     22        border: 1px solid red;
    2323        -webkit-flow-from: flow1;
    2424    }
     
    3232        width: 400px;
    3333        height: 200px;
     34        margin-left: 300px;
     35        margin-top: 50px;
    3436    }
    3537
  • trunk/LayoutTests/fast/regions/webkit-flow-float-unable-to-push-expected.html

    r149802 r159337  
    1313    /* Created to justify the last line of text in the div */
    1414    #paragraph1:after {
    15         content: " ____";
     15        content: " ________";
    1616        line-height: 0;
    1717        visibility: hidden;
    1818    }
     19
     20    .region {
     21        border: 3px solid black;
     22        border-left: 10px solid black;
     23    }
     24
     25    .content {
     26        border: 2px solid red;
     27        padding: 5px;
     28    }
     29
     30    .first-box {
     31        border: 3px solid blue;
     32        background-color: #ffff00;
     33    }
     34
     35    .second-box {
     36        border: 6px solid green;
     37        background-color: #ffffaa;
     38    }
    1939   
    2040    #region1 {
    21         border: 1px solid black;
    22         width: 390px;
    23         height: 80px;
    24         padding: 5px;
     41        width: 400px;
     42        height: 90px;
     43        margin-left: 50px;
     44    }
     45
     46    #content1 {
     47        border-bottom: none;
     48        height: 78px;
    2549    }
    2650   
    2751    #first-box1 {
    28         border: 1px solid blue;
    2952        border-bottom: none;
     53        height: 80px;
    3054    }
    3155   
    3256    #second-box1 {
    3357        margin:10px;
    34         border: 1px solid green;
    3558        border-bottom: none;
    36         width: 366px;
    37         height: 73px;
     59        height: 64px;
    3860    }
    3961
     
    4466    /* Created to justify the last line of text in the div */
    4567    #second-paragraph2:after {
    46         content: " ____";
     68        content: " ________";
    4769        line-height: 0;
    4870        visibility: hidden;
     
    5072   
    5173    #region2 {
    52         border: 1px solid black;
    53         width: 290px;
    54         height: 80px;
    55         padding: 5px;
     74        width: 300px;
     75        height: 90px;
     76        margin-top: 70px;
     77    }
     78
     79    #content2 {
     80        border-bottom: none;
     81        border-top: none;
     82        height: 85px;
     83        padding-top: 0px;
    5684    }
    5785   
    5886    #first-box2 {
    59         border: 1px solid blue;
    6087        border-top: none;
    6188        border-bottom: none;
     89        padding-left: 10px;
     90        padding-right: 10px;
    6291    }
    6392   
    6493    #second-box2 {
    65         margin-left:10px;
    66         margin-top: -5px;
    67         padding: 0px;
    68         border: 1px solid green;
    6994        border-top: none;
    7095        border-bottom: none;
    71         width: 266px;
    7296        height: 90px;
    7397    }
     
    78102
    79103    #region3 {
    80         border: 1px solid black;
    81         width: 390px;
    82         height: 80px;
    83         padding: 5px;
     104        width: 400px;
     105        height: 120px;
     106        margin-top: 50px;
     107        margin-left: 20px;
     108    }
     109
     110    #content3 {
     111        border-top: none;
     112        aheight: 109px;
     113        padding-top: 0px;
    84114    }
    85115   
    86116    #first-box3 {
    87         border: 1px solid blue;
    88117        border-top: none;
     118        padding-left: 10px;
     119        padding-right: 10px;
     120        padding-bottom: 10px;
    89121    }
    90122   
    91123    #second-box3 {
    92         margin:10px;
    93         margin-top: -5px;
    94         border: 1px solid green;
    95124        border-top: none;
    96         width: 366px;
    97     }
    98 
    99     .imgFloat {
    100         float: right;
    101         background-color:green;
    102125    }
    103126
    104127    #float1 {
     128        float: right;
     129        background-color:green;
     130        border: 2px solid red;
    105131        width: 130px;
    106         height: 63px;
     132        height: 100px;
    107133    }
    108134
    109135    #float2 {
    110         width: 30px;
    111         height: 37px;
    112     }
    113 
    114     #imgAbsolute {
    115         position: absolute;
    116         background-color: green;
    117         width: 100px;
    118         height: 37px;
    119         left: 292px;
    120         top: 101px;
     136        float: right;
     137        width: 34px;
     138        height: 70px;
     139        visibility: hidden;
    121140    }
    122141</style>
    123142
    124 <div id="content">
    125     <div id="region1">
    126         <div id="first-box1">
    127             <div id="second-box1">
    128                 <div class="test_paragraph" id="paragraph1">This <img class="imgFloat" id="float1" src="resources/transparent.png">line of text should not get out of the region. This line of text should not get out of the region. This line of text should not</div>
     143<div>
     144    <div class="region" id="region1">
     145        <div class="content" id="content1">
     146            <div class="first-box" id="first-box1">
     147                <div class="second-box" id="second-box1">
     148                    <div class="test_paragraph" id="paragraph1">This <img id="float1" src="resources/transparent.png">line of text should not get out of the region. This line of text should not get out of the</div>
     149                </div>
    129150            </div>
    130151        </div>
    131152    </div>
    132153   
    133     <div id="region2">
    134         <div id="first-box2">
    135             <div id="second-box2">
    136                 <div class="test_paragraph" id="first-paragraph2">get<img class="imgFloat" id="float2" src="resources/transparent.png"> out of the region. This line of text should not get out of the region.</div>
    137                 <div class="test_paragraph" id="second-paragraph2">This line of text should not get out of the region. This line of text should not get out of the region.</div>
     154    <div class="region" id="region2">
     155        <div class="content" id="content2">
     156            <div class="first-box" id="first-box2">
     157                <div class="second-box" id="second-box2">
     158                    <div class="test_paragraph" id="first-paragraph2">region. <img id="float2" src="resources/transparent.png">This line of text should not get out of the region. This line of text should not get out of the region.</div>
     159                    <div class="test_paragraph" id="second-paragraph2">This line of text should not get out of the</div>
     160                </div>
    138161            </div>
    139162        </div>
    140163    </div>
    141164
    142     <img id="imgAbsolute" src="resources/transparent.png">
    143    
    144     <div id="region3">
    145         <div id="first-box3">
    146             <div id="second-box3">
    147                 <div class="test_paragraph" id="first-paragraph3">This line of text should not get out of the region. This line of text should not get out of the region.</div>
    148                 <div class="test_paragraph" id="second-paragraph3">This line of text should not get out of the region.</div>
     165    <div class="region" id="region3">
     166        <div class="content" id="content3">
     167            <div class="first-box" id="first-box3">
     168                <div class="second-box" id="second-box3">
     169                    <div class="test_paragraph" id="first-paragraph3">region. This line of text should not get out of the region. This line of text should not get out of the region. This line of text should not get out of the region.</div>
     170                    <div class="test_paragraph" id="second-paragraph3">This line of text should not get out of the region.</div>
     171                </div>
    149172            </div>
    150173        </div>
  • trunk/LayoutTests/fast/regions/webkit-flow-float-unable-to-push.html

    r149802 r159337  
    99        font-family: Ahem;
    1010        -webkit-font-smoothing: none;
     11        border: 2px solid red;
    1112    }
    1213   
    1314    #first-box {
    14         border: 1px solid blue;
     15        border: 3px solid blue;
     16        background-color: #ffff00;
    1517    }
    1618   
    1719    #second-box {
    1820        margin:10px;
    19         border: 1px solid green;
     21        border: 6px solid green;
     22        background-color: #ffffaa;
    2023    }
    2124   
     
    2528        height: 100px;
    2629        background-color:green;
     30        border: 2px solid red;
    2731    }
    2832   
    2933    #region1, #region2, #region3 {
    30         border: 1px solid black;
     34        border: 3px solid black;
     35        border-left: 10px solid black;
    3136        -webkit-flow-from: flow1;
    3237    }
     
    3540        width: 400px;
    3641        height: 90px;
     42        margin-left: 50px;
    3743    }
    3844   
     
    4046        width: 300px;
    4147        height: 90px;
     48        margin-top: 70px;
    4249    }
    4350   
    4451    #region3 {
    4552        width: 400px;
    46         height: 90px;
     53        height: 120px;
     54        margin-top: 50px;
     55        margin-left: 20px;
    4756    }
    4857</style>
  • trunk/LayoutTests/fast/repaint/increasing-region-content-height-expected.txt

    r159132 r159337  
    1 On success, the text inside the region should not be clipped
    21This text should not get clipped
    32(repaint rects
    4   (rect 0 18 800 50)
    5   (rect 0 218 800 50)
    6   (rect 0 218 800 50)
    7   (rect 0 18 400 200)
    8   (rect 0 68 400 200)
     3  (rect 0 0 800 50)
     4  (rect 0 200 800 50)
     5  (rect 0 200 800 50)
     6  (rect 0 0 400 200)
     7  (rect 0 50 400 200)
     8  (rect 0 50 400 200)
    99)
    1010
  • trunk/LayoutTests/fast/repaint/increasing-region-content-height.html

    r159132 r159337  
    2121        </head>
    2222        <body onload="runRepaintTest();">
    23                 <p>On success, the text inside the region should not be clipped</p>
    2423                <div id="box"></div>
    2524                <div class="content">
  • trunk/LayoutTests/platform/mac-wk2/TestExpectations

    r159257 r159337  
    338338webkit.org/b/107018 svg/animations/mozilla/animateMotion-mpath-pathLength-1.svg [ ImageOnlyFailure Pass ]
    339339
    340 # Region overflow doesn't quite work with tiled drawing.
    341 webkit.org/b/122233 fast/regions/percentage-margins-mixed-ltr-dominant-regions.html [ ImageOnlyFailure ]
    342 webkit.org/b/122233 fast/regions/percentage-margins-mixed-rtl-dominant-regions.html [ ImageOnlyFailure ]
    343 webkit.org/b/122233 fast/regions/percentage-margins-rtl-variable-width-regions.html [ ImageOnlyFailure ]
    344 webkit.org/b/122233 fast/regions/percentage-margins-variable-width-regions.html [ ImageOnlyFailure ]
    345 webkit.org/b/122233 fast/regions/frame-view-overflow-scroll.html [ ImageOnlyFailure ]
    346 
    347340# Color space issues from switching to tiled drawing.
    348341webkit.org/b/122234 fast/css/computed-image-width-with-percent-height.html [ ImageOnlyFailure ]
  • trunk/Source/WebCore/ChangeLog

    r159335 r159337  
     12013-11-15  Radu Stavila  <stavila@adobe.com>
     2
     3        [CSS Regions] Implement visual overflow for first & last regions
     4        https://bugs.webkit.org/show_bug.cgi?id=118665
     5
     6        In order to properly propagate the visual overflow of elements flowed inside regions,
     7        the responsiblity of painting and hit-testing content inside flow threads has been
     8        moved to the flow thread layer's level.
     9        Each region keeps the associated overflow with each box in the RenderBoxRegionInfo
     10        structure, including one for the flow thread itself. This data is used during
     11        painting and hit-testing.
     12
     13        Reviewed by David Hyatt.
     14
     15        Tests: fast/regions/overflow-first-and-last-regions-in-container-hidden.html
     16               fast/regions/overflow-first-and-last-regions.html
     17               fast/regions/overflow-nested-regions.html
     18               fast/regions/overflow-region-float.html
     19               fast/regions/overflow-region-inline.html
     20               fast/regions/overflow-region-transform.html
     21
     22        * rendering/InlineFlowBox.cpp:
     23        (WebCore::InlineFlowBox::setLayoutOverflow):
     24        (WebCore::InlineFlowBox::setVisualOverflow):
     25        * rendering/InlineFlowBox.h:
     26        * rendering/RenderBlock.cpp:
     27        (WebCore::RenderBlock::addOverflowFromChildren):
     28        (WebCore::RenderBlock::paint):
     29        (WebCore::RenderBlock::paintObject):
     30        (WebCore::RenderBlock::estimateRegionRangeForBoxChild):
     31        (WebCore::RenderBlock::updateRegionRangeForBoxChild):
     32        * rendering/RenderBlockFlow.cpp:
     33        (WebCore::RenderBlockFlow::hasNextPage):
     34        (WebCore::RenderBlockFlow::relayoutForPagination):
     35        * rendering/RenderBlockLineLayout.cpp:
     36        (WebCore::RenderBlockFlow::positionNewFloatOnLine):
     37        * rendering/RenderBox.cpp:
     38        (WebCore::RenderBox::borderBoxRectInRegion):
     39        (WebCore::RenderBox::computeRectForRepaint):
     40        (WebCore::RenderBox::addLayoutOverflow):
     41        (WebCore::RenderBox::addVisualOverflow):
     42        (WebCore::RenderBox::isUnsplittableForPagination):
     43        (WebCore::RenderBox::overflowRectForPaintRejection):
     44        * rendering/RenderBox.h:
     45        (WebCore::RenderBox::canHaveOutsideRegionRange):
     46        * rendering/RenderBoxModelObject.cpp:
     47        (WebCore::RenderBoxModelObject::paintMaskForTextFillBox):
     48        (WebCore::RenderBoxModelObject::paintFillLayerExtended):
     49        * rendering/RenderBoxModelObject.h:
     50        * rendering/RenderBoxRegionInfo.h:
     51        (WebCore::RenderBoxRegionInfo::createOverflow):
     52        * rendering/RenderFlowThread.cpp:
     53        (WebCore::RenderFlowThread::objectShouldPaintInFlowRegion):
     54        (WebCore::RenderFlowThread::mapFromLocalToFlowThread):
     55        (WebCore::RenderFlowThread::mapFromFlowThreadToLocal):
     56        (WebCore::RenderFlowThread::decorationsClipRectForBoxInRegion):
     57        (WebCore::RenderFlowThread::flipForWritingModeLocalCoordinates):
     58        (WebCore::RenderFlowThread::addRegionsOverflowFromChild):
     59        (WebCore::RenderFlowThread::addRegionsVisualOverflow):
     60        (WebCore::CurrentRenderFlowThreadMaintainer::CurrentRenderFlowThreadMaintainer):
     61        * rendering/RenderFlowThread.h:
     62        * rendering/RenderLayer.cpp:
     63        (WebCore::RenderLayer::updateLayerPositions):
     64        (WebCore::expandClipRectForRegionAndReflection):
     65        (WebCore::expandClipRectForDescendantsAndReflection):
     66        (WebCore::RenderLayer::paintLayer):
     67        (WebCore::RenderLayer::paintLayerContents):
     68        (WebCore::RenderLayer::updatePaintingInfoForFragments):
     69        (WebCore::RenderLayer::paintForegroundForFragments):
     70        (WebCore::RenderLayer::hitTest):
     71        (WebCore::RenderLayer::hitTestLayer):
     72        (WebCore::RenderLayer::mapLayerClipRectsToFragmentationLayer):
     73        (WebCore::RenderLayer::calculateClipRects):
     74        (WebCore::RenderLayer::parentClipRects):
     75        (WebCore::RenderLayer::calculateRects):
     76        (WebCore::RenderLayer::intersectsDamageRect):
     77        (WebCore::RenderLayer::updateDescendantsLayerListsIfNeeded):
     78        (WebCore::RenderLayer::repaintIncludingDescendants):
     79        (WebCore::RenderLayer::paintNamedFlowThreadInsideRegion):
     80        (WebCore::RenderLayer::paintFlowThreadIfRegion):
     81        (WebCore::RenderLayer::hitTestFlowThreadIfRegion):
     82        * rendering/RenderLayer.h:
     83        (WebCore::ClipRect::inflateX):
     84        (WebCore::ClipRect::inflateY):
     85        (WebCore::ClipRect::inflate):
     86        * rendering/RenderLayerCompositor.cpp:
     87        (WebCore::RenderLayerCompositor::computeCompositingRequirements):
     88        * rendering/RenderListItem.cpp:
     89        (WebCore::RenderListItem::addOverflowFromChildren):
     90        * rendering/RenderMultiColumnSet.cpp:
     91        (WebCore::RenderMultiColumnSet::flowThreadPortionOverflowRect):
     92        (WebCore::RenderMultiColumnSet::repaintFlowThreadContent):
     93        * rendering/RenderMultiColumnSet.h:
     94        * rendering/RenderNamedFlowFragment.cpp:
     95        (WebCore::RenderNamedFlowFragment::createStyle):
     96        (WebCore::RenderNamedFlowFragment::namedFlowThread):
     97        * rendering/RenderNamedFlowFragment.h:
     98        * rendering/RenderOverflow.h:
     99        * rendering/RenderRegion.cpp:
     100        (WebCore::RenderRegion::flowThreadPortionOverflowRect):
     101        (WebCore::RenderRegion::flowThreadPortionLocation):
     102        (WebCore::RenderRegion::regionContainerLayer):
     103        (WebCore::RenderRegion::overflowRectForFlowThreadPortion):
     104        (WebCore::RenderRegion::computeOverflowFromFlowThread):
     105        (WebCore::RenderRegion::repaintFlowThreadContent):
     106        (WebCore::RenderRegion::repaintFlowThreadContentRectangle):
     107        (WebCore::RenderRegion::insertedIntoTree):
     108        (WebCore::RenderRegion::ensureOverflowForBox):
     109        (WebCore::RenderRegion::rectFlowPortionForBox):
     110        (WebCore::RenderRegion::addLayoutOverflowForBox):
     111        (WebCore::RenderRegion::addVisualOverflowForBox):
     112        (WebCore::RenderRegion::layoutOverflowRectForBox):
     113        (WebCore::RenderRegion::visualOverflowRectForBox):
     114        (WebCore::RenderRegion::visualOverflowRectForBoxForPropagation):
     115        * rendering/RenderRegion.h:
     116        * rendering/RenderReplaced.cpp:
     117        (WebCore::RenderReplaced::shouldPaint):
     118        * rendering/RootInlineBox.cpp:
     119        (WebCore::RootInlineBox::paint):
     120
    11212013-11-15  Stephane Jadaud  <sjadaud@sii.fr>
    2122
  • trunk/Source/WebCore/rendering/InlineFlowBox.cpp

    r159049 r159337  
    976976
    977977    if (!m_overflow)
    978         m_overflow = adoptPtr(new RenderOverflow(frameBox, frameBox));
     978        m_overflow = adoptRef(new RenderOverflow(frameBox, frameBox));
    979979   
    980980    m_overflow->setLayoutOverflow(rect);
     
    988988       
    989989    if (!m_overflow)
    990         m_overflow = adoptPtr(new RenderOverflow(frameBox, frameBox));
     990        m_overflow = adoptRef(new RenderOverflow(frameBox, frameBox));
    991991   
    992992    m_overflow->setVisualOverflow(rect);
  • trunk/Source/WebCore/rendering/InlineFlowBox.h

    r159049 r159337  
    303303
    304304protected:
    305     OwnPtr<RenderOverflow> m_overflow;
     305    RefPtr<RenderOverflow> m_overflow;
    306306
    307307    InlineBox* m_firstChild;
  • trunk/Source/WebCore/rendering/RenderBlock.cpp

    r159192 r159337  
    16131613        else
    16141614            addOverflowFromBlockChildren();
     1615       
     1616        // If this block is flowed inside a flow thread, make sure its overflow is propagated to the containing regions.
     1617        if (m_overflow) {
     1618            if (RenderFlowThread* containingFlowThread = flowThreadContainingBlock())
     1619                containingFlowThread->addRegionsVisualOverflow(this, m_overflow->visualOverflowRect());
     1620        }
    16151621    } else {
    16161622        ColumnInfo* colInfo = columnInfo();
     
    21782184    PaintPhase phase = paintInfo.phase;
    21792185
     2186    // Check our region range to make sure we need to be painting in this region.
     2187    if (paintInfo.renderRegion && !paintInfo.renderRegion->flowThread()->objectShouldPaintInFlowRegion(this, paintInfo.renderRegion))
     2188        return;
     2189
    21802190    // Check if we need to do anything at all.
    21812191    // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView
    21822192    // paints the root's background.
    21832193    if (!isRoot()) {
    2184         LayoutRect overflowBox = overflowRectForPaintRejection();
     2194        LayoutRect overflowBox = overflowRectForPaintRejection(paintInfo.renderRegion);
    21852195        flipForWritingMode(overflowBox);
    21862196        overflowBox.inflate(maximalOutlineSize(paintInfo.phase));
     
    24712481    // 1. paint background, borders etc
    24722482    if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) && style().visibility() == VISIBLE) {
    2473         if (hasBoxDecorations())
     2483        if (hasBoxDecorations()) {
     2484            bool didClipToRegion = false;
     2485           
     2486            if (paintInfo.paintContainer && paintInfo.renderRegion && paintInfo.paintContainer->isRenderFlowThread()) {
     2487                // If this box goes beyond the current region, then make sure not to overflow the region.
     2488                // This (overflowing region X altough also fragmented to region X+1) could happen when one of this box's children
     2489                // overflows region X and is an unsplittable element (like an image).
     2490                // The same applies for a box overflowing the top of region X when that box is also fragmented in region X-1.
     2491
     2492                paintInfo.context->save();
     2493                didClipToRegion = true;
     2494
     2495                paintInfo.context->clip(toRenderFlowThread(paintInfo.paintContainer)->decorationsClipRectForBoxInRegion(*this, *paintInfo.renderRegion));
     2496            }
     2497
    24742498            paintBoxDecorations(paintInfo, paintOffset);
     2499           
     2500            if (didClipToRegion)
     2501                paintInfo.context->restore();
     2502        }
    24752503        if (hasColumns() && !paintInfo.paintRootBackgroundOnly())
    24762504            paintColumnRules(paintInfo, paintOffset);
     
    51795207}
    51805208
    5181 
    51825209ColumnInfo::PaginationUnit RenderBlock::paginationUnit() const
    51835210{
     
    52375264{
    52385265    RenderFlowThread* flowThread = flowThreadContainingBlock();
    5239     if (!flowThread || !flowThread->hasRegions())
     5266    if (!flowThread || !flowThread->hasRegions() || !box.canHaveOutsideRegionRange())
    52405267        return;
    52415268
     
    52585285{
    52595286    RenderFlowThread* flowThread = flowThreadContainingBlock();
    5260     if (!flowThread || !flowThread->hasRegions())
     5287    if (!flowThread || !flowThread->hasRegions() || !box.canHaveOutsideRegionRange())
    52615288        return false;
    52625289
  • trunk/Source/WebCore/rendering/RenderBlockFlow.cpp

    r159150 r159337  
    15711571    // See if we're in the last region.
    15721572    LayoutUnit pageOffset = offsetFromLogicalTopOfFirstPage() + logicalOffset;
    1573     RenderRegion* region = flowThread->regionAtBlockOffset(this, pageOffset, this);
     1573    RenderRegion* region = flowThread->regionAtBlockOffset(this, pageOffset, true);
    15741574    if (!region)
    15751575        return false;
     
    15771577        return region->isRenderRegionSet() || region->style().regionFragment() == BreakRegionFragment
    15781578            || (pageBoundaryRule == IncludePageBoundary && pageOffset == region->logicalTopForFlowThreadContent());
     1579
     1580    RenderRegion* startRegion = 0;
     1581    RenderRegion* endRegion = 0;
     1582    flowThread->getRegionRangeForBox(this, startRegion, endRegion);
     1583
     1584    if (region == endRegion)
     1585        return false;
    15791586    return true;
    15801587}
     
    30923099        return false;
    30933100
    3094     OwnPtr<RenderOverflow> savedOverflow = m_overflow.release();
     3101    RefPtr<RenderOverflow> savedOverflow = m_overflow.release();
    30953102    if (childrenInline())
    30963103        addOverflowFromInlineChildren();
  • trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp

    r159071 r159337  
    36613661            RenderBox& floatBox = floatingObject->renderer();
    36623662            setLogicalTopForChild(floatBox, logicalTopForChild(floatBox) + marginBeforeForChild(floatBox) + paginationStrut);
    3663             if (floatBox.isRenderBlock())
     3663
     3664            if (updateRegionRangeForBoxChild(floatingObject->renderer()))
     3665                floatBox.setNeedsLayout(MarkOnlyThis);
     3666            else if (floatBox.isRenderBlock())
    36643667                toRenderBlock(floatBox).setChildNeedsLayout(MarkOnlyThis);
    36653668            floatBox.layoutIfNeeded();
     3669
    36663670            // Save the old logical top before calling removePlacedObject which will set
    36673671            // isPlaced to false. Otherwise it will trigger an assert in logicalTopForFloat.
  • trunk/Source/WebCore/rendering/RenderBox.cpp

    r159027 r159337  
    165165    RenderRegion* endRegion = 0;
    166166    flowThread->getRegionRangeForBox(this, startRegion, endRegion);
    167 
     167   
    168168    // FIXME: In a perfect world this condition should never happen.
    169169    if (!startRegion || !endRegion)
    170170        return borderBoxRect();
    171171
    172     // FIXME: Once overflow is implemented this assertion needs to be enabled. Right now the overflow content is painted
    173     // in regions outside the box range so the assert is disabled.
    174     // ASSERT(clampToStartAndEndRegions(region) == region);
    175 
    176     // FIXME: Remove once boxes are painted inside their region range.
    177     region = clampToStartAndEndRegions(region);
     172    ASSERT(flowThread->regionInRange(region, startRegion, endRegion));
    178173
    179174    // Compute the logical width and placement in this region.
     
    20662061    if (!o)
    20672062        return;
     2063
     2064    if (o->isRenderFlowThread()) {
     2065        RenderRegion* firstRegion = 0;
     2066        RenderRegion* lastRegion = 0;
     2067        toRenderFlowThread(o)->getRegionRangeForBox(this, firstRegion, lastRegion);
     2068        if (firstRegion)
     2069            rect.moveBy(firstRegion->flowThreadPortionRect().location());
     2070    }
    20682071
    20692072    if (isWritingModeRoot() && !isOutOfFlowPositioned())
     
    42754278
    42764279    if (!m_overflow)
    4277         m_overflow = adoptPtr(new RenderOverflow(clientBox, borderBoxRect()));
     4280        m_overflow = adoptRef(new RenderOverflow(clientBox, borderBoxRect()));
    42784281   
    42794282    m_overflow->addLayoutOverflow(overflowRect);
     
    42874290       
    42884291    if (!m_overflow)
    4289         m_overflow = adoptPtr(new RenderOverflow(clientBoxRect(), borderBox));
     4292        m_overflow = adoptRef(new RenderOverflow(clientBoxRect(), borderBox));
    42904293   
    42914294    m_overflow->addVisualOverflow(rect);
     
    43684371bool RenderBox::isUnsplittableForPagination() const
    43694372{
    4370     return isReplaced() || hasUnsplittableScrollingOverflow() || (parent() && isWritingModeRoot());
     4373    return isReplaced() || hasUnsplittableScrollingOverflow() || (parent() && isWritingModeRoot())
     4374        // FIXME: Treat multi-column elements as unsplittable for now. Remove once we implement the correct
     4375        // fragmentation model for multicolumn.
     4376        || isRenderMultiColumnBlock();
    43714377}
    43724378
     
    44754481}
    44764482
    4477 LayoutRect RenderBox::overflowRectForPaintRejection() const
     4483LayoutRect RenderBox::overflowRectForPaintRejection(RenderRegion* region) const
    44784484{
    44794485    LayoutRect overflowRect = visualOverflowRect();
     4486   
     4487    // When using regions, some boxes might have their frame rect relative to the flow thread, which could
     4488    // cause the paint rejection algorithm to prevent them from painting when using different width regions.
     4489    // e.g. an absolutely positioned box with bottom:0px and right:0px would have it's frameRect.x relative
     4490    // to the flow thread, not the last region (in which it will end up because of bottom:0px)
     4491    if (region) {
     4492        if (RenderFlowThread* flowThread = region->flowThread()) {
     4493            RenderRegion* startRegion = 0;
     4494            RenderRegion* endRegion = 0;
     4495            flowThread->getRegionRangeForBox(this, startRegion, endRegion);
     4496
     4497            if (startRegion && endRegion)
     4498                overflowRect.unite(region->visualOverflowRectForBox(this));
     4499        }
     4500    }
     4501   
    44804502    if (!m_overflow || !usesCompositedScrolling())
    44814503        return overflowRect;
  • trunk/Source/WebCore/rendering/RenderBox.h

    r158842 r159337  
    190190    LayoutUnit logicalRightVisualOverflow() const { return style().isHorizontalWritingMode() ? visualOverflowRect().maxX() : visualOverflowRect().maxY(); }
    191191
    192     LayoutRect overflowRectForPaintRejection() const;
     192    LayoutRect overflowRectForPaintRejection(RenderRegion*) const;
    193193   
    194194    void addLayoutOverflow(const LayoutRect&);
     
    602602#endif
    603603
     604    // True if this box can have a range in an outside fragmentation context.
     605    bool canHaveOutsideRegionRange() const { return !isInFlowRenderFlowThread(); }
     606
    604607protected:
    605608    RenderBox(Element&, PassRef<RenderStyle>, unsigned baseTypeFlags);
     
    707710
    708711    // Our overflow information.
    709     OwnPtr<RenderOverflow> m_overflow;
     712    RefPtr<RenderOverflow> m_overflow;
    710713
    711714private:
  • trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp

    r159027 r159337  
    3838#include "RenderInline.h"
    3939#include "RenderLayer.h"
     40#include "RenderNamedFlowFragment.h"
    4041#include "RenderNamedFlowThread.h"
    4142#include "RenderRegion.h"
     
    572573}
    573574
     575void RenderBoxModelObject::paintMaskForTextFillBox(ImageBuffer* maskImage, const IntRect& maskRect, InlineFlowBox* box, const LayoutRect& scrolledPaintRect, RenderRegion* region)
     576{
     577    GraphicsContext* maskImageContext = maskImage->context();
     578    maskImageContext->translate(-maskRect.x(), -maskRect.y());
     579
     580    // Now add the text to the clip. We do this by painting using a special paint phase that signals to
     581    // InlineTextBoxes that they should just add their contents to the clip.
     582    PaintInfo info(maskImageContext, maskRect, PaintPhaseTextClip, PaintBehaviorForceBlackText, 0, region);
     583    if (box) {
     584        const RootInlineBox& rootBox = box->root();
     585        box->paint(info, LayoutPoint(scrolledPaintRect.x() - box->x(), scrolledPaintRect.y() - box->y()), rootBox.lineTop(), rootBox.lineBottom());
     586    } else if (isRenderNamedFlowFragmentContainer()) {
     587        RenderNamedFlowFragment* region = toRenderBlockFlow(this)->renderNamedFlowFragment();
     588        if (!region->flowThread())
     589            return;
     590        region->flowThread()->layer()->paintNamedFlowThreadInsideRegion(maskImageContext, region, maskRect, maskRect.location(), PaintBehaviorForceBlackText, RenderLayer::PaintLayerTemporaryClipRects);
     591    } else {
     592        LayoutSize localOffset = isBox() ? toRenderBox(this)->locationOffset() : LayoutSize();
     593        paint(info, scrolledPaintRect.location() - localOffset);
     594    }
     595}
     596
    574597void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, const Color& color, const FillLayer* bgLayer, const LayoutRect& rect,
    575598    BackgroundBleedAvoidance bleedAvoidance, InlineFlowBox* box, const LayoutSize& boxSize, CompositeOperator op, RenderElement* backgroundObject)
     
    704727        if (!maskImage)
    705728            return;
    706 
    707         GraphicsContext* maskImageContext = maskImage->context();
    708         maskImageContext->translate(-maskRect.x(), -maskRect.y());
    709 
    710         // Now add the text to the clip.  We do this by painting using a special paint phase that signals to
    711         // InlineTextBoxes that they should just add their contents to the clip.
    712         PaintInfo info(maskImageContext, maskRect, PaintPhaseTextClip, PaintBehaviorForceBlackText, 0, paintInfo.renderRegion);
    713         if (box) {
    714             const RootInlineBox& rootBox = box->root();
    715             box->paint(info, LayoutPoint(scrolledPaintRect.x() - box->x(), scrolledPaintRect.y() - box->y()), rootBox.lineTop(), rootBox.lineBottom());
    716         } else {
    717             LayoutSize localOffset = isBox() ? toRenderBox(this)->locationOffset() : LayoutSize();
    718             paint(info, scrolledPaintRect.location() - localOffset);
    719         }
     729        paintMaskForTextFillBox(maskImage.get(), maskRect, box, scrolledPaintRect, paintInfo.renderRegion);
    720730
    721731        // The mask has been created.  Now we just need to clip to it.
  • trunk/Source/WebCore/rendering/RenderBoxModelObject.h

    r159307 r159337  
    5252};
    5353
     54class ImageBuffer;
     55class InlineFlowBox;
    5456class KeyframeList;
    55 class InlineFlowBox;
    5657class RenderTextFragment;
    5758class StickyPositionViewportConstraints;
     
    180181
    181182    bool canHaveBoxInfoInRegion() const { return !isFloating() && !isReplaced() && !isInline() && !hasColumns() && !isTableCell() && isRenderBlock() && !isRenderSVGBlock(); }
    182 
    183183
    184184    void getGeometryForBackgroundImage(const RenderLayerModelObject* paintContainer, IntRect& destRect, IntPoint& phase, IntSize& tileSize) const;
     
    343343                            float thickness, float drawThickness, BoxSide, const RenderStyle*,
    344344                            Color, EBorderStyle, BackgroundBleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge);
     345    void paintMaskForTextFillBox(ImageBuffer*, const IntRect&, InlineFlowBox*, const LayoutRect&, RenderRegion*);
    345346};
    346347
  • trunk/Source/WebCore/rendering/RenderBoxRegionInfo.h

    r155026 r159337  
    5050    bool isShifted() const { return m_isShifted; }
    5151
    52     void createOverflow(const LayoutRect& layoutOverflow, const LayoutRect& visualOverflow) { m_overflow = adoptPtr(new RenderOverflow(layoutOverflow, visualOverflow)); }
     52    void createOverflow(const LayoutRect& layoutOverflow, const LayoutRect& visualOverflow) { m_overflow = adoptRef(new RenderOverflow(layoutOverflow, visualOverflow)); }
    5353    RenderOverflow* overflow() const { return m_overflow.get(); }
    5454    void clearOverflow()
     
    6262    LayoutUnit m_logicalWidth;
    6363    bool m_isShifted;
    64     OwnPtr<RenderOverflow> m_overflow;
     64    RefPtr<RenderOverflow> m_overflow;
    6565};
    6666
  • trunk/Source/WebCore/rendering/RenderFlowThread.cpp

    r158559 r159337  
    409409}
    410410
    411 void RenderFlowThread::paintFlowThreadPortionInRegion(PaintInfo& paintInfo, RenderRegion* region, const LayoutRect& flowThreadPortionRect, const LayoutRect& flowThreadPortionOverflowRect, const LayoutPoint& paintOffset) const
    412 {
    413     GraphicsContext* context = paintInfo.context;
    414     if (!context)
    415         return;
    416 
    417     // RenderFlowThread should start painting its content in a position that is offset
    418     // from the region rect's current position. The amount of offset is equal to the location of
    419     // the flow thread portion in the flow thread's local coordinates.
    420     // Note that we have to pixel snap the location at which we're going to paint, since this is necessary
    421     // to minimize the amount of incorrect snapping that would otherwise occur.
    422     // If we tried to paint by applying a non-integral translation, then all the
    423     // layout code that attempted to pixel snap would be incorrect.
    424     IntPoint adjustedPaintOffset;
    425     LayoutPoint portionLocation;
    426     if (style().isFlippedBlocksWritingMode()) {
    427         LayoutRect flippedFlowThreadPortionRect(flowThreadPortionRect);
    428         flipForWritingMode(flippedFlowThreadPortionRect);
    429         portionLocation = flippedFlowThreadPortionRect.location();
    430     } else
    431         portionLocation = flowThreadPortionRect.location();
    432     adjustedPaintOffset = roundedIntPoint(paintOffset - portionLocation);
    433 
    434     // The clipping rect for the region is set up by assuming the flowThreadPortionRect is going to paint offset from adjustedPaintOffset.
    435     // Remember that we pixel snapped and moved the paintOffset and stored the snapped result in adjustedPaintOffset. Now we add back in
    436     // the flowThreadPortionRect's location to get the spot where we expect the portion to actually paint. This can be non-integral and
    437     // that's ok. We then pixel snap the resulting clipping rect to account for snapping that will occur when the flow thread paints.
    438     IntRect regionClippingRect = pixelSnappedIntRect(computeRegionClippingRect(adjustedPaintOffset + portionLocation, flowThreadPortionRect, flowThreadPortionOverflowRect));
    439 
    440     PaintInfo info(paintInfo);
    441     info.rect.intersect(regionClippingRect);
    442 
    443     if (!info.rect.isEmpty()) {
    444         context->save();
    445 
    446         context->clip(regionClippingRect);
    447 
    448         context->translate(adjustedPaintOffset.x(), adjustedPaintOffset.y());
    449         info.rect.moveBy(-adjustedPaintOffset);
    450        
    451         PaintBehavior paintBehavior = 0;
    452         if (info.phase == PaintPhaseTextClip)
    453             paintBehavior |= PaintBehaviorForceBlackText;
    454         else if (info.phase == PaintPhaseSelection)
    455             paintBehavior |= PaintBehaviorSelectionOnly;
    456 
    457         layer()->paint(context, info.rect, paintBehavior, 0, region, RenderLayer::PaintLayerTemporaryClipRects);
    458 
    459         context->restore();
    460     }
    461 }
    462 
    463411bool RenderFlowThread::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
    464412{
     
    466414        return false;
    467415    return RenderBlockFlow::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, hitTestAction);
    468 }
    469 
    470 bool RenderFlowThread::hitTestFlowThreadPortionInRegion(RenderRegion* region, const LayoutRect& flowThreadPortionRect, const LayoutRect& flowThreadPortionOverflowRect, const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) const
    471 {
    472     LayoutRect regionClippingRect = computeRegionClippingRect(accumulatedOffset, flowThreadPortionRect, flowThreadPortionOverflowRect);
    473     if (!regionClippingRect.contains(locationInContainer.point()))
    474         return false;
    475 
    476     LayoutSize renderFlowThreadOffset;
    477     if (style().isFlippedBlocksWritingMode()) {
    478         LayoutRect flippedFlowThreadPortionRect(flowThreadPortionRect);
    479         flipForWritingMode(flippedFlowThreadPortionRect);
    480         renderFlowThreadOffset = accumulatedOffset - flippedFlowThreadPortionRect.location();
    481     } else
    482         renderFlowThreadOffset = accumulatedOffset - flowThreadPortionRect.location();
    483 
    484     // Always ignore clipping, since the RenderFlowThread has nothing to do with the bounds of the FrameView.
    485     HitTestRequest newRequest(request.type() | HitTestRequest::IgnoreClipping | HitTestRequest::DisallowShadowContent);
    486 
    487     // Make a new temporary HitTestLocation in the new region.
    488     HitTestLocation newHitTestLocation(locationInContainer, -renderFlowThreadOffset, region);
    489 
    490     bool isPointInsideFlowThread = layer()->hitTest(newRequest, newHitTestLocation, result);
    491 
    492     // FIXME: Should we set result.m_localPoint back to the RenderRegion's coordinate space or leave it in the RenderFlowThread's coordinate
    493     // space? Right now it's staying in the RenderFlowThread's coordinate space, which may end up being ok. We will know more when we get around to
    494     // patching positionForPoint.
    495     return isPointInsideFlowThread;
    496416}
    497417
     
    926846    m_hasRegionsWithStyling = hasRegionsWithStyling;
    927847}
     848   
     849bool RenderFlowThread::objectShouldPaintInFlowRegion(const RenderObject* object, const RenderRegion* region) const
     850{
     851    ASSERT(object);
     852    ASSERT(region);
     853   
     854    RenderFlowThread* flowThread = object->flowThreadContainingBlock();
     855    if (flowThread != this)
     856        return false;
     857    if (!m_regionList.contains(const_cast<RenderRegion*>(region)))
     858        return false;
     859   
     860    RenderBox* enclosingBox = object->enclosingBox();
     861    RenderRegion* enclosingBoxStartRegion = 0;
     862    RenderRegion* enclosingBoxEndRegion = 0;
     863    getRegionRangeForBox(enclosingBox, enclosingBoxStartRegion, enclosingBoxEndRegion);
     864   
     865    // If the box has no range, do not check regionInRange. Boxes inside inlines do not get ranges.
     866    // Instead, the containing RootInlineBox will abort when trying to paint inside the wrong region.
     867    if (enclosingBoxStartRegion && enclosingBoxEndRegion && !regionInRange(region, enclosingBoxStartRegion, enclosingBoxEndRegion))
     868        return false;
     869   
     870    return object->isBox();
     871}
    928872
    929873bool RenderFlowThread::objectInFlowRegion(const RenderObject* object, const RenderRegion* region) const
     
    13131257        LayoutPoint currentBoxLocation = box->location();
    13141258
    1315         if (containerBlock->style().writingMode() != box->style().writingMode()) {
    1316             if (containerBlock->style().isFlippedBlocksWritingMode()) {
    1317                 if (containerBlock->isHorizontalWritingMode())
    1318                     boxRect.setY(box->height() - boxRect.maxY());
    1319                 else
    1320                     boxRect.setX(box->width() - boxRect.maxX());
    1321             }
     1259        if (containerBlock->style().writingMode() != box->style().writingMode())
    13221260            box->flipForWritingMode(boxRect);
    1323         }
     1261
    13241262        boxRect.moveBy(currentBoxLocation);
    13251263        box = containerBlock;
     
    13451283    localRect.moveBy(-currentBoxLocation);
    13461284
    1347     if (containerBlock->style().writingMode() != box->style().writingMode()) {
    1348         if (containerBlock->style().isFlippedBlocksWritingMode()) {
    1349             if (containerBlock->isHorizontalWritingMode())
    1350                 localRect.setY(box->height() - localRect.maxY());
     1285    if (containerBlock->style().writingMode() != box->style().writingMode())
     1286        box->flipForWritingMode(localRect);
     1287
     1288    return localRect;
     1289}
     1290
     1291LayoutRect RenderFlowThread::decorationsClipRectForBoxInRegion(const RenderBox& box, RenderRegion& region) const
     1292{
     1293    LayoutRect visualOverflowRect = region.visualOverflowRectForBox(&box);
     1294   
     1295    // The visual overflow rect returned by visualOverflowRectForBox is already flipped but the
     1296    // RenderRegion::rectFlowPortionForBox method expects it unflipped.
     1297    flipForWritingModeLocalCoordinates(visualOverflowRect);
     1298    visualOverflowRect = region.rectFlowPortionForBox(&box, visualOverflowRect);
     1299   
     1300    // Now flip it again.
     1301    flipForWritingModeLocalCoordinates(visualOverflowRect);
     1302   
     1303    // Layers are in physical coordinates so the origin must be moved to the physical top-left of the flowthread.
     1304    if (style().isFlippedBlocksWritingMode()) {
     1305        if (style().isHorizontalWritingMode())
     1306            visualOverflowRect.moveBy(LayoutPoint(0, height()));
     1307        else
     1308            visualOverflowRect.moveBy(LayoutPoint(width(), 0));
     1309    }
     1310   
     1311    const RenderBox* iterBox = &box;
     1312    while (iterBox && iterBox != this) {
     1313        RenderBlock* containerBlock = iterBox->containingBlock();
     1314       
     1315        LayoutRect currentBoxRect = iterBox->frameRect();
     1316        if (iterBox->style().isFlippedBlocksWritingMode()) {
     1317            if (iterBox->style().isHorizontalWritingMode())
     1318                currentBoxRect.setY(currentBoxRect.height() - currentBoxRect.maxY());
    13511319            else
    1352                 localRect.setX(box->width() - localRect.maxX());
     1320                currentBoxRect.setX(currentBoxRect.width() - currentBoxRect.maxX());
    13531321        }
    1354         box->flipForWritingMode(localRect);
    1355     }
    1356 
    1357     return localRect;
     1322       
     1323        if (containerBlock->style().writingMode() != iterBox->style().writingMode())
     1324            iterBox->flipForWritingMode(currentBoxRect);
     1325       
     1326        visualOverflowRect.moveBy(currentBoxRect.location());
     1327        iterBox = containerBlock;
     1328    }
     1329   
     1330    return visualOverflowRect;
     1331}
     1332
     1333void RenderFlowThread::flipForWritingModeLocalCoordinates(LayoutRect& rect) const
     1334{
     1335    if (!style().isFlippedBlocksWritingMode())
     1336        return;
     1337   
     1338    if (isHorizontalWritingMode())
     1339        rect.setY(0 - rect.maxY());
     1340    else
     1341        rect.setX(0 - rect.maxX());
    13581342}
    13591343
     
    14101394    for (auto iter = m_regionList.find(startRegion), end = m_regionList.end(); iter != end; ++iter) {
    14111395        RenderRegion* region = *iter;
    1412         if (!regionInRange(region, containerStartRegion, containerEndRegion))
     1396        if (!regionInRange(region, containerStartRegion, containerEndRegion)) {
     1397            if (region == endRegion)
     1398                break;
    14131399            continue;
     1400        }
    14141401
    14151402        LayoutRect childLayoutOverflowRect = region->layoutOverflowRectForBoxForPropagation(child);
     
    14171404        region->addLayoutOverflowForBox(box, childLayoutOverflowRect);
    14181405
    1419         if (child->hasSelfPaintingLayer() || box->hasOverflowClip())
     1406        if (child->hasSelfPaintingLayer() || box->hasOverflowClip()) {
     1407            if (region == endRegion)
     1408                break;
    14201409            continue;
     1410        }
    14211411        LayoutRect childVisualOverflowRect = region->visualOverflowRectForBoxForPropagation(child);
    14221412        childVisualOverflowRect.move(delta);
     
    14271417    }
    14281418}
    1429 
     1419   
    14301420void RenderFlowThread::addRegionsLayoutOverflow(const RenderBox* box, const LayoutRect& layoutOverflow)
    14311421{
     
    14451435}
    14461436
    1447 void RenderFlowThread::clearRegionsOverflow(const RenderBox* box)
     1437void RenderFlowThread::addRegionsVisualOverflow(const RenderBox* box, const LayoutRect& visualOverflow)
    14481438{
    14491439    RenderRegion* startRegion = 0;
    14501440    RenderRegion* endRegion = 0;
    14511441    getRegionRangeForBox(box, startRegion, endRegion);
     1442   
     1443    for (RenderRegionList::iterator iter = m_regionList.find(startRegion); iter != m_regionList.end(); ++iter) {
     1444        RenderRegion* region = *iter;
     1445        LayoutRect visualOverflowInRegion = region->rectFlowPortionForBox(box, visualOverflow);
     1446       
     1447        region->addVisualOverflowForBox(box, visualOverflowInRegion);
     1448       
     1449        if (region == endRegion)
     1450            break;
     1451    }
     1452}
     1453
     1454void RenderFlowThread::clearRegionsOverflow(const RenderBox* box)
     1455{
     1456    RenderRegion* startRegion = 0;
     1457    RenderRegion* endRegion = 0;
     1458    getRegionRangeForBox(box, startRegion, endRegion);
    14521459
    14531460    for (auto iter = m_regionList.find(startRegion), end = m_regionList.end(); iter != end; ++iter) {
     
    14701477    FlowThreadController& controller = m_renderFlowThread->view().flowThreadController();
    14711478    m_previousRenderFlowThread = controller.currentRenderFlowThread();
    1472     ASSERT(!m_previousRenderFlowThread || !renderFlowThread->isRenderNamedFlowThread());
     1479    // Remove the assert so we can use this to change the flow thread context.
     1480    // ASSERT(!m_previousRenderFlowThread || !renderFlowThread->isRenderNamedFlowThread());
    14731481    controller.setCurrentRenderFlowThread(m_renderFlowThread);
    14741482}
  • trunk/Source/WebCore/rendering/RenderFlowThread.h

    r159159 r159337  
    8484    virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const OVERRIDE;
    8585
    86     void paintFlowThreadPortionInRegion(PaintInfo&, RenderRegion*, const LayoutRect& flowThreadPortionRect, const LayoutRect& flowThreadPortionOverflowRect, const LayoutPoint&) const;
    87     bool hitTestFlowThreadPortionInRegion(RenderRegion*, const LayoutRect& flowThreadPortionRect, const LayoutRect& flowThreadPortionOverflowRect, const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) const;
    8886    virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
    8987
     
    146144    // Check if the object is in region and the region is part of this flow thread.
    147145    bool objectInFlowRegion(const RenderObject*, const RenderRegion*) const;
     146   
     147    // Check if the object should be painted in this region and if the region is part of this flow thread.
     148    bool objectShouldPaintInFlowRegion(const RenderObject*, const RenderRegion*) const;
    148149
    149150    void markAutoLogicalHeightRegionsForLayout();
     
    206207    void clearRenderBoxRegionInfoAndCustomStyle(const RenderBox*, const RenderRegion*, const RenderRegion*, const RenderRegion*, const RenderRegion*);
    207208
    208     LayoutRect mapFromFlowThreadToLocal(const RenderBox*, const LayoutRect&) const;
    209     LayoutRect mapFromLocalToFlowThread(const RenderBox*, const LayoutRect&) const;
    210 
    211209    void addRegionsVisualEffectOverflow(const RenderBox*);
    212210    void addRegionsVisualOverflowFromTheme(const RenderBlock*);
    213211    void addRegionsOverflowFromChild(const RenderBox*, const RenderBox*, const LayoutSize&);
    214212    void addRegionsLayoutOverflow(const RenderBox*, const LayoutRect&);
     213    void addRegionsVisualOverflow(const RenderBox*, const LayoutRect&);
    215214    void clearRegionsOverflow(const RenderBox*);
     215
     216    LayoutRect mapFromFlowThreadToLocal(const RenderBox*, const LayoutRect&) const;
     217    LayoutRect mapFromLocalToFlowThread(const RenderBox*, const LayoutRect&) const;
     218   
     219    LayoutRect decorationsClipRectForBoxInRegion(const RenderBox&, RenderRegion&) const;
     220   
     221    void flipForWritingModeLocalCoordinates(LayoutRect&) const;
    216222
    217223    // Used to estimate the maximum height of the flow thread.
    218224    static LayoutUnit maxLogicalHeight() { return LayoutUnit::max() / 2; }
     225   
     226    bool regionInRange(const RenderRegion* targetRegion, const RenderRegion* startRegion, const RenderRegion* endRegion) const;
    219227
    220228protected:
     
    229237    void updateRegionsFlowThreadPortionRect(const RenderRegion* = 0);
    230238    bool shouldRepaint(const LayoutRect&) const;
    231     bool regionInRange(const RenderRegion* targetRegion, const RenderRegion* startRegion, const RenderRegion* endRegion) const;
    232239
    233240    LayoutRect computeRegionClippingRect(const LayoutPoint&, const LayoutRect&, const LayoutRect&) const;
  • trunk/Source/WebCore/rendering/RenderLayer.cpp

    r159082 r159337  
    8383#include "RenderInline.h"
    8484#include "RenderMarquee.h"
     85#include "RenderNamedFlowFragment.h"
    8586#include "RenderNamedFlowThread.h"
    8687#include "RenderRegion.h"
     
    443444        if (flags & CheckForRepaint) {
    444445            if (!renderer().view().printing()) {
     446                bool didRepaint = false;
    445447                if (m_repaintStatus & NeedsFullRepaint) {
    446448                    renderer().repaintUsingContainer(repaintContainer, pixelSnappedIntRect(oldRepaintRect));
    447                     if (m_repaintRect != oldRepaintRect)
     449                    if (m_repaintRect != oldRepaintRect) {
    448450                        renderer().repaintUsingContainer(repaintContainer, pixelSnappedIntRect(m_repaintRect));
    449                 } else if (shouldRepaintAfterLayout())
     451                        didRepaint = true;
     452                    }
     453                } else if (shouldRepaintAfterLayout()) {
    450454                    renderer().repaintAfterLayoutIfNeeded(repaintContainer, oldRepaintRect, oldOutlineBox, &m_repaintRect, &m_outlineBox);
     455                    didRepaint = true;
     456                }
     457
     458                if (didRepaint && renderer().isRenderNamedFlowFragmentContainer()) {
     459                    // If we just repainted a region, we must also repaint the flow thread since it is the one
     460                    // doing the actual painting of the flowed content.
     461                    RenderNamedFlowFragment* region = toRenderBlockFlow(&renderer())->renderNamedFlowFragment();
     462                    if (region->flowThread())
     463                        region->flowThread()->layer()->repaintIncludingDescendants();
     464                }
    451465            }
    452466        }
     
    16251639static LayoutRect transparencyClipBox(const RenderLayer*, const RenderLayer* rootLayer, TransparencyClipBoxBehavior, TransparencyClipBoxMode, PaintBehavior = 0);
    16261640
     1641static void expandClipRectForRegionAndReflection(LayoutRect& clipRect, const RenderLayer* layer, const RenderLayer* rootLayer,
     1642    TransparencyClipBoxBehavior transparencyBehavior, PaintBehavior paintBehavior)
     1643{
     1644    // If this is a region, then the painting is actually done by its flow thread's layer.
     1645    if (layer->renderer().isRenderNamedFlowFragmentContainer()) {
     1646        RenderBlockFlow* regionContainer = toRenderBlockFlow(&layer->renderer());
     1647        RenderNamedFlowFragment* region = regionContainer->renderNamedFlowFragment();
     1648        RenderLayer* flowThreadLayer = region->flowThread()->layer();
     1649        if (!layer->reflection() || layer->reflectionLayer() != flowThreadLayer) {
     1650            LayoutRect flowThreadClipRect = transparencyClipBox(flowThreadLayer, rootLayer, transparencyBehavior, DescendantsOfTransparencyClipBox, paintBehavior);
     1651           
     1652            LayoutPoint offsetFromRoot;
     1653            layer->convertToLayerCoords(flowThreadLayer, offsetFromRoot);
     1654
     1655            LayoutSize moveOffset = (offsetFromRoot + regionContainer->contentBoxRect().location()) - region->flowThreadPortionRect().location();
     1656            flowThreadClipRect.move(moveOffset);
     1657           
     1658            clipRect.unite(flowThreadClipRect);
     1659        }
     1660    }
     1661}
     1662
    16271663static void expandClipRectForDescendantsAndReflection(LayoutRect& clipRect, const RenderLayer* layer, const RenderLayer* rootLayer,
    16281664    TransparencyClipBoxBehavior transparencyBehavior, PaintBehavior paintBehavior)
     
    16381674        }
    16391675    }
     1676
     1677    expandClipRectForRegionAndReflection(clipRect, layer, rootLayer, transparencyBehavior, paintBehavior);
    16401678
    16411679    // If we have a reflection, then we need to account for that when we push the clip.  Reflect our entire
     
    36053643        return;
    36063644
     3645    // Don't paint the layer if the renderer doesn't belong to this region.
     3646    // This is true as long as we clamp the range of a box to its containing block range.
     3647
     3648    // FIXME: Hack to disable region information for in flow threads. Implement this logic in a different way.
     3649    LayerPaintingInfo& info = const_cast<LayerPaintingInfo&>(paintingInfo);
     3650    RenderRegion* region = info.region;
     3651    if (region) {
     3652        if (enclosingPaginationLayer())
     3653            info.region = 0;
     3654        else {
     3655            RenderFlowThread* flowThread = region->flowThread();
     3656            ASSERT(flowThread);
     3657
     3658            if (!flowThread->objectShouldPaintInFlowRegion(&renderer(), region))
     3659                return;
     3660        }
     3661    }
     3662
    36073663    if (paintsWithTransparency(paintingInfo.paintBehavior))
    36083664        paintFlags |= PaintLayerHaveTransparency;
     
    36123668        TransformationMatrix layerTransform = renderableTransform(paintingInfo.paintBehavior);
    36133669        // If the transform can't be inverted, then don't paint anything.
    3614         if (!layerTransform.isInvertible())
     3670        if (!layerTransform.isInvertible()) {
     3671            info.region = region;
    36153672            return;
     3673        }
    36163674
    36173675        // If we have a transparency layer enclosing us and we are the root of a transform, then we need to establish the transparency
     
    36263684        if (enclosingPaginationLayer()) {
    36273685            paintTransformedLayerIntoFragments(context, paintingInfo, paintFlags);
     3686            info.region = region;
    36283687            return;
    36293688        }
     
    36473706            parent()->restoreClip(context, paintingInfo.paintDirtyRect, clipRect);
    36483707
     3708        info.region = region;
    36493709        return;
    36503710    }
    36513711   
    36523712    paintLayerContentsAndReflection(context, paintingInfo, paintFlags);
     3713    info.region = region;
    36533714}
    36543715
     
    39143975
    39153976    LayerFragments layerFragments;
     3977    LayoutRect paintDirtyRect = localPaintingInfo.paintDirtyRect;
    39163978    if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars) {
    39173979        // Collect the fragments. This will compute the clip rectangles and paint offsets for each layer fragment, as well as whether or not the content of each
    39183980        // fragment should paint. If the parent's filter dictates full repaint to ensure proper filter effect,
    39193981        // use the overflow clip as dirty rect, instead of no clipping. It maintains proper clipping for overflow::scroll.
    3920         LayoutRect paintDirtyRect = localPaintingInfo.paintDirtyRect;
    39213982        if (!paintingInfo.clipToDirtyRect && renderer().hasOverflowClip()) {
    39223983            // We can turn clipping back by requesting full repaint for the overflow area.
     
    39574018        paintList(posZOrderList(), context, localPaintingInfo, localPaintFlags);
    39584019
    3959         // Paint the fixed elements from flow threads
     4020        // Paint the fixed elements from flow threads.
    39604021        paintFixedLayersInNamedFlows(context, localPaintingInfo, localPaintFlags);
     4022       
     4023        // If this is a region, paint its contents via the flow thread's layer.
     4024        paintFlowThreadIfRegion(context, localPaintingInfo, localPaintFlags, offsetFromRoot, paintDirtyRect, isPaintingOverflowContents);
    39614025    }
    39624026
     
    41214185        if (this != localPaintingInfo.rootLayer || !(localPaintFlags & PaintLayerPaintingOverflowContents)) {
    41224186            LayoutPoint newOffsetFromRoot = *offsetFromRoot + fragment.paginationOffset;
    4123             fragment.shouldPaintContent &= intersectsDamageRect(fragment.layerBounds, fragment.backgroundRect.rect(), localPaintingInfo.rootLayer, &newOffsetFromRoot);
     4187            fragment.shouldPaintContent &= intersectsDamageRect(fragment.layerBounds, fragment.backgroundRect.rect(), localPaintingInfo.rootLayer, &newOffsetFromRoot, localPaintingInfo.region);
    41244188        }
    41254189    }
     
    42074271    // Optimize clipping for the single fragment case.
    42084272    bool shouldClip = localPaintingInfo.clipToDirtyRect && layerFragments.size() == 1 && layerFragments[0].shouldPaintContent && !layerFragments[0].foregroundRect.isEmpty();
    4209     if (shouldClip)
    4210         clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, layerFragments[0].foregroundRect);
     4273    ClipRect clippedRect;
     4274    if (shouldClip) {
     4275        clippedRect = layerFragments[0].foregroundRect;
     4276        clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, clippedRect);
     4277    }
    42114278   
    42124279    // We have to loop through every fragment multiple times, since we have to repaint in each specific phase in order for
     
    42184285        paintForegroundForFragmentsWithPhase(PaintPhaseFloat, layerFragments, context, localPaintingInfo, localPaintBehavior, subtreePaintRootForRenderer);
    42194286        paintForegroundForFragmentsWithPhase(PaintPhaseForeground, layerFragments, context, localPaintingInfo, localPaintBehavior, subtreePaintRootForRenderer);
     4287
     4288        // Switch the clipping rectangle to the outline version.
     4289        if (shouldClip && clippedRect != layerFragments[0].outlineRect) {
     4290            restoreClip(context, localPaintingInfo.paintDirtyRect, clippedRect);
     4291           
     4292            if (!layerFragments[0].outlineRect.isEmpty()) {
     4293                clippedRect = layerFragments[0].outlineRect;
     4294                clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, clippedRect);
     4295            } else
     4296                shouldClip = false;
     4297        }
     4298
    42204299        paintForegroundForFragmentsWithPhase(PaintPhaseChildOutlines, layerFragments, context, localPaintingInfo, localPaintBehavior, subtreePaintRootForRenderer);
    42214300    }
    42224301   
    42234302    if (shouldClip)
    4224         restoreClip(context, localPaintingInfo.paintDirtyRect, layerFragments[0].foregroundRect);
     4303        restoreClip(context, localPaintingInfo.paintDirtyRect, clippedRect);
    42254304}
    42264305
     
    44084487
    44094488    renderer().document().updateLayout();
    4410    
    4411     LayoutRect hitTestArea = isOutOfFlowRenderFlowThread() ? toRenderFlowThread(renderer()).borderBoxRect() : renderer().view().documentRect();
     4489
     4490    LayoutRect hitTestArea = isOutOfFlowRenderFlowThread() ? toRenderFlowThread(&renderer())->visualOverflowRect() : renderer().view().documentRect();
    44124491    if (!request.ignoreClipping())
    44134492        hitTestArea.intersect(renderer().view().frameView().visibleContentRect());
     
    45994678    if (renderer().fixedPositionedWithNamedFlowContainingBlock() && hitTestLocation.region())
    46004679        return 0;
     4680
     4681    // Don't hit-test the layer if the renderer doesn't belong to this region.
     4682    // This is true as long as we clamp the range of a box to its containing block range.
     4683    // FIXME: Fix hit testing with in-flow threads included in out-of-flow threads.
     4684    if (hitTestLocation.region()) {
     4685        RenderFlowThread* flowThread = hitTestLocation.region()->flowThread();
     4686        ASSERT(flowThread);
     4687
     4688        if (!flowThread->objectShouldPaintInFlowRegion(&renderer(), hitTestLocation.region()))
     4689            return 0;
     4690    }
    46014691
    46024692    // The natural thing would be to keep HitTestingTransformState on the stack, but it's big, so we heap-allocate.
     
    46964786    hitLayer = hitTestList(m_normalFlowList.get(), rootLayer, request, result, hitTestRect, hitTestLocation,
    46974787                           localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
     4788    if (hitLayer) {
     4789        if (!depthSortDescendants)
     4790            return hitLayer;
     4791        candidateLayer = hitLayer;
     4792    }
     4793
     4794    hitLayer = hitTestFlowThreadIfRegion(rootLayer, request, result, hitTestRect, hitTestLocation, localTransformState.get(), zOffsetForDescendantsPtr);
    46984795    if (hitLayer) {
    46994796        if (!depthSortDescendants)
     
    50725169}
    50735170
     5171void RenderLayer::mapLayerClipRectsToFragmentationLayer(RenderRegion* region, ClipRects& clipRects) const
     5172{
     5173    ASSERT(region && region->parent() && region->parent()->isRenderNamedFlowFragmentContainer());
     5174
     5175    ClipRectsContext targetClipRectsContext(region->regionContainerLayer(), 0, TemporaryClipRects);
     5176    region->regionContainerLayer()->calculateClipRects(targetClipRectsContext, clipRects);
     5177
     5178    LayoutRect flowThreadPortionRect = region->flowThreadPortionRect();
     5179
     5180    LayoutPoint portionLocation = flowThreadPortionRect.location();
     5181    LayoutRect regionContentBox = region->contentBoxRect();
     5182    LayoutSize moveOffset = portionLocation - regionContentBox.location();
     5183
     5184    ClipRect newOverflowClipRect = clipRects.overflowClipRect();
     5185    newOverflowClipRect.move(moveOffset);
     5186    clipRects.setOverflowClipRect(newOverflowClipRect);
     5187
     5188    ClipRect newFixedClipRect = clipRects.fixedClipRect();
     5189    newFixedClipRect.move(moveOffset);
     5190    clipRects.setFixedClipRect(newFixedClipRect);
     5191
     5192    ClipRect newPosClipRect = clipRects.posClipRect();
     5193    newPosClipRect.move(moveOffset);
     5194    clipRects.setPosClipRect(newPosClipRect);
     5195}
     5196
    50745197void RenderLayer::calculateClipRects(const ClipRectsContext& clipRectsContext, ClipRects& clipRects) const
    50755198{
     
    50835206    bool useCached = clipRectsType != TemporaryClipRects;
    50845207
     5208    if (renderer().isRenderFlowThread() && clipRectsContext.region) {
     5209        mapLayerClipRectsToFragmentationLayer(clipRectsContext.region, clipRects);
     5210        return;
     5211    }
     5212
    50855213    // For transformed layers, the root layer was shifted to be us, so there is no need to
    5086     // examine the parent.  We want to cache clip rects with us as the root.
     5214    // examine the parent. We want to cache clip rects with us as the root.
    50875215    RenderLayer* parentLayer = clipRectsContext.rootLayer != this ? parent() : 0;
    50885216   
     
    51425270{
    51435271    ASSERT(parent());
     5272    if (renderer().isRenderFlowThread() && clipRectsContext.region) {
     5273        mapLayerClipRectsToFragmentationLayer(clipRectsContext.region, clipRects);
     5274        return;
     5275    }
     5276
    51445277    if (clipRectsContext.clipRectsType == TemporaryClipRects) {
    51455278        parent()->calculateClipRects(clipRectsContext, clipRects);
     
    51965329        backgroundRect = paintDirtyRect;
    51975330
    5198     foregroundRect = backgroundRect;
    5199     outlineRect = backgroundRect;
    5200    
    52015331    LayoutPoint offset;
    52025332    if (offsetFromRoot)
     
    52135343
    52145344    layerBounds = LayoutRect(offset, size());
     5345
     5346    foregroundRect = backgroundRect;
     5347    outlineRect = backgroundRect;
     5348
     5349    RenderFlowThread* flowThread = clipRectsContext.region ? clipRectsContext.region->flowThread() : 0;
     5350    if (isSelfPaintingLayer() && flowThread && !renderer().isInFlowRenderFlowThread() && renderBox()) {
     5351        // FIXME: Handle the case where the renderer is not a RenderBox.
     5352        LayoutRect layerBoundsWithVisualOverflow = clipRectsContext.region->visualOverflowRectForBox(renderBox());
     5353
     5354        // Layers are in physical coordinates so the origin must be moved to the physical top-left of the flowthread.
     5355        if (flowThread->style().isFlippedBlocksWritingMode()) {
     5356            if (flowThread->style().isHorizontalWritingMode())
     5357                layerBoundsWithVisualOverflow.moveBy(LayoutPoint(0, flowThread->height()));
     5358            else
     5359                layerBoundsWithVisualOverflow.moveBy(LayoutPoint(flowThread->width(), 0));
     5360        }
     5361
     5362        layerBoundsWithVisualOverflow.moveBy(offset);
     5363        backgroundRect.intersect(layerBoundsWithVisualOverflow);
     5364
     5365        foregroundRect = backgroundRect;
     5366        outlineRect = backgroundRect;
     5367       
     5368        // If the region does not clip its overflow, inflate the outline rect.
     5369        if (!(clipRectsContext.region->parent()->hasOverflowClip() && (clipRectsContext.region->regionContainerLayer() != clipRectsContext.rootLayer || clipRectsContext.respectOverflowClip == RespectOverflowClip)))
     5370            outlineRect.inflate(renderer().maximalOutlineSize(PaintPhaseOutline));
     5371    }
    52155372
    52165373    // Update the clip rects that will be passed to child layers.
     
    52375394            // FIXME: Does not do the right thing with CSS regions yet, since we don't yet factor in the
    52385395            // individual region boxes as overflow.
    5239             LayoutRect layerBoundsWithVisualOverflow = renderBox()->visualOverflowRect();
     5396            LayoutRect layerBoundsWithVisualOverflow = clipRectsContext.region ? clipRectsContext.region->visualOverflowRectForBox(renderBox()) : renderBox()->visualOverflowRect();
    52405397            renderBox()->flipForWritingMode(layerBoundsWithVisualOverflow); // Layers are in physical coordinates, so the overflow has to be flipped.
    52415398            layerBoundsWithVisualOverflow.moveBy(offset);
     
    52455402            // Shift the bounds to be for our region only.
    52465403            LayoutRect bounds = renderBox()->borderBoxRectInRegion(clipRectsContext.region);
     5404            if (clipRectsContext.region)
     5405                bounds = clipRectsContext.region->rectFlowPortionForBox(renderBox(), bounds);
     5406
    52475407            bounds.moveBy(offset);
    52485408            if (this != clipRectsContext.rootLayer || clipRectsContext.respectOverflowClip == RespectOverflowClip)
     
    53285488}
    53295489
    5330 bool RenderLayer::intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect& damageRect, const RenderLayer* rootLayer, const LayoutPoint* offsetFromRoot) const
     5490bool RenderLayer::intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect& damageRect, const RenderLayer* rootLayer, const LayoutPoint* offsetFromRoot, RenderRegion* region) const
    53315491{
    53325492    // Always examine the canvas and the root.
     
    53445504            return true;
    53455505    }
    5346        
     5506
     5507    // When using regions, some boxes might have their frame rect relative to the flow thread, which could
     5508    // cause the paint rejection algorithm to prevent them from painting when using different width regions.
     5509    // e.g. an absolutely positioned box with bottom:0px and right:0px would have it's frameRect.x relative
     5510    // to the flow thread, not the last region (in which it will end up because of bottom:0px)
     5511    if (region && renderer().isBox() && renderer().flowThreadContainingBlock()) {
     5512        LayoutRect b = layerBounds;
     5513        b.moveBy(region->visualOverflowRectForBox(toRenderBox(&renderer())).location());
     5514        b.inflate(renderer().view().maximalOutlineSize());
     5515        if (b.intersects(damageRect))
     5516            return true;
     5517    }
     5518
    53475519    // Otherwise we need to compute the bounding box of this single layer and see if it intersects
    53485520    // the damage rect.
     
    58816053}
    58826054
     6055void RenderLayer::updateDescendantsLayerListsIfNeeded(bool recursive)
     6056{
     6057    Vector<RenderLayer*> layersToUpdate;
     6058   
     6059    if (isStackingContainer()) {
     6060        if (Vector<RenderLayer*>* list = negZOrderList()) {
     6061            size_t listSize = list->size();
     6062            for (size_t i = 0; i < listSize; ++i) {
     6063                RenderLayer* childLayer = list->at(i);
     6064                layersToUpdate.append(childLayer);
     6065            }
     6066        }
     6067    }
     6068   
     6069    if (Vector<RenderLayer*>* list = normalFlowList()) {
     6070        size_t listSize = list->size();
     6071        for (size_t i = 0; i < listSize; ++i) {
     6072            RenderLayer* childLayer = list->at(i);
     6073            layersToUpdate.append(childLayer);
     6074        }
     6075    }
     6076   
     6077    if (isStackingContainer()) {
     6078        if (Vector<RenderLayer*>* list = posZOrderList()) {
     6079            size_t listSize = list->size();
     6080            for (size_t i = 0; i < listSize; ++i) {
     6081                RenderLayer* childLayer = list->at(i);
     6082                layersToUpdate.append(childLayer);
     6083            }
     6084        }
     6085    }
     6086   
     6087    size_t listSize = layersToUpdate.size();
     6088    for (size_t i = 0; i < listSize; ++i) {
     6089        RenderLayer* childLayer = layersToUpdate.at(i);
     6090        childLayer->updateLayerListsIfNeeded();
     6091       
     6092        if (recursive)
     6093            childLayer->updateDescendantsLayerListsIfNeeded(true);
     6094    }
     6095}
     6096
    58836097void RenderLayer::updateCompositingAndLayerListsIfNeeded()
    58846098{
     
    58986112    for (RenderLayer* curr = firstChild(); curr; curr = curr->nextSibling())
    58996113        curr->repaintIncludingDescendants();
     6114
     6115    // If this is a region, we must also repaint the flow thread's layer since it is the one
     6116    // doing the actual painting of the flowed content.
     6117    if (renderer().isRenderNamedFlowFragmentContainer())
     6118        toRenderBlockFlow(&renderer())->renderNamedFlowFragment()->flowThread()->layer()->repaintIncludingDescendants();
    59006119}
    59016120
     
    65106729#endif
    65116730
     6731void RenderLayer::paintNamedFlowThreadInsideRegion(GraphicsContext* context, RenderNamedFlowFragment* region, LayoutRect paintDirtyRect, LayoutPoint paintOffset, PaintBehavior paintBehavior, PaintLayerFlags paintFlags)
     6732{
     6733    LayoutRect regionContentBox = toRenderBox(region->layerOwner())->contentBoxRect();
     6734    LayoutSize moveOffset = region->flowThreadPortionLocation() - (paintOffset + regionContentBox.location());
     6735    IntPoint adjustedPaintOffset = roundedIntPoint(-moveOffset);
     6736    paintDirtyRect.move(moveOffset);
     6737
     6738    context->save();
     6739    context->translate(adjustedPaintOffset.x(), adjustedPaintOffset.y());
     6740
     6741    region->setRegionObjectsRegionStyle();
     6742    paint(context, paintDirtyRect, paintBehavior, 0, region, paintFlags | PaintLayerTemporaryClipRects);
     6743    region->restoreRegionObjectsOriginalStyle();
     6744
     6745    context->restore();
     6746}
     6747
     6748void RenderLayer::paintFlowThreadIfRegion(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags, LayoutPoint paintOffset, LayoutRect dirtyRect, bool isPaintingOverflowContents)
     6749{
     6750    if (!renderer().isRenderNamedFlowFragmentContainer())
     6751        return;
     6752   
     6753    RenderBlockFlow* renderNamedFlowFragmentContainer = toRenderBlockFlow(&renderer());
     6754    RenderNamedFlowFragment* region = renderNamedFlowFragmentContainer->renderNamedFlowFragment();
     6755    if (!region->isValid())
     6756        return;
     6757   
     6758    ClipRect regionClipRect;
     6759    if (paintingInfo.rootLayer != this && parent()) {
     6760        ClipRectsContext clipRectsContext(paintingInfo.rootLayer, region,
     6761            (paintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects,
     6762            IgnoreOverlayScrollbarSize, (isPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip);
     6763        regionClipRect = backgroundClipRect(clipRectsContext);
     6764    } else
     6765        regionClipRect = dirtyRect;
     6766
     6767    RenderNamedFlowThread* flowThread = region->namedFlowThread();
     6768    LayoutRect regionContentBox = renderNamedFlowFragmentContainer->contentBoxRect();
     6769   
     6770    RenderLayer* flowThreadLayer = flowThread->layer();
     6771    bool isLastRegionWithRegionFragmentBreak = (region->isLastRegion() && region->style().regionFragment() == BreakRegionFragment);
     6772    if (region->hasOverflowClip() || isLastRegionWithRegionFragmentBreak) {
     6773        LayoutPoint regionOffsetFromRoot;
     6774        convertToLayerCoords(flowThreadLayer, regionOffsetFromRoot);
     6775        regionClipRect = regionContentBox;
     6776        regionClipRect.moveBy(regionOffsetFromRoot);
     6777    }
     6778
     6779    // Optimize clipping for the single fragment case.
     6780    if (!regionClipRect.isEmpty())
     6781        clipToRect(paintingInfo.rootLayer, context, paintingInfo.paintDirtyRect, regionClipRect);
     6782
     6783    flowThreadLayer->paintNamedFlowThreadInsideRegion(context, region, paintingInfo.paintDirtyRect, paintOffset, paintingInfo.paintBehavior, paintFlags);
     6784
     6785    if (!regionClipRect.isEmpty())
     6786        restoreClip(context, paintingInfo.paintDirtyRect, regionClipRect);
     6787}
     6788
     6789RenderLayer* RenderLayer::hitTestFlowThreadIfRegion(RenderLayer* rootLayer, const HitTestRequest& request, HitTestResult& result, const LayoutRect& hitTestRect,
     6790    const HitTestLocation& hitTestLocation,
     6791    const HitTestingTransformState* transformState,
     6792    double* zOffsetForDescendants)
     6793{
     6794    if (!renderer().isRenderNamedFlowFragmentContainer())
     6795        return 0;
     6796
     6797    RenderNamedFlowFragment* region = toRenderBlockFlow(&renderer())->renderNamedFlowFragment();
     6798    if (!region->isValid())
     6799        return 0;
     6800
     6801    RenderFlowThread* flowThread = region->flowThread();
     6802
     6803    LayoutPoint regionOffsetFromRoot;
     6804    convertToLayerCoords(rootLayer, regionOffsetFromRoot);
     6805
     6806    LayoutPoint portionLocation = region->flowThreadPortionRect().location();
     6807
     6808    if (flowThread->style().isFlippedBlocksWritingMode()) {
     6809        // The portion location coordinate must be translated into physical coordinates.
     6810        if (flowThread->style().isHorizontalWritingMode())
     6811            portionLocation.setY(flowThread->height() - (portionLocation.y() + region->contentHeight()));
     6812        else
     6813            portionLocation.setX(flowThread->width() - (portionLocation.x() + region->contentWidth()));
     6814    }
     6815
     6816    LayoutRect regionContentBox = toRenderBlockFlow(&renderer())->contentBoxRect();
     6817    LayoutSize hitTestOffset = portionLocation - (regionOffsetFromRoot + regionContentBox.location());
     6818
     6819    // Always ignore clipping, since the RenderFlowThread has nothing to do with the bounds of the FrameView.
     6820    HitTestRequest newRequest(request.type() | HitTestRequest::IgnoreClipping | HitTestRequest::DisallowShadowContent);
     6821
     6822    // Make a new temporary HitTestLocation in the new region.
     6823    HitTestLocation newHitTestLocation(hitTestLocation, hitTestOffset, region);
     6824
     6825    // Expand the hit-test rect to the flow thread's coordinate system.
     6826    LayoutRect hitTestRectInFlowThread = hitTestRect;
     6827    hitTestRectInFlowThread.move(hitTestOffset.width(), hitTestOffset.height());
     6828    hitTestRectInFlowThread.expand(LayoutSize(fabs((double)hitTestOffset.width()), fabs((double)hitTestOffset.height())));
     6829
     6830    return flowThread->layer()->hitTestLayer(flowThread->layer(), 0, newRequest, result, hitTestRectInFlowThread, newHitTestLocation, false, transformState, zOffsetForDescendants);
     6831}
     6832
    65126833} // namespace WebCore
    65136834
  • trunk/Source/WebCore/rendering/RenderLayer.h

    r158163 r159337  
    6363class RenderLayerCompositor;
    6464class RenderMarquee;
     65class RenderNamedFlowFragment;
    6566class RenderReplica;
    6667class RenderScrollbarPart;
     
    114115    bool intersects(const LayoutRect& rect) const { return m_rect.intersects(rect); }
    115116    bool intersects(const HitTestLocation&) const;
     117
     118    void inflateX(LayoutUnit dx) { m_rect.inflateX(dx); }
     119    void inflateY(LayoutUnit dy) { m_rect.inflateY(dy); }
     120    void inflate(LayoutUnit d) { inflateX(d); inflateY(d); }
    116121
    117122private:
     
    528533    // Update our normal and z-index lists.
    529534    void updateLayerListsIfNeeded();
     535
     536    // Update the normal and z-index lists of our descendants.
     537    void updateDescendantsLayerListsIfNeeded(bool recursive);
    530538
    531539    // FIXME: We should ASSERT(!m_visibleContentStatusDirty) here, but see https://bugs.webkit.org/show_bug.cgi?id=71044
     
    630638    void paintOverlayScrollbars(GraphicsContext*, const LayoutRect& damageRect, PaintBehavior, RenderObject* subtreePaintRoot = 0);
    631639
     640    void paintNamedFlowThreadInsideRegion(GraphicsContext*, RenderNamedFlowFragment*, LayoutRect, LayoutPoint, PaintBehavior = PaintBehaviorNormal, PaintLayerFlags = 0);
     641
    632642    struct ClipRectsContext {
    633643        ClipRectsContext(const RenderLayer* inRootLayer, RenderRegion* inRegion, ClipRectsType inClipRectsType, OverlayScrollbarSizeRelevancy inOverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize, ShouldRespectOverflowClip inRespectOverflowClip = RespectOverflowClip)
     
    669679
    670680    // Pass offsetFromRoot if known.
    671     bool intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect& damageRect, const RenderLayer* rootLayer, const LayoutPoint* offsetFromRoot = 0) const;
     681    bool intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect& damageRect, const RenderLayer* rootLayer, const LayoutPoint* offsetFromRoot = 0, RenderRegion* = 0) const;
    672682
    673683    enum CalculateLayerBoundsFlag {
     
    11331143    bool overflowControlsIntersectRect(const IntRect& localRect) const;
    11341144
     1145    RenderLayer* hitTestFlowThreadIfRegion(RenderLayer*, const HitTestRequest&, HitTestResult&,
     1146        const LayoutRect&, const HitTestLocation&,
     1147        const HitTestingTransformState*, double*);
     1148    void paintFlowThreadIfRegion(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags, LayoutPoint, LayoutRect, bool);
     1149    void mapLayerClipRectsToFragmentationLayer(RenderRegion*, ClipRects&) const;
     1150
    11351151private:
    11361152    // The bitfields are up here so they will fall into the padding from ScrollableArea on 64-bit.
  • trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp

    r159300 r159337  
    940940        RenderFlowThread& flowThread = toRenderFlowThread(layer.renderer());
    941941        layer.setHasCompositingDescendant(flowThread.hasCompositingRegionDescendant());
     942
     943        // Before returning, we need to update the lists of all child layers. This is required because,
     944        // if this flow thread will not be painted (for instance because of having no regions, or only invalid regions),
     945        // the child layers will never have their lists updated (which would normally happen during painting).
     946        layer.updateDescendantsLayerListsIfNeeded(true);
     947
    942948        return;
    943949    }
  • trunk/Source/WebCore/rendering/RenderListItem.cpp

    r159027 r159337  
    313313void RenderListItem::addOverflowFromChildren()
    314314{
     315    positionListMarker();
    315316    RenderBlockFlow::addOverflowFromChildren();
    316     positionListMarker();
    317317}
    318318
  • trunk/Source/WebCore/rendering/RenderMultiColumnSet.cpp

    r159027 r159337  
    255255}
    256256
    257 LayoutRect RenderMultiColumnSet::flowThreadPortionOverflowRect(const LayoutRect& portionRect, unsigned index, unsigned colCount, LayoutUnit colGap) const
     257LayoutRect RenderMultiColumnSet::flowThreadPortionOverflowRect(const LayoutRect& portionRect, unsigned index, unsigned colCount, LayoutUnit colGap)
    258258{
    259259    // This function determines the portion of the flow thread that paints for the column. Along the inline axis, columns are
     
    364364}
    365365
    366 void RenderMultiColumnSet::repaintFlowThreadContent(const LayoutRect& repaintRect, bool immediate) const
     366void RenderMultiColumnSet::repaintFlowThreadContent(const LayoutRect& repaintRect, bool immediate)
    367367{
    368368    // Figure out the start and end columns and only check within that range so that we don't walk the
     
    393393        // Get the portion of the flow thread that corresponds to this column.
    394394        LayoutRect flowThreadPortion = flowThreadPortionRectAt(i);
    395        
     395
    396396        // Now get the overflow rect that corresponds to the column.
    397397        LayoutRect flowThreadOverflowPortion = flowThreadPortionOverflowRect(flowThreadPortion, i, colCount, colGap);
    398398
    399399        // Do a repaint for this specific column.
    400         repaintFlowThreadContentRectangle(repaintRect, immediate, flowThreadPortion, flowThreadOverflowPortion, colRect.location());
     400        repaintFlowThreadContentRectangle(repaintRect, immediate, flowThreadPortion, colRect.location(), &flowThreadOverflowPortion);
    401401    }
    402402}
  • trunk/Source/WebCore/rendering/RenderMultiColumnSet.h

    r158097 r159337  
    115115    virtual bool shouldHaveAutoLogicalHeight() const OVERRIDE { return false; }
    116116   
    117     virtual void repaintFlowThreadContent(const LayoutRect& repaintRect, bool immediate) const OVERRIDE;
     117    virtual void repaintFlowThreadContent(const LayoutRect& repaintRect, bool immediate) OVERRIDE;
    118118
    119119    virtual void collectLayerFragments(LayerFragments&, const LayoutRect& layerBoundingBox, const LayoutRect& dirtyRect) OVERRIDE;
     
    130130
    131131    LayoutRect flowThreadPortionRectAt(unsigned index) const;
    132     LayoutRect flowThreadPortionOverflowRect(const LayoutRect& flowThreadPortion, unsigned index, unsigned colCount, LayoutUnit colGap) const;
     132    LayoutRect flowThreadPortionOverflowRect(const LayoutRect& flowThreadPortion, unsigned index, unsigned colCount, LayoutUnit colGap);
    133133
    134134    enum ColumnIndexCalculationMode {
  • trunk/Source/WebCore/rendering/RenderNamedFlowFragment.cpp

    r159027 r159337  
    5757    style.get().setRegionThread(parentStyle.regionThread());
    5858    style.get().setRegionFragment(parentStyle.regionFragment());
     59    style.get().setOverflowX(parentStyle.overflowX());
     60    style.get().setOverflowY(parentStyle.overflowY());
    5961#if ENABLE(CSS_SHAPES)
    6062    style.get().setShapeInside(parentStyle.shapeInside());
     
    9597}
    9698
     99RenderNamedFlowThread* RenderNamedFlowFragment::namedFlowThread() const
     100{
     101    return toRenderNamedFlowThread(flowThread());
     102}
     103
    97104} // namespace WebCore
  • trunk/Source/WebCore/rendering/RenderNamedFlowFragment.h

    r158184 r159337  
    6969        toRenderLayerModelObject(parent()) : nullptr; }
    7070
     71    RenderNamedFlowThread* namedFlowThread() const;
     72
    7173private:
    7274    virtual bool shouldHaveAutoLogicalHeight() const OVERRIDE;
  • trunk/Source/WebCore/rendering/RenderOverflow.h

    r149867 r159337  
    2323
    2424#include "LayoutRect.h"
     25#include <wtf/RefCounted.h>
    2526
    2627namespace WebCore
     
    3839
    3940// This object is allocated only when some of these fields have non-default values in the owning box.
    40 class RenderOverflow {
     41class RenderOverflow : public WTF::RefCounted<RenderOverflow> {
    4142    WTF_MAKE_NONCOPYABLE(RenderOverflow); WTF_MAKE_FAST_ALLOCATED;
    4243public:
  • trunk/Source/WebCore/rendering/RenderRegion.cpp

    r159057 r159337  
    155155}
    156156
    157 LayoutRect RenderRegion::flowThreadPortionOverflowRect() const
     157LayoutRect RenderRegion::flowThreadPortionOverflowRect()
    158158{
    159159    return overflowRectForFlowThreadPortion(flowThreadPortionRect(), isFirstRegion(), isLastRegion(), VisualOverflow);
    160160}
    161161
    162 LayoutRect RenderRegion::overflowRectForFlowThreadPortion(const LayoutRect& flowThreadPortionRect, bool isFirstPortion, bool isLastPortion, OverflowType overflowType) const
     162LayoutPoint RenderRegion::flowThreadPortionLocation() const
     163{
     164    LayoutPoint portionLocation;
     165    LayoutRect portionRect = flowThreadPortionRect();
     166
     167    if (flowThread()->style().isFlippedBlocksWritingMode()) {
     168        LayoutRect flippedFlowThreadPortionRect(portionRect);
     169        flowThread()->flipForWritingMode(flippedFlowThreadPortionRect);
     170        portionLocation = flippedFlowThreadPortionRect.location();
     171    } else
     172        portionLocation = portionRect.location();
     173
     174    return portionLocation;
     175}
     176
     177RenderLayer* RenderRegion::regionContainerLayer() const
     178{
     179    ASSERT(parent() && parent()->isRenderNamedFlowFragmentContainer());
     180    return toRenderBlockFlow(parent())->layer();
     181}
     182
     183LayoutRect RenderRegion::overflowRectForFlowThreadPortion(const LayoutRect& flowThreadPortionRect, bool isFirstPortion, bool isLastPortion, OverflowType overflowType)
    163184{
    164185    ASSERT(isValid());
     
    172193        return flowThreadPortionRect;
    173194
    174     LayoutRect flowThreadOverflow = overflowType == VisualOverflow ? m_flowThread->visualOverflowRect() : m_flowThread->layoutOverflowRect();
     195    LayoutRect flowThreadOverflow = overflowType == VisualOverflow ? visualOverflowRectForBox(m_flowThread) : layoutOverflowRectForBox(m_flowThread);
    175196
    176197    // We are interested about the outline size only when computing the visual overflow.
     
    230251}
    231252
    232 static bool shouldPaintRegionContentsInPhase(PaintPhase phase)
    233 {
    234     return phase == PaintPhaseBlockBackground
    235         || phase == PaintPhaseChildBlockBackground
    236         || phase == PaintPhaseSelection
    237         || phase == PaintPhaseTextClip;
    238 }
    239 
    240 void RenderRegion::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
    241 {
    242     if (style().visibility() != VISIBLE)
    243         return;
    244 
    245     RenderBlockFlow::paintObject(paintInfo, paintOffset);
    246 
    247     if (!isValid())
    248         return;
    249 
    250     // We do not want to paint a region's contents multiple times (for each paint phase of the region object).
    251     // Thus, we only paint the region's contents in certain phases.
    252     if (!shouldPaintRegionContentsInPhase(paintInfo.phase))
    253         return;
    254 
    255     // Delegate the painting of a region's contents to RenderFlowThread.
    256     // RenderFlowThread is a self painting layer because it's a positioned object.
    257     // RenderFlowThread paints its children, the collected objects.
    258     setRegionObjectsRegionStyle();
    259     m_flowThread->paintFlowThreadPortionInRegion(paintInfo, this, flowThreadPortionRect(), flowThreadPortionOverflowRect(), LayoutPoint(paintOffset.x() + borderLeft() + paddingLeft(), paintOffset.y() + borderTop() + paddingTop()));
    260     restoreRegionObjectsOriginalStyle();
    261 }
    262 
    263 // Hit Testing
    264 bool RenderRegion::hitTestContents(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action)
    265 {
    266     if (!isValid() || action != HitTestForeground)
    267         return false;
    268 
    269     LayoutRect boundsRect = borderBoxRectInRegion(locationInContainer.region());
    270     boundsRect.moveBy(accumulatedOffset);
    271     if (visibleToHitTesting() && locationInContainer.intersects(boundsRect)) {
    272         if (m_flowThread->hitTestFlowThreadPortionInRegion(this, flowThreadPortionRect(), flowThreadPortionOverflowRect(), request, result,
    273             locationInContainer, LayoutPoint(accumulatedOffset.x() + borderLeft() + paddingLeft(), accumulatedOffset.y() + borderTop() + paddingTop())))
    274             return true;
    275     }
    276 
    277     return false;
    278 }
    279 
    280253void RenderRegion::checkRegionStyle()
    281254{
     
    389362{
    390363    ASSERT(isValid());
    391 
    392     LayoutRect layoutRect = layoutOverflowRectForBox(m_flowThread);
     364   
     365    LayoutRect layoutRect;
     366    {
     367        // When getting the overflow from the flow thread we need to temporarly reset the current flow thread because
     368        // we're changing flows.
     369        CurrentRenderFlowThreadMaintainer flowThreadMaintainer(m_flowThread);
     370        layoutRect = layoutOverflowRectForBox(m_flowThread);
     371    }
    393372
    394373    layoutRect.setLocation(contentBoxRect().location() + (layoutRect.location() - m_flowThreadPortionRect.location()));
     
    404383}
    405384
    406 void RenderRegion::repaintFlowThreadContent(const LayoutRect& repaintRect, bool immediate) const
    407 {
    408     repaintFlowThreadContentRectangle(repaintRect, immediate, flowThreadPortionRect(), flowThreadPortionOverflowRect(), contentBoxRect().location());
    409 }
    410 
    411 void RenderRegion::repaintFlowThreadContentRectangle(const LayoutRect& repaintRect, bool immediate, const LayoutRect& flowThreadPortionRect, const LayoutRect& flowThreadPortionOverflowRect, const LayoutPoint& regionLocation) const
     385void RenderRegion::repaintFlowThreadContent(const LayoutRect& repaintRect, bool immediate)
     386{
     387    repaintFlowThreadContentRectangle(repaintRect, immediate, flowThreadPortionRect(), contentBoxRect().location());
     388}
     389
     390void RenderRegion::repaintFlowThreadContentRectangle(const LayoutRect& repaintRect, bool immediate, const LayoutRect& flowThreadPortionRect, const LayoutPoint& regionLocation, const LayoutRect* flowThreadPortionClipRect)
    412391{
    413392    ASSERT(isValid());
     
    415394    // We only have to issue a repaint in this region if the region rect intersects the repaint rect.
    416395    LayoutRect flippedFlowThreadPortionRect(flowThreadPortionRect);
    417     LayoutRect flippedFlowThreadPortionOverflowRect(flowThreadPortionOverflowRect);
    418396    flowThread()->flipForWritingMode(flippedFlowThreadPortionRect); // Put the region rects into physical coordinates.
    419     flowThread()->flipForWritingMode(flippedFlowThreadPortionOverflowRect);
    420397
    421398    LayoutRect clippedRect(repaintRect);
    422     clippedRect.intersect(flippedFlowThreadPortionOverflowRect);
     399
     400    if (flowThreadPortionClipRect) {
     401        LayoutRect flippedFlowThreadPortionClipRect(*flowThreadPortionClipRect);
     402        flowThread()->flipForWritingMode(flippedFlowThreadPortionClipRect);
     403        clippedRect.intersect(flippedFlowThreadPortionClipRect);
     404    }
     405
    423406    if (clippedRect.isEmpty())
    424407        return;
     
    612595void RenderRegion::insertedIntoTree()
    613596{
    614     RenderBlockFlow::insertedIntoTree();
    615 
    616597    attachRegion();
     598    if (isValid())
     599        RenderBlockFlow::insertedIntoTree();
    617600}
    618601
     
    788771}
    789772
    790 
    791 RenderOverflow* RenderRegion::ensureOverflowForBox(const RenderBox* box)
    792 {
     773void RenderRegion::ensureOverflowForBox(const RenderBox* box, RefPtr<RenderOverflow>& overflow, bool forceCreation)
     774{
     775    RenderFlowThread* flowThread = this->flowThread();
     776    ASSERT(flowThread);
     777   
    793778    RenderBoxRegionInfo* boxInfo = renderBoxRegionInfo(box);
    794     if (!boxInfo)
    795         return 0;
    796 
    797     if (boxInfo->overflow())
    798         return boxInfo->overflow();
    799 
     779    if (!boxInfo && !forceCreation)
     780        return;
     781
     782    if (boxInfo && boxInfo->overflow()) {
     783        overflow = boxInfo->overflow();
     784        return;
     785    }
     786   
    800787    LayoutRect borderBox = box->borderBoxRectInRegion(this);
    801     borderBox = rectFlowPortionForBox(box, borderBox);
    802 
    803     LayoutRect clientBox = box->clientBoxRectInRegion(this);
    804     clientBox = rectFlowPortionForBox(box, clientBox);
    805 
    806     boxInfo->createOverflow(clientBox, borderBox);
    807 
    808     return boxInfo->overflow();
     788    LayoutRect clientBox;
     789    ASSERT(flowThread->objectShouldPaintInFlowRegion(box, this));
     790
     791    if (!borderBox.isEmpty()) {
     792        borderBox = rectFlowPortionForBox(box, borderBox);
     793       
     794        clientBox = box->clientBoxRectInRegion(this);
     795        clientBox = rectFlowPortionForBox(box, clientBox);
     796       
     797        flowThread->flipForWritingModeLocalCoordinates(borderBox);
     798        flowThread->flipForWritingModeLocalCoordinates(clientBox);
     799    }
     800
     801    if (boxInfo) {
     802        boxInfo->createOverflow(clientBox, borderBox);
     803        overflow = boxInfo->overflow();
     804    } else
     805        overflow = adoptRef(new RenderOverflow(clientBox, borderBox));
    809806}
    810807
     
    815812    m_flowThread->getRegionRangeForBox(box, startRegion, endRegion);
    816813
    817     // FIXME: Is this writing mode friendly?
    818814    LayoutRect mappedRect = m_flowThread->mapFromLocalToFlowThread(box, rect);
    819     if (this != startRegion)
    820         mappedRect.shiftYEdgeTo(std::max<LayoutUnit>(logicalTopForFlowThreadContent(), mappedRect.y()));
    821     if (this != endRegion)
    822         mappedRect.setHeight(std::max<LayoutUnit>(0, std::min<LayoutUnit>(logicalBottomForFlowThreadContent() - mappedRect.y(), mappedRect.height())));
     815    if (flowThread()->isHorizontalWritingMode()) {
     816        if (this != startRegion)
     817            mappedRect.shiftYEdgeTo(std::max<LayoutUnit>(logicalTopForFlowThreadContent(), mappedRect.y()));
     818
     819        if (this != endRegion)
     820            mappedRect.setHeight(std::max<LayoutUnit>(0, std::min<LayoutUnit>(logicalBottomForFlowThreadContent() - mappedRect.y(), mappedRect.height())));
     821    } else {
     822        if (this != startRegion)
     823            mappedRect.shiftXEdgeTo(std::max<LayoutUnit>(logicalTopForFlowThreadContent(), mappedRect.x()));
     824           
     825        if (this != endRegion)
     826            mappedRect.setWidth(std::max<LayoutUnit>(0, std::min<LayoutUnit>(logicalBottomForFlowThreadContent() - mappedRect.x(), mappedRect.width())));
     827    }
    823828
    824829    bool clipX = style().overflowX() != OVISIBLE;
     
    828833        mappedRect.intersect(flowThreadPortionRect());
    829834
    830     return m_flowThread->mapFromFlowThreadToLocal(box, mappedRect);
     835    return mappedRect.isEmpty() ? mappedRect : m_flowThread->mapFromFlowThreadToLocal(box, mappedRect);
    831836}
    832837
    833838void RenderRegion::addLayoutOverflowForBox(const RenderBox* box, const LayoutRect& rect)
    834839{
    835     RenderOverflow* regionOverflow = ensureOverflowForBox(box);
     840    if (rect.isEmpty())
     841        return;
     842
     843    RefPtr<RenderOverflow> regionOverflow;
     844    ensureOverflowForBox(box, regionOverflow, false);
    836845
    837846    if (!regionOverflow)
     
    843852void RenderRegion::addVisualOverflowForBox(const RenderBox* box, const LayoutRect& rect)
    844853{
    845     RenderOverflow* regionOverflow = ensureOverflowForBox(box);
     854    if (rect.isEmpty())
     855        return;
     856
     857    RefPtr<RenderOverflow> regionOverflow;
     858    ensureOverflowForBox(box, regionOverflow, false);
    846859
    847860    if (!regionOverflow)
    848861        return;
    849862
    850     regionOverflow->addVisualOverflow(rect);
     863    LayoutRect flippedRect = rect;
     864    flowThread()->flipForWritingModeLocalCoordinates(flippedRect);
     865    regionOverflow->addVisualOverflow(flippedRect);
    851866}
    852867
    853868LayoutRect RenderRegion::layoutOverflowRectForBox(const RenderBox* box)
    854869{
    855     RenderOverflow* overflow = ensureOverflowForBox(box);
    856     if (!overflow)
    857         return box->layoutOverflowRect();
    858 
     870    RefPtr<RenderOverflow> overflow;
     871    ensureOverflowForBox(box, overflow, true);
     872   
     873    ASSERT(overflow);
    859874    return overflow->layoutOverflowRect();
    860875}
     
    862877LayoutRect RenderRegion::visualOverflowRectForBox(const RenderBox* box)
    863878{
    864     RenderOverflow* overflow = ensureOverflowForBox(box);
    865     if (!overflow)
    866         return box->visualOverflowRect();
    867 
     879    RefPtr<RenderOverflow> overflow;
     880    ensureOverflowForBox(box, overflow, true);
     881   
     882    ASSERT(overflow);
    868883    return overflow->visualOverflowRect();
    869884}
     
    890905}
    891906
    892 // FIXME: This doesn't work for writing modes.
    893907LayoutRect RenderRegion::visualOverflowRectForBoxForPropagation(const RenderBox* box)
    894908{
    895909    LayoutRect rect = visualOverflowRectForBox(box);
     910    flowThread()->flipForWritingModeLocalCoordinates(rect);
     911
    896912    return rect;
    897913}
  • trunk/Source/WebCore/rendering/RenderRegion.h

    r159057 r159337  
    5050    virtual bool isRenderRegion() const OVERRIDE FINAL { return true; }
    5151
    52     virtual bool hitTestContents(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
    53 
    5452    virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
    5553
    5654    void setFlowThreadPortionRect(const LayoutRect& rect) { m_flowThreadPortionRect = rect; }
    5755    LayoutRect flowThreadPortionRect() const { return m_flowThreadPortionRect; }
    58     LayoutRect flowThreadPortionOverflowRect() const;
     56    LayoutRect flowThreadPortionOverflowRect();
     57
     58    LayoutPoint flowThreadPortionLocation() const;
     59   
     60    RenderLayer* regionContainerLayer() const;
    5961
    6062    void attachRegion();
     
    136138    virtual bool isRenderRegionSet() const { return false; }
    137139   
    138     virtual void repaintFlowThreadContent(const LayoutRect& repaintRect, bool immediate) const;
     140    virtual void repaintFlowThreadContent(const LayoutRect& repaintRect, bool immediate);
    139141
    140142    virtual void collectLayerFragments(LayerFragments&, const LayoutRect&, const LayoutRect&) { }
     
    150152
    151153    LayoutRect rectFlowPortionForBox(const RenderBox*, const LayoutRect&) const;
     154   
     155    void setRegionObjectsRegionStyle();
     156    void restoreRegionObjectsOriginalStyle();
    152157
    153158    virtual bool canHaveChildren() const OVERRIDE { return false; }
     
    159164    RenderRegion(Document&, PassRef<RenderStyle>, RenderFlowThread*);
    160165
    161     RenderOverflow* ensureOverflowForBox(const RenderBox*);
    162 
    163     void setRegionObjectsRegionStyle();
    164     void restoreRegionObjectsOriginalStyle();
     166    void ensureOverflowForBox(const RenderBox*, RefPtr<RenderOverflow>&, bool);
    165167
    166168    virtual void computePreferredLogicalWidths() OVERRIDE;
     
    171173        VisualOverflow
    172174    };
    173     LayoutRect overflowRectForFlowThreadPortion(const LayoutRect& flowThreadPortionRect, bool isFirstPortion, bool isLastPortion, OverflowType) const;
    174 
    175     void repaintFlowThreadContentRectangle(const LayoutRect& repaintRect, bool immediate, const LayoutRect& flowThreadPortionRect,
    176         const LayoutRect& flowThreadPortionOverflowRect, const LayoutPoint& regionLocation) const;
    177 
     175
     176    LayoutRect overflowRectForFlowThreadPortion(const LayoutRect& flowThreadPortionRect, bool isFirstPortion, bool isLastPortion, OverflowType);
     177    void repaintFlowThreadContentRectangle(const LayoutRect& repaintRect, bool immediate, const LayoutRect& flowThreadPortionRect, const LayoutPoint& regionLocation, const LayoutRect* flowThreadPortionClipRect = 0);
    178178    virtual bool shouldHaveAutoLogicalHeight() const;
    179179
     
    187187
    188188    virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0) OVERRIDE;
    189     virtual void paintObject(PaintInfo&, const LayoutPoint&) OVERRIDE;
    190189
    191190    virtual void installFlowThread();
  • trunk/Source/WebCore/rendering/RenderReplaced.cpp

    r159027 r159337  
    3131#include "Page.h"
    3232#include "RenderBlock.h"
     33#include "RenderFlowThread.h"
    3334#include "RenderLayer.h"
     35#include "RenderRegion.h"
    3436#include "RenderTheme.h"
    3537#include "RenderView.h"
     
    188190    // if we're invisible or haven't received a layout yet, then just bail.
    189191    if (style().visibility() != VISIBLE)
     192        return false;
     193   
     194    // Check our region range to make sure we need to be painting in this region.
     195    if (paintInfo.renderRegion && !paintInfo.renderRegion->flowThread()->objectShouldPaintInFlowRegion(this, paintInfo.renderRegion))
    190196        return false;
    191197
  • trunk/Source/WebCore/rendering/RootInlineBox.cpp

    r159049 r159337  
    194194void RootInlineBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit lineTop, LayoutUnit lineBottom)
    195195{
     196    // Check if we are in the correct region.
     197    if (paintInfo.renderRegion && containingRegion() && containingRegion() != paintInfo.renderRegion)
     198        return;
     199   
    196200    InlineFlowBox::paint(paintInfo, paintOffset, lineTop, lineBottom);
    197201    paintEllipsisBox(paintInfo, paintOffset, lineTop, lineBottom);
Note: See TracChangeset for help on using the changeset viewer.