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)));
             }