https://bugs.webkit.org/show_bug.cgi?id=47370
authorhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Oct 2010 21:16:49 +0000 (21:16 +0000)
committerhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Oct 2010 21:16:49 +0000 (21:16 +0000)
Reviewed by Sam Weinig.

Make line box placement in the inline direction writing-mode-aware.  Lines now set their y-position instead of x-position
when vertical.

Refactored shadow overflow to give text-shadow the same helpers in RenderStyle that box-shadow has so that the shadow-walking loop in
placeBoxesInInlineDirection can be replaced with the helper.

Overflow had to be patched to be writing-mode-aware so that the correct physical directions would be set for vertical line
boxes.

Vertical lines are still not testable until they can be placed in the block direction.  Then the render tree dumps
become meaningful (even if the pixel results look horrible).

* rendering/InlineBox.h:
(WebCore::InlineBox::logicalRight):
* rendering/InlineFlowBox.cpp:
(WebCore::InlineFlowBox::placeBoxesInInlineDirection):
* rendering/InlineFlowBox.h:
(WebCore::InlineFlowBox::logicalLeftLayoutOverflow):
(WebCore::InlineFlowBox::logicalRightLayoutOverflow):
(WebCore::InlineFlowBox::logicalLeftVisualOverflow):
(WebCore::InlineFlowBox::logicalRightVisualOverflow):
(WebCore::InlineFlowBox::setInlineDirectionOverflowPositions):
* rendering/RenderBlockLineLayout.cpp:
(WebCore::RenderBlock::computeInlineDirectionPositionsForLine):
* rendering/style/RenderStyle.cpp:
(WebCore::RenderStyle::getShadowExtent):
(WebCore::RenderStyle::getShadowHorizontalExtent):
(WebCore::RenderStyle::getShadowVerticalExtent):
* rendering/style/RenderStyle.h:
(WebCore::InheritedFlags::getTextShadowExtent):
(WebCore::InheritedFlags::getTextShadowHorizontalExtent):
(WebCore::InheritedFlags::getTextShadowVerticalExtent):
(WebCore::InheritedFlags::getTextShadowInlineDirectionExtent):
(WebCore::InheritedFlags::getBoxShadowExtent):
(WebCore::InheritedFlags::getBoxShadowHorizontalExtent):
(WebCore::InheritedFlags::getBoxShadowVerticalExtent):
(WebCore::InheritedFlags::getBoxShadowInlineDirectionExtent):
(WebCore::InheritedFlags::getShadowInlineDirectionExtent):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@69341 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/rendering/InlineBox.h
WebCore/rendering/InlineFlowBox.cpp
WebCore/rendering/InlineFlowBox.h
WebCore/rendering/RenderBlockLineLayout.cpp
WebCore/rendering/style/RenderStyle.cpp
WebCore/rendering/style/RenderStyle.h

index 1a67f1e..7e3cfe2 100644 (file)
@@ -1,3 +1,48 @@
+2010-10-07  David Hyatt  <hyatt@apple.com>
+
+        Reviewed by Sam Weinig.
+
+        https://bugs.webkit.org/show_bug.cgi?id=47370
+        
+        Make line box placement in the inline direction writing-mode-aware.  Lines now set their y-position instead of x-position
+        when vertical.
+        
+        Refactored shadow overflow to give text-shadow the same helpers in RenderStyle that box-shadow has so that the shadow-walking loop in
+        placeBoxesInInlineDirection can be replaced with the helper.
+
+        Overflow had to be patched to be writing-mode-aware so that the correct physical directions would be set for vertical line
+        boxes.
+
+        Vertical lines are still not testable until they can be placed in the block direction.  Then the render tree dumps
+        become meaningful (even if the pixel results look horrible).
+
+        * rendering/InlineBox.h:
+        (WebCore::InlineBox::logicalRight):
+        * rendering/InlineFlowBox.cpp:
+        (WebCore::InlineFlowBox::placeBoxesInInlineDirection):
+        * rendering/InlineFlowBox.h:
+        (WebCore::InlineFlowBox::logicalLeftLayoutOverflow):
+        (WebCore::InlineFlowBox::logicalRightLayoutOverflow):
+        (WebCore::InlineFlowBox::logicalLeftVisualOverflow):
+        (WebCore::InlineFlowBox::logicalRightVisualOverflow):
+        (WebCore::InlineFlowBox::setInlineDirectionOverflowPositions):
+        * rendering/RenderBlockLineLayout.cpp:
+        (WebCore::RenderBlock::computeInlineDirectionPositionsForLine):
+        * rendering/style/RenderStyle.cpp:
+        (WebCore::RenderStyle::getShadowExtent):
+        (WebCore::RenderStyle::getShadowHorizontalExtent):
+        (WebCore::RenderStyle::getShadowVerticalExtent):
+        * rendering/style/RenderStyle.h:
+        (WebCore::InheritedFlags::getTextShadowExtent):
+        (WebCore::InheritedFlags::getTextShadowHorizontalExtent):
+        (WebCore::InheritedFlags::getTextShadowVerticalExtent):
+        (WebCore::InheritedFlags::getTextShadowInlineDirectionExtent):
+        (WebCore::InheritedFlags::getBoxShadowExtent):
+        (WebCore::InheritedFlags::getBoxShadowHorizontalExtent):
+        (WebCore::InheritedFlags::getBoxShadowVerticalExtent):
+        (WebCore::InheritedFlags::getBoxShadowInlineDirectionExtent):
+        (WebCore::InheritedFlags::getShadowInlineDirectionExtent):
+
 2010-10-07  Dan Bernstein  <mitz@apple.com>
 
         Reviewed by Simon Fraser.
