OSDN Git Service

Merge WebKit at r71558: Initial merge by git.
[android-x86/external-webkit.git] / WebCore / rendering / RenderInline.cpp
index e91822e..1a792e7 100644 (file)
@@ -31,6 +31,7 @@
 #include "RenderArena.h"
 #include "RenderBlock.h"
 #include "RenderLayer.h"
+#include "RenderTheme.h"
 #include "RenderView.h"
 #include "TransformState.h"
 #include "VisiblePosition.h"
@@ -413,7 +414,7 @@ void RenderInline::absoluteRects(Vector<IntRect>& rects, int tx, int ty)
 {
     if (InlineFlowBox* curr = firstLineBox()) {
         for (; curr; curr = curr->nextLineBox())
-            rects.append(IntRect(tx + curr->x(), ty + curr->y(), curr->width(), curr->height()));
+            rects.append(IntRect(tx + curr->x(), ty + curr->y(), curr->logicalWidth(), curr->logicalHeight()));
     } else
         rects.append(IntRect(tx, ty, 0, 0));
 
@@ -432,7 +433,7 @@ void RenderInline::absoluteQuads(Vector<FloatQuad>& quads)
 {
     if (InlineFlowBox* curr = firstLineBox()) {
         for (; curr; curr = curr->nextLineBox()) {
-            FloatRect localRect(curr->x(), curr->y(), curr->width(), curr->height());
+            FloatRect localRect(curr->x(), curr->y(), curr->logicalWidth(), curr->logicalHeight());
             quads.append(localToAbsoluteQuad(localRect));
         }
     } else
@@ -458,28 +459,53 @@ int RenderInline::offsetTop() const
     return y;
 }
 
-int RenderInline::marginLeft() const
+static int computeMargin(const RenderInline* renderer, const Length& margin)
 {
-    Length margin = style()->marginLeft();
     if (margin.isAuto())
         return 0;
     if (margin.isFixed())
         return margin.value();
     if (margin.isPercent())
-        return margin.calcMinValue(max(0, containingBlock()->availableWidth()));
+        return margin.calcMinValue(max(0, renderer->containingBlock()->availableLogicalWidth()));
     return 0;
 }
 
+int RenderInline::marginLeft() const
+{
+    if (!style()->isHorizontalWritingMode())
+        return 0;
+    return computeMargin(this, style()->marginLeft());
+}
+
 int RenderInline::marginRight() const
 {
-    Length margin = style()->marginRight();
-    if (margin.isAuto())
+    if (!style()->isHorizontalWritingMode())
         return 0;
-    if (margin.isFixed())
-        return margin.value();
-    if (margin.isPercent())
-        return margin.calcMinValue(max(0, containingBlock()->availableWidth()));
-    return 0;
+    return computeMargin(this, style()->marginRight());
+}
+
+int RenderInline::marginTop() const
+{
+    if (style()->isHorizontalWritingMode())
+        return 0;
+    return computeMargin(this, style()->marginTop());
+}
+
+int RenderInline::marginBottom() const
+{
+    if (style()->isHorizontalWritingMode())
+        return 0;
+    return computeMargin(this, style()->marginBottom());
+}
+
+int RenderInline::marginStart() const
+{
+    return computeMargin(this, style()->marginStart());
+}
+
+int RenderInline::marginEnd() const
+{
+    return computeMargin(this, style()->marginEnd());
 }
 
 const char* RenderInline::renderName() const
@@ -533,18 +559,22 @@ IntRect RenderInline::linesBoundingBox() const
     ASSERT(!firstLineBox() == !lastLineBox());  // Either both are null or both exist.
     if (firstLineBox() && lastLineBox()) {
         // Return the width of the minimal left side and the maximal right side.
-        int leftSide = 0;
-        int rightSide = 0;
+        int logicalLeftSide = 0;
+        int logicalRightSide = 0;
         for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
-            if (curr == firstLineBox() || curr->x() < leftSide)
-                leftSide = curr->x();
-            if (curr == firstLineBox() || curr->x() + curr->width() > rightSide)
-                rightSide = curr->x() + curr->width();
+            if (curr == firstLineBox() || curr->logicalLeft() < logicalLeftSide)
+                logicalLeftSide = curr->logicalLeft();
+            if (curr == firstLineBox() || curr->logicalRight() > logicalRightSide)
+                logicalRightSide = curr->logicalRight();
         }
-        result.setWidth(rightSide - leftSide);
-        result.setX(leftSide);
-        result.setHeight(lastLineBox()->y() + lastLineBox()->height() - firstLineBox()->y());
-        result.setY(firstLineBox()->y());
+        
+        bool isHorizontal = style()->isHorizontalWritingMode();
+        
+        int x = isHorizontal ? logicalLeftSide : firstLineBox()->x();
+        int y = isHorizontal ? firstLineBox()->y() : logicalLeftSide;
+        int width = isHorizontal ? logicalRightSide - logicalLeftSide : lastLineBox()->logicalBottom() - x;
+        int height = isHorizontal ? lastLineBox()->logicalBottom() - y : logicalRightSide - logicalLeftSide;
+        result = IntRect(x, y, width, height);
     }
 
     return result;
