Source/WebCore/ChangeLog

 12012-09-10 Bear Travis <betravis@adobe.com>
 2
 3 [CSS Exclusions] Enable css exclusions for multiple blocks per element
 4 https://bugs.webkit.org/show_bug.cgi?id=89993
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Similar to multi-column layout, a parent RenderBlock's WrapShapeInfo may affect
 9 the inline content of its children. This patch follows the example of ColumnInfo
 10 and adds WrapShapeInfo to LayoutState, which tracks the current shape-inside that
 11 inline content should respect.
 12
 13 Test: fast/exclusions/shape-inside/shape-inside-multiple-blocks.html
 14
 15 * rendering/LayoutState.cpp:
 16 (WebCore::LayoutState::LayoutState): Initialize m_wrapShapeInfo.
 17 * rendering/LayoutState.h:
 18 (WebCore):
 19 (WebCore::LayoutState::LayoutState): Initialize m_wrapShapeInfo.
 20 (LayoutState):
 21 (WebCore::LayoutState::wrapShapeInfo): Getter for m_wrapShapeInfo.
 22 * rendering/RenderBlockLineLayout.cpp:
 23 (WebCore::LineWidth::LineWidth): Use LayoutState to lookup WrapShapeInfo.
 24 (WebCore::RenderBlock::computeInlineDirectionPositionsForLine): Ditto.
 25 (WebCore::RenderBlock::layoutRunsAndFloatsInRange): Ditto.
 26 * rendering/RenderView.h:
 27 (WebCore::RenderView::pushLayoutState): Push LayoutState if a WrapShapeInfo
 28 is present.
 29
1302012-09-10 Justin Novosad <junov@chromium.org>
231
332 Implement canvas v5 line dash feature

Source/WebCore/rendering/LayoutState.cpp