index 888186d..0afd1df 100644 (file)
@@ -217,6 +217,7 @@ public:
 
     // The logicalLeft position is the left edge of the line box in a horizontal line and the top edge in a vertical line.
     int logicalLeft() const { return !m_isVertical ? m_x : m_y; }
+    int logicalRight() const { return logicalLeft() + logicalWidth(); }
     void setLogicalLeft(int left)
     {
         if (!m_isVertical)
index 5436b25..cb01c5f 100644 (file)
@@ -253,24 +253,24 @@ void InlineFlowBox::determineSpacingForFlowBoxes(bool lastLine, RenderObject* en
     }
 }
 
-int InlineFlowBox::placeBoxesInInlineDirection(int xPos, bool& needsWordSpacing, GlyphOverflowAndFallbackFontsMap& textBoxDataMap)
+int InlineFlowBox::placeBoxesInInlineDirection(int logicalLeft, bool& needsWordSpacing, GlyphOverflowAndFallbackFontsMap& textBoxDataMap)
 {
     // Set our x position.
-    setX(xPos);
+    setLogicalLeft(logicalLeft);
 
-    int leftLayoutOverflow = xPos;
-    int rightLayoutOverflow = xPos;
-    int leftVisualOverflow = xPos;
-    int rightVisualOverflow = xPos;
+    int logicalLeftLayoutOverflow = logicalLeft;
+    int logicalRightLayoutOverflow = logicalLeft;
+    int logicalLeftVisualOverflow = logicalLeft;
+    int logicalRightVisualOverflow = logicalLeft;
 
-    int boxShadowLeft;
-    int boxShadowRight;
-    renderer()->style(m_firstLine)->getBoxShadowHorizontalExtent(boxShadowLeft, boxShadowRight);
+    int boxShadowLogicalLeft;
+    int boxShadowLogicalRight;
+    renderer()->style(m_firstLine)->getBoxShadowInlineDirectionExtent(boxShadowLogicalLeft, boxShadowLogicalRight);
 
-    leftVisualOverflow = min(xPos + boxShadowLeft, leftVisualOverflow);
+    logicalLeftVisualOverflow = min(logicalLeft + boxShadowLogicalLeft, logicalLeftVisualOverflow);
 
-    int startX = xPos;
-    xPos += borderLogicalLeft() + paddingLogicalLeft();
+    int startLogicalLeft = logicalLeft;
+    logicalLeft += borderLogicalLeft() + paddingLogicalLeft();
     
     for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
         if (curr->renderer()->isText()) {
@@ -278,81 +278,87 @@ int InlineFlowBox::placeBoxesInInlineDirection(int xPos, bool& needsWordSpacing,
             RenderText* rt = toRenderText(text->renderer());
             if (rt->textLength()) {
                 if (needsWordSpacing && isSpaceOrNewline(rt->characters()[text->start()]))
-                    xPos += rt->style(m_firstLine)->font().wordSpacing();
+                    logicalLeft += rt->style(m_firstLine)->font().wordSpacing();
                 needsWordSpacing = !isSpaceOrNewline(rt->characters()[text->end()]);
             }
-            text->setX(xPos);
+            text->setLogicalLeft(logicalLeft);
             
             int strokeOverflow = static_cast<int>(ceilf(rt->style()->textStrokeWidth() / 2.0f));
             
             // If letter-spacing is negative, we should factor that into right layout overflow. (Even in RTL, letter-spacing is
             // applied to the right, so this is not an issue with left overflow.
             int letterSpacing = min(0, (int)rt->style(m_firstLine)->font().letterSpacing());
-            rightLayoutOverflow = max(xPos + text->logicalWidth() - letterSpacing, rightLayoutOverflow);
+            logicalRightLayoutOverflow = max(logicalLeft + text->logicalWidth() - letterSpacing, logicalRightLayoutOverflow);
 
             GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.find(static_cast<InlineTextBox*>(curr));
             GlyphOverflow* glyphOverflow = it == textBoxDataMap.end() ? 0 : &it->second.second;
 
-            int leftGlyphOverflow = -strokeOverflow - (glyphOverflow ? glyphOverflow->left : 0);
-            int rightGlyphOverflow = strokeOverflow - letterSpacing + (glyphOverflow ? glyphOverflow->right : 0);
+            int logicalLeftGlyphOverflow = -strokeOverflow - (glyphOverflow ? glyphOverflow->left : 0);
+            int logicalRightGlyphOverflow = strokeOverflow - letterSpacing + (glyphOverflow ? glyphOverflow->right : 0);
             
-            int childOverflowLeft = leftGlyphOverflow;
-            int childOverflowRight = rightGlyphOverflow;
-            for (const ShadowData* shadow = rt->style()->textShadow(); shadow; shadow = shadow->next()) {
-                childOverflowLeft = min(childOverflowLeft, shadow->x() - shadow->blur() + leftGlyphOverflow);
-                childOverflowRight = max(childOverflowRight, shadow->x() + shadow->blur() + rightGlyphOverflow);
-            }
-            
-            leftVisualOverflow = min(xPos + childOverflowLeft, leftVisualOverflow);
-            rightVisualOverflow = max(xPos + text->logicalWidth() + childOverflowRight, rightVisualOverflow);
+            int childOverflowLogicalLeft = logicalLeftGlyphOverflow;
+            int childOverflowLogicalRight = logicalRightGlyphOverflow;
+            int textShadowLogicalLeft;
+            int textShadowLogicalRight;
+            rt->style(m_firstLine)->getTextShadowInlineDirectionExtent(textShadowLogicalLeft, textShadowLogicalRight);
+            childOverflowLogicalLeft = min(childOverflowLogicalLeft, textShadowLogicalLeft);
+            childOverflowLogicalRight = max(childOverflowLogicalRight, textShadowLogicalRight);
+            logicalLeftVisualOverflow = min(logicalLeft + childOverflowLogicalLeft, logicalLeftVisualOverflow);
+            logicalRightVisualOverflow = max(logicalLeft + text->logicalWidth() + childOverflowLogicalRight, logicalRightVisualOverflow);
             
-            xPos += text->logicalWidth();
+            logicalLeft += text->logicalWidth();
         } else {
             if (curr->renderer()->isPositioned()) {
                 if (curr->renderer()->parent()->style()->isLeftToRightDirection())
-                    curr->setX(xPos);
+                    curr->setLogicalLeft(logicalLeft);
                 else
                     // Our offset that we cache needs to be from the edge of the right border box and
                     // not the left border box.  We have to subtract |x| from the width of the block
                     // (which can be obtained from the root line box).
-                    curr->setX(root()->block()->width() - xPos);
+                    curr->setLogicalLeft(root()->block()->logicalWidth() - logicalLeft);
                 continue; // The positioned object has no effect on the width.
             }
             if (curr->renderer()->isRenderInline()) {
                 InlineFlowBox* flow = static_cast<InlineFlowBox*>(curr);
-                xPos += flow->marginLogicalLeft();
-                xPos = flow->placeBoxesInInlineDirection(xPos, needsWordSpacing, textBoxDataMap);
-                xPos += flow->marginLogicalRight();
-                leftLayoutOverflow = min(leftLayoutOverflow, flow->leftLayoutOverflow());
-                rightLayoutOverflow = max(rightLayoutOverflow, flow->rightLayoutOverflow());
-                leftVisualOverflow = min(leftVisualOverflow, flow->leftVisualOverflow());
-                rightVisualOverflow = max(rightVisualOverflow, flow->rightVisualOverflow());
+                logicalLeft += flow->marginLogicalLeft();
+                logicalLeft = flow->placeBoxesInInlineDirection(logicalLeft, needsWordSpacing, textBoxDataMap);
+                logicalLeft += flow->marginLogicalRight();
+                logicalLeftLayoutOverflow = min(logicalLeftLayoutOverflow, flow->logicalLeftLayoutOverflow());
+                logicalRightLayoutOverflow = max(logicalRightLayoutOverflow, flow->logicalRightLayoutOverflow());
+                logicalLeftVisualOverflow = min(logicalLeftVisualOverflow, flow->logicalLeftVisualOverflow());
+                logicalRightVisualOverflow = max(logicalRightVisualOverflow, flow->logicalRightVisualOverflow());
             } else if (!curr->renderer()->isListMarker() || toRenderListMarker(curr->renderer())->isInside()) {
-                xPos += curr->boxModelObject()->marginLeft();
-                curr->setX(xPos);
-                 
+                // The box can have a different writing-mode than the overall line, so this is a bit complicated.
+                // Just get all the physical margin and overflow values by hand based off |isVertical|.
+                int logicalLeftMargin = !isVertical() ? curr->boxModelObject()->marginLeft() : curr->boxModelObject()->marginTop();
+                int logicalRightMargin = !isVertical() ? curr->boxModelObject()->marginRight() : curr->boxModelObject()->marginBottom();
+                
+                logicalLeft += logicalLeftMargin;
+                curr->setX(logicalLeft);
+                       
                 RenderBox* box = toRenderBox(curr->renderer());
-                int childLeftOverflow = box->hasOverflowClip() ? 0 : box->leftLayoutOverflow();
-                int childRightOverflow = box->hasOverflowClip() ? curr->logicalWidth() : box->rightLayoutOverflow();
+
+                int childOverflowLogicalLeft = box->hasOverflowClip() ? 0 : (!isVertical() ? box->leftLayoutOverflow() : box->topLayoutOverflow());
+                int childOverflowLogicalRight = box->hasOverflowClip() ? curr->logicalWidth() : (!isVertical() ? box->rightLayoutOverflow() : box->bottomLayoutOverflow());
                 
-                leftLayoutOverflow = min(xPos + childLeftOverflow, leftLayoutOverflow);
-                rightLayoutOverflow = max(xPos + childRightOverflow, rightLayoutOverflow);
+                logicalLeftLayoutOverflow = min(logicalLeft + childOverflowLogicalLeft, logicalLeftLayoutOverflow);
+                logicalRightLayoutOverflow = max(logicalLeft + childOverflowLogicalRight, logicalRightLayoutOverflow);
 
-                leftVisualOverflow = min(xPos + box->leftVisualOverflow(), leftVisualOverflow);
-                rightVisualOverflow = max(xPos + box->rightVisualOverflow(), rightVisualOverflow);
+                logicalLeftVisualOverflow = min(logicalLeft + (!isVertical() ? box->leftVisualOverflow() : box->topVisualOverflow()), logicalLeftVisualOverflow);
+                logicalRightVisualOverflow = max(logicalLeft + (!isVertical() ? box->rightVisualOverflow() : box->bottomVisualOverflow()), logicalRightVisualOverflow);
                
-                xPos += curr->logicalWidth() + curr->boxModelObject()->marginRight();
+                logicalLeft += curr->logicalWidth() + logicalRightMargin;
             }
         }
     }
 
-    xPos += borderLogicalRight() + paddingLogicalRight();
-    setLogicalWidth(xPos - startX);
-    rightVisualOverflow = max(x() + logicalWidth() + boxShadowRight, rightVisualOverflow);
-    rightLayoutOverflow = max(x() + logicalWidth(), rightLayoutOverflow);
+    logicalLeft += borderLogicalRight() + paddingLogicalRight();
+    setLogicalWidth(logicalLeft - startLogicalLeft);
+    logicalRightVisualOverflow = max(logicalLeft + boxShadowLogicalRight, logicalRightVisualOverflow);
+    logicalRightLayoutOverflow = max(logicalLeft, logicalRightLayoutOverflow);
 
-    setInlineDirectionOverflowPositions(leftLayoutOverflow, rightLayoutOverflow, leftVisualOverflow, rightVisualOverflow);
-    return xPos;
+    setInlineDirectionOverflowPositions(logicalLeftLayoutOverflow, logicalRightLayoutOverflow, logicalLeftVisualOverflow, logicalRightVisualOverflow);
+    return logicalLeft;
 }
 
 void InlineFlowBox::adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent,
