Diff
Modified: trunk/Source/WebCore/ChangeLog (158120 => 158121)
--- trunk/Source/WebCore/ChangeLog 2013-10-28 18:48:47 UTC (rev 158120)
+++ trunk/Source/WebCore/ChangeLog 2013-10-28 19:22:51 UTC (rev 158121)
@@ -1,3 +1,20 @@
+2013-10-24 Sam Weinig <[email protected]>
+
+ Move RenderBlock functions only used by RenderBlockFlow to RenderBlockFlow
+ https://bugs.webkit.org/show_bug.cgi?id=123318
+
+ Reviewed by David Hyatt.
+
+ * rendering/LineLayoutState.h:
+ Move FloatWithRect from RenderBlock.
+
+ * rendering/RenderBlock.cpp:
+ * rendering/RenderBlock.h:
+ * rendering/RenderBlockFlow.cpp:
+ * rendering/RenderBlockFlow.h:
+ * rendering/RenderBlockLineLayout.cpp:
+ Move pagination and float functions.
+
2013-10-28 Sergio Villar Senin <[email protected]>
[CSS Grid Layout] Add support for order inside grid items
Modified: trunk/Source/WebCore/rendering/LineLayoutState.h (158120 => 158121)
--- trunk/Source/WebCore/rendering/LineLayoutState.h 2013-10-28 18:48:47 UTC (rev 158120)
+++ trunk/Source/WebCore/rendering/LineLayoutState.h 2013-10-28 19:22:51 UTC (rev 158121)
@@ -34,8 +34,24 @@
#ifndef LineLayoutState_h
#define LineLayoutState_h
+#include "LayoutRect.h"
+#include "RenderBox.h"
+
namespace WebCore {
+struct FloatWithRect {
+ FloatWithRect(RenderBox& f)
+ : object(f)
+ , rect(LayoutRect(f.x() - f.marginLeft(), f.y() - f.marginTop(), f.width() + f.marginWidth(), f.height() + f.marginHeight()))
+ , everHadLayout(f.everHadLayout())
+ {
+ }
+
+ RenderBox& object;
+ LayoutRect rect;
+ bool everHadLayout;
+};
+
// Like LayoutState for layout(), LineLayoutState keeps track of global information
// during an entire linebox tree layout pass (aka layoutInlineChildren).
class LineLayoutState {
@@ -53,7 +69,8 @@
, m_checkForFloatsFromLastLine(false)
, m_isFullLayout(fullLayout)
, m_usesRepaintBounds(false)
- { }
+ {
+ }
LineInfo& lineInfo() { return m_lineInfo; }
const LineInfo& lineInfo() const { return m_lineInfo; }
@@ -67,7 +84,7 @@
FloatingObject* lastFloat() const { return m_lastFloat; }
void setLastFloat(FloatingObject* lastFloat) { m_lastFloat = lastFloat; }
- Vector<RenderBlock::FloatWithRect>& floats() { return m_floats; }
+ Vector<FloatWithRect>& floats() { return m_floats; }
unsigned floatIndex() const { return m_floatIndex; }
void setFloatIndex(unsigned floatIndex) { m_floatIndex = floatIndex; }
@@ -108,7 +125,7 @@
RootInlineBox* m_endLine;
FloatingObject* m_lastFloat;
- Vector<RenderBlock::FloatWithRect> m_floats;
+ Vector<FloatWithRect> m_floats;
unsigned m_floatIndex;
LayoutUnit m_adjustedLogicalLineTop;
Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (158120 => 158121)
--- trunk/Source/WebCore/rendering/RenderBlock.cpp 2013-10-28 18:48:47 UTC (rev 158120)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp 2013-10-28 19:22:51 UTC (rev 158121)
@@ -2485,19 +2485,6 @@
}
}
-LayoutPoint RenderBlock::flipFloatForWritingModeForChild(const FloatingObject* child, const LayoutPoint& point) const
-{
- if (!style()->isFlippedBlocksWritingMode())
- return point;
-
- // This is similar to RenderBox::flipForWritingModeForChild. We have to subtract out our left/top offsets twice, since
- // it's going to get added back in. We hide this complication here so that the calling code looks normal for the unflipped
- // case.
- if (isHorizontalWritingMode())
- return LayoutPoint(point.x(), point.y() + height() - child->renderer().height() - 2 * yPositionForFloatIncludingMargin(child));
- return LayoutPoint(point.x() + width() - child->renderer().width() - 2 * xPositionForFloatIncludingMargin(child), point.y());
-}
-
RenderInline* RenderBlock::inlineElementContinuation() const
{
RenderBoxModelObject* continuation = this->continuation();
@@ -5094,154 +5081,12 @@
return createAnonymousWithParentRendererAndDisplay(parent, style()->display());
}
-bool RenderBlock::hasNextPage(LayoutUnit logicalOffset, PageBoundaryRule pageBoundaryRule) const
-{
- ASSERT(view().layoutState() && view().layoutState()->isPaginated());
- RenderFlowThread* flowThread = flowThreadContainingBlock();
- if (!flowThread)
- return true; // Printing and multi-column both make new pages to accommodate content.
-
- // See if we're in the last region.
- LayoutUnit pageOffset = offsetFromLogicalTopOfFirstPage() + logicalOffset;
- RenderRegion* region = flowThread->regionAtBlockOffset(this, pageOffset, this);
- if (!region)
- return false;
- if (region->isLastRegion())
- return region->isRenderRegionSet() || region->style()->regionFragment() == BreakRegionFragment
- || (pageBoundaryRule == IncludePageBoundary && pageOffset == region->logicalTopForFlowThreadContent());
- return true;
-}
-
-LayoutUnit RenderBlock::nextPageLogicalTop(LayoutUnit logicalOffset, PageBoundaryRule pageBoundaryRule) const
-{
- LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset);
- if (!pageLogicalHeight)
- return logicalOffset;
-
- // The logicalOffset is in our coordinate space. We can add in our pushed offset.
- LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logicalOffset);
- if (pageBoundaryRule == ExcludePageBoundary)
- return logicalOffset + (remainingLogicalHeight ? remainingLogicalHeight : pageLogicalHeight);
- return logicalOffset + remainingLogicalHeight;
-}
-
ColumnInfo::PaginationUnit RenderBlock::paginationUnit() const
{
return ColumnInfo::Column;
}
-LayoutUnit RenderBlock::pageLogicalTopForOffset(LayoutUnit offset) const
-{
- LayoutUnit firstPageLogicalTop = isHorizontalWritingMode() ? view().layoutState()->m_pageOffset.height() : view().layoutState()->m_pageOffset.width();
- LayoutUnit blockLogicalTop = isHorizontalWritingMode() ? view().layoutState()->m_layoutOffset.height() : view().layoutState()->m_layoutOffset.width();
-
- LayoutUnit cumulativeOffset = offset + blockLogicalTop;
- RenderFlowThread* flowThread = flowThreadContainingBlock();
- if (!flowThread) {
- LayoutUnit pageLogicalHeight = view().layoutState()->pageLogicalHeight();
- if (!pageLogicalHeight)
- return 0;
- return cumulativeOffset - roundToInt(cumulativeOffset - firstPageLogicalTop) % roundToInt(pageLogicalHeight);
- }
- return flowThread->pageLogicalTopForOffset(cumulativeOffset);
-}
-
-LayoutUnit RenderBlock::pageLogicalHeightForOffset(LayoutUnit offset) const
-{
- RenderFlowThread* flowThread = flowThreadContainingBlock();
- if (!flowThread)
- return view().layoutState()->m_pageLogicalHeight;
- return flowThread->pageLogicalHeightForOffset(offset + offsetFromLogicalTopOfFirstPage());
-}
-
-LayoutUnit RenderBlock::pageRemainingLogicalHeightForOffset(LayoutUnit offset, PageBoundaryRule pageBoundaryRule) const
-{
- offset += offsetFromLogicalTopOfFirstPage();
-
- RenderFlowThread* flowThread = flowThreadContainingBlock();
- if (!flowThread) {
- LayoutUnit pageLogicalHeight = view().layoutState()->m_pageLogicalHeight;
- LayoutUnit remainingHeight = pageLogicalHeight - intMod(offset, pageLogicalHeight);
- if (pageBoundaryRule == IncludePageBoundary) {
- // If includeBoundaryPoint is true the line exactly on the top edge of a
- // column will act as being part of the previous column.
- remainingHeight = intMod(remainingHeight, pageLogicalHeight);
- }
- return remainingHeight;
- }
-
- return flowThread->pageRemainingLogicalHeightForOffset(offset, pageBoundaryRule);
-}
-
-LayoutUnit RenderBlock::adjustForUnsplittableChild(RenderBox& child, LayoutUnit logicalOffset, bool includeMargins)
-{
- bool checkColumnBreaks = view().layoutState()->isPaginatingColumns();
- bool checkPageBreaks = !checkColumnBreaks && view().layoutState()->m_pageLogicalHeight;
- RenderFlowThread* flowThread = flowThreadContainingBlock();
- bool checkRegionBreaks = flowThread && flowThread->isRenderNamedFlowThread();
- bool isUnsplittable = child.isUnsplittableForPagination() || (checkColumnBreaks && child.style()->columnBreakInside() == PBAVOID)
- || (checkPageBreaks && child.style()->pageBreakInside() == PBAVOID)
- || (checkRegionBreaks && child.style()->regionBreakInside() == PBAVOID);
- if (!isUnsplittable)
- return logicalOffset;
- LayoutUnit childLogicalHeight = logicalHeightForChild(child) + (includeMargins ? marginBeforeForChild(child) + marginAfterForChild(child) : LayoutUnit());
- LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset);
- bool hasUniformPageLogicalHeight = !flowThread || flowThread->regionsHaveUniformLogicalHeight();
- updateMinimumPageHeight(logicalOffset, childLogicalHeight);
- if (!pageLogicalHeight || (hasUniformPageLogicalHeight && childLogicalHeight > pageLogicalHeight)
- || !hasNextPage(logicalOffset))
- return logicalOffset;
- LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logicalOffset, ExcludePageBoundary);
- if (remainingLogicalHeight < childLogicalHeight) {
- if (!hasUniformPageLogicalHeight && !pushToNextPageWithMinimumLogicalHeight(remainingLogicalHeight, logicalOffset, childLogicalHeight))
- return logicalOffset;
- return logicalOffset + remainingLogicalHeight;
- }
- return logicalOffset;
-}
-
-bool RenderBlock::pushToNextPageWithMinimumLogicalHeight(LayoutUnit& adjustment, LayoutUnit logicalOffset, LayoutUnit minimumLogicalHeight) const
-{
- bool checkRegion = false;
- for (LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset + adjustment); pageLogicalHeight;
- pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset + adjustment)) {
- if (minimumLogicalHeight <= pageLogicalHeight)
- return true;
- if (!hasNextPage(logicalOffset + adjustment))
- return false;
- adjustment += pageLogicalHeight;
- checkRegion = true;
- }
- return !checkRegion;
-}
-
-void RenderBlock::setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage)
-{
- if (RenderFlowThread* flowThread = flowThreadContainingBlock())
- flowThread->setPageBreak(this, offsetFromLogicalTopOfFirstPage() + offset, spaceShortage);
-}
-
-void RenderBlock::updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight)
-{
- if (RenderFlowThread* flowThread = flowThreadContainingBlock())
- flowThread->updateMinimumPageHeight(this, offsetFromLogicalTopOfFirstPage() + offset, minHeight);
- else if (ColumnInfo* colInfo = view().layoutState()->m_columnInfo)
- colInfo->updateMinimumColumnHeight(minHeight);
-}
-
-bool RenderBlock::lineWidthForPaginatedLineChanged(RootInlineBox* rootBox, LayoutUnit lineDelta, RenderFlowThread* flowThread) const
-{
- if (!flowThread)
- return false;
-
- RenderRegion* currentRegion = regionAtBlockOffset(rootBox->lineTopWithLeading() + lineDelta);
- // Just bail if the region didn't change.
- if (rootBox->containingRegion() == currentRegion)
- return false;
- return rootBox->paginatedLineWidth() != availableLogicalWidthForContent(currentRegion);
-}
-
LayoutUnit RenderBlock::offsetFromLogicalTopOfFirstPage() const
{
LayoutState* layoutState = view().layoutState();
Modified: trunk/Source/WebCore/rendering/RenderBlock.h (158120 => 158121)
--- trunk/Source/WebCore/rendering/RenderBlock.h 2013-10-28 18:48:47 UTC (rev 158120)
+++ trunk/Source/WebCore/rendering/RenderBlock.h 2013-10-28 19:22:51 UTC (rev 158121)
@@ -329,13 +329,14 @@
virtual void updateFirstLetter();
- virtual void scrollbarsChanged(bool /*horizontalScrollbarChanged*/, bool /*verticalScrollbarChanged*/) { };
+ virtual void scrollbarsChanged(bool /*horizontalScrollbarChanged*/, bool /*verticalScrollbarChanged*/) { }
LayoutUnit logicalLeftOffsetForContent(RenderRegion*) const;
LayoutUnit logicalRightOffsetForContent(RenderRegion*) const;
LayoutUnit availableLogicalWidthForContent(RenderRegion* region) const
{
- return std::max<LayoutUnit>(0, logicalRightOffsetForContent(region) - logicalLeftOffsetForContent(region)); }
+ return std::max<LayoutUnit>(0, logicalRightOffsetForContent(region) - logicalLeftOffsetForContent(region));
+ }
LayoutUnit startOffsetForContent(RenderRegion* region) const
{
return style()->isLeftToRightDirection() ? logicalLeftOffsetForContent(region) : logicalWidth() - logicalRightOffsetForContent(region);
@@ -553,37 +554,6 @@
Node* nodeForHitTest() const;
- struct FloatWithRect {
- FloatWithRect(RenderBox& f)
- : object(f)
- , rect(LayoutRect(f.x() - f.marginLeft(), f.y() - f.marginTop(), f.width() + f.marginWidth(), f.height() + f.marginHeight()))
- , everHadLayout(f.everHadLayout())
- {
- }
-
- RenderBox& object;
- LayoutRect rect;
- bool everHadLayout;
- };
-
- LayoutPoint flipFloatForWritingModeForChild(const FloatingObject*, const LayoutPoint&) const;
-
- LayoutUnit xPositionForFloatIncludingMargin(const FloatingObject* child) const
- {
- if (isHorizontalWritingMode())
- return child->x() + child->renderer().marginLeft();
- else
- return child->x() + marginBeforeForChild(child->renderer());
- }
-
- LayoutUnit yPositionForFloatIncludingMargin(const FloatingObject* child) const
- {
- if (isHorizontalWritingMode())
- return child->y() + marginBeforeForChild(child->renderer());
- else
- return child->y() + child->renderer().marginTop();
- }
-
// FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
virtual void paintFloats(PaintInfo&, const LayoutPoint&, bool) { }
virtual void paintInlineChildren(PaintInfo&, const LayoutPoint&) { }
@@ -678,43 +648,12 @@
void determineLogicalLeftPositionForChild(RenderBox& child, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
- // Returns the logicalOffset at the top of the next page. If the offset passed in is already at the top of the current page,
- // then nextPageLogicalTop with ExcludePageBoundary will still move to the top of the next page. nextPageLogicalTop with
- // IncludePageBoundary set will not.
- //
- // For a page height of 800px, the first rule will return 800 if the value passed in is 0. The second rule will simply return 0.
- enum PageBoundaryRule { ExcludePageBoundary, IncludePageBoundary };
- LayoutUnit nextPageLogicalTop(LayoutUnit logicalOffset, PageBoundaryRule = ExcludePageBoundary) const;
- bool hasNextPage(LayoutUnit logicalOffset, PageBoundaryRule = ExcludePageBoundary) const;
-
virtual ColumnInfo::PaginationUnit paginationUnit() const;
-public:
- LayoutUnit pageLogicalTopForOffset(LayoutUnit offset) const;
- LayoutUnit pageLogicalHeightForOffset(LayoutUnit offset) const;
- LayoutUnit pageRemainingLogicalHeightForOffset(LayoutUnit offset, PageBoundaryRule = IncludePageBoundary) const;
-
protected:
- bool pushToNextPageWithMinimumLogicalHeight(LayoutUnit& adjustment, LayoutUnit logicalOffset, LayoutUnit minimumLogicalHeight) const;
-
- // A page break is required at some offset due to space shortage in the current fragmentainer.
- void setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage);
-
- // Update minimum page height required to avoid fragmentation where it shouldn't occur (inside
- // unbreakable content, between orphans and widows, etc.). This will be used as a hint to the
- // column balancer to help set a good minimum column height.
- void updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight);
-
- LayoutUnit adjustForUnsplittableChild(RenderBox& child, LayoutUnit logicalOffset, bool includeMargins = false); // If the child is unsplittable and can't fit on the current page, return the top of the next page/column.
-
// Adjust from painting offsets to the local coords of this renderer
void offsetForContents(LayoutPoint&) const;
- // This function is called to test a line box that has moved in the block direction to see if it has ended up in a new
- // region/page/column that has a different available line width than the old one. Used to know when you have to dirty a
- // line, i.e., that it can't be re-used.
- bool lineWidthForPaginatedLineChanged(RootInlineBox*, LayoutUnit lineDelta, RenderFlowThread*) const;
-
virtual bool requiresColumns(int desiredColumnCount) const;
virtual bool updateLogicalWidthAndColumnWidth();
Modified: trunk/Source/WebCore/rendering/RenderBlockFlow.cpp (158120 => 158121)
--- trunk/Source/WebCore/rendering/RenderBlockFlow.cpp 2013-10-28 18:48:47 UTC (rev 158120)
+++ trunk/Source/WebCore/rendering/RenderBlockFlow.cpp 2013-10-28 19:22:51 UTC (rev 158121)
@@ -1565,6 +1565,138 @@
return true;
}
+bool RenderBlockFlow::hasNextPage(LayoutUnit logicalOffset, PageBoundaryRule pageBoundaryRule) const
+{
+ ASSERT(view().layoutState() && view().layoutState()->isPaginated());
+
+ RenderFlowThread* flowThread = flowThreadContainingBlock();
+ if (!flowThread)
+ return true; // Printing and multi-column both make new pages to accommodate content.
+
+ // See if we're in the last region.
+ LayoutUnit pageOffset = offsetFromLogicalTopOfFirstPage() + logicalOffset;
+ RenderRegion* region = flowThread->regionAtBlockOffset(this, pageOffset, this);
+ if (!region)
+ return false;
+ if (region->isLastRegion())
+ return region->isRenderRegionSet() || region->style()->regionFragment() == BreakRegionFragment
+ || (pageBoundaryRule == IncludePageBoundary && pageOffset == region->logicalTopForFlowThreadContent());
+ return true;
+}
+
+LayoutUnit RenderBlockFlow::adjustForUnsplittableChild(RenderBox& child, LayoutUnit logicalOffset, bool includeMargins)
+{
+ bool checkColumnBreaks = view().layoutState()->isPaginatingColumns();
+ bool checkPageBreaks = !checkColumnBreaks && view().layoutState()->m_pageLogicalHeight;
+ RenderFlowThread* flowThread = flowThreadContainingBlock();
+ bool checkRegionBreaks = flowThread && flowThread->isRenderNamedFlowThread();
+ bool isUnsplittable = child.isUnsplittableForPagination() || (checkColumnBreaks && child.style()->columnBreakInside() == PBAVOID)
+ || (checkPageBreaks && child.style()->pageBreakInside() == PBAVOID)
+ || (checkRegionBreaks && child.style()->regionBreakInside() == PBAVOID);
+ if (!isUnsplittable)
+ return logicalOffset;
+ LayoutUnit childLogicalHeight = logicalHeightForChild(child) + (includeMargins ? marginBeforeForChild(child) + marginAfterForChild(child) : LayoutUnit());
+ LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset);
+ bool hasUniformPageLogicalHeight = !flowThread || flowThread->regionsHaveUniformLogicalHeight();
+ updateMinimumPageHeight(logicalOffset, childLogicalHeight);
+ if (!pageLogicalHeight || (hasUniformPageLogicalHeight && childLogicalHeight > pageLogicalHeight)
+ || !hasNextPage(logicalOffset))
+ return logicalOffset;
+ LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logicalOffset, ExcludePageBoundary);
+ if (remainingLogicalHeight < childLogicalHeight) {
+ if (!hasUniformPageLogicalHeight && !pushToNextPageWithMinimumLogicalHeight(remainingLogicalHeight, logicalOffset, childLogicalHeight))
+ return logicalOffset;
+ return logicalOffset + remainingLogicalHeight;
+ }
+ return logicalOffset;
+}
+
+bool RenderBlockFlow::pushToNextPageWithMinimumLogicalHeight(LayoutUnit& adjustment, LayoutUnit logicalOffset, LayoutUnit minimumLogicalHeight) const
+{
+ bool checkRegion = false;
+ for (LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset + adjustment); pageLogicalHeight;
+ pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset + adjustment)) {
+ if (minimumLogicalHeight <= pageLogicalHeight)
+ return true;
+ if (!hasNextPage(logicalOffset + adjustment))
+ return false;
+ adjustment += pageLogicalHeight;
+ checkRegion = true;
+ }
+ return !checkRegion;
+}
+
+void RenderBlockFlow::setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage)
+{
+ if (RenderFlowThread* flowThread = flowThreadContainingBlock())
+ flowThread->setPageBreak(this, offsetFromLogicalTopOfFirstPage() + offset, spaceShortage);
+}
+
+void RenderBlockFlow::updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight)
+{
+ if (RenderFlowThread* flowThread = flowThreadContainingBlock())
+ flowThread->updateMinimumPageHeight(this, offsetFromLogicalTopOfFirstPage() + offset, minHeight);
+ else if (ColumnInfo* colInfo = view().layoutState()->m_columnInfo)
+ colInfo->updateMinimumColumnHeight(minHeight);
+}
+
+LayoutUnit RenderBlockFlow::nextPageLogicalTop(LayoutUnit logicalOffset, PageBoundaryRule pageBoundaryRule) const
+{
+ LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset);
+ if (!pageLogicalHeight)
+ return logicalOffset;
+
+ // The logicalOffset is in our coordinate space. We can add in our pushed offset.
+ LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logicalOffset);
+ if (pageBoundaryRule == ExcludePageBoundary)
+ return logicalOffset + (remainingLogicalHeight ? remainingLogicalHeight : pageLogicalHeight);
+ return logicalOffset + remainingLogicalHeight;
+}
+
+LayoutUnit RenderBlockFlow::pageLogicalTopForOffset(LayoutUnit offset) const
+{
+ LayoutUnit firstPageLogicalTop = isHorizontalWritingMode() ? view().layoutState()->m_pageOffset.height() : view().layoutState()->m_pageOffset.width();
+ LayoutUnit blockLogicalTop = isHorizontalWritingMode() ? view().layoutState()->m_layoutOffset.height() : view().layoutState()->m_layoutOffset.width();
+
+ LayoutUnit cumulativeOffset = offset + blockLogicalTop;
+ RenderFlowThread* flowThread = flowThreadContainingBlock();
+ if (!flowThread) {
+ LayoutUnit pageLogicalHeight = view().layoutState()->pageLogicalHeight();
+ if (!pageLogicalHeight)
+ return 0;
+ return cumulativeOffset - roundToInt(cumulativeOffset - firstPageLogicalTop) % roundToInt(pageLogicalHeight);
+ }
+ return flowThread->pageLogicalTopForOffset(cumulativeOffset);
+}
+
+LayoutUnit RenderBlockFlow::pageLogicalHeightForOffset(LayoutUnit offset) const
+{
+ RenderFlowThread* flowThread = flowThreadContainingBlock();
+ if (!flowThread)
+ return view().layoutState()->m_pageLogicalHeight;
+ return flowThread->pageLogicalHeightForOffset(offset + offsetFromLogicalTopOfFirstPage());
+}
+
+LayoutUnit RenderBlockFlow::pageRemainingLogicalHeightForOffset(LayoutUnit offset, PageBoundaryRule pageBoundaryRule) const
+{
+ offset += offsetFromLogicalTopOfFirstPage();
+
+ RenderFlowThread* flowThread = flowThreadContainingBlock();
+ if (!flowThread) {
+ LayoutUnit pageLogicalHeight = view().layoutState()->m_pageLogicalHeight;
+ LayoutUnit remainingHeight = pageLogicalHeight - intMod(offset, pageLogicalHeight);
+ if (pageBoundaryRule == IncludePageBoundary) {
+ // If includeBoundaryPoint is true the line exactly on the top edge of a
+ // column will act as being part of the previous column.
+ remainingHeight = intMod(remainingHeight, pageLogicalHeight);
+ }
+ return remainingHeight;
+ }
+
+ return flowThread->pageRemainingLogicalHeightForOffset(offset, pageBoundaryRule);
+}
+
+
void RenderBlockFlow::layoutLineGridBox()
{
if (style()->lineGrid() == RenderStyle::initialLineGrid()) {
@@ -2334,6 +2466,19 @@
}
}
+LayoutPoint RenderBlockFlow::flipFloatForWritingModeForChild(const FloatingObject* child, const LayoutPoint& point) const
+{
+ if (!style()->isFlippedBlocksWritingMode())
+ return point;
+
+ // This is similar to RenderBox::flipForWritingModeForChild. We have to subtract out our left/top offsets twice, since
+ // it's going to get added back in. We hide this complication here so that the calling code looks normal for the unflipped
+ // case.
+ if (isHorizontalWritingMode())
+ return LayoutPoint(point.x(), point.y() + height() - child->renderer().height() - 2 * yPositionForFloatIncludingMargin(child));
+ return LayoutPoint(point.x() + width() - child->renderer().width() - 2 * xPositionForFloatIncludingMargin(child), point.y());
+}
+
LayoutUnit RenderBlockFlow::getClearDelta(RenderBox& child, LayoutUnit logicalTop)
{
// There is no need to compute clearance if we have no floats.
Modified: trunk/Source/WebCore/rendering/RenderBlockFlow.h (158120 => 158121)
--- trunk/Source/WebCore/rendering/RenderBlockFlow.h 2013-10-28 18:48:47 UTC (rev 158120)
+++ trunk/Source/WebCore/rendering/RenderBlockFlow.h 2013-10-28 19:22:51 UTC (rev 158121)
@@ -31,6 +31,7 @@
class LineBreaker;
class RenderNamedFlowFragment;
+struct FloatWithRect;
class RenderBlockFlow : public RenderBlock {
public:
@@ -302,6 +303,11 @@
floatingObject->setHeight(logicalWidth);
}
+ LayoutUnit xPositionForFloatIncludingMargin(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->x() + child->renderer().marginLeft() : child->x() + marginBeforeForChild(child->renderer()); }
+ LayoutUnit yPositionForFloatIncludingMargin(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->y() + marginBeforeForChild(child->renderer()) : child->y() + child->renderer().marginTop(); }
+
+ LayoutPoint flipFloatForWritingModeForChild(const FloatingObject*, const LayoutPoint&) const;
+
RenderLineBoxList& lineBoxes() { return m_lineBoxes; }
const RenderLineBoxList& lineBoxes() const { return m_lineBoxes; }
@@ -332,7 +338,34 @@
virtual void showLineTreeAndMark(const InlineBox* = nullptr, const char* = nullptr, const InlineBox* = nullptr, const char* = nullptr, const RenderObject* = nullptr) const OVERRIDE;
#endif
+ // Returns the logicalOffset at the top of the next page. If the offset passed in is already at the top of the current page,
+ // then nextPageLogicalTop with ExcludePageBoundary will still move to the top of the next page. nextPageLogicalTop with
+ // IncludePageBoundary set will not.
+ //
+ // For a page height of 800px, the first rule will return 800 if the value passed in is 0. The second rule will simply return 0.
+ enum PageBoundaryRule { ExcludePageBoundary, IncludePageBoundary };
+ LayoutUnit nextPageLogicalTop(LayoutUnit logicalOffset, PageBoundaryRule = ExcludePageBoundary) const;
+ LayoutUnit pageLogicalTopForOffset(LayoutUnit offset) const;
+ LayoutUnit pageLogicalHeightForOffset(LayoutUnit offset) const;
+ LayoutUnit pageRemainingLogicalHeightForOffset(LayoutUnit offset, PageBoundaryRule = IncludePageBoundary) const;
+ bool hasNextPage(LayoutUnit logicalOffset, PageBoundaryRule = ExcludePageBoundary) const;
+
protected:
+ // A page break is required at some offset due to space shortage in the current fragmentainer.
+ void setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage);
+
+ // Update minimum page height required to avoid fragmentation where it shouldn't occur (inside
+ // unbreakable content, between orphans and widows, etc.). This will be used as a hint to the
+ // column balancer to help set a good minimum column height.
+ void updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight);
+ bool pushToNextPageWithMinimumLogicalHeight(LayoutUnit& adjustment, LayoutUnit logicalOffset, LayoutUnit minimumLogicalHeight) const;
+
+ // If the child is unsplittable and can't fit on the current page, return the top of the next page/column.
+ LayoutUnit adjustForUnsplittableChild(RenderBox& child, LayoutUnit logicalOffset, bool includeMargins = false);
+ LayoutUnit adjustBlockChildForPagination(LayoutUnit logicalTopAfterClear, LayoutUnit estimateWithoutPagination, RenderBox& child, bool atBeforeSideOfBlock);
+ LayoutUnit applyBeforeBreak(RenderBox& child, LayoutUnit logicalOffset); // If the child has a before break, then return a new yPos that shifts to the top of the next page/column.
+ LayoutUnit applyAfterBreak(RenderBox& child, LayoutUnit logicalOffset, MarginInfo&); // If the child has an after break, then return a new offset that shifts to the top of the next page/column.
+
LayoutUnit maxPositiveMarginBefore() const { return m_rareData ? m_rareData->m_margins.positiveMarginBefore() : RenderBlockFlowRareData::positiveMarginBeforeDefault(*this); }
LayoutUnit maxNegativeMarginBefore() const { return m_rareData ? m_rareData->m_margins.negativeMarginBefore() : RenderBlockFlowRareData::negativeMarginBeforeDefault(*this); }
LayoutUnit maxPositiveMarginAfter() const { return m_rareData ? m_rareData->m_margins.positiveMarginAfter() : RenderBlockFlowRareData::positiveMarginAfterDefault(*this); }
@@ -362,10 +395,6 @@
bool mustSeparateMarginBeforeForChild(const RenderBox&) const;
bool mustSeparateMarginAfterForChild(const RenderBox&) const;
- LayoutUnit applyBeforeBreak(RenderBox& child, LayoutUnit logicalOffset); // If the child has a before break, then return a new yPos that shifts to the top of the next page/column.
- LayoutUnit applyAfterBreak(RenderBox& child, LayoutUnit logicalOffset, MarginInfo&); // If the child has an after break, then return a new offset that shifts to the top of the next page/column.
- LayoutUnit adjustBlockChildForPagination(LayoutUnit logicalTopAfterClear, LayoutUnit estimateWithoutPagination, RenderBox& child, bool atBeforeSideOfBlock);
-
virtual void styleWillChange(StyleDifference, const RenderStyle& newStyle) OVERRIDE;
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
@@ -467,8 +496,11 @@
// Positions new floats and also adjust all floats encountered on the line if any of them
// have to move to the next page/column.
bool positionNewFloatOnLine(FloatingObject* newFloat, FloatingObject* lastFloatFromPreviousLine, LineInfo&, LineWidth&);
+ // This function is called to test a line box that has moved in the block direction to see if it has ended up in a new
+ // region/page/column that has a different available line width than the old one. Used to know when you have to dirty a
+ // line, i.e., that it can't be re-used.
+ bool lineWidthForPaginatedLineChanged(RootInlineBox*, LayoutUnit lineDelta, RenderFlowThread*) const;
-
// END METHODS DEFINED IN RenderBlockLineLayout
bool namedFlowFragmentNeedsUpdate() const;
Modified: trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp (158120 => 158121)
--- trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp 2013-10-28 18:48:47 UTC (rev 158120)
+++ trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp 2013-10-28 19:22:51 UTC (rev 158121)
@@ -2173,6 +2173,18 @@
return true;
}
+bool RenderBlockFlow::lineWidthForPaginatedLineChanged(RootInlineBox* rootBox, LayoutUnit lineDelta, RenderFlowThread* flowThread) const
+{
+ if (!flowThread)
+ return false;
+
+ RenderRegion* currentRegion = regionAtBlockOffset(rootBox->lineTopWithLeading() + lineDelta);
+ // Just bail if the region didn't change.
+ if (rootBox->containingRegion() == currentRegion)
+ return false;
+ return rootBox->paginatedLineWidth() != availableLogicalWidthForContent(currentRegion);
+}
+
bool RenderBlockFlow::matchedEndLine(LineLayoutState& layoutState, const InlineBidiResolver& resolver, const InlineIterator& endLineStart, const BidiStatus& endLineStatus)
{
if (resolver.position() == endLineStart) {