@@LayoutState::LayoutState(LayoutState* prev, RenderBox* renderer, const LayoutSiz
4242#ifndef NDEBUG
4343 , m_renderer(renderer)
4444#endif
 45#if ENABLE(CSS_EXCLUSIONS)
 46 , m_wrapShapeInfo(0)
 47#endif
4548{
4649 ASSERT(m_next);
4750

@@LayoutState::LayoutState(LayoutState* prev, RenderBox* renderer, const LayoutSiz
107110 if (!m_columnInfo)
108111 m_columnInfo = m_next->m_columnInfo;
109112
 113#if ENABLE(CSS_EXCLUSIONS)
 114 if (renderer->isRenderBlock()) {
 115 RenderBlock* renderBlock = toRenderBlock(renderer);
 116 m_wrapShapeInfo = renderBlock->wrapShapeInfo();
 117 if (!m_wrapShapeInfo)
 118 m_wrapShapeInfo = m_next->m_wrapShapeInfo;
 119 }
 120#endif
 121
110122 m_layoutDelta = m_next->m_layoutDelta;
111123
112124 m_isPaginated = m_pageLogicalHeight || m_columnInfo || renderer->isRenderFlowThread();

@@LayoutState::LayoutState(RenderObject* root)
132144#ifndef NDEBUG
133145 , m_renderer(root)
134146#endif
 147#if ENABLE(CSS_EXCLUSIONS)
 148 , m_wrapShapeInfo(0)
 149#endif
135150{
136151 RenderObject* container = root->container();
137152 FloatPoint absContentPoint = container->localToAbsolute(FloatPoint(), false, true);

Source/WebCore/rendering/LayoutState.h

@@class RenderBlock;
3838class RenderBox;
3939class RenderObject;
4040class RenderFlowThread;
 41#if ENABLE(CSS_EXCLUSIONS)
 42class WrapShapeInfo;
 43#endif
4144
4245class LayoutState {
4346 WTF_MAKE_NONCOPYABLE(LayoutState);

@@public:
5356#ifndef NDEBUG
5457 , m_renderer(0)
5558#endif
 59#if ENABLE(CSS_EXCLUSIONS)
 60 , m_wrapShapeInfo(0)
 61#endif
5662 {
5763 }
5864

@@public:
8894
8995 bool needsBlockDirectionLocationSetBeforeLayout() const { return m_lineGrid || (m_isPaginated && m_pageLogicalHeight); }
9096
 97#if ENABLE(CSS_EXCLUSIONS)
 98 WrapShapeInfo* wrapShapeInfo() const { return m_wrapShapeInfo; }
 99#endif
91100private:
92101 // The normal operator new is disallowed.
93102 void* operator new(size_t) throw();

@@public:
129138#ifndef NDEBUG
130139 RenderObject* m_renderer;
131140#endif
 141#if ENABLE(CSS_EXCLUSIONS)
 142 WrapShapeInfo* m_wrapShapeInfo;
 143#endif
132144};
133145
134146} // namespace WebCore

Source/WebCore/rendering/RenderBlockLineLayout.cpp

@@namespace WebCore {
6363// We don't let our line box tree for a single line get any deeper than this.
6464const unsigned cMaxLineDepth = 200;
6565
 66#if ENABLE(CSS_EXCLUSIONS)
 67static inline WrapShapeInfo* layoutWrapShapeInfo(const RenderBlock* block)
 68{
 69 return block->view()->layoutState()->wrapShapeInfo();
 70}
 71#endif
 72
6673class LineWidth {
6774public:
6875 LineWidth(RenderBlock* block, bool isFirstLine)

@@public:
8087 {
8188 ASSERT(block);
8289#if ENABLE(CSS_EXCLUSIONS)
83  WrapShapeInfo* wrapShapeInfo = m_block->wrapShapeInfo();
 90 WrapShapeInfo* wrapShapeInfo = layoutWrapShapeInfo(m_block);
8491 // FIXME: Bug 91878: Add support for multiple segments, currently we only support one
8592 if (wrapShapeInfo && wrapShapeInfo->lineState() == WrapShapeInfo::LINE_INSIDE_SHAPE) {
8693 // All interior shape positions should have at least one segment

@@void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox,
804811 float logicalLeft = pixelSnappedLogicalLeftOffsetForLine(logicalHeight(), firstLine, lineLogicalHeight);
805812 float logicalRight = pixelSnappedLogicalRightOffsetForLine(logicalHeight(), firstLine, lineLogicalHeight);
806813#if ENABLE(CSS_EXCLUSIONS)
807  WrapShapeInfo* wrapShapeInfo = this->wrapShapeInfo();
 814 WrapShapeInfo* wrapShapeInfo = layoutWrapShapeInfo(this);
808815 if (wrapShapeInfo && wrapShapeInfo->lineState() == WrapShapeInfo::LINE_INSIDE_SHAPE) {
809816 logicalLeft = max<float>(roundToInt(wrapShapeInfo->segments()[0].logicalLeft), logicalLeft);
810817 logicalRight = min<float>(floorToInt(wrapShapeInfo->segments()[0].logicalRight), logicalRight);

@@void RenderBlock::layoutRunsAndFloatsInRange(LineLayoutState& layoutState, Inlin
12951302 LineBreaker lineBreaker(this);
12961303
12971304#if ENABLE(CSS_EXCLUSIONS)
 1305 LayoutUnit absoluteLogicalTop;
12981306 WrapShapeInfo* wrapShapeInfo = this->wrapShapeInfo();
 1307 if (!wrapShapeInfo && (wrapShapeInfo = layoutWrapShapeInfo(this))) {
 1308 absoluteLogicalTop = logicalTop();
 1309 // FIXME: If layout state is disabled, the offset will be incorrect
 1310 if (isHorizontalWritingMode())
 1311 absoluteLogicalTop += view()->layoutState()->layoutOffset().height();
 1312 else
 1313 absoluteLogicalTop += view()->layoutState()->layoutOffset().width();
 1314 }
12991315 // Move to the top of the shape inside to begin layout
1300  if (wrapShapeInfo && logicalHeight() < wrapShapeInfo->shapeLogicalTop())
1301  setLogicalHeight(wrapShapeInfo->shapeLogicalTop());
 1316 if (wrapShapeInfo && logicalHeight() + absoluteLogicalTop < wrapShapeInfo->shapeLogicalTop())
 1317 setLogicalHeight(wrapShapeInfo->shapeLogicalTop() - absoluteLogicalTop);
13021318#endif
13031319
13041320 while (!end.atEnd()) {

@@void RenderBlock::layoutRunsAndFloatsInRange(LineLayoutState& layoutState, Inlin
13201336 bool isNewUBAParagraph = layoutState.lineInfo().previousLineBrokeCleanly();
13211337 FloatingObject* lastFloatFromPreviousLine = (m_floatingObjects && !m_floatingObjects->set().isEmpty()) ? m_floatingObjects->set().last() : 0;
13221338#if ENABLE(CSS_EXCLUSIONS)
1323  // FIXME: Bug 89993: If the wrap shape comes from a parent, we will need to adjust
1324  // the height coordinate
13251339 if (wrapShapeInfo)
1326  wrapShapeInfo->computeSegmentsForLine(logicalHeight());
 1340 wrapShapeInfo->computeSegmentsForLine(logicalHeight() + absoluteLogicalTop);
13271341#endif
13281342 end = lineBreaker.nextLineBreak(resolver, layoutState.lineInfo(), renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines);
13291343 if (resolver.position().atEnd()) {

Source/WebCore/rendering/RenderView.h

@@private:
222222 {
223223 // We push LayoutState even if layoutState is disabled because it stores layoutDelta too.
224224 if (!doingFullRepaint() || m_layoutState->isPaginated() || renderer->hasColumns() || renderer->inRenderFlowThread()
225  || m_layoutState->lineGrid() || (renderer->style()->lineGrid() != RenderStyle::initialLineGrid() && renderer->isBlockFlow())) {
 225 || m_layoutState->lineGrid() || (renderer->style()->lineGrid() != RenderStyle::initialLineGrid() && renderer->isBlockFlow())
 226#if ENABLE(CSS_EXCLUSIONS)
 227 || (renderer->isRenderBlock() && toRenderBlock(renderer)->wrapShapeInfo())
 228#endif
 229 ) {
226230 m_layoutState = new (renderArena()) LayoutState(m_layoutState, renderer, offset, pageHeight, pageHeightChanged, colInfo);
227231 return true;
228232 }

LayoutTests/ChangeLog

 12012-09-10 Bear Travis <betravis@adobe.com>
 2
 3 [CSS Exclusions] Enable css exclusions for multiple blocks per element
 4 https://bugs.webkit.org/show_bug.cgi?id=89993
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Adding tests to cover the case where a shape-inside affects block children's
 9 inline content.
 10
 11 * fast/exclusions/shape-inside/shape-inside-multiple-blocks-expected.html: Added.
 12 * fast/exclusions/shape-inside/shape-inside-multiple-blocks.html: Added.
 13
1142012-09-10 Fady Samuel <fsamuel@chromium.org>
215
316 Mark gradient-with-scaled-ancestor.html as flaky

LayoutTests/fast/exclusions/shape-inside/shape-inside-multiple-blocks-expected.html

 1<!DOCTYPE html>
 2<html>
 3<head>
 4<style>
 5 #shape-inside {
 6 padding: 10px;
 7 width: 180px;
 8 height: 280px;
 9 position: relative;
 10 }
 11 #border {
 12 position: absolute;
 13 top: 8px;
 14 left: 8px;
 15 width: 180px;
 16 height: 280px;
 17 border: 2px solid blue;
 18 }
 19 p {
 20 margin-top: 0;
 21 }
 22</style>
 23</head>
 24<body>
 25 <div id="shape-inside">
 26 <div id="border"></div>
 27 <div>
 28 <p>Paragraph 1. This paragraph should be just below the top edge of the blue
 29 rectangle. It's left and right edges should be within the blue rectangle.
 30 </div>
 31 <p>Paragraph 2. This paragraph should be just below paragraph 1. It's left
 32 and right edges should also be within the blue rectangle.
 33 </div>
 34</body>
 35</html>

LayoutTests/fast/exclusions/shape-inside/shape-inside-multiple-blocks.html

 1<!DOCTYPE html>
 2<html>
 3<head>
 4<script>
 5 if (window.internals)
 6 window.internals.settings.setCSSExclusionsEnabled(true);
 7</script>
 8<style>
 9 #shape-inside {
 10 width: 200px;
 11 height: 300px;
 12 -webkit-shape-inside: rectangle(10px, 10px, 180px, 280px);
 13 position: relative;
 14 }
 15 #border {
 16 position: absolute;
 17 top: 8px;
 18 left: 8px;
 19 width: 180px;
 20 height: 280px;
 21 border: 2px solid blue;
 22 }
 23 p {
 24 margin-top: 0;
 25 }
 26</style>
 27</head>
 28<body>
 29 <div id="shape-inside">
 30 <div id="border"></div>
 31 <div>
 32 <p>Paragraph 1. This paragraph should be just below the top edge of the blue
 33 rectangle. It's left and right edges should be within the blue rectangle.
 34 </div>
 35 <p>Paragraph 2. This paragraph should be just below paragraph 1. It's left
 36 and right edges should also be within the blue rectangle.
 37 </div>
 38</body>
 39</html>