index 2d57cca..31072c3 100644 (file)
@@ -185,15 +185,21 @@ public:
     int leftLayoutOverflow() const { return m_overflow ? m_overflow->leftLayoutOverflow() : m_x; }
     int rightLayoutOverflow() const { return m_overflow ? m_overflow->rightLayoutOverflow() : m_x + m_logicalWidth; }
     IntRect layoutOverflowRect() const { return m_overflow ? m_overflow->layoutOverflowRect() : IntRect(m_x, m_y, m_logicalWidth, logicalHeight()); }
-
+    int logicalLeftLayoutOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? leftLayoutOverflow() : topLayoutOverflow(); }
+    int logicalRightLayoutOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? rightLayoutOverflow() : bottomLayoutOverflow(); }
+    
     int topVisualOverflow() const { return m_overflow ? m_overflow->topVisualOverflow() : m_y; }
     int bottomVisualOverflow() const { return m_overflow ? m_overflow->bottomVisualOverflow() : m_y + logicalHeight(); }
     int leftVisualOverflow() const { return m_overflow ? m_overflow->leftVisualOverflow() : m_x; }
     int rightVisualOverflow() const { return m_overflow ? m_overflow->rightVisualOverflow() : m_x + m_logicalWidth; }
     IntRect visualOverflowRect() const { return m_overflow ? m_overflow->visualOverflowRect() : IntRect(m_x, m_y, m_logicalWidth, logicalHeight()); }