@@ -556,15 +586,20 @@ IntRect RenderInline::linesVisibleOverflowBoundingBox() const
         return IntRect();
 
     // Return the width of the minimal left side and the maximal right side.
-    int leftSide = numeric_limits<int>::max();
-    int rightSide = numeric_limits<int>::min();
+    int logicalLeftSide = numeric_limits<int>::max();
+    int logicalRightSide = numeric_limits<int>::min();
     for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
-        leftSide = min(leftSide, curr->leftVisibleOverflow());
-        rightSide = max(rightSide, curr->rightVisibleOverflow());
+        logicalLeftSide = min(logicalLeftSide, curr->logicalLeftVisibleOverflow());
+        logicalRightSide = max(logicalRightSide, curr->logicalRightVisibleOverflow());
     }
 
-    return IntRect(leftSide, firstLineBox()->topVisibleOverflow(), rightSide - leftSide,
-        lastLineBox()->bottomVisibleOverflow() - firstLineBox()->topVisibleOverflow());
+    bool isHorizontal = style()->isHorizontalWritingMode();
+        
+    int x = isHorizontal ? logicalLeftSide : firstLineBox()->leftVisibleOverflow();
+    int y = isHorizontal ? firstLineBox()->topVisibleOverflow() : logicalLeftSide;
+    int width = isHorizontal ? logicalRightSide - logicalLeftSide : lastLineBox()->rightVisibleOverflow() - firstLineBox()->leftVisibleOverflow();
+    int height = isHorizontal ? lastLineBox()->bottomVisibleOverflow() - firstLineBox()->topVisibleOverflow() : logicalRightSide - logicalLeftSide;
+    return IntRect(x, y, width, height);
 }
 
 IntRect RenderInline::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer)
@@ -593,6 +628,8 @@ IntRect RenderInline::clippedOverflowRectForRepaint(RenderBoxModelObject* repain
     }
 
     IntRect r(-ow + left, -ow + top, boundingBox.width() + ow * 2, boundingBox.height() + ow * 2);
+    cb->flipForWritingMode(r);
+
     if (cb->hasColumns())
         cb->adjustRectForColumns(r);
 
