summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/LayoutState.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2016-04-10 09:28:39 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2016-04-10 09:28:39 +0000
commit32761a6cee1d0dee366b885b7b9c777e67885688 (patch)
treed6bec92bebfb216f4126356e55518842c2f476a1 /Source/WebCore/rendering/LayoutState.cpp
parenta4e969f4965059196ca948db781e52f7cfebf19e (diff)
downloadWebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/WebCore/rendering/LayoutState.cpp')
-rw-r--r--Source/WebCore/rendering/LayoutState.cpp125
1 files changed, 97 insertions, 28 deletions
diff --git a/Source/WebCore/rendering/LayoutState.cpp b/Source/WebCore/rendering/LayoutState.cpp
index 9677c8c16..bed4756e2 100644
--- a/Source/WebCore/rendering/LayoutState.cpp
+++ b/Source/WebCore/rendering/LayoutState.cpp
@@ -26,16 +26,21 @@
#include "config.h"
#include "LayoutState.h"
+#include "ColumnInfo.h"
#include "RenderFlowThread.h"
#include "RenderInline.h"
#include "RenderLayer.h"
-#include "RenderMultiColumnFlowThread.h"
#include "RenderView.h"
namespace WebCore {
-LayoutState::LayoutState(std::unique_ptr<LayoutState> next, RenderBox* renderer, const LayoutSize& offset, LayoutUnit pageLogicalHeight, bool pageLogicalHeightChanged)
- : m_next(WTFMove(next))
+LayoutState::LayoutState(std::unique_ptr<LayoutState> next, RenderBox* renderer, const LayoutSize& offset, LayoutUnit pageLogicalHeight, bool pageLogicalHeightChanged, ColumnInfo* columnInfo)
+ : m_columnInfo(columnInfo)
+ , m_lineGrid(0)
+ , m_next(std::move(next))
+#if ENABLE(CSS_SHAPES)
+ , m_shapeInsideInfo(nullptr)
+#endif
#ifndef NDEBUG
, m_renderer(renderer)
#endif
@@ -52,8 +57,8 @@ LayoutState::LayoutState(std::unique_ptr<LayoutState> next, RenderBox* renderer,
if (renderer->isOutOfFlowPositioned() && !fixed) {
if (RenderElement* container = renderer->container()) {
- if (container->isInFlowPositioned() && is<RenderInline>(*container))
- m_paintOffset += downcast<RenderInline>(*container).offsetForInFlowPositionedInline(renderer);
+ if (container->isInFlowPositioned() && container->isRenderInline())
+ m_paintOffset += toRenderInline(container)->offsetForInFlowPositionedInline(renderer);
}
}
@@ -67,7 +72,7 @@ LayoutState::LayoutState(std::unique_ptr<LayoutState> next, RenderBox* renderer,
m_clipRect = m_next->m_clipRect;
if (renderer->hasOverflowClip()) {
- LayoutRect clipRect(toLayoutPoint(m_paintOffset) + renderer->view().layoutDelta(), renderer->cachedSizeForOverflowClip());
+ LayoutRect clipRect(toPoint(m_paintOffset) + renderer->view().layoutDelta(), renderer->cachedSizeForOverflowClip());
if (m_clipped)
m_clipRect.intersect(clipRect);
else {
@@ -80,13 +85,12 @@ LayoutState::LayoutState(std::unique_ptr<LayoutState> next, RenderBox* renderer,
// If we establish a new page height, then cache the offset to the top of the first page.
// We can compare this later on to figure out what part of the page we're actually on,
- if (pageLogicalHeight || renderer->isRenderFlowThread()) {
+ if (pageLogicalHeight || m_columnInfo || renderer->isRenderFlowThread()) {
m_pageLogicalHeight = pageLogicalHeight;
bool isFlipped = renderer->style().isFlippedBlocksWritingMode();
m_pageOffset = LayoutSize(m_layoutOffset.width() + (!isFlipped ? renderer->borderLeft() + renderer->paddingLeft() : renderer->borderRight() + renderer->paddingRight()),
m_layoutOffset.height() + (!isFlipped ? renderer->borderTop() + renderer->paddingTop() : renderer->borderBottom() + renderer->paddingBottom()));
m_pageLogicalHeightChanged = pageLogicalHeightChanged;
- m_isPaginated = true;
} else {
// If we don't establish a new page height, then propagate the old page height and offset down.
m_pageLogicalHeight = m_next->m_pageLogicalHeight;
@@ -95,28 +99,39 @@ LayoutState::LayoutState(std::unique_ptr<LayoutState> next, RenderBox* renderer,
// Disable pagination for objects we don't support. For now this includes overflow:scroll/auto, inline blocks and
// writing mode roots.
- if (renderer->isUnsplittableForPagination()) {
+ if (renderer->isUnsplittableForPagination())
m_pageLogicalHeight = 0;
- m_isPaginated = false;
- } else
- m_isPaginated = m_pageLogicalHeight || renderer->flowThreadContainingBlock();
}
// Propagate line grid information.
propagateLineGridInfo(renderer);
+ if (!m_columnInfo)
+ m_columnInfo = m_next->m_columnInfo;
+
+#if ENABLE(CSS_SHAPES)
+ if (renderer->isRenderBlock()) {
+ const RenderBlock* renderBlock = toRenderBlock(renderer);
+ m_shapeInsideInfo = renderBlock->shapeInsideInfo();
+ if (!m_shapeInsideInfo && m_next->m_shapeInsideInfo && renderBlock->allowsShapeInsideInfoSharing())
+ m_shapeInsideInfo = m_next->m_shapeInsideInfo;
+ }
+#endif
+
m_layoutDelta = m_next->m_layoutDelta;
-#if !ASSERT_DISABLED
+#if !ASSERT_DISABLED && ENABLE(SATURATED_LAYOUT_ARITHMETIC)
m_layoutDeltaXSaturated = m_next->m_layoutDeltaXSaturated;
m_layoutDeltaYSaturated = m_next->m_layoutDeltaYSaturated;
#endif
+
+ m_isPaginated = m_pageLogicalHeight || m_columnInfo || renderer->isRenderFlowThread();
- if (lineGrid() && (lineGrid()->style().writingMode() == renderer->style().writingMode()) && is<RenderMultiColumnFlowThread>(*renderer))
- downcast<RenderMultiColumnFlowThread>(*renderer).computeLineGridPaginationOrigin(*this);
+ if (lineGrid() && renderer->hasColumns() && renderer->style().hasInlineColumnAxis())
+ computeLineGridPaginationOrigin(renderer);
// If we have a new grid to track, then add it to our set.
- if (renderer->style().lineGrid() != RenderStyle::initialLineGrid() && is<RenderBlockFlow>(*renderer))
- establishLineGrid(downcast<RenderBlockFlow>(renderer));
+ if (renderer->style().lineGrid() != RenderStyle::initialLineGrid() && renderer->isRenderBlockFlow())
+ establishLineGrid(toRenderBlockFlow(renderer));
// FIXME: <http://bugs.webkit.org/show_bug.cgi?id=13443> Apply control clip if present.
}
@@ -125,31 +140,36 @@ LayoutState::LayoutState(RenderObject& root)
: m_clipped(false)
, m_isPaginated(false)
, m_pageLogicalHeightChanged(false)
-#if !ASSERT_DISABLED
+#if !ASSERT_DISABLED && ENABLE(SATURATED_LAYOUT_ARITHMETIC)
, m_layoutDeltaXSaturated(false)
, m_layoutDeltaYSaturated(false)
#endif
+ , m_columnInfo(0)
+ , m_lineGrid(0)
+#if ENABLE(CSS_SHAPES)
+ , m_shapeInsideInfo(nullptr)
+#endif
+ , m_pageLogicalHeight(0)
#ifndef NDEBUG
, m_renderer(&root)
#endif
{
- if (RenderElement* container = root.container()) {
- FloatPoint absContentPoint = container->localToAbsolute(FloatPoint(), UseTransforms);
- m_paintOffset = LayoutSize(absContentPoint.x(), absContentPoint.y());
+ RenderElement* container = root.container();
+ FloatPoint absContentPoint = container->localToAbsolute(FloatPoint(), UseTransforms);
+ m_paintOffset = LayoutSize(absContentPoint.x(), absContentPoint.y());
- if (container->hasOverflowClip()) {
- m_clipped = true;
- auto& containerBox = downcast<RenderBox>(*container);
- m_clipRect = LayoutRect(toLayoutPoint(m_paintOffset), containerBox.cachedSizeForOverflowClip());
- m_paintOffset -= containerBox.scrolledContentOffset();
- }
+ if (container->hasOverflowClip()) {
+ m_clipped = true;
+ RenderBox* containerBox = toRenderBox(container);
+ m_clipRect = LayoutRect(toPoint(m_paintOffset), containerBox->cachedSizeForOverflowClip());
+ m_paintOffset -= containerBox->scrolledContentOffset();
}
}
-
void LayoutState::clearPaginationInformation()
{
m_pageLogicalHeight = m_next->m_pageLogicalHeight;
m_pageOffset = m_next->m_pageOffset;
+ m_columnInfo = m_next->m_columnInfo;
}
LayoutUnit LayoutState::pageLogicalOffset(RenderBox* child, LayoutUnit childLogicalOffset) const
@@ -159,6 +179,13 @@ LayoutUnit LayoutState::pageLogicalOffset(RenderBox* child, LayoutUnit childLogi
return m_layoutOffset.width() + childLogicalOffset - m_pageOffset.width();
}
+void LayoutState::addForcedColumnBreak(RenderBox* child, LayoutUnit childLogicalOffset)
+{
+ if (!m_columnInfo || m_columnInfo->columnHeight())
+ return;
+ m_columnInfo->addForcedBreak(pageLogicalOffset(child, childLogicalOffset));
+}
+
void LayoutState::propagateLineGridInfo(RenderBox* renderer)
{
// Disable line grids for objects we don't support. For now this includes overflow:scroll/auto, inline blocks and
@@ -197,4 +224,46 @@ void LayoutState::establishLineGrid(RenderBlockFlow* block)
m_lineGridOffset = m_layoutOffset;
}
+void LayoutState::computeLineGridPaginationOrigin(RenderBox* renderer)
+{
+ // We need to cache a line grid pagination origin so that we understand how to reset the line grid
+ // at the top of each column.
+ // Get the current line grid and offset.
+ if (!lineGrid() || lineGrid()->style().writingMode() != renderer->style().writingMode())
+ return;
+
+ // Get the hypothetical line box used to establish the grid.
+ RootInlineBox* lineGridBox = lineGrid()->lineGridBox();
+ if (!lineGridBox)
+ return;
+
+ bool isHorizontalWritingMode = lineGrid()->isHorizontalWritingMode();
+
+ LayoutUnit lineGridBlockOffset = isHorizontalWritingMode ? lineGridOffset().height() : lineGridOffset().width();
+
+ // Now determine our position on the grid. Our baseline needs to be adjusted to the nearest baseline multiple
+ // as established by the line box.
+ // FIXME: Need to handle crazy line-box-contain values that cause the root line box to not be considered. I assume
+ // the grid should honor line-box-contain.
+ LayoutUnit gridLineHeight = lineGridBox->lineBottomWithLeading() - lineGridBox->lineTopWithLeading();
+ if (!gridLineHeight)
+ return;
+
+ LayoutUnit firstLineTopWithLeading = lineGridBlockOffset + lineGridBox->lineTopWithLeading();
+
+ if (isPaginated() && pageLogicalHeight()) {
+ LayoutUnit pageLogicalTop = renderer->isHorizontalWritingMode() ? m_pageOffset.height() : m_pageOffset.width();
+ if (pageLogicalTop > firstLineTopWithLeading) {
+ // Shift to the next highest line grid multiple past the page logical top. Cache the delta
+ // between this new value and the page logical top as the pagination origin.
+ LayoutUnit remainder = roundToInt(pageLogicalTop - firstLineTopWithLeading) % roundToInt(gridLineHeight);
+ LayoutUnit paginationDelta = gridLineHeight - remainder;
+ if (isHorizontalWritingMode)
+ m_lineGridPaginationOrigin.setHeight(paginationDelta);
+ else
+ m_lineGridPaginationOrigin.setWidth(paginationDelta);
+ }
+ }
+}
+
} // namespace WebCore