-
-    void setInlineDirectionOverflowPositions(int leftLayoutOverflow, int rightLayoutOverflow, int leftVisualOverflow, int rightVisualOverflow);
-    void setBlockDirectionOverflowPositions(int topLayoutOverflow, int bottomLayoutOverflow, int topVisualOverflow, int bottomVisualOverflow, int boxHeight);
+    int logicalLeftVisualOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? leftVisualOverflow() : topVisualOverflow(); }
+    int logicalRightVisualOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? rightVisualOverflow() : bottomVisualOverflow(); }
+    
+    void setInlineDirectionOverflowPositions(int logicalLeftLayoutOverflow, int logicalRightLayoutOverflow,
+                                             int logicalLeftVisualOverflow, int logicalRightVisualOverflow);
+    void setBlockDirectionOverflowPositions(int logicalTopLayoutOverflow, int logicalBottomLayoutOverflow,
+                                            int logicalTopVisualOverflow, int logicalBottomVisualOverflow, int boxLogicalHeight);
 
 protected:
     OwnPtr<RenderOverflow> m_overflow;
@@ -215,18 +221,31 @@ protected:
 #endif
 };
 
-inline void InlineFlowBox::setInlineDirectionOverflowPositions(int leftLayoutOverflow, int rightLayoutOverflow, int leftVisualOverflow, int rightVisualOverflow) 
+inline void InlineFlowBox::setInlineDirectionOverflowPositions(int logicalLeftLayoutOverflow, int logicalRightLayoutOverflow, 
+                                                               int logicalLeftVisualOverflow, int logicalRightVisualOverflow) 
 { 
     if (!m_overflow) {
-        if (leftLayoutOverflow == m_x && rightLayoutOverflow == m_x + m_logicalWidth && leftVisualOverflow == m_x && rightVisualOverflow == m_x + m_logicalWidth)
+        if (logicalLeftLayoutOverflow == logicalLeft() && logicalRightLayoutOverflow == logicalRight() 
+            && logicalLeftVisualOverflow == logicalLeft() && logicalRightVisualOverflow == logicalRight())
             return;
-        m_overflow = adoptPtr(new RenderOverflow(IntRect(m_x, m_y, m_logicalWidth, m_renderer->style(m_firstLine)->font().height())));    
+        
+        int width = isVertical() ? m_renderer->style(m_firstLine)->font().height() : logicalWidth();
+        int height = isVertical() ? logicalWidth() : m_renderer->style(m_firstLine)->font().height();
+        
+        m_overflow = adoptPtr(new RenderOverflow(IntRect(m_x, m_y, width, height)));   
     }
 
-    m_overflow->setLeftLayoutOverflow(leftLayoutOverflow);
-    m_overflow->setRightLayoutOverflow(rightLayoutOverflow);
-    m_overflow->setLeftVisualOverflow(leftVisualOverflow); 
-    m_overflow->setRightVisualOverflow(rightVisualOverflow);  
+    if (isVertical()) {
+        m_overflow->setTopLayoutOverflow(logicalLeftLayoutOverflow);
+        m_overflow->setBottomLayoutOverflow(logicalRightLayoutOverflow);
+        m_overflow->setTopVisualOverflow(logicalLeftVisualOverflow); 
+        m_overflow->setBottomVisualOverflow(logicalRightVisualOverflow);  
+    } else {
+        m_overflow->setLeftLayoutOverflow(logicalLeftLayoutOverflow);
+        m_overflow->setRightLayoutOverflow(logicalRightLayoutOverflow);
+        m_overflow->setLeftVisualOverflow(logicalLeftVisualOverflow); 
+        m_overflow->setRightVisualOverflow(logicalRightVisualOverflow);
+    }
 }
 
 inline void InlineFlowBox::setBlockDirectionOverflowPositions(int topLayoutOverflow, int bottomLayoutOverflow, int topVisualOverflow, int bottomVisualOverflow, int boxHeight)