@@ -647,7 +684,7 @@ void RenderInline::computeRectForRepaint(RenderBoxModelObject* repaintContainer,
             LayoutState* layoutState = v->layoutState();
             if (style()->position() == RelativePosition && layer())
                 rect.move(layer()->relativePositionOffset());
-            rect.move(layoutState->m_offset);
+            rect.move(layoutState->m_paintOffset);
             if (layoutState->m_clipped)
                 rect.intersect(layoutState->m_clipRect);
             return;
@@ -734,7 +771,7 @@ void RenderInline::mapLocalToContainer(RenderBoxModelObject* repaintContainer, b
     if (RenderView *v = view()) {
         if (v->layoutStateEnabled() && !repaintContainer) {
             LayoutState* layoutState = v->layoutState();
-            IntSize offset = layoutState->m_offset;
+            IntSize offset = layoutState->m_paintOffset;
             if (style()->position() == RelativePosition && layer())
                 offset += layer()->relativePositionOffset();
             transformState.move(offset);
@@ -853,7 +890,7 @@ InlineFlowBox* RenderInline::createAndAppendInlineFlowBox()
     return flowBox;
 }
 
-int RenderInline::lineHeight(bool firstLine, bool /*isRootLineBox*/) const
+int RenderInline::lineHeight(bool firstLine, LineDirectionMode /*direction*/, LinePositionMode /*linePositionMode*/) const
 {
     if (firstLine && document()->usesFirstLineRules()) {
         RenderStyle* s = style(firstLine);
@@ -867,6 +904,12 @@ int RenderInline::lineHeight(bool firstLine, bool /*isRootLineBox*/) const
     return m_lineHeight;
 }
 
+int RenderInline::baselinePosition(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
+{
+    const Font& f = style(firstLine)->font();
+    return f.ascent() + (lineHeight(firstLine, direction, linePositionMode) - f.height()) / 2;
+}
+
 int RenderInline::verticalPositionFromCache(bool firstLine) const
 {
     if (firstLine) // We're only really a first-line style if the document actually uses first-line rules.
@@ -931,8 +974,8 @@ void RenderInline::addFocusRingRects(Vector<IntRect>& rects, int tx, int ty)
     for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
         RootInlineBox* root = curr->root();
         int top = max(root->lineTop(), curr->y());
-        int bottom = min(root->lineBottom(), curr->y() + curr->height());
-        IntRect rect(tx + curr->x(), ty + top, curr->width(), bottom - top);
+        int bottom = min(root->lineBottom(), curr->y() + curr->logicalHeight());
+        IntRect rect(tx + curr->x(), ty + top, curr->logicalWidth(), bottom - top);
         if (!rect.isEmpty())
             rects.append(rect);
     }
@@ -968,15 +1011,10 @@ void RenderInline::paintOutline(GraphicsContext* graphicsContext, int tx, int ty
     
     RenderStyle* styleToUse = style();
     if (styleToUse->outlineStyleIsAuto() || hasOutlineAnnotation()) {
-        int ow = styleToUse->outlineWidth();
-        Color oc = styleToUse->visitedDependentColor(CSSPropertyOutlineColor);
-
-        Vector<IntRect> focusRingRects;
-        addFocusRingRects(focusRingRects, tx, ty);
-        if (styleToUse->outlineStyleIsAuto())
-            graphicsContext->drawFocusRing(focusRingRects, ow, styleToUse->outlineOffset(), oc);
-        else
-            addPDFURLRect(graphicsContext, unionRect(focusRingRects));
+        if (!theme()->supportsFocusRing(styleToUse)) {
+            // Only paint the focus ring by hand if the theme isn't able to draw the focus ring.
+            paintFocusRing(graphicsContext, tx, ty, styleToUse);
+        }
     }
 
     if (styleToUse->outlineStyleIsAuto() || styleToUse->outlineStyle() == BNONE)
@@ -988,8 +1026,8 @@ void RenderInline::paintOutline(GraphicsContext* graphicsContext, int tx, int ty
     for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
         RootInlineBox* root = curr->root();
         int top = max(root->lineTop(), curr->y());
-        int bottom = min(root->lineBottom(), curr->y() + curr->height());
-        rects.append(IntRect(curr->x(), top, curr->width(), bottom - top));
+        int bottom = min(root->lineBottom(), curr->y() + curr->logicalHeight());
+        rects.append(IntRect(curr->x(), top, curr->logicalWidth(), bottom - top));
     }
     rects.append(IntRect());