https://bugs.webkit.org/show_bug.cgi?id=46421, make multi-column layout work with vertical text.
Reviewed by Dan Bernstein.
Added new tests in fast/multicol/vertical-lr and fast/multicol/vertical-rl.
Source/WebCore:
* css/html.css:
Update p, blockquote and h1-h6 to respect directionality so that column layout tests that use those
elements work properly.
* rendering/InlineFlowBox.cpp:
(WebCore::InlineFlowBox::placeBoxesInBlockDirection):
Fix a flipping bug with the computation of lineTopIncludingMargins where it could be incorrectly shrunk
in some cases (causing lines to all stack on top of one another).
* rendering/InlineTextBox.h:
(WebCore::InlineTextBox::calculateBoundaries):
Fix calculateBoundaries to be physical rather than logical.
* rendering/LayoutState.cpp:
(WebCore::LayoutState::addForcedColumnBreak):
* rendering/LayoutState.h:
Rename childY to childLogicalOffset.
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::layoutBlock):
(WebCore::RenderBlock::addOverflowFromChildren):
(WebCore::RenderBlock::addOverflowFromFloats):
(WebCore::RenderBlock::collapseMargins):
(WebCore::RenderBlock::estimateLogicalTopPosition):
(WebCore::RenderBlock::layoutBlockChild):
(WebCore::RenderBlock::markForPaginationRelayoutIfNeeded):
(WebCore::RenderBlock::paintColumnRules):
(WebCore::RenderBlock::paintColumnContents):
(WebCore::RenderBlock::paintFloats):
(WebCore::RenderBlock::selectionGaps):
(WebCore::RenderBlock::removeFloatingObjectsBelow):
(WebCore::RenderBlock::addOverhangingFloats):
(WebCore::RenderBlock::hitTestFloats):
(WebCore::RenderBlock::hitTestColumns):
(WebCore::RenderBlock::calcColumnWidth):
(WebCore::RenderBlock::desiredColumnWidth):
(WebCore::RenderBlock::columnRectAt):
(WebCore::RenderBlock::layoutColumns):
(WebCore::RenderBlock::adjustPointToColumnContents):
(WebCore::RenderBlock::adjustRectForColumns):
(WebCore::RenderBlock::flipForWritingModeIncludingColumns):
(WebCore::RenderBlock::adjustForColumns):
(WebCore::RenderBlock::adjustForBorderFit):
(WebCore::RenderBlock::nextPageLogicalTop):
(WebCore::RenderBlock::applyBeforeBreak):
(WebCore::RenderBlock::applyAfterBreak):
(WebCore::RenderBlock::adjustForUnsplittableChild):
(WebCore::RenderBlock::adjustLinePositionForPagination):
* rendering/RenderBlock.h:
(WebCore::RenderBlock::logicalRightOffsetForContent):
(WebCore::RenderBlock::logicalLeftOffsetForContent):
(WebCore::RenderBlock::leftForFloatIncludingMargin):
(WebCore::RenderBlock::topForFloatIncludingMargin):
* rendering/RenderBlockLineLayout.cpp:
(WebCore::RenderBlock::layoutInlineChildren):
(WebCore::RenderBlock::determineStartPosition):
Reworking of all the RenderBlock column functions to support flipping and vertical modes.
* rendering/RenderBox.cpp:
(WebCore::RenderBox::offsetFromContainer):
(WebCore::RenderBox::flipForWritingModeIncludingColumns):
Patch offsetFromContainer to be aware of flipped block writing modes when dealing with column layouts.
* rendering/RenderBox.h:
(WebCore::RenderBox::clientLogicalBottom):
Fix a bug in clientLogicalBottom where it didn't add in the right border/padding.
* rendering/RenderFlexibleBox.cpp:
(WebCore::RenderFlexibleBox::layoutBlock):
Better terminology for pagination.
* rendering/RenderInline.cpp:
(WebCore::RenderInline::offsetFromContainer):
(WebCore::RenderInline::mapLocalToContainer):
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::paintChildLayerIntoColumns):
(WebCore::RenderLayer::hitTestChildLayerColumns):
(WebCore::RenderLayer::localBoundingBox):
(WebCore::RenderLayer::boundingBox):
Patch painting in RenderLayers to be vertical-text-aware.
* rendering/RenderObject.cpp:
(WebCore::RenderObject::mapLocalToContainer):
Add code to be flipped block-aware with columns.
* rendering/RenderTable.cpp:
(WebCore::RenderTable::layout):
* rendering/RenderTableRow.cpp:
(WebCore::RenderTableRow::layout):
* rendering/RenderTableSection.cpp:
(WebCore::RenderTableSection::layoutRows):
Fix pagination to use better terminology.
* rendering/RenderText.cpp:
(WebCore::RenderText::absoluteQuads):
(WebCore::RenderText::absoluteQuadsForRange):
Fix a bug where vertical text wasn't taken into account.
LayoutTests:
* fast/multicol/break-properties-expected.txt:
* fast/multicol/break-properties.html:
* fast/multicol/float-truncation.html:
* fast/multicol/vertical-lr: Added.
* fast/multicol/vertical-lr/border-padding-pagination.html: Added.
* fast/multicol/vertical-lr/break-properties-expected.txt: Added.
* fast/multicol/vertical-lr/break-properties.html: Added.
* fast/multicol/vertical-lr/column-break-with-balancing.html: Added.
* fast/multicol/vertical-lr/column-count-with-rules.html: Added.
* fast/multicol/vertical-lr/column-rules.html: Added.
* fast/multicol/vertical-lr/float-avoidance.html: Added.
* fast/multicol/vertical-lr/float-multicol.html: Added.
* fast/multicol/vertical-lr/float-paginate-complex.html: Added.
* fast/multicol/vertical-lr/float-paginate.html: Added.
* fast/multicol/vertical-lr/float-truncation-expected.txt: Added.
* fast/multicol/vertical-lr/float-truncation.html: Added.
* fast/multicol/vertical-lr/gap-non-negative-expected.txt: Added.
* fast/multicol/vertical-lr/gap-non-negative.html: Added.
* fast/multicol/vertical-lr/image-inside-nested-blocks-with-border-expected.txt: Added.
* fast/multicol/vertical-lr/image-inside-nested-blocks-with-border.html: Added.
* fast/multicol/vertical-lr/nested-columns.html: Added.
* fast/multicol/vertical-lr/resources: Added.
* fast/multicol/vertical-lr/resources/blimp.png: Added.
* fast/multicol/vertical-lr/unsplittable-inline-block.html: Added.
* fast/multicol/vertical-rl: Added.
* fast/multicol/vertical-rl/border-padding-pagination.html: Added.
* fast/multicol/vertical-rl/break-properties-expected.txt: Added.
* fast/multicol/vertical-rl/break-properties.html: Added.
* fast/multicol/vertical-rl/column-break-with-balancing.html: Added.
* fast/multicol/vertical-rl/column-count-with-rules.html: Added.
* fast/multicol/vertical-rl/column-rules.html: Added.
* fast/multicol/vertical-rl/float-avoidance.html: Added.
* fast/multicol/vertical-rl/float-multicol.html: Added.
* fast/multicol/vertical-rl/float-paginate-complex.html: Added.
* fast/multicol/vertical-rl/float-paginate.html: Added.
* fast/multicol/vertical-rl/float-truncation-expected.txt: Added.
* fast/multicol/vertical-rl/float-truncation.html: Added.
* fast/multicol/vertical-rl/gap-non-negative-expected.txt: Added.
* fast/multicol/vertical-rl/gap-non-negative.html: Added.
* fast/multicol/vertical-rl/image-inside-nested-blocks-with-border-expected.txt: Added.
* fast/multicol/vertical-rl/image-inside-nested-blocks-with-border.html: Added.
* fast/multicol/vertical-rl/nested-columns.html: Added.
* fast/multicol/vertical-rl/resources: Added.
* fast/multicol/vertical-rl/resources/blimp.png: Added.
* fast/multicol/vertical-rl/unsplittable-inline-block.html: Added.
* platform/mac/fast/multicol/vertical-lr: Added.
* platform/mac/fast/multicol/vertical-lr/border-padding-pagination-expected.checksum: Added.
* platform/mac/fast/multicol/vertical-lr/border-padding-pagination-expected.png: Added.
* platform/mac/fast/multicol/vertical-lr/border-padding-pagination-expected.txt: Added.
* platform/mac/fast/multicol/vertical-lr/column-break-with-balancing-expected.checksum: Added.
* platform/mac/fast/multicol/vertical-lr/column-break-with-balancing-expected.png: Added.
* platform/mac/fast/multicol/vertical-lr/column-break-with-balancing-expected.txt: Added.
* platform/mac/fast/multicol/vertical-lr/column-count-with-rules-expected.checksum: Added.
* platform/mac/fast/multicol/vertical-lr/column-count-with-rules-expected.png: Added.
* platform/mac/fast/multicol/vertical-lr/column-count-with-rules-expected.txt: Added.
* platform/mac/fast/multicol/vertical-lr/column-rules-expected.checksum: Added.
* platform/mac/fast/multicol/vertical-lr/column-rules-expected.png: Added.
* platform/mac/fast/multicol/vertical-lr/column-rules-expected.txt: Added.
* platform/mac/fast/multicol/vertical-lr/float-avoidance-expected.checksum: Added.
* platform/mac/fast/multicol/vertical-lr/float-avoidance-expected.png: Added.
* platform/mac/fast/multicol/vertical-lr/float-avoidance-expected.txt: Added.
* platform/mac/fast/multicol/vertical-lr/float-multicol-expected.checksum: Added.
* platform/mac/fast/multicol/vertical-lr/float-multicol-expected.png: Added.
* platform/mac/fast/multicol/vertical-lr/float-multicol-expected.txt: Added.
* platform/mac/fast/multicol/vertical-lr/float-paginate-complex-expected.checksum: Added.
* platform/mac/fast/multicol/vertical-lr/float-paginate-complex-expected.png: Added.
* platform/mac/fast/multicol/vertical-lr/float-paginate-complex-expected.txt: Added.
* platform/mac/fast/multicol/vertical-lr/float-paginate-expected.checksum: Added.
* platform/mac/fast/multicol/vertical-lr/float-paginate-expected.png: Added.
* platform/mac/fast/multicol/vertical-lr/float-paginate-expected.txt: Added.
* platform/mac/fast/multicol/vertical-lr/nested-columns-expected.checksum: Added.
* platform/mac/fast/multicol/vertical-lr/nested-columns-expected.png: Added.
* platform/mac/fast/multicol/vertical-lr/nested-columns-expected.txt: Added.
* platform/mac/fast/multicol/vertical-lr/unsplittable-inline-block-expected.checksum: Added.
* platform/mac/fast/multicol/vertical-lr/unsplittable-inline-block-expected.png: Added.
* platform/mac/fast/multicol/vertical-lr/unsplittable-inline-block-expected.txt: Added.
* platform/mac/fast/multicol/vertical-rl: Added.
* platform/mac/fast/multicol/vertical-rl/border-padding-pagination-expected.checksum: Added.
* platform/mac/fast/multicol/vertical-rl/border-padding-pagination-expected.png: Added.
* platform/mac/fast/multicol/vertical-rl/border-padding-pagination-expected.txt: Added.
* platform/mac/fast/multicol/vertical-rl/column-break-with-balancing-expected.checksum: Added.
* platform/mac/fast/multicol/vertical-rl/column-break-with-balancing-expected.png: Added.
* platform/mac/fast/multicol/vertical-rl/column-break-with-balancing-expected.txt: Added.
* platform/mac/fast/multicol/vertical-rl/column-count-with-rules-expected.checksum: Added.
* platform/mac/fast/multicol/vertical-rl/column-count-with-rules-expected.png: Added.
* platform/mac/fast/multicol/vertical-rl/column-count-with-rules-expected.txt: Added.
* platform/mac/fast/multicol/vertical-rl/column-rules-expected.checksum: Added.
* platform/mac/fast/multicol/vertical-rl/column-rules-expected.png: Added.
* platform/mac/fast/multicol/vertical-rl/column-rules-expected.txt: Added.
* platform/mac/fast/multicol/vertical-rl/float-avoidance-expected.checksum: Added.
* platform/mac/fast/multicol/vertical-rl/float-avoidance-expected.png: Added.
* platform/mac/fast/multicol/vertical-rl/float-avoidance-expected.txt: Added.
* platform/mac/fast/multicol/vertical-rl/float-multicol-expected.checksum: Added.
* platform/mac/fast/multicol/vertical-rl/float-multicol-expected.png: Added.
* platform/mac/fast/multicol/vertical-rl/float-multicol-expected.txt: Added.
* platform/mac/fast/multicol/vertical-rl/float-paginate-complex-expected.checksum: Added.
* platform/mac/fast/multicol/vertical-rl/float-paginate-complex-expected.png: Added.
* platform/mac/fast/multicol/vertical-rl/float-paginate-complex-expected.txt: Added.
* platform/mac/fast/multicol/vertical-rl/float-paginate-expected.checksum: Added.
* platform/mac/fast/multicol/vertical-rl/float-paginate-expected.png: Added.
* platform/mac/fast/multicol/vertical-rl/float-paginate-expected.txt: Added.
* platform/mac/fast/multicol/vertical-rl/nested-columns-expected.checksum: Added.
* platform/mac/fast/multicol/vertical-rl/nested-columns-expected.png: Added.
* platform/mac/fast/multicol/vertical-rl/nested-columns-expected.txt: Added.
* platform/mac/fast/multicol/vertical-rl/unsplittable-inline-block-expected.checksum: Added.
* platform/mac/fast/multicol/vertical-rl/unsplittable-inline-block-expected.png: Added.
* platform/mac/fast/multicol/vertical-rl/unsplittable-inline-block-expected.txt: Added.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@76726 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/rendering/InlineFlowBox.cpp b/Source/WebCore/rendering/InlineFlowBox.cpp
index 5e141cc..cafbae8 100644
--- a/Source/WebCore/rendering/InlineFlowBox.cpp
+++ b/Source/WebCore/rendering/InlineFlowBox.cpp
@@ -604,7 +604,7 @@
}
int newLogicalTop = curr->logicalTop();
- int newLogicalTopIncludingMargins;
+ int newLogicalTopIncludingMargins = newLogicalTop;
int boxHeight = curr->logicalHeight();
int boxHeightIncludingMargins = boxHeight;
diff --git a/Source/WebCore/rendering/InlineTextBox.h b/Source/WebCore/rendering/InlineTextBox.h
index 0076703..8a4cd72 100644
--- a/Source/WebCore/rendering/InlineTextBox.h
+++ b/Source/WebCore/rendering/InlineTextBox.h
@@ -81,7 +81,7 @@
int selectionHeight();
public:
- virtual IntRect calculateBoundaries() const { return IntRect(x(), y(), logicalWidth(), logicalHeight()); }
+ virtual IntRect calculateBoundaries() const { return IntRect(x(), y(), width(), height()); }
virtual IntRect selectionRect(int absx, int absy, int startPos, int endPos);
bool isSelected(int startPos, int endPos) const;
diff --git a/Source/WebCore/rendering/LayoutState.cpp b/Source/WebCore/rendering/LayoutState.cpp
index aeba416..8e4201e 100644
--- a/Source/WebCore/rendering/LayoutState.cpp
+++ b/Source/WebCore/rendering/LayoutState.cpp
@@ -167,11 +167,11 @@
return m_layoutOffset.height() + childLogicalOffset - m_pageOffset.height();
}
-void LayoutState::addForcedColumnBreak(int childY)
+void LayoutState::addForcedColumnBreak(int childLogicalOffset)
{
if (!m_columnInfo || m_columnInfo->columnHeight())
return;
- m_columnInfo->addForcedBreak(pageLogicalOffset(childY));
+ m_columnInfo->addForcedBreak(pageLogicalOffset(childLogicalOffset));
}
} // namespace WebCore
diff --git a/Source/WebCore/rendering/LayoutState.h b/Source/WebCore/rendering/LayoutState.h
index c499435..f14c9ff 100644
--- a/Source/WebCore/rendering/LayoutState.h
+++ b/Source/WebCore/rendering/LayoutState.h
@@ -71,7 +71,7 @@
// direction (so an x-offset in vertical text and a y-offset for horizontal text).
int pageLogicalOffset(int childLogicalOffset) const;
- void addForcedColumnBreak(int childY);
+ void addForcedColumnBreak(int childLogicalOffset);
bool pageLogicalHeight() const { return m_pageLogicalHeight; }
bool pageLogicalHeightChanged() const { return m_pageLogicalHeightChanged; }
diff --git a/Source/WebCore/rendering/RenderBlock.cpp b/Source/WebCore/rendering/RenderBlock.cpp
index 9535403..e992355 100644
--- a/Source/WebCore/rendering/RenderBlock.cpp
+++ b/Source/WebCore/rendering/RenderBlock.cpp
@@ -1259,7 +1259,7 @@
statePusher.pop();
if (view()->layoutState()->m_pageLogicalHeight)
- setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(y()));
+ setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(logicalTop()));
updateLayerTransform();
@@ -1322,10 +1322,18 @@
ColumnInfo* colInfo = columnInfo();
if (columnCount(colInfo)) {
IntRect lastRect = columnRectAt(colInfo, columnCount(colInfo) - 1);
- int overflowLeft = !style()->isLeftToRightDirection() ? min(0, lastRect.x()) : 0;
- int overflowRight = style()->isLeftToRightDirection() ? max(width(), lastRect.x() + lastRect.width()) : 0;
- int overflowHeight = borderTop() + paddingTop() + colInfo->columnHeight();
- addLayoutOverflow(IntRect(overflowLeft, 0, overflowRight - overflowLeft, overflowHeight));
+ if (style()->isHorizontalWritingMode()) {
+ int overflowLeft = !style()->isLeftToRightDirection() ? min(0, lastRect.x()) : 0;
+ int overflowRight = style()->isLeftToRightDirection() ? max(width(), lastRect.right()) : 0;
+ int overflowHeight = borderBefore() + paddingBefore() + colInfo->columnHeight();
+ addLayoutOverflow(IntRect(overflowLeft, 0, overflowRight - overflowLeft, overflowHeight));
+ } else {
+ IntRect lastRect = columnRectAt(colInfo, columnCount(colInfo) - 1);
+ int overflowTop = !style()->isLeftToRightDirection() ? min(0, lastRect.y()) : 0;
+ int overflowBottom = style()->isLeftToRightDirection() ? max(height(), lastRect.bottom()) : 0;
+ int overflowWidth = borderBefore() + paddingBefore() + colInfo->columnHeight();
+ addLayoutOverflow(IntRect(0, overflowTop, overflowWidth, overflowBottom - overflowTop));
+ }
}
}
}
@@ -1375,7 +1383,7 @@
DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
for (; (r = it.current()); ++it) {
if (r->m_isDescendant)
- addOverflowFromChild(r->m_renderer, IntSize(r->left() + r->m_renderer->marginLeft(), r->top() + r->m_renderer->marginTop()));
+ addOverflowFromChild(r->m_renderer, IntSize(leftForFloatIncludingMargin(r), topForFloatIncludingMargin(r)));
}
return;
}
@@ -1641,7 +1649,7 @@
bool paginated = view()->layoutState()->isPaginated();
if (paginated && logicalTop > beforeCollapseLogicalTop) {
int oldLogicalTop = logicalTop;
- logicalTop = min(logicalTop, nextPageTop(beforeCollapseLogicalTop));
+ logicalTop = min(logicalTop, nextPageLogicalTop(beforeCollapseLogicalTop));
setLogicalHeight(logicalHeight() + (logicalTop - oldLogicalTop));
}
return logicalTop;
@@ -1711,7 +1719,7 @@
// Adjust logicalTopEstimate down to the next page if the margins are so large that we don't fit on the current
// page.
if (paginated && logicalTopEstimate > logicalHeight())
- logicalTopEstimate = min(logicalTopEstimate, nextPageTop(logicalHeight()));
+ logicalTopEstimate = min(logicalTopEstimate, nextPageLogicalTop(logicalHeight()));
logicalTopEstimate += getClearDelta(child, logicalTopEstimate);
@@ -2054,7 +2062,7 @@
if (paginated) {
// Check for an after page/column break.
- int newHeight = applyAfterBreak(child, height(), marginInfo);
+ int newHeight = applyAfterBreak(child, logicalHeight(), marginInfo);
if (newHeight != height())
setLogicalHeight(newHeight);
}
@@ -2151,7 +2159,7 @@
if (needsLayout())
return;
- if (view()->layoutState()->pageLogicalHeightChanged() || (view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(y()) != pageLogicalOffset()))
+ if (view()->layoutState()->pageLogicalHeightChanged() || (view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(logicalTop()) != pageLogicalOffset()))
setChildNeedsLayout(true, false);
}
@@ -2228,32 +2236,34 @@
// We need to do multiple passes, breaking up our child painting into strips.
ColumnInfo* colInfo = columnInfo();
unsigned colCount = columnCount(colInfo);
- int currXOffset = style()->isLeftToRightDirection() ? 0 : contentWidth();
- int ruleAdd = borderLeft() + paddingLeft();
- int ruleX = style()->isLeftToRightDirection() ? 0 : contentWidth();
+ int currLogicalLeftOffset = style()->isLeftToRightDirection() ? 0 : contentLogicalWidth();
+ int ruleAdd = logicalLeftOffsetForContent();
+ int ruleLogicalLeft = style()->isLeftToRightDirection() ? 0 : contentLogicalWidth();
for (unsigned i = 0; i < colCount; i++) {
IntRect colRect = columnRectAt(colInfo, i);
+ int inlineDirectionSize = style()->isHorizontalWritingMode() ? colRect.width() : colRect.height();
+
// Move to the next position.
if (style()->isLeftToRightDirection()) {
- ruleX += colRect.width() + colGap / 2;
- currXOffset += colRect.width() + colGap;
+ ruleLogicalLeft += inlineDirectionSize + colGap / 2;
+ currLogicalLeftOffset += inlineDirectionSize + colGap;
} else {
- ruleX -= (colRect.width() + colGap / 2);
- currXOffset -= (colRect.width() + colGap);
+ ruleLogicalLeft -= (inlineDirectionSize + colGap / 2);
+ currLogicalLeftOffset -= (inlineDirectionSize + colGap);
}
// Now paint the column rule.
if (i < colCount - 1) {
- int ruleStart = tx + ruleX - ruleWidth / 2 + ruleAdd;
- int ruleEnd = ruleStart + ruleWidth;
- int ruleTop = ty + borderTop() + paddingTop();
- int ruleBottom = ruleTop + contentHeight();
- drawLineForBoxSide(paintInfo.context, ruleStart, ruleTop, ruleEnd, ruleBottom,
+ int ruleLeft = style()->isHorizontalWritingMode() ? tx + ruleLogicalLeft - ruleWidth / 2 + ruleAdd : tx + borderBefore() + paddingBefore();
+ int ruleRight = style()->isHorizontalWritingMode() ? ruleLeft + ruleWidth : ruleLeft + contentWidth();
+ int ruleTop = style()->isHorizontalWritingMode() ? ty + borderTop() + paddingTop() : ty + ruleLogicalLeft - ruleWidth / 2 + ruleAdd;
+ int ruleBottom = style()->isHorizontalWritingMode() ? ruleTop + contentHeight() : ruleTop + ruleWidth;
+ drawLineForBoxSide(paintInfo.context, ruleLeft, ruleTop, ruleRight, ruleBottom,
style()->isLeftToRightDirection() ? BSLeft : BSRight, ruleColor, ruleStyle, 0, 0);
}
- ruleX = currXOffset;
+ ruleLogicalLeft = currLogicalLeftOffset;
}
}
@@ -2261,16 +2271,17 @@
{
// We need to do multiple passes, breaking up our child painting into strips.
GraphicsContext* context = paintInfo.context;
- int colGap = columnGap();
ColumnInfo* colInfo = columnInfo();
unsigned colCount = columnCount(colInfo);
if (!colCount)
return;
- int currXOffset = style()->isLeftToRightDirection() ? 0 : contentWidth() - columnRectAt(colInfo, 0).width();
- int currYOffset = 0;
+ int currLogicalTopOffset = 0;
for (unsigned i = 0; i < colCount; i++) {
// For each rect, we clip to the rect, and then we adjust our coords.
IntRect colRect = columnRectAt(colInfo, i);
+ flipForWritingMode(colRect);
+ int logicalLeftOffset = (style()->isHorizontalWritingMode() ? colRect.x() : colRect.y()) - logicalLeftOffsetForContent();
+ IntSize offset = style()->isHorizontalWritingMode() ? IntSize(logicalLeftOffset, currLogicalTopOffset) : IntSize(currLogicalTopOffset, logicalLeftOffset);
colRect.move(tx, ty);
PaintInfo info(paintInfo);
info.rect.intersect(colRect);
@@ -2281,10 +2292,10 @@
// Each strip pushes a clip, since column boxes are specified as being
// like overflow:hidden.
context->clip(colRect);
-
+
// Adjust our x and y when painting.
- int finalX = tx + currXOffset;
- int finalY = ty + currYOffset;
+ int finalX = tx + offset.width();
+ int finalY = ty + offset.height();
if (paintingFloats)
paintFloats(info, finalX, finalY, paintInfo.phase == PaintPhaseSelection || paintInfo.phase == PaintPhaseTextClip);
else
@@ -2292,14 +2303,12 @@
context->restore();
}
-
- // Move to the next position.
- if (style()->isLeftToRightDirection())
- currXOffset += colRect.width() + colGap;
+
+ int blockDelta = (style()->isHorizontalWritingMode() ? colRect.height() : colRect.width());
+ if (style()->isFlippedBlocksWritingMode())
+ currLogicalTopOffset += blockDelta;
else
- currXOffset -= (colRect.width() + colGap);
-
- currYOffset -= colRect.height();
+ currLogicalTopOffset -= blockDelta;
}
}
@@ -2476,6 +2485,19 @@
}
}
+IntPoint RenderBlock::flipFloatForWritingMode(const FloatingObject* child, const IntPoint& point) const
+{
+ if (!style()->isFlippedBlocksWritingMode())
+ return point;
+
+ // This is similar to the ParentToChildFlippingAdjustment in RenderBox::flipForWritingMode. 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 (style()->isHorizontalWritingMode())
+ return IntPoint(point.x(), point.y() + height() - child->renderer()->height() - 2 * topForFloatIncludingMargin(child));
+ return IntPoint(point.x() + width() - child->width() - 2 * leftForFloatIncludingMargin(child), point.y());
+}
+
void RenderBlock::paintFloats(PaintInfo& paintInfo, int tx, int ty, bool preservePhase)
{
if (!m_floatingObjects)
@@ -2488,7 +2510,7 @@
if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer()) {
PaintInfo currentPaintInfo(paintInfo);
currentPaintInfo.phase = preservePhase ? paintInfo.phase : PaintPhaseBlockBackground;
- IntPoint childPoint = flipForWritingMode(r->m_renderer, IntPoint(tx + r->left() + r->m_renderer->marginLeft() - r->m_renderer->x(), ty + r->top() + r->m_renderer->marginTop() - r->m_renderer->y()), ParentToChildFlippingAdjustment);
+ IntPoint childPoint = flipFloatForWritingMode(r, IntPoint(tx + leftForFloatIncludingMargin(r) - r->m_renderer->x(), ty + topForFloatIncludingMargin(r) - r->m_renderer->y()));
r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
if (!preservePhase) {
currentPaintInfo.phase = PaintPhaseChildBlockBackgrounds;
@@ -2722,8 +2744,8 @@
if (m_floatingObjects) {
for (DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects); it.current(); ++it) {
FloatingObject* r = it.current();
- IntRect floatBox = IntRect(offsetFromRootBlock.width() + r->left() + r->m_renderer->marginLeft(),
- offsetFromRootBlock.height() + r->top() + r->m_renderer->marginTop(),
+ IntRect floatBox = IntRect(offsetFromRootBlock.width() + leftForFloatIncludingMargin(r),
+ offsetFromRootBlock.height() + topForFloatIncludingMargin(r),
r->m_renderer->width(), r->m_renderer->height());
rootBlock->flipForWritingMode(floatBox);
floatBox.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y());
@@ -3093,13 +3115,13 @@
}
}
-void RenderBlock::removeFloatingObjectsBelow(FloatingObject* lastFloat, int y)
+void RenderBlock::removeFloatingObjectsBelow(FloatingObject* lastFloat, int logicalOffset)
{
if (!m_floatingObjects)
return;
FloatingObject* curr = m_floatingObjects->last();
- while (curr != lastFloat && (!curr->isPlaced() || curr->top() >= y)) {
+ while (curr != lastFloat && (!curr->isPlaced() || logicalTopForFloat(curr) >= logicalOffset)) {
m_floatingObjects->removeLast();
curr = m_floatingObjects->last();
}
@@ -3611,7 +3633,7 @@
// Since the float doesn't overhang, it didn't get put into our list. We need to go ahead and add its overflow in to the
// child now.
if (r->m_isDescendant)
- child->addOverflowFromChild(r->m_renderer, IntSize(r->left() + r->m_renderer->marginLeft(), r->top() + r->m_renderer->marginTop()));
+ child->addOverflowFromChild(r->m_renderer, IntSize(leftForFloatIncludingMargin(r), topForFloatIncludingMargin(r)));
}
}
return lowestFloatLogicalBottom;
@@ -3849,9 +3871,9 @@
DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
for (it.toLast(); (floatingObject = it.current()); --it) {
if (floatingObject->m_shouldPaint && !floatingObject->m_renderer->hasSelfPaintingLayer()) {
- int xOffset = floatingObject->left() + floatingObject->m_renderer->marginLeft() - floatingObject->m_renderer->x();
- int yOffset = floatingObject->top() + floatingObject->m_renderer->marginTop() - floatingObject->m_renderer->y();
- IntPoint childPoint = flipForWritingMode(floatingObject->m_renderer, IntPoint(tx + xOffset, ty + yOffset), ParentToChildFlippingAdjustment);
+ int xOffset = leftForFloatIncludingMargin(floatingObject) - floatingObject->m_renderer->x();
+ int yOffset = topForFloatIncludingMargin(floatingObject) - floatingObject->m_renderer->y();
+ IntPoint childPoint = flipFloatForWritingMode(floatingObject, IntPoint(tx + xOffset, ty + yOffset));
if (floatingObject->m_renderer->hitTest(request, result, IntPoint(x, y), childPoint.x(), childPoint.y())) {
updateHitTestResult(result, IntPoint(x - childPoint.x(), y - childPoint.y()));
return true;
@@ -3869,23 +3891,36 @@
int colCount = columnCount(colInfo);
if (!colCount)
return false;
- int left = borderLeft() + paddingLeft();
- int currYOffset = 0;
+ int logicalLeft = logicalLeftOffsetForContent();
+ int currLogicalTopOffset = 0;
int i;
- for (i = 0; i < colCount; i++)
- currYOffset -= columnRectAt(colInfo, i).height();
+ bool isHorizontal = style()->isHorizontalWritingMode();
+ for (i = 0; i < colCount; i++) {
+ IntRect colRect = columnRectAt(colInfo, i);
+ int blockDelta = (isHorizontal ? colRect.height() : colRect.width());
+ if (style()->isFlippedBlocksWritingMode())
+ currLogicalTopOffset += blockDelta;
+ else
+ currLogicalTopOffset -= blockDelta;
+ }
for (i = colCount - 1; i >= 0; i--) {
IntRect colRect = columnRectAt(colInfo, i);
- int currXOffset = colRect.x() - left;
- currYOffset += colRect.height();
+ flipForWritingMode(colRect);
+ int currLogicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - logicalLeft;
+ int blockDelta = (isHorizontal ? colRect.height() : colRect.width());
+ if (style()->isFlippedBlocksWritingMode())
+ currLogicalTopOffset -= blockDelta;
+ else
+ currLogicalTopOffset += blockDelta;
colRect.move(tx, ty);
if (colRect.intersects(result.rectForPoint(x, y))) {
// The point is inside this column.
// Adjust tx and ty to change where we hit test.
- int finalX = tx + currXOffset;
- int finalY = ty + currYOffset;
+ IntSize offset = isHorizontal ? IntSize(currLogicalLeftOffset, currLogicalTopOffset) : IntSize(currLogicalTopOffset, currLogicalLeftOffset);
+ int finalX = tx + offset.width();
+ int finalY = ty + offset.height();
if (result.isRectBasedTest() && !colRect.contains(result.rectForPoint(x, y)))
hitTestContents(request, result, x, y, finalX, finalY, hitTestAction);
else
@@ -4105,7 +4140,7 @@
{
// Calculate our column width and column count.
unsigned desiredColumnCount = 1;
- int desiredColumnWidth = contentWidth();
+ int desiredColumnWidth = contentLogicalWidth();
// For now, we don't support multi-column layouts when printing, since we have to do a lot of work for proper pagination.
if (document()->paginated() || (style()->hasAutoColumnCount() && style()->hasAutoColumnWidth())) {
@@ -4180,7 +4215,7 @@
int RenderBlock::desiredColumnWidth() const
{
if (!hasColumns())
- return contentWidth();
+ return contentLogicalWidth();
return gColumnInfoMap->get(this)->desiredColumnWidth();
}
@@ -4209,14 +4244,17 @@
ASSERT(hasColumns() && gColumnInfoMap->get(this) == colInfo);
// Compute the appropriate rect based off our information.
- int colWidth = colInfo->desiredColumnWidth();
- int colHeight = colInfo->columnHeight();
- int colTop = borderTop() + paddingTop();
+ int colLogicalWidth = colInfo->desiredColumnWidth();
+ int colLogicalHeight = colInfo->columnHeight();
+ int colLogicalTop = borderBefore() + paddingBefore();
int colGap = columnGap();
- int colLeft = style()->isLeftToRightDirection() ?
- borderLeft() + paddingLeft() + (index * (colWidth + colGap))
- : borderLeft() + paddingLeft() + contentWidth() - colWidth - (index * (colWidth + colGap));
- return IntRect(colLeft, colTop, colWidth, colHeight);
+ int colLogicalLeft = style()->isLeftToRightDirection() ?
+ logicalLeftOffsetForContent() + (index * (colLogicalWidth + colGap))
+ : logicalLeftOffsetForContent() + contentLogicalWidth() - colLogicalWidth - (index * (colLogicalWidth + colGap));
+ IntRect rect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLogicalHeight);
+ if (style()->isHorizontalWritingMode())
+ return IntRect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLogicalHeight);
+ return IntRect(colLogicalTop, colLogicalLeft, colLogicalHeight, colLogicalWidth);
}
bool RenderBlock::layoutColumns(bool hasSpecifiedPageLogicalHeight, int pageLogicalHeight, LayoutStateMaintainer& statePusher)
@@ -4236,12 +4274,12 @@
// maximum page break distance.
if (!pageLogicalHeight) {
int distanceBetweenBreaks = max(colInfo->maximumDistanceBetweenForcedBreaks(),
- view()->layoutState()->pageLogicalOffset(borderTop() + paddingTop() + contentHeight()) - colInfo->forcedBreakOffset());
+ view()->layoutState()->pageLogicalOffset(borderBefore() + paddingBefore() + contentLogicalHeight()) - colInfo->forcedBreakOffset());
columnHeight = max(colInfo->minimumColumnHeight(), distanceBetweenBreaks);
}
- } else if (contentHeight() > pageLogicalHeight * desiredColumnCount) {
+ } else if (contentLogicalHeight() > pageLogicalHeight * desiredColumnCount) {
// Now that we know the intrinsic height of the columns, we have to rebalance them.
- columnHeight = max(colInfo->minimumColumnHeight(), (int)ceilf((float)contentHeight() / desiredColumnCount));
+ columnHeight = max(colInfo->minimumColumnHeight(), (int)ceilf((float)contentLogicalHeight() / desiredColumnCount));
}
if (columnHeight && columnHeight != pageLogicalHeight) {
@@ -4253,10 +4291,10 @@
}
if (pageLogicalHeight)
- colInfo->setColumnCountAndHeight(ceilf((float)contentHeight() / pageLogicalHeight), pageLogicalHeight);
+ colInfo->setColumnCountAndHeight(ceilf((float)contentLogicalHeight() / pageLogicalHeight), pageLogicalHeight);
if (columnCount(colInfo)) {
- setLogicalHeight(borderTop() + paddingTop() + colInfo->columnHeight() + borderBottom() + paddingBottom() + horizontalScrollbarHeight());
+ setLogicalHeight(borderBefore() + paddingBefore() + colInfo->columnHeight() + borderAfter() + paddingAfter() + scrollbarLogicalHeight());
m_overflow.clear();
}
@@ -4275,34 +4313,57 @@
// Determine which columns we intersect.
int colGap = columnGap();
- int leftGap = colGap / 2;
+ int halfColGap = colGap / 2;
IntPoint columnPoint(columnRectAt(colInfo, 0).location());
- int yOffset = 0;
+ int logicalOffset = 0;
for (unsigned i = 0; i < colInfo->columnCount(); i++) {
// Add in half the column gap to the left and right of the rect.
IntRect colRect = columnRectAt(colInfo, i);
- IntRect gapAndColumnRect(colRect.x() - leftGap, colRect.y(), colRect.width() + colGap, colRect.height());
+ if (style()->isHorizontalWritingMode()) {
+ IntRect gapAndColumnRect(colRect.x() - halfColGap, colRect.y(), colRect.width() + colGap, colRect.height());
+ if (point.x() >= gapAndColumnRect.x() && point.x() < gapAndColumnRect.right()) {
+ // FIXME: The clamping that follows is not completely right for right-to-left
+ // content.
+ // Clamp everything above the column to its top left.
+ if (point.y() < gapAndColumnRect.y())
+ point = gapAndColumnRect.location();
+ // Clamp everything below the column to the next column's top left. If there is
+ // no next column, this still maps to just after this column.
+ else if (point.y() >= gapAndColumnRect.bottom()) {
+ point = gapAndColumnRect.location();
+ point.move(0, gapAndColumnRect.height());
+ }
- if (point.x() >= gapAndColumnRect.x() && point.x() < gapAndColumnRect.right()) {
- // FIXME: The clamping that follows is not completely right for right-to-left
- // content.
- // Clamp everything above the column to its top left.
- if (point.y() < gapAndColumnRect.y())
- point = gapAndColumnRect.location();
- // Clamp everything below the column to the next column's top left. If there is
- // no next column, this still maps to just after this column.
- else if (point.y() >= gapAndColumnRect.bottom()) {
- point = gapAndColumnRect.location();
- point.move(0, gapAndColumnRect.height());
+ // We're inside the column. Translate the x and y into our column coordinate space.
+ point.move(columnPoint.x() - colRect.x(), logicalOffset);
+ return;
}
+
+ // Move to the next position.
+ logicalOffset += colRect.height();
+ } else {
+ IntRect gapAndColumnRect(colRect.x(), colRect.y() - halfColGap, colRect.width(), colRect.height() + colGap);
+ if (point.y() >= gapAndColumnRect.y() && point.y() < gapAndColumnRect.bottom()) {
+ // FIXME: The clamping that follows is not completely right for right-to-left
+ // content.
+ // Clamp everything above the column to its top left.
+ if (point.x() < gapAndColumnRect.x())
+ point = gapAndColumnRect.location();
+ // Clamp everything below the column to the next column's top left. If there is
+ // no next column, this still maps to just after this column.
+ else if (point.x() >= gapAndColumnRect.right()) {
+ point = gapAndColumnRect.location();
+ point.move(gapAndColumnRect.width(), 0);
+ }
- // We're inside the column. Translate the x and y into our column coordinate space.
- point.move(columnPoint.x() - colRect.x(), yOffset);
- return;
+ // We're inside the column. Translate the x and y into our column coordinate space.
+ point.move(logicalOffset, columnPoint.y() - colRect.y());
+ return;
+ }
+
+ // Move to the next position.
+ logicalOffset += colRect.width();
}
-
- // Move to the next position.
- yOffset += colRect.height();
}
}
@@ -4322,27 +4383,56 @@
if (!colCount)
return;
- int left = borderLeft() + paddingLeft();
-
- int currYOffset = 0;
+ int logicalLeft = logicalLeftOffsetForContent();
+ int currLogicalOffset = 0;
+
for (unsigned i = 0; i < colCount; i++) {
IntRect colRect = columnRectAt(colInfo, i);
- int currXOffset = colRect.x() - left;
-
IntRect repaintRect = r;
- repaintRect.move(currXOffset, currYOffset);
-
+ if (style()->isHorizontalWritingMode()) {
+ int currXOffset = colRect.x() - logicalLeft;
+ repaintRect.move(currXOffset, currLogicalOffset);
+ currLogicalOffset -= colRect.height();
+ } else {
+ int currYOffset = colRect.y() - logicalLeft;
+ repaintRect.move(currLogicalOffset, currYOffset);
+ currLogicalOffset -= colRect.width();
+ }
repaintRect.intersect(colRect);
-
result.unite(repaintRect);
-
- // Move to the next position.
- currYOffset -= colRect.height();
}
r = result;
}
+IntPoint RenderBlock::flipForWritingModeIncludingColumns(const IntPoint& point) const
+{
+ ASSERT(hasColumns());
+ if (!hasColumns() || !style()->isFlippedBlocksWritingMode())
+ return point;
+ ColumnInfo* colInfo = columnInfo();
+ int columnLogicalHeight = colInfo->columnHeight();
+ int expandedLogicalHeight = borderBefore() + paddingBefore() + columnCount(colInfo) * columnLogicalHeight + borderAfter() + paddingAfter() + scrollbarLogicalHeight();
+ if (style()->isHorizontalWritingMode())
+ return IntPoint(point.x(), expandedLogicalHeight - point.y());
+ return IntPoint(expandedLogicalHeight - point.x(), point.y());
+}
+
+void RenderBlock::flipForWritingModeIncludingColumns(IntRect& rect) const
+{
+ ASSERT(hasColumns());
+ if (!hasColumns() || !style()->isFlippedBlocksWritingMode())
+ return;
+
+ ColumnInfo* colInfo = columnInfo();
+ int columnLogicalHeight = colInfo->columnHeight();
+ int expandedLogicalHeight = borderBefore() + paddingBefore() + columnCount(colInfo) * columnLogicalHeight + borderAfter() + paddingAfter() + scrollbarLogicalHeight();
+ if (style()->isHorizontalWritingMode())
+ rect.setY(expandedLogicalHeight - rect.bottom());
+ else
+ rect.setX(expandedLogicalHeight - rect.right());
+}
+
void RenderBlock::adjustForColumns(IntSize& offset, const IntPoint& point) const
{
if (!hasColumns())
@@ -4350,18 +4440,34 @@
ColumnInfo* colInfo = columnInfo();
- int left = borderLeft() + paddingLeft();
- int yOffset = 0;
+ int logicalLeft = logicalLeftOffsetForContent();
size_t colCount = columnCount(colInfo);
- for (size_t i = 0; i < colCount; ++i) {
- IntRect columnRect = columnRectAt(colInfo, i);
- int xOffset = columnRect.x() - left;
- if (point.y() < columnRect.bottom() + yOffset) {
- offset.expand(xOffset, -yOffset);
- return;
- }
+ int colLogicalWidth = colInfo->desiredColumnWidth();
+ int colLogicalHeight = colInfo->columnHeight();
- yOffset += columnRect.height();
+ for (size_t i = 0; i < colCount; ++i) {
+ // Compute the edges for a given column in the block progression direction.
+ IntRect sliceRect = IntRect(logicalLeft, borderBefore() + paddingBefore() + i * colLogicalHeight, colLogicalWidth, colLogicalHeight);
+ if (!style()->isHorizontalWritingMode())
+ sliceRect = sliceRect.transposedRect();
+
+ // If we have a flipped blocks writing mode, then convert the column so that it's coming from the after edge (either top or left edge).
+ flipForWritingModeIncludingColumns(sliceRect);
+
+ int logicalOffset = style()->isFlippedBlocksWritingMode() ? (colCount - 1 - i) * colLogicalHeight : i * colLogicalHeight;
+
+ // Now we're in the same coordinate space as the point. See if it is inside the rectangle.
+ if (style()->isHorizontalWritingMode()) {
+ if (point.y() >= sliceRect.y() && point.y() < sliceRect.bottom()) {
+ offset.expand(columnRectAt(colInfo, i).x() - logicalLeft, -logicalOffset);
+ return;
+ }
+ } else {
+ if (point.x() >= sliceRect.x() && point.x() < sliceRect.right()) {
+ offset.expand(-logicalOffset, columnRectAt(colInfo, i).y() - logicalLeft);
+ return;
+ }
+ }
}
}
@@ -4501,16 +4607,13 @@
static int getBorderPaddingMargin(const RenderBoxModelObject* child, bool endOfInline)
{
RenderStyle* cstyle = child->style();
- int result = 0;
- bool leftSide = (cstyle->isLeftToRightDirection()) ? !endOfInline : endOfInline;
- result += getBPMWidth((leftSide ? child->marginLeft() : child->marginRight()),
- (leftSide ? cstyle->marginLeft() :
- cstyle->marginRight()));
- result += getBPMWidth((leftSide ? child->paddingLeft() : child->paddingRight()),
- (leftSide ? cstyle->paddingLeft() :
- cstyle->paddingRight()));
- result += leftSide ? child->borderLeft() : child->borderRight();
- return result;
+ if (endOfInline)
+ return getBPMWidth(child->marginEnd(), cstyle->marginEnd()) +
+ getBPMWidth(child->paddingEnd(), cstyle->paddingEnd()) +
+ child->borderEnd();
+ return getBPMWidth(child->marginStart(), cstyle->marginStart()) +
+ getBPMWidth(child->paddingStart(), cstyle->paddingStart()) +
+ child->borderStart();
}
static inline void stripTrailingSpace(int& inlineMax, int& inlineMin,
@@ -4533,7 +4636,7 @@
int inlineMax = 0;
int inlineMin = 0;
- int cw = containingBlock()->contentWidth();
+ int cw = containingBlock()->contentLogicalWidth();
// If we are at the start of a line, we want to ignore all white-space.
// Also strip spaces if we previously had text that ended in a trailing space.
@@ -4543,7 +4646,7 @@
// Firefox and Opera will allow a table cell to grow to fit an image inside it under
// very specific cirucumstances (in order to match common WinIE renderings).
// Not supporting the quirk has caused us to mis-render some real sites. (See Bugzilla 10517.)
- bool allowImagesToBreak = !document()->inQuirksMode() || !isTableCell() || !style()->width().isIntrinsicOrAuto();
+ bool allowImagesToBreak = !document()->inQuirksMode() || !isTableCell() || !style()->logicalWidth().isIntrinsicOrAuto();
bool autoWrap, oldAutoWrap;
autoWrap = oldAutoWrap = style()->autoWrap();
@@ -4611,12 +4714,12 @@
} else {
// Inline replaced elts add in their margins to their min/max values.
int margins = 0;
- Length leftMargin = cstyle->marginLeft();
- Length rightMargin = cstyle->marginRight();
- if (leftMargin.isFixed())
- margins += leftMargin.value();
- if (rightMargin.isFixed())
- margins += rightMargin.value();
+ Length startMargin = cstyle->marginStart();
+ Length endMargin = cstyle->marginEnd();
+ if (startMargin.isFixed())
+ margins += startMargin.value();
+ if (endMargin.isFixed())
+ margins += endMargin.value();
childMin += margins;
childMax += margins;
}
@@ -4655,8 +4758,8 @@
if (!addedTextIndent) {
addedTextIndent = true;
ti = style()->textIndent().calcMinValue(cw);
- childMin+=ti;
- childMax+=ti;
+ childMin += ti;
+ childMax += ti;
}
// Add our width to the max.
@@ -4818,14 +4921,16 @@
// A margin basically has three types: fixed, percentage, and auto (variable).
// Auto and percentage margins simply become 0 when computing min/max width.
// Fixed margins can be added in as is.
- Length ml = child->style()->marginLeft();
- Length mr = child->style()->marginRight();
- int margin = 0, marginLeft = 0, marginRight = 0;
- if (ml.isFixed())
- marginLeft += ml.value();
- if (mr.isFixed())
- marginRight += mr.value();
- margin = marginLeft + marginRight;
+ Length startMarginLength = child->style()->marginStart();
+ Length endMarginLength = child->style()->marginEnd();
+ int margin = 0;
+ int marginStart = 0;
+ int marginEnd = 0;
+ if (startMarginLength.isFixed())
+ marginStart += startMarginLength.value();
+ if (endMarginLength.isFixed())
+ marginEnd += endMarginLength.value();
+ margin = marginStart + marginEnd;
int w = child->minPreferredLogicalWidth() + margin;
m_minPreferredLogicalWidth = max(w, m_minPreferredLogicalWidth);
@@ -4841,8 +4946,11 @@
// Determine a left and right max value based off whether or not the floats can fit in the
// margins of the object. For negative margins, we will attempt to overlap the float if the negative margin
// is smaller than the float width.
- int maxLeft = marginLeft > 0 ? max(floatLeftWidth, marginLeft) : floatLeftWidth + marginLeft;
- int maxRight = marginRight > 0 ? max(floatRightWidth, marginRight) : floatRightWidth + marginRight;
+ bool ltr = containingBlock()->style()->isLeftToRightDirection();
+ int marginLogicalLeft = ltr ? marginStart : marginEnd;
+ int marginLogicalRight = ltr ? marginEnd : marginStart;
+ int maxLeft = marginLogicalLeft > 0 ? max(floatLeftWidth, marginLogicalLeft) : floatLeftWidth + marginLogicalLeft;
+ int maxRight = marginLogicalRight > 0 ? max(floatRightWidth, marginLogicalRight) : floatRightWidth + marginLogicalRight;
w = child->maxPreferredLogicalWidth() + maxLeft + maxRight;
w = max(w, floatLeftWidth + floatRightWidth);
}
@@ -4872,7 +4980,7 @@
// of 100px because of the table.
// We can achieve this effect by making the maxwidth of blocks that contain tables
// with percentage widths be infinite (as long as they are not inside a table cell).
- if (document()->inQuirksMode() && child->style()->width().isPercent() &&
+ if (document()->inQuirksMode() && child->style()->logicalWidth().isPercent() &&
!isTableCell() && child->isTable() && m_maxPreferredLogicalWidth < BLOCK_MAX_WIDTH) {
RenderBlock* cb = containingBlock();
while (!cb->isRenderView() && !cb->isTableCell())
@@ -5370,7 +5478,7 @@
for (; (r = it.current()); ++it) {
// Only examine the object if our m_shouldPaint flag is set.
if (r->m_shouldPaint) {
- int floatLeft = r->left() - r->m_renderer->x() + r->m_renderer->marginLeft();
+ int floatLeft = leftForFloatIncludingMargin(r) - r->m_renderer->x();
int floatRight = floatLeft + r->m_renderer->width();
left = min(left, floatLeft);
right = max(right, floatRight);
@@ -5725,16 +5833,18 @@
return newBox;
}
-int RenderBlock::nextPageTop(int yPos) const
+int RenderBlock::nextPageLogicalTop(int logicalOffset) const
{
LayoutState* layoutState = view()->layoutState();
if (!layoutState->m_pageLogicalHeight)
- return yPos;
+ return logicalOffset;
- // The yPos is in our coordinate space. We can add in our pushed offset.
+ // The logicalOffset is in our coordinate space. We can add in our pushed offset.
int pageLogicalHeight = layoutState->m_pageLogicalHeight;
- int remainingHeight = (pageLogicalHeight - ((layoutState->m_layoutOffset - layoutState->m_pageOffset).height() + yPos) % pageLogicalHeight) % pageLogicalHeight;
- return yPos + remainingHeight;
+ IntSize delta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
+ int offset = style()->isHorizontalWritingMode() ? delta.height() : delta.width();
+ int remainingLogicalHeight = (pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight) % pageLogicalHeight;
+ return logicalOffset + remainingLogicalHeight;
}
static bool inNormalFlow(RenderBox* child)
@@ -5751,7 +5861,7 @@
return true;
}
-int RenderBlock::applyBeforeBreak(RenderBox* child, int yPos)
+int RenderBlock::applyBeforeBreak(RenderBox* child, int logicalOffset)
{
// FIXME: Add page break checking here when we support printing.
bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns();
@@ -5759,13 +5869,13 @@
bool checkBeforeAlways = (checkColumnBreaks && child->style()->columnBreakBefore() == PBALWAYS) || (checkPageBreaks && child->style()->pageBreakBefore() == PBALWAYS);
if (checkBeforeAlways && inNormalFlow(child)) {
if (checkColumnBreaks)
- view()->layoutState()->addForcedColumnBreak(yPos);
- return nextPageTop(yPos);
+ view()->layoutState()->addForcedColumnBreak(logicalOffset);
+ return nextPageLogicalTop(logicalOffset);
}
- return yPos;
+ return logicalOffset;
}
-int RenderBlock::applyAfterBreak(RenderBox* child, int yPos, MarginInfo& marginInfo)
+int RenderBlock::applyAfterBreak(RenderBox* child, int logicalOffset, MarginInfo& marginInfo)
{
// FIXME: Add page break checking here when we support printing.
bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns();
@@ -5774,28 +5884,30 @@
if (checkAfterAlways && inNormalFlow(child)) {
marginInfo.setMarginAfterQuirk(true); // Cause margins to be discarded for any following content.
if (checkColumnBreaks)
- view()->layoutState()->addForcedColumnBreak(yPos);
- return nextPageTop(yPos);
+ view()->layoutState()->addForcedColumnBreak(logicalOffset);
+ return nextPageLogicalTop(logicalOffset);
}
- return yPos;
+ return logicalOffset;
}
-int RenderBlock::adjustForUnsplittableChild(RenderBox* child, int yPos, bool includeMargins)
+int RenderBlock::adjustForUnsplittableChild(RenderBox* child, int logicalOffset, bool includeMargins)
{
bool isUnsplittable = child->isReplaced() || child->scrollsOverflow();
if (!isUnsplittable)
- return yPos;
- int childHeight = child->height() + (includeMargins ? child->marginTop() + child->marginBottom() : 0);
+ return logicalOffset;
+ int childLogicalHeight = logicalHeightForChild(child) + (includeMargins ? marginBeforeForChild(child) + marginAfterForChild(child) : 0);
LayoutState* layoutState = view()->layoutState();
if (layoutState->m_columnInfo)
- layoutState->m_columnInfo->updateMinimumColumnHeight(childHeight);
+ layoutState->m_columnInfo->updateMinimumColumnHeight(childLogicalHeight);
int pageLogicalHeight = layoutState->m_pageLogicalHeight;
- if (!pageLogicalHeight || childHeight > pageLogicalHeight)
- return yPos;
- int remainingHeight = (pageLogicalHeight - ((layoutState->m_layoutOffset - layoutState->m_pageOffset).height() + yPos) % pageLogicalHeight) % pageLogicalHeight;
- if (remainingHeight < childHeight)
- return yPos + remainingHeight;
- return yPos;
+ if (!pageLogicalHeight || childLogicalHeight > pageLogicalHeight)
+ return logicalOffset;
+ IntSize delta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
+ int offset = style()->isHorizontalWritingMode() ? delta.height() : delta.width();
+ int remainingLogicalHeight = (pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight) % pageLogicalHeight;
+ if (remainingLogicalHeight < childLogicalHeight)
+ return logicalOffset + remainingLogicalHeight;
+ return logicalOffset;
}
void RenderBlock::adjustLinePositionForPagination(RootInlineBox* lineBox, int& delta)
@@ -5818,22 +5930,24 @@
// line and all following lines.
LayoutState* layoutState = view()->layoutState();
int pageLogicalHeight = layoutState->m_pageLogicalHeight;
- int yPos = lineBox->topVisualOverflow();
- int lineHeight = lineBox->bottomVisualOverflow() - yPos;
+ int logicalOffset = lineBox->logicalTopVisualOverflow();
+ int lineHeight = lineBox->logicalBottomVisualOverflow() - logicalOffset;
if (layoutState->m_columnInfo)
layoutState->m_columnInfo->updateMinimumColumnHeight(lineHeight);
- yPos += delta;
+ logicalOffset += delta;
lineBox->setPaginationStrut(0);
if (!pageLogicalHeight || lineHeight > pageLogicalHeight)
return;
- int remainingHeight = pageLogicalHeight - ((layoutState->m_layoutOffset - layoutState->m_pageOffset).height() + yPos) % pageLogicalHeight;
- if (remainingHeight < lineHeight) {
- int totalHeight = lineHeight + max(0, yPos);
- if (lineBox == firstRootBox() && totalHeight < pageLogicalHeight && !isPositioned() && !isTableCell())
- setPaginationStrut(remainingHeight + max(0, yPos));
+ IntSize offsetDelta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
+ int offset = style()->isHorizontalWritingMode() ? offsetDelta.height() : offsetDelta.width();
+ int remainingLogicalHeight = pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight;
+ if (remainingLogicalHeight < lineHeight) {
+ int totalLogicalHeight = lineHeight + max(0, logicalOffset);
+ if (lineBox == firstRootBox() && totalLogicalHeight < pageLogicalHeight && !isPositioned() && !isTableCell())
+ setPaginationStrut(remainingLogicalHeight + max(0, logicalOffset));
else {
- delta += remainingHeight;
- lineBox->setPaginationStrut(remainingHeight);
+ delta += remainingLogicalHeight;
+ lineBox->setPaginationStrut(remainingLogicalHeight);
}
}
}
diff --git a/Source/WebCore/rendering/RenderBlock.h b/Source/WebCore/rendering/RenderBlock.h
index e43b87d..cc98000 100644
--- a/Source/WebCore/rendering/RenderBlock.h
+++ b/Source/WebCore/rendering/RenderBlock.h
@@ -106,6 +106,9 @@
// Block flows subclass availableWidth to handle multi column layout (shrinking the width available to children when laying out.)
virtual int availableLogicalWidth() const;
+ IntPoint flipForWritingModeIncludingColumns(const IntPoint&) const;
+ void flipForWritingModeIncludingColumns(IntRect&) const;
+
RootInlineBox* firstRootBox() const { return static_cast<RootInlineBox*>(firstLineBox()); }
RootInlineBox* lastRootBox() const { return static_cast<RootInlineBox*>(lastLineBox()); }
@@ -212,6 +215,9 @@
virtual void scrollbarsChanged(bool /*horizontalScrollbarChanged*/, bool /*verticalScrollbarChanged*/) { };
+ int logicalRightOffsetForContent() const { return style()->isHorizontalWritingMode() ? borderLeft() + paddingLeft() + availableLogicalWidth() : borderTop() + paddingTop() + availableLogicalWidth(); }
+ int logicalLeftOffsetForContent() const { return style()->isHorizontalWritingMode() ? borderLeft() + paddingLeft() : borderTop() + paddingTop(); }
+
protected:
// These functions are only used internally to manipulate the render tree structure via remove/insert/appendChildNode.
// Since they are typically called only to move objects around within anonymous blocks (which only have layers in
@@ -261,8 +267,6 @@
virtual void paint(PaintInfo&, int tx, int ty);
virtual void paintObject(PaintInfo&, int tx, int ty);
- int logicalRightOffsetForContent() const { return style()->isHorizontalWritingMode() ? borderLeft() + paddingLeft() + availableLogicalWidth() : borderTop() + paddingTop() + availableLogicalWidth(); }
- int logicalLeftOffsetForContent() const { return style()->isHorizontalWritingMode() ? borderLeft() + paddingLeft() : borderTop() + paddingTop(); }
int logicalRightOffsetForLine(int position, int fixedOffset, bool applyTextIndent = true, int* logicalHeightRemaining = 0) const;
int logicalLeftOffsetForLine(int position, int fixedOffset, bool applyTextIndent = true, int* logicalHeightRemaining = 0) const;
@@ -399,7 +403,7 @@
int bottom() const { ASSERT(isPlaced()); return m_frameRect.bottom(); }
int width() const { return m_frameRect.width(); }
int height() const { return m_frameRect.height(); }
-
+
void setLeft(int left) { m_frameRect.setX(left); }
void setTop(int top) { m_frameRect.setY(top); }
void setWidth(int width) { m_frameRect.setWidth(width); }
@@ -417,11 +421,13 @@
bool m_isPlaced : 1;
};
- int logicalTopForFloat(FloatingObject* child) const { return style()->isHorizontalWritingMode() ? child->top() : child->left(); }
- int logicalBottomForFloat(FloatingObject* child) const { return style()->isHorizontalWritingMode() ? child->bottom() : child->right(); }
- int logicalLeftForFloat(FloatingObject* child) const { return style()->isHorizontalWritingMode() ? child->left() : child->top(); }
- int logicalRightForFloat(FloatingObject* child) const { return style()->isHorizontalWritingMode() ? child->right() : child->bottom(); }
- int logicalWidthForFloat(FloatingObject* child) const { return style()->isHorizontalWritingMode() ? child->width() : child->height(); }
+ IntPoint flipFloatForWritingMode(const FloatingObject*, const IntPoint&) const;
+
+ int logicalTopForFloat(const FloatingObject* child) const { return style()->isHorizontalWritingMode() ? child->top() : child->left(); }
+ int logicalBottomForFloat(const FloatingObject* child) const { return style()->isHorizontalWritingMode() ? child->bottom() : child->right(); }
+ int logicalLeftForFloat(const FloatingObject* child) const { return style()->isHorizontalWritingMode() ? child->left() : child->top(); }
+ int logicalRightForFloat(const FloatingObject* child) const { return style()->isHorizontalWritingMode() ? child->right() : child->bottom(); }
+ int logicalWidthForFloat(const FloatingObject* child) const { return style()->isHorizontalWritingMode() ? child->width() : child->height(); }
void setLogicalTopForFloat(FloatingObject* child, int logicalTop)
{
if (style()->isHorizontalWritingMode())
@@ -451,6 +457,22 @@
child->setHeight(logicalWidth);
}
+ int leftForFloatIncludingMargin(const FloatingObject* child) const
+ {
+ if (style()->isHorizontalWritingMode())
+ return child->left() + child->renderer()->marginLeft();
+ else
+ return child->left() + marginBeforeForChild(child->renderer());
+ }
+
+ int topForFloatIncludingMargin(const FloatingObject* child) const
+ {
+ if (style()->isHorizontalWritingMode())
+ return child->top() + marginBeforeForChild(child->renderer());
+ else
+ return child->top() + child->renderer()->marginTop();
+ }
+
// The following functions' implementations are in RenderBlockLineLayout.cpp.
RootInlineBox* determineStartPosition(bool& firstLine, bool& fullLayout, bool& previousLineBrokeCleanly,
InlineBidiResolver&, Vector<FloatWithRect>& floats, unsigned& numCleanFloats,
@@ -488,7 +510,7 @@
FloatingObject* insertFloatingObject(RenderBox*);
void removeFloatingObject(RenderBox*);
- void removeFloatingObjectsBelow(FloatingObject*, int y);
+ void removeFloatingObjectsBelow(FloatingObject*, int logicalOffset);
// Called from lineWidth, to position the floats added in the last line.
// Returns true if and only if it has positioned any floats.
@@ -667,11 +689,11 @@
// End helper functions and structs used by layoutBlockChildren.
// Pagination routines.
- int nextPageTop(int yPos) const; // Returns the top of the next page following yPos.
- int applyBeforeBreak(RenderBox* child, int yPos); // If the child has a before break, then return a new yPos that shifts to the top of the next page/column.
- int applyAfterBreak(RenderBox* child, int yPos, MarginInfo& marginInfo); // If the child has an after break, then return a new yPos that shifts to the top of the next page/column.
- int adjustForUnsplittableChild(RenderBox* child, int yPos, bool includeMargins = false); // If the child is unsplittable and can't fit on the current page, return the top of the next page/column.
- void adjustLinePositionForPagination(RootInlineBox*, int& deltaY); // Computes a deltaY value that put a line at the top of the next page if it doesn't fit on the current page.
+ int nextPageLogicalTop(int logicalOffset) const; // Returns the top of the next page following logicalOffset.
+ int applyBeforeBreak(RenderBox* child, int logicalOffset); // If the child has a before break, then return a new yPos that shifts to the top of the next page/column.
+ int applyAfterBreak(RenderBox* child, int logicalOffset, MarginInfo& marginInfo); // If the child has an after break, then return a new offset that shifts to the top of the next page/column.
+ int adjustForUnsplittableChild(RenderBox* child, int 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.
+ void adjustLinePositionForPagination(RootInlineBox*, int& deltaOffset); // Computes a deltaOffset value that put a line at the top of the next page if it doesn't fit on the current page.
typedef PositionedObjectsListHashSet::const_iterator Iterator;
DeprecatedPtrList<FloatingObject>* m_floatingObjects;
diff --git a/Source/WebCore/rendering/RenderBlockLineLayout.cpp b/Source/WebCore/rendering/RenderBlockLineLayout.cpp
index 108f529..2637bc0 100644
--- a/Source/WebCore/rendering/RenderBlockLineLayout.cpp
+++ b/Source/WebCore/rendering/RenderBlockLineLayout.cpp
@@ -790,7 +790,7 @@
adjustLinePositionForPagination(lineBox, adjustment);
if (adjustment) {
int oldLineWidth = availableLogicalWidthForLine(oldLogicalHeight, firstLine);
- lineBox->adjustPosition(0, adjustment);
+ lineBox->adjustBlockDirectionPosition(adjustment);
if (useRepaintBounds) // This can only be a positive adjustment, so no need to update repaintTop.
repaintLogicalBottom = max(repaintLogicalBottom, afterSideVisualOverflowForLine(lineBox));
@@ -848,7 +848,7 @@
if (delta) {
repaintLogicalTop = min(repaintLogicalTop, beforeSideVisualOverflowForLine(line) + min(delta, 0));
repaintLogicalBottom = max(repaintLogicalBottom, afterSideVisualOverflowForLine(line) + max(delta, 0));
- line->adjustPosition(0, delta);
+ line->adjustBlockDirectionPosition(delta);
}
if (Vector<RenderBox*>* cleanLineFloats = line->floatsPtr()) {
Vector<RenderBox*>::iterator end = cleanLineFloats->end();
@@ -965,7 +965,7 @@
repaintLogicalTop = min(repaintLogicalTop, beforeSideVisualOverflowForLine(curr) + min(paginationDelta, 0));
repaintLogicalBottom = max(repaintLogicalBottom, afterSideVisualOverflowForLine(curr) + max(paginationDelta, 0));
- curr->adjustPosition(0, paginationDelta);
+ curr->adjustBlockDirectionPosition(paginationDelta);
}
}
diff --git a/Source/WebCore/rendering/RenderBox.cpp b/Source/WebCore/rendering/RenderBox.cpp
index 86ba374..9428519 100644
--- a/Source/WebCore/rendering/RenderBox.cpp
+++ b/Source/WebCore/rendering/RenderBox.cpp
@@ -1268,8 +1268,14 @@
if (!isInline() || isReplaced()) {
if (style()->position() != AbsolutePosition && style()->position() != FixedPosition) {
- o->adjustForColumns(offset, IntPoint(point.x() + x(), point.y() + y()));
- offset += locationOffsetIncludingFlipping();
+ if (o->hasColumns()) {
+ IntRect columnRect(frameRect());
+ toRenderBlock(o)->flipForWritingModeIncludingColumns(columnRect);
+ offset += IntSize(columnRect.location().x(), columnRect.location().y());
+ columnRect.move(point.x(), point.y());
+ o->adjustForColumns(offset, columnRect.location());
+ } else
+ offset += locationOffsetIncludingFlipping();
} else
offset += locationOffset();
}
@@ -3328,6 +3334,13 @@
return style()->isHorizontalWritingMode() ? IntPoint(position.x(), height() - position.y()) : IntPoint(width() - position.x(), position.y());
}
+IntPoint RenderBox::flipForWritingModeIncludingColumns(const IntPoint& point) const
+{
+ if (!hasColumns() || !style()->isFlippedBlocksWritingMode())
+ return flipForWritingMode(point);
+ return toRenderBlock(this)->flipForWritingModeIncludingColumns(point);
+}
+
IntSize RenderBox::flipForWritingMode(const IntSize& offset) const
{
if (!style()->isFlippedBlocksWritingMode())
diff --git a/Source/WebCore/rendering/RenderBox.h b/Source/WebCore/rendering/RenderBox.h
index 7bc4910..595947f 100644
--- a/Source/WebCore/rendering/RenderBox.h
+++ b/Source/WebCore/rendering/RenderBox.h
@@ -172,7 +172,7 @@
int clientTop() const { return borderTop(); }
int clientWidth() const;
int clientHeight() const;
- int clientLogicalBottom() const { return style()->isHorizontalWritingMode() ? clientTop() + clientHeight() : clientLeft() + clientWidth(); }
+ int clientLogicalBottom() const { return borderBefore() + (style()->isHorizontalWritingMode() ? clientHeight() : clientWidth()); }
IntRect clientBoxRect() const { return IntRect(clientLeft(), clientTop(), clientWidth(), clientHeight()); }
// scrollWidth/scrollHeight will be the same as clientWidth/clientHeight unless the
@@ -378,6 +378,7 @@
IntPoint flipForWritingMode(const RenderBox* child, const IntPoint&, FlippingAdjustment) const;
int flipForWritingMode(int position) const; // The offset is in the block direction (y for horizontal writing modes, x for vertical writing modes).
IntPoint flipForWritingMode(const IntPoint&) const;
+ IntPoint flipForWritingModeIncludingColumns(const IntPoint&) const;
IntSize flipForWritingMode(const IntSize&) const;
void flipForWritingMode(IntRect&) const;
IntSize locationOffsetIncludingFlipping() const;
diff --git a/Source/WebCore/rendering/RenderFlexibleBox.cpp b/Source/WebCore/rendering/RenderFlexibleBox.cpp
index 15362d6..75be4f6 100644
--- a/Source/WebCore/rendering/RenderFlexibleBox.cpp
+++ b/Source/WebCore/rendering/RenderFlexibleBox.cpp
@@ -280,7 +280,7 @@
updateLayerTransform();
if (view()->layoutState()->pageLogicalHeight())
- setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(y()));
+ setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(logicalTop()));
// Update our scrollbars if we're overflow:auto/scroll/hidden now that we know if
// we overflow or not.
diff --git a/Source/WebCore/rendering/RenderInline.cpp b/Source/WebCore/rendering/RenderInline.cpp
index b5ca8a4..ad0081d 100644
--- a/Source/WebCore/rendering/RenderInline.cpp
+++ b/Source/WebCore/rendering/RenderInline.cpp
@@ -749,7 +749,7 @@
IntSize RenderInline::offsetFromContainer(RenderObject* container, const IntPoint& point) const
{
ASSERT(container == this->container());
-
+
IntSize offset;
if (isRelPositioned())
offset += relativePositionOffset();
@@ -783,6 +783,10 @@
if (!o)
return;
+ IntPoint centerPoint = roundedIntPoint(transformState.mappedPoint());
+ if (o->isBox() && o->style()->isFlippedBlocksWritingMode())
+ transformState.move(toRenderBox(o)->flipForWritingModeIncludingColumns(roundedIntPoint(transformState.mappedPoint())) - centerPoint);
+
IntSize containerOffset = offsetFromContainer(o, roundedIntPoint(transformState.mappedPoint()));
bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D());
diff --git a/Source/WebCore/rendering/RenderLayer.cpp b/Source/WebCore/rendering/RenderLayer.cpp
index c9ec87b..a9b005d 100644
--- a/Source/WebCore/rendering/RenderLayer.cpp
+++ b/Source/WebCore/rendering/RenderLayer.cpp
@@ -2569,13 +2569,18 @@
int layerY = 0;
columnBlock->layer()->convertToLayerCoords(rootLayer, layerX, layerY);
+ bool isHorizontal = columnBlock->style()->isHorizontalWritingMode();
+
ColumnInfo* colInfo = columnBlock->columnInfo();
unsigned colCount = columnBlock->columnCount(colInfo);
- int currYOffset = 0;
+ int currLogicalTopOffset = 0;
for (unsigned i = 0; i < colCount; i++) {
// For each rect, we clip to the rect, and then we adjust our coords.
IntRect colRect = columnBlock->columnRectAt(colInfo, i);
- int currXOffset = colRect.x() - (columnBlock->borderLeft() + columnBlock->paddingLeft());
+ columnBlock->flipForWritingMode(colRect);
+ int logicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - columnBlock->logicalLeftOffsetForContent();
+ IntSize offset = isHorizontal ? IntSize(logicalLeftOffset, currLogicalTopOffset) : IntSize(currLogicalTopOffset, logicalLeftOffset);
+
colRect.move(layerX, layerY);
IntRect localDirtyRect(paintDirtyRect);
@@ -2595,7 +2600,7 @@
if (oldHasTransform)
oldTransform = *childLayer->transform();
TransformationMatrix newTransform(oldTransform);
- newTransform.translateRight(currXOffset, currYOffset);
+ newTransform.translateRight(offset.width(), offset.height());
childLayer->m_transform.set(new TransformationMatrix(newTransform));
childLayer->paintLayer(rootLayer, context, localDirtyRect, paintBehavior, paintingRoot, overlapTestRequests, paintFlags);
@@ -2610,7 +2615,7 @@
int childY = 0;
columnLayers[colIndex - 1]->convertToLayerCoords(rootLayer, childX, childY);
TransformationMatrix transform;
- transform.translateRight(childX + currXOffset, childY + currYOffset);
+ transform.translateRight(childX + offset.width(), childY + offset.height());
// Apply the transform.
context->concatCTM(transform.toAffineTransform());
@@ -2625,7 +2630,11 @@
}
// Move to the next position.
- currYOffset -= colRect.height();
+ int blockDelta = isHorizontal ? colRect.height() : colRect.width();
+ if (columnBlock->style()->isFlippedBlocksWritingMode())
+ currLogicalTopOffset += blockDelta;
+ else
+ currLogicalTopOffset -= blockDelta;
}
}
@@ -3038,21 +3047,35 @@
int colCount = columnBlock->columnCount(colInfo);
// We have to go backwards from the last column to the first.
- int left = columnBlock->borderLeft() + columnBlock->paddingLeft();
- int currYOffset = 0;
+ bool isHorizontal = columnBlock->style()->isHorizontalWritingMode();
+ int logicalLeft = columnBlock->logicalLeftOffsetForContent();
+ int currLogicalTopOffset = 0;
int i;
- for (i = 0; i < colCount; i++)
- currYOffset -= columnBlock->columnRectAt(colInfo, i).height();
+ for (i = 0; i < colCount; i++) {
+ IntRect colRect = columnBlock->columnRectAt(colInfo, i);
+ int blockDelta = (isHorizontal ? colRect.height() : colRect.width());
+ if (columnBlock->style()->isFlippedBlocksWritingMode())
+ currLogicalTopOffset += blockDelta;
+ else
+ currLogicalTopOffset -= blockDelta;
+ }
for (i = colCount - 1; i >= 0; i--) {
// For each rect, we clip to the rect, and then we adjust our coords.
IntRect colRect = columnBlock->columnRectAt(colInfo, i);
- int currXOffset = colRect.x() - left;
- currYOffset += colRect.height();
+ columnBlock->flipForWritingMode(colRect);
+ int currLogicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - logicalLeft;
+ int blockDelta = (isHorizontal ? colRect.height() : colRect.width());
+ if (columnBlock->style()->isFlippedBlocksWritingMode())
+ currLogicalTopOffset -= blockDelta;
+ else
+ currLogicalTopOffset += blockDelta;
colRect.move(layerX, layerY);
IntRect localClipRect(hitTestRect);
localClipRect.intersect(colRect);
+ IntSize offset = isHorizontal ? IntSize(currLogicalLeftOffset, currLogicalTopOffset) : IntSize(currLogicalTopOffset, currLogicalLeftOffset);
+
if (!localClipRect.isEmpty() && localClipRect.intersects(result.rectForPoint(hitTestPoint))) {
RenderLayer* hitLayer = 0;
if (!columnIndex) {
@@ -3062,7 +3085,7 @@
if (oldHasTransform)
oldTransform = *childLayer->transform();
TransformationMatrix newTransform(oldTransform);
- newTransform.translateRight(currXOffset, currYOffset);
+ newTransform.translateRight(offset.width(), offset.height());
childLayer->m_transform.set(new TransformationMatrix(newTransform));
hitLayer = childLayer->hitTestLayer(rootLayer, columnLayers[0], request, result, localClipRect, hitTestPoint, false, transformState, zOffset);
@@ -3075,7 +3098,7 @@
// This involves subtracting out the position of the layer in our current coordinate space.
RenderLayer* nextLayer = columnLayers[columnIndex - 1];
RefPtr<HitTestingTransformState> newTransformState = nextLayer->createLocalTransformState(rootLayer, nextLayer, localClipRect, hitTestPoint, transformState);
- newTransformState->translate(currXOffset, currYOffset, HitTestingTransformState::AccumulateTransform);
+ newTransformState->translate(offset.width(), offset.height(), HitTestingTransformState::AccumulateTransform);
IntPoint localPoint = roundedIntPoint(newTransformState->mappedPoint());
IntRect localHitTestRect = newTransformState->mappedQuad().enclosingBoundingBox();
newTransformState->flatten();
@@ -3345,19 +3368,9 @@
// as part of our bounding box. We do this because we are the responsible layer for both hit testing and painting those
// floats.
IntRect result;
- if (renderer()->isRenderInline()) {
- // Go from our first line box to our last line box.
- RenderInline* inlineFlow = toRenderInline(renderer());
- InlineFlowBox* firstBox = inlineFlow->firstLineBox();
- if (!firstBox)
- return result;
- int top = firstBox->topVisualOverflow();
- int bottom = inlineFlow->lastLineBox()->bottomVisualOverflow();
- int left = firstBox->x();
- for (InlineFlowBox* curr = firstBox->nextLineBox(); curr; curr = curr->nextLineBox())
- left = min(left, curr->x());
- result = IntRect(left, top, width(), bottom - top);
- } else if (renderer()->isTableRow()) {
+ if (renderer()->isRenderInline())
+ result = toRenderInline(renderer())->linesVisualOverflowBoundingBox();
+ else if (renderer()->isTableRow()) {
// Our bounding box is just the union of all of our cells' border/overflow rects.
for (RenderObject* child = renderer()->firstChild(); child; child = child->nextSibling()) {
if (child->isTableCell()) {
@@ -3393,7 +3406,10 @@
IntRect RenderLayer::boundingBox(const RenderLayer* ancestorLayer) const
{
IntRect result = localBoundingBox();
-
+ if (renderer()->isBox())
+ renderBox()->flipForWritingMode(result);
+ else
+ renderer()->containingBlock()->flipForWritingMode(result);
int deltaX = 0, deltaY = 0;
convertToLayerCoords(ancestorLayer, deltaX, deltaY);
result.move(deltaX, deltaY);
diff --git a/Source/WebCore/rendering/RenderObject.cpp b/Source/WebCore/rendering/RenderObject.cpp
index cfaa65d..1729236 100644
--- a/Source/WebCore/rendering/RenderObject.cpp
+++ b/Source/WebCore/rendering/RenderObject.cpp
@@ -1947,6 +1947,10 @@
if (!o)
return;
+ IntPoint centerPoint = roundedIntPoint(transformState.mappedPoint());
+ if (o->isBox() && o->style()->isFlippedBlocksWritingMode())
+ transformState.move(toRenderBox(o)->flipForWritingModeIncludingColumns(roundedIntPoint(transformState.mappedPoint())) - centerPoint);
+
IntSize columnOffset;
o->adjustForColumns(columnOffset, roundedIntPoint(transformState.mappedPoint()));
if (!columnOffset.isZero())
diff --git a/Source/WebCore/rendering/RenderTable.cpp b/Source/WebCore/rendering/RenderTable.cpp
index 3534d9a..1b54440 100644
--- a/Source/WebCore/rendering/RenderTable.cpp
+++ b/Source/WebCore/rendering/RenderTable.cpp
@@ -394,7 +394,7 @@
statePusher.pop();
if (view()->layoutState()->pageLogicalHeight())
- setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(y()));
+ setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(logicalTop()));
bool didFullRepaint = repainter.repaintAfterLayout();
// Repaint with our new bounds if they are different from our old bounds.
diff --git a/Source/WebCore/rendering/RenderTableRow.cpp b/Source/WebCore/rendering/RenderTableRow.cpp
index 595e156..7300c19 100644
--- a/Source/WebCore/rendering/RenderTableRow.cpp
+++ b/Source/WebCore/rendering/RenderTableRow.cpp
@@ -125,7 +125,7 @@
for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
if (child->isTableCell()) {
RenderTableCell* cell = toRenderTableCell(child);
- if (!cell->needsLayout() && paginated && view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(cell->y()) != cell->pageLogicalOffset())
+ if (!cell->needsLayout() && paginated && view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(cell->logicalTop()) != cell->pageLogicalOffset())
cell->setChildNeedsLayout(true, false);
if (child->needsLayout()) {
diff --git a/Source/WebCore/rendering/RenderTableSection.cpp b/Source/WebCore/rendering/RenderTableSection.cpp
index fa557bc..81b5fee 100644
--- a/Source/WebCore/rendering/RenderTableSection.cpp
+++ b/Source/WebCore/rendering/RenderTableSection.cpp
@@ -617,7 +617,7 @@
if (intrinsicPaddingBefore != oldIntrinsicPaddingBefore || intrinsicPaddingAfter != oldIntrinsicPaddingAfter)
cell->setNeedsLayout(true, false);
- if (!cell->needsLayout() && view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(cell->y()) != cell->pageLogicalOffset())
+ if (!cell->needsLayout() && view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(cell->logicalTop()) != cell->pageLogicalOffset())
cell->setChildNeedsLayout(true, false);
cell->layoutIfNeeded();
diff --git a/Source/WebCore/rendering/RenderText.cpp b/Source/WebCore/rendering/RenderText.cpp
index 58c41ab..3f1dad5 100644
--- a/Source/WebCore/rendering/RenderText.cpp
+++ b/Source/WebCore/rendering/RenderText.cpp
@@ -345,8 +345,12 @@
// Shorten the width of this text box if it ends in an ellipsis.
IntRect ellipsisRect = (option == ClipToEllipsis) ? ellipsisRectForBox(box, 0, textLength()) : IntRect();
- if (!ellipsisRect.isEmpty())
- boundaries.setWidth(ellipsisRect.right() - boundaries.x());
+ if (!ellipsisRect.isEmpty()) {
+ if (style()->isHorizontalWritingMode())
+ boundaries.setWidth(ellipsisRect.right() - boundaries.x());
+ else
+ boundaries.setHeight(ellipsisRect.bottom() - boundaries.y());
+ }
quads.append(localToAbsoluteQuad(FloatRect(boundaries)));
}
}
@@ -374,8 +378,13 @@
IntRect r(box->calculateBoundaries());
if (useSelectionHeight) {
IntRect selectionRect = box->selectionRect(0, 0, start, end);
- r.setHeight(selectionRect.height());
- r.setY(selectionRect.y());
+ if (box->isHorizontal()) {
+ r.setHeight(selectionRect.height());
+ r.setY(selectionRect.y());
+ } else {
+ r.setWidth(selectionRect.width());
+ r.setX(selectionRect.x());
+ }
}
quads.append(localToAbsoluteQuad(FloatRect(r)));
} else {
@@ -384,8 +393,13 @@
if (r.height()) {
if (!useSelectionHeight) {
// change the height and y position because selectionRect uses selection-specific values
- r.setHeight(box->logicalHeight());
- r.setY(box->y());
+ if (box->isHorizontal()) {
+ r.setHeight(box->logicalHeight());
+ r.setY(box->y());
+ } else {
+ r.setWidth(box->logicalHeight());
+ r.setX(box->x());
+ }
}
quads.append(localToAbsoluteQuad(FloatRect(r)));
}