index ff473a7..b2acbb6 100644 (file)
@@ -294,9 +294,9 @@ RootInlineBox* RenderBlock::constructLine(unsigned runCount, BidiRun* firstRun,
 
 void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox, bool firstLine, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, GlyphOverflowAndFallbackFontsMap& textBoxDataMap)
 {
-    // First determine our total width.
-    int availableWidth = availableLogicalWidthForLine(logicalHeight(), firstLine);
-    int totWidth = lineBox->getFlowSpacingLogicalWidth();
+    // First determine our total logical width.
+    int availableLogicalWidth = availableLogicalWidthForLine(logicalHeight(), firstLine);
+    int totalLogicalWidth = lineBox->getFlowSpacingLogicalWidth();
     bool needsWordSpacing = false;
     unsigned numSpaces = 0;
     ETextAlign textAlign = style()->textAlign();
@@ -320,7 +320,7 @@ void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox,
 
             if (int length = rt->textLength()) {
                 if (!r->m_start && needsWordSpacing && isSpaceOrNewline(rt->characters()[r->m_start]))
-                    totWidth += rt->style(firstLine)->font().wordSpacing();
+                    totalLogicalWidth += rt->style(firstLine)->font().wordSpacing();
                 needsWordSpacing = !isSpaceOrNewline(rt->characters()[r->m_stop - 1]) && r->m_stop == length;          
             }
             HashSet<const SimpleFontData*> fallbackFonts;
@@ -330,7 +330,7 @@ void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox,
                 const AtomicString& hyphenString = rt->style()->hyphenString();
                 hyphenWidth = rt->style(firstLine)->font().width(TextRun(hyphenString.characters(), hyphenString.length()));
             }
