diff options
Diffstat (limited to 'Source/WebCore/rendering/RenderBlock.cpp')
-rw-r--r-- | Source/WebCore/rendering/RenderBlock.cpp | 530 |
1 files changed, 316 insertions, 214 deletions
diff --git a/Source/WebCore/rendering/RenderBlock.cpp b/Source/WebCore/rendering/RenderBlock.cpp index 7275461..87aa630 100644 --- a/Source/WebCore/rendering/RenderBlock.cpp +++ b/Source/WebCore/rendering/RenderBlock.cpp @@ -36,6 +36,7 @@ #include "HitTestResult.h" #include "InlineTextBox.h" #include "PaintInfo.h" +#include "RenderCombineText.h" #include "RenderFlexibleBox.h" #include "RenderImage.h" #include "RenderInline.h" @@ -1267,7 +1268,7 @@ void RenderBlock::layoutBlock(bool relayoutChildren, int pageLogicalHeight) statePusher.pop(); if (view()->layoutState()->m_pageLogicalHeight) - setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(y())); + setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(logicalTop())); updateLayerTransform(); @@ -1330,10 +1331,18 @@ void RenderBlock::addOverflowFromChildren() 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.maxX()) : 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.maxY()) : 0; + int overflowWidth = borderBefore() + paddingBefore() + colInfo->columnHeight(); + addLayoutOverflow(IntRect(0, overflowTop, overflowWidth, overflowBottom - overflowTop)); + } } } } @@ -1376,14 +1385,13 @@ void RenderBlock::addOverflowFromBlockChildren() void RenderBlock::addOverflowFromFloats() { - IntRect result; if (!m_floatingObjects) return; FloatingObject* r; 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(xPositionForFloatIncludingMargin(r), yPositionForFloatIncludingMargin(r))); } return; } @@ -1649,7 +1657,7 @@ int RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo) 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; @@ -1719,7 +1727,7 @@ int RenderBlock::estimateLogicalTopPosition(RenderBox* child, const MarginInfo& // 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); @@ -2062,7 +2070,7 @@ void RenderBlock::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, int 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); } @@ -2166,7 +2174,7 @@ void RenderBlock::markForPaginationRelayoutIfNeeded() 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); } @@ -2243,32 +2251,34 @@ void RenderBlock::paintColumnRules(PaintInfo& paintInfo, int tx, int ty) // 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; } } @@ -2276,16 +2286,17 @@ void RenderBlock::paintColumnContents(PaintInfo& paintInfo, int tx, int ty, bool { // 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); @@ -2296,10 +2307,10 @@ void RenderBlock::paintColumnContents(PaintInfo& paintInfo, int tx, int ty, bool // 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 @@ -2307,14 +2318,12 @@ void RenderBlock::paintColumnContents(PaintInfo& paintInfo, int tx, int ty, bool 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; } } @@ -2352,14 +2361,14 @@ void RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty) bool checkBeforeAlways = !childrenInline() && (usePrintRect && child->style()->pageBreakBefore() == PBALWAYS); if (checkBeforeAlways && (ty + child->y()) > paintInfo.rect.y() - && (ty + child->y()) < paintInfo.rect.bottom()) { + && (ty + child->y()) < paintInfo.rect.maxY()) { view()->setBestTruncatedAt(ty + child->y(), this, true); return; } if (!child->isFloating() && child->isReplaced() && usePrintRect && child->height() <= renderView->printRect().height()) { // Paginate block-level replaced elements. - if (ty + child->y() + child->height() > renderView->printRect().bottom()) { + if (ty + child->y() + child->height() > renderView->printRect().maxY()) { if (ty + child->y() < renderView->truncatedAt()) renderView->setBestTruncatedAt(ty + child->y(), child); // If we were able to truncate, don't paint. @@ -2376,7 +2385,7 @@ void RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty) bool checkAfterAlways = !childrenInline() && (usePrintRect && child->style()->pageBreakAfter() == PBALWAYS); if (checkAfterAlways && (ty + child->y() + child->height()) > paintInfo.rect.y() - && (ty + child->y() + child->height()) < paintInfo.rect.bottom()) { + && (ty + child->y() + child->height()) < paintInfo.rect.maxY()) { view()->setBestTruncatedAt(ty + child->y() + child->height() + max(0, child->collapsedMarginAfter()), this, true); return; } @@ -2491,6 +2500,19 @@ void RenderBlock::paintObject(PaintInfo& paintInfo, int tx, int ty) } } +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 * yPositionForFloatIncludingMargin(child)); + return IntPoint(point.x() + width() - child->width() - 2 * xPositionForFloatIncludingMargin(child), point.y()); +} + void RenderBlock::paintFloats(PaintInfo& paintInfo, int tx, int ty, bool preservePhase) { if (!m_floatingObjects) @@ -2503,7 +2525,7 @@ void RenderBlock::paintFloats(PaintInfo& paintInfo, int tx, int ty, bool preserv 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 + xPositionForFloatIncludingMargin(r) - r->m_renderer->x(), ty + yPositionForFloatIncludingMargin(r) - r->m_renderer->y())); r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y()); if (!preservePhase) { currentPaintInfo.phase = PaintPhaseChildBlockBackgrounds; @@ -2529,7 +2551,7 @@ void RenderBlock::paintEllipsisBoxes(PaintInfo& paintInfo, int tx, int ty) // intersect. int yPos = ty + firstLineBox()->y(); int h = lastLineBox()->y() + lastLineBox()->logicalHeight() - firstLineBox()->y(); - if (yPos >= paintInfo.rect.bottom() || yPos + h <= paintInfo.rect.y()) + if (yPos >= paintInfo.rect.maxY() || yPos + h <= paintInfo.rect.y()) return; // See if our boxes intersect with the dirty rect. If so, then we paint @@ -2538,7 +2560,7 @@ void RenderBlock::paintEllipsisBoxes(PaintInfo& paintInfo, int tx, int ty) for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) { yPos = ty + curr->y(); h = curr->logicalHeight(); - if (curr->ellipsisBox() && yPos < paintInfo.rect.bottom() && yPos + h > paintInfo.rect.y()) + if (curr->ellipsisBox() && yPos < paintInfo.rect.maxY() && yPos + h > paintInfo.rect.y()) curr->paintEllipsisBox(paintInfo, tx, ty); } } @@ -2737,8 +2759,8 @@ GapRects RenderBlock::selectionGaps(RenderBlock* rootBlock, const IntPoint& root 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() + xPositionForFloatIncludingMargin(r), + offsetFromRootBlock.height() + yPositionForFloatIncludingMargin(r), r->m_renderer->width(), r->m_renderer->height()); rootBlock->flipForWritingMode(floatBox); floatBox.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y()); @@ -2808,8 +2830,8 @@ GapRects RenderBlock::inlineSelectionGaps(RenderBlock* rootBlock, const IntPoint IntRect logicalRect(curr->logicalLeft(), selTop, curr->logicalWidth(), selTop + selHeight); logicalRect.move(style()->isHorizontalWritingMode() ? offsetFromRootBlock : IntSize(offsetFromRootBlock.height(), offsetFromRootBlock.width())); IntRect physicalRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, logicalRect); - if (!paintInfo || (style()->isHorizontalWritingMode() && physicalRect.y() < paintInfo->rect.bottom() && physicalRect.bottom() > paintInfo->rect.y()) - || (!style()->isHorizontalWritingMode() && physicalRect.x() < paintInfo->rect.right() && physicalRect.right() > paintInfo->rect.x())) + if (!paintInfo || (style()->isHorizontalWritingMode() && physicalRect.y() < paintInfo->rect.maxY() && physicalRect.maxY() > paintInfo->rect.y()) + || (!style()->isHorizontalWritingMode() && physicalRect.x() < paintInfo->rect.maxX() && physicalRect.maxX() > paintInfo->rect.x())) result.unite(curr->lineSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, selTop, selHeight, paintInfo)); lastSelectedLine = curr; @@ -3098,7 +3120,7 @@ void RenderBlock::removeFloatingObject(RenderBox* o) // Special-case zero- and less-than-zero-height floats: those don't touch // the line that they're on, but it still needs to be dirtied. This is // accomplished by pretending they have a height of 1. - logicalBottom = max(logicalBottom, logicalTop + 1); + logicalBottom = max(logicalBottom, logicalTop == numeric_limits<int>::max() ? logicalTop : logicalTop + 1); markLinesDirtyInBlockRange(0, logicalBottom); } m_floatingObjects->removeRef(it.current()); @@ -3108,13 +3130,13 @@ void RenderBlock::removeFloatingObject(RenderBox* o) } } -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(); } @@ -3460,7 +3482,7 @@ void RenderBlock::markLinesDirtyInBlockRange(int logicalTop, int logicalBottom, RootInlineBox* lowestDirtyLine = lastRootBox(); RootInlineBox* afterLowest = lowestDirtyLine; - while (lowestDirtyLine && lowestDirtyLine->blockLogicalHeight() >= logicalBottom) { + while (lowestDirtyLine && lowestDirtyLine->blockLogicalHeight() >= logicalBottom && logicalBottom < numeric_limits<int>::max()) { afterLowest = lowestDirtyLine; lowestDirtyLine = lowestDirtyLine->prevRootBox(); } @@ -3591,7 +3613,7 @@ int RenderBlock::addOverhangingFloats(RenderBlock* child, int logicalLeftOffset, if (!containsFloat(r->m_renderer)) { int leftOffset = style()->isHorizontalWritingMode() ? logicalLeftOffset : logicalTopOffset; int topOffset = style()->isHorizontalWritingMode() ? logicalTopOffset : logicalLeftOffset; - FloatingObject* floatingObj = new FloatingObject(r->type(), IntRect(r->left() - leftOffset, r->top() - topOffset, r->width(), r->height())); + FloatingObject* floatingObj = new FloatingObject(r->type(), IntRect(r->x() - leftOffset, r->y() - topOffset, r->width(), r->height())); floatingObj->m_renderer = r->m_renderer; // The nearest enclosing layer always paints the float (so that zindex and stacking @@ -3626,7 +3648,7 @@ int RenderBlock::addOverhangingFloats(RenderBlock* child, int logicalLeftOffset, // 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(xPositionForFloatIncludingMargin(r), yPositionForFloatIncludingMargin(r))); } } return lowestFloatLogicalBottom; @@ -3658,7 +3680,7 @@ void RenderBlock::addIntrudingFloats(RenderBlock* prev, int logicalLeftOffset, i int leftOffset = style()->isHorizontalWritingMode() ? logicalLeftOffset : logicalTopOffset; int topOffset = style()->isHorizontalWritingMode() ? logicalTopOffset : logicalLeftOffset; - FloatingObject* floatingObj = new FloatingObject(r->type(), IntRect(r->left() - leftOffset, r->top() - topOffset, r->width(), r->height())); + FloatingObject* floatingObj = new FloatingObject(r->type(), IntRect(r->x() - leftOffset, r->y() - topOffset, r->width(), r->height())); // Applying the child's margin makes no sense in the case where the child was passed in. // since this margin was added already through the modification of the |logicalLeftOffset| variable @@ -3667,9 +3689,9 @@ void RenderBlock::addIntrudingFloats(RenderBlock* prev, int logicalLeftOffset, i // will get applied twice. if (prev != parent()) { if (style()->isHorizontalWritingMode()) - floatingObj->setLeft(floatingObj->left() + prev->marginLeft()); + floatingObj->setX(floatingObj->x() + prev->marginLeft()); else - floatingObj->setTop(floatingObj->top() + prev->marginTop()); + floatingObj->setY(floatingObj->y() + prev->marginTop()); } floatingObj->m_shouldPaint = false; // We are not in the direct inheritance chain for this float. We will never paint it. @@ -3864,9 +3886,9 @@ bool RenderBlock::hitTestFloats(const HitTestRequest& request, HitTestResult& re 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 = xPositionForFloatIncludingMargin(floatingObject) - floatingObject->m_renderer->x(); + int yOffset = yPositionForFloatIncludingMargin(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; @@ -3884,23 +3906,36 @@ bool RenderBlock::hitTestColumns(const HitTestRequest& request, HitTestResult& r 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 @@ -3947,25 +3982,6 @@ Position RenderBlock::positionForBox(InlineBox *box, bool start) const return Position(box->renderer()->node(), start ? textBox->start() : textBox->start() + textBox->len()); } -Position RenderBlock::positionForRenderer(RenderObject* renderer, bool start) const -{ - if (!renderer) - return Position(node(), 0); - - Node* n = renderer->node() ? renderer->node() : node(); - if (!n) - return Position(); - - ASSERT(renderer == n->renderer()); - - int offset = start ? renderer->caretMinOffset() : renderer->caretMaxOffset(); - - // FIXME: This was a runtime check that seemingly couldn't fail; changed it to an assertion for now. - ASSERT(!n->isCharacterDataNode() || renderer->isText()); - - return Position(n, offset); -} - // FIXME: This function should go on RenderObject as an instance method. Then // all cases in which positionForPoint recurs could call this instead to // prevent crossing editable boundaries. This would require many tests. @@ -4139,7 +4155,7 @@ void RenderBlock::calcColumnWidth() { // 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())) { @@ -4214,7 +4230,7 @@ void RenderBlock::setDesiredColumnCountAndWidth(int count, int width) int RenderBlock::desiredColumnWidth() const { if (!hasColumns()) - return contentWidth(); + return contentLogicalWidth(); return gColumnInfoMap->get(this)->desiredColumnWidth(); } @@ -4243,14 +4259,17 @@ IntRect RenderBlock::columnRectAt(ColumnInfo* colInfo, unsigned index) const 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) @@ -4270,12 +4289,12 @@ bool RenderBlock::layoutColumns(bool hasSpecifiedPageLogicalHeight, int pageLogi // 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) { @@ -4287,10 +4306,10 @@ bool RenderBlock::layoutColumns(bool hasSpecifiedPageLogicalHeight, int pageLogi } 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(); } @@ -4309,34 +4328,57 @@ void RenderBlock::adjustPointToColumnContents(IntPoint& point) const // 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 (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 (style()->isHorizontalWritingMode()) { + IntRect gapAndColumnRect(colRect.x() - halfColGap, colRect.y(), colRect.width() + colGap, colRect.height()); + if (point.x() >= gapAndColumnRect.x() && point.x() < gapAndColumnRect.maxX()) { + // 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.maxY()) { + 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.maxY()) { + // 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.maxX()) { + 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(); } } @@ -4356,27 +4398,56 @@ void RenderBlock::adjustRectForColumns(IntRect& r) const 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.maxY()); + else + rect.setX(expandedLogicalHeight - rect.maxX()); +} + void RenderBlock::adjustForColumns(IntSize& offset, const IntPoint& point) const { if (!hasColumns()) @@ -4384,18 +4455,34 @@ void RenderBlock::adjustForColumns(IntSize& offset, const IntPoint& point) const ColumnInfo* colInfo = columnInfo(); - int left = borderLeft() + paddingLeft(); - int yOffset = 0; + int logicalLeft = logicalLeftOffsetForContent(); size_t colCount = columnCount(colInfo); + int colLogicalWidth = colInfo->desiredColumnWidth(); + int colLogicalHeight = colInfo->columnHeight(); + 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; - } + // 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; - yOffset += columnRect.height(); + // 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.maxY()) { + offset.expand(columnRectAt(colInfo, i).x() - logicalLeft, -logicalOffset); + return; + } + } else { + if (point.x() >= sliceRect.x() && point.x() < sliceRect.maxX()) { + offset.expand(-logicalOffset, columnRectAt(colInfo, i).y() - logicalLeft); + return; + } + } } } @@ -4535,16 +4622,13 @@ static int getBPMWidth(int childValue, Length cssUnit) 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, @@ -4567,7 +4651,7 @@ void RenderBlock::computeInlinePreferredLogicalWidths() 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. @@ -4577,7 +4661,7 @@ void RenderBlock::computeInlinePreferredLogicalWidths() // 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(); @@ -4645,12 +4729,12 @@ void RenderBlock::computeInlinePreferredLogicalWidths() } 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; } @@ -4689,8 +4773,8 @@ void RenderBlock::computeInlinePreferredLogicalWidths() if (!addedTextIndent) { addedTextIndent = true; ti = style()->textIndent().calcMinValue(cw); - childMin+=ti; - childMax+=ti; + childMin += ti; + childMax += ti; } // Add our width to the max. @@ -4725,6 +4809,9 @@ void RenderBlock::computeInlinePreferredLogicalWidths() continue; } + if (t->style()->hasTextCombine()) + toRenderCombineText(t)->combineText(); + // Determine if we have a breakable character. Pass in // whether or not we should ignore any spaces at the front // of the string. If those are going to be stripped out, @@ -4852,14 +4939,16 @@ void RenderBlock::computeBlockPreferredLogicalWidths() // 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); @@ -4875,8 +4964,11 @@ void RenderBlock::computeBlockPreferredLogicalWidths() // 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); } @@ -4906,7 +4998,7 @@ void RenderBlock::computeBlockPreferredLogicalWidths() // 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()) @@ -4992,8 +5084,8 @@ int RenderBlock::baselinePosition(FontBaseline baselineType, bool firstLine, Lin return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode); } - const Font& f = style(firstLine)->font(); - return f.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - f.height()) / 2; + const FontMetrics& fontMetrics = style(firstLine)->fontMetrics(); + return fontMetrics.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - fontMetrics.height()) / 2; } int RenderBlock::firstLineBoxBaseline() const @@ -5003,7 +5095,7 @@ int RenderBlock::firstLineBoxBaseline() const if (childrenInline()) { if (firstLineBox()) - return firstLineBox()->logicalTop() + style(true)->font().ascent(firstRootBox()->baselineType()); + return firstLineBox()->logicalTop() + style(true)->fontMetrics().ascent(firstRootBox()->baselineType()); else return -1; } @@ -5029,11 +5121,13 @@ int RenderBlock::lastLineBoxBaseline() const if (childrenInline()) { if (!firstLineBox() && hasLineIfEmpty()) { - const Font& f = firstLineStyle()->font(); - return f.ascent() + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - f.height()) / 2 + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight()); + const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics(); + return fontMetrics.ascent() + + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2 + + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight()); } if (lastLineBox()) - return lastLineBox()->logicalTop() + style(lastLineBox() == firstLineBox())->font().ascent(lastRootBox()->baselineType()); + return lastLineBox()->logicalTop() + style(lastLineBox() == firstLineBox())->fontMetrics().ascent(lastRootBox()->baselineType()); return -1; } else { bool haveNormalFlowChild = false; @@ -5046,8 +5140,10 @@ int RenderBlock::lastLineBoxBaseline() const } } if (!haveNormalFlowChild && hasLineIfEmpty()) { - const Font& f = firstLineStyle()->font(); - return f.ascent() + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - f.height()) / 2 + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight()); + const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics(); + return fontMetrics.ascent() + + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2 + + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight()); } } @@ -5400,7 +5496,7 @@ void RenderBlock::adjustForBorderFit(int x, int& left, int& right) const 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 = xPositionForFloatIncludingMargin(r) - r->m_renderer->x(); int floatRight = floatLeft + r->m_renderer->width(); left = min(left, floatLeft); right = max(right, floatRight); @@ -5755,16 +5851,18 @@ RenderBlock* RenderBlock::createAnonymousColumnSpanBlock() const 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) @@ -5781,7 +5879,7 @@ static bool inNormalFlow(RenderBox* child) 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(); @@ -5789,13 +5887,13 @@ int RenderBlock::applyBeforeBreak(RenderBox* child, int yPos) 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(); @@ -5804,28 +5902,30 @@ int RenderBlock::applyAfterBreak(RenderBox* child, int yPos, MarginInfo& marginI 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) @@ -5848,22 +5948,24 @@ void RenderBlock::adjustLinePositionForPagination(RootInlineBox* lineBox, int& d // 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); } } } |