-            r->m_box->setLogicalWidth(rt->width(r->m_start, r->m_stop - r->m_start, totWidth, firstLine, &fallbackFonts, &glyphOverflow) + hyphenWidth);
+            r->m_box->setLogicalWidth(rt->width(r->m_start, r->m_stop - r->m_start, totalLogicalWidth, firstLine, &fallbackFonts, &glyphOverflow) + hyphenWidth);
             if (!fallbackFonts.isEmpty()) {
                 ASSERT(r->m_box->isText());
                 GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.add(static_cast<InlineTextBox*>(r->m_box), make_pair(Vector<const SimpleFontData*>(), GlyphOverflow())).first;
@@ -345,37 +345,37 @@ void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox,
         } else if (!r->m_object->isRenderInline()) {
             RenderBox* renderBox = toRenderBox(r->m_object);
             renderBox->computeLogicalWidth();
-            r->m_box->setLogicalWidth(renderBox->width());
-            totWidth += renderBox->marginLeft() + renderBox->marginRight();
+            r->m_box->setLogicalWidth(logicalWidthForChild(renderBox));
+            totalLogicalWidth += marginStartForChild(renderBox) + marginEndForChild(renderBox);
         }
 
-        totWidth += r->m_box->logicalWidth();
+        totalLogicalWidth += r->m_box->logicalWidth();
     }
 
     // Armed with the total width of the line (without justification),
     // we now examine our text-align property in order to determine where to position the
     // objects horizontally.  The total width of the line can be increased if we end up
     // justifying text.
-    int x = logicalLeftOffsetForLine(height(), firstLine);
+    int logicalLeft = logicalLeftOffsetForLine(logicalHeight(), firstLine);
     switch (textAlign) {
         case LEFT:
         case WEBKIT_LEFT:
             // The direction of the block should determine what happens with wide lines.  In
             // particular with RTL blocks, wide lines should still spill out to the left.
             if (style()->isLeftToRightDirection()) {
-                if (totWidth > availableWidth && trailingSpaceRun)
-                    trailingSpaceRun->m_box->setLogicalWidth(max(0, trailingSpaceRun->m_box->logicalWidth() - totWidth + availableWidth));
+                if (totalLogicalWidth > availableLogicalWidth && trailingSpaceRun)
+                    trailingSpaceRun->m_box->setLogicalWidth(max(0, trailingSpaceRun->m_box->logicalWidth() - totalLogicalWidth + availableLogicalWidth));
             } else {
                 if (trailingSpaceRun)
                     trailingSpaceRun->m_box->setLogicalWidth(0);
-                else if (totWidth > availableWidth)
-                    x -= (totWidth - availableWidth);
+                else if (totalLogicalWidth > availableLogicalWidth)
+                    logicalLeft -= (totalLogicalWidth - availableLogicalWidth);
             }
             break;
         case JUSTIFY:
             if (numSpaces && !reachedEnd && !lineBox->endsWithBreak()) {
                 if (trailingSpaceRun) {
-                    totWidth -= trailingSpaceRun->m_box->logicalWidth();
+                    totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
                     trailingSpaceRun->m_box->setLogicalWidth(0);
                 }
                 break;
@@ -385,8 +385,8 @@ void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox,
             numSpaces = 0;
             // for right to left fall through to right aligned
             if (style()->isLeftToRightDirection()) {
-                if (totWidth > availableWidth && trailingSpaceRun)
-                    trailingSpaceRun->m_box->setLogicalWidth(max(0, trailingSpaceRun->m_box->logicalWidth() - totWidth + availableWidth));
+                if (totalLogicalWidth > availableLogicalWidth && trailingSpaceRun)
+                    trailingSpaceRun->m_box->setLogicalWidth(max(0, trailingSpaceRun->m_box->logicalWidth() - totalLogicalWidth + availableLogicalWidth));
                 break;
             }
         case RIGHT:
@@ -396,31 +396,31 @@ void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox,
             // side of the block.
             if (style()->isLeftToRightDirection()) {
                 if (trailingSpaceRun) {
-                    totWidth -= trailingSpaceRun->m_box->logicalWidth();
+                    totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
                     trailingSpaceRun->m_box->setLogicalWidth(0);
                 }
-                if (totWidth < availableWidth)
-                    x += availableWidth - totWidth;
+                if (totalLogicalWidth < availableLogicalWidth)
+                    logicalLeft += availableLogicalWidth - totalLogicalWidth;
             } else {
-                if (totWidth > availableWidth && trailingSpaceRun) {
-                    trailingSpaceRun->m_box->setLogicalWidth(max(0, trailingSpaceRun->m_box->logicalWidth() - totWidth + availableWidth));
-                    totWidth -= trailingSpaceRun->m_box->logicalWidth();
+                if (totalLogicalWidth > availableLogicalWidth && trailingSpaceRun) {
+                    trailingSpaceRun->m_box->setLogicalWidth(max(0, trailingSpaceRun->m_box->logicalWidth() - totalLogicalWidth + availableLogicalWidth));
+                    totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
                 } else
-                    x += availableWidth - totWidth;
+                    logicalLeft += availableLogicalWidth - totalLogicalWidth;
             }
             break;
         case CENTER:
         case WEBKIT_CENTER:
             int trailingSpaceWidth = 0;
             if (trailingSpaceRun) {
-                totWidth -= trailingSpaceRun->m_box->logicalWidth();
-                trailingSpaceWidth = min(trailingSpaceRun->m_box->logicalWidth(), (availableWidth - totWidth + 1) / 2);
+                totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
+                trailingSpaceWidth = min(trailingSpaceRun->m_box->logicalWidth(), (availableLogicalWidth - totalLogicalWidth + 1) / 2);
                 trailingSpaceRun->m_box->setLogicalWidth(max(0, trailingSpaceWidth));
             }
             if (style()->isLeftToRightDirection())
-                x += max((availableWidth - totWidth) / 2, 0);
+                logicalLeft += max((availableLogicalWidth - totalLogicalWidth) / 2, 0);
             else
-                x += totWidth > availableWidth ? (availableWidth - totWidth) : (availableWidth - totWidth) / 2 - trailingSpaceWidth;
+                logicalLeft += totalLogicalWidth > availableLogicalWidth ? (availableLogicalWidth - totalLogicalWidth) : (availableLogicalWidth - totalLogicalWidth) / 2 - trailingSpaceWidth;
             break;
     }
 
@@ -443,9 +443,9 @@ void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox,
 
                 // Only justify text if whitespace is collapsed.
                 if (r->m_object->style()->collapseWhiteSpace()) {
-                    spaceAdd = (availableWidth - totWidth) * spaces / numSpaces;
+                    spaceAdd = (availableLogicalWidth - totalLogicalWidth) * spaces / numSpaces;
                     static_cast<InlineTextBox*>(r->m_box)->setSpaceAdd(spaceAdd);
-                    totWidth += spaceAdd;
+                    totalLogicalWidth += spaceAdd;
                 }
                 numSpaces -= spaces;
                 if (!numSpaces)
@@ -457,7 +457,7 @@ void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox,
     // The widths of all runs are now known.  We can now place every inline box (and
     // compute accurate widths for the inline flow boxes).
     needsWordSpacing = false;
-    lineBox->placeBoxesInInlineDirection(x, needsWordSpacing, textBoxDataMap);
+    lineBox->placeBoxesInInlineDirection(logicalLeft, needsWordSpacing, textBoxDataMap);
 }
 
 void RenderBlock::computeBlockDirectionPositionsForLine(RootInlineBox* lineBox, BidiRun* firstRun, GlyphOverflowAndFallbackFontsMap& textBoxDataMap)
index 43aba57..b56bb1e 100644 (file)
@@ -935,52 +935,52 @@ void RenderStyle::setBlendedFontSize(int size)
     font().update(currentFontSelector);
 }
 
-void RenderStyle::getBoxShadowExtent(int &top, int &right, int &bottom, int &left) const
+void RenderStyle::getShadowExtent(const ShadowData* shadow, int &top, int &right, int &bottom, int &left) const
 {
     top = 0;
     right = 0;
     bottom = 0;
     left = 0;
 
-    for (const ShadowData* boxShadow = this->boxShadow(); boxShadow; boxShadow = boxShadow->next()) {
-        if (boxShadow->style() == Inset)
+    for ( ; shadow; shadow = shadow->next()) {
+        if (shadow->style() == Inset)
             continue;
-        int blurAndSpread = boxShadow->blur() + boxShadow->spread();
+        int blurAndSpread = shadow->blur() + shadow->spread();
 
-        top = min(top, boxShadow->y() - blurAndSpread);
-        right = max(right, boxShadow->x() + blurAndSpread);
-        bottom = max(bottom, boxShadow->y() + blurAndSpread);
-        left = min(left, boxShadow->x() - blurAndSpread);
+        top = min(top, shadow->y() - blurAndSpread);
+        right = max(right, shadow->x() + blurAndSpread);
+        bottom = max(bottom, shadow->y() + blurAndSpread);
+        left = min(left, shadow->x() - blurAndSpread);
     }
 }
 
-void RenderStyle::getBoxShadowHorizontalExtent(int &left, int &right) const
+void RenderStyle::getShadowHorizontalExtent(const ShadowData* shadow, int &left, int &right) const
 {
     left = 0;
     right = 0;
 
-    for (const ShadowData* boxShadow = this->boxShadow(); boxShadow; boxShadow = boxShadow->next()) {
-        if (boxShadow->style() == Inset)
+    for ( ; shadow; shadow = shadow->next()) {
+        if (shadow->style() == Inset)
             continue;
-        int blurAndSpread = boxShadow->blur() + boxShadow->spread();
+        int blurAndSpread = shadow->blur() + shadow->spread();
 
-        left = min(left, boxShadow->x() - blurAndSpread);
-        right = max(right, boxShadow->x() + blurAndSpread);
+        left = min(left, shadow->x() - blurAndSpread);
+        right = max(right, shadow->x() + blurAndSpread);
     }
 }
 
-void RenderStyle::getBoxShadowVerticalExtent(int &top, int &bottom) const
+void RenderStyle::getShadowVerticalExtent(const ShadowData* shadow, int &top, int &bottom) const
 {
     top = 0;
     bottom = 0;
 
-    for (const ShadowData* boxShadow = this->boxShadow(); boxShadow; boxShadow = boxShadow->next()) {
-        if (boxShadow->style() == Inset)
+    for ( ; shadow; shadow = shadow->next()) {
+        if (shadow->style() == Inset)
             continue;
-        int blurAndSpread = boxShadow->blur() + boxShadow->spread();
+        int blurAndSpread = shadow->blur() + shadow->spread();
 
-        top = min(top, boxShadow->y() - blurAndSpread);
-        bottom = max(bottom, boxShadow->y() + blurAndSpread);
+        top = min(top, shadow->y() - blurAndSpread);
+        bottom = max(bottom, shadow->y() + blurAndSpread);
     }
 }
 
index b9f77d2..9f39e0f 100644 (file)
@@ -637,6 +637,11 @@ public:
     }
 
     const ShadowData* textShadow() const { return rareInheritedData->textShadow; }
+    void getTextShadowExtent(int& top, int& right, int& bottom, int& left) const { getShadowExtent(textShadow(), top, right, bottom, left); }
+    void getTextShadowHorizontalExtent(int& left, int& right) const { getShadowHorizontalExtent(textShadow(), left, right); }
+    void getTextShadowVerticalExtent(int& top, int& bottom) const { getShadowVerticalExtent(textShadow(), top, bottom); }
+    void getTextShadowInlineDirectionExtent(int& logicalLeft, int& logicalRight) { getShadowInlineDirectionExtent(textShadow(), logicalLeft, logicalRight); }
+
     float textStrokeWidth() const { return rareInheritedData->textStrokeWidth; }
     ColorSpace colorSpace() const { return static_cast<ColorSpace>(rareInheritedData->colorSpace); }
     float opacity() const { return rareNonInheritedData->opacity; }
@@ -651,9 +656,10 @@ public:
     EBoxAlignment boxPack() const { return static_cast<EBoxAlignment>(rareNonInheritedData->flexibleBox->pack); }
 
     const ShadowData* boxShadow() const { return rareNonInheritedData->m_boxShadow.get(); }
-    void getBoxShadowExtent(int &top, int &right, int &bottom, int &left) const;
-    void getBoxShadowHorizontalExtent(int &left, int &right) const;
-    void getBoxShadowVerticalExtent(int &top, int &bottom) const;
+    void getBoxShadowExtent(int& top, int& right, int& bottom, int& left) const { getShadowExtent(boxShadow(), top, right, bottom, left); }
+    void getBoxShadowHorizontalExtent(int& left, int& right) const { getShadowHorizontalExtent(boxShadow(), left, right); }
+    void getBoxShadowVerticalExtent(int& top, int& bottom) const { getShadowVerticalExtent(boxShadow(), top, bottom); }
+    void getBoxShadowInlineDirectionExtent(int& logicalLeft, int& logicalRight) { getShadowInlineDirectionExtent(boxShadow(), logicalLeft, logicalRight); }
 
     StyleReflection* boxReflect() const { return rareNonInheritedData->m_boxReflect.get(); }
     EBoxSizing boxSizing() const { return m_box->boxSizing(); }
@@ -1263,6 +1269,14 @@ public:
 #endif
 
 private:
+    void getShadowExtent(const ShadowData*, int& top, int& right, int& bottom, int& left) const;
+    void getShadowHorizontalExtent(const ShadowData*, int& left, int& right) const;
+    void getShadowVerticalExtent(const ShadowData*, int& top, int& bottom) const;
+    void getShadowInlineDirectionExtent(const ShadowData* shadow, int& logicalLeft, int& logicalRight) const
+    {
+        return isHorizontalWritingMode() ? getShadowHorizontalExtent(shadow, logicalLeft, logicalRight) : getShadowVerticalExtent(shadow, logicalLeft, logicalRight);
+    }
+
     // Color accessors are all private to make sure callers use visitedDependentColor instead to access them.
     const Color& borderLeftColor() const { return surround->border.left().color(); }
     const Color& borderRightColor() const { return surround->border.right().color(); }