https://bugs.webkit.org/show_bug.cgi?id=48001
authorhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 20 Oct 2010 20:51:40 +0000 (20:51 +0000)
committerhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 20 Oct 2010 20:51:40 +0000 (20:51 +0000)
Reviewed by Dan Bernstein.

Make boxes place themselves properly in the block direction.  Get basic painting working for spans and add a test that
verifies that span painting and replaced element painting (like images) works correctly.

Added fast/blockflow/basic-vertical-line.html

WebCore:

* rendering/InlineBox.cpp:
(WebCore::InlineBox::logicalHeight):
* rendering/InlineFlowBox.cpp:
(WebCore::InlineFlowBox::placeBoxesInInlineDirection):
(WebCore::InlineFlowBox::adjustMaxAscentAndDescent):
(WebCore::verticalPositionForBox):
(WebCore::InlineFlowBox::computeLogicalBoxHeights):
(WebCore::InlineFlowBox::placeBoxesInBlockDirection):
(WebCore::InlineFlowBox::flipLinesInBlockDirection):
(WebCore::InlineFlowBox::paintBoxDecorations):
(WebCore::InlineFlowBox::paintMask):
* rendering/InlineFlowBox.h:
* rendering/style/RenderStyle.h:
(WebCore::InheritedFlags::isFlippedLinesWritingMode):

LayoutTests:

* fast/blockflow/basic-vertical-line.html: Added.
* platform/mac/fast/blockflow/basic-vertical-line-expected.checksum: Added.
* platform/mac/fast/blockflow/basic-vertical-line-expected.png: Added.
* platform/mac/fast/blockflow/basic-vertical-line-expected.txt: Added.

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

LayoutTests/ChangeLog
LayoutTests/fast/blockflow/basic-vertical-line.html [new file with mode: 0644]
LayoutTests/platform/mac/fast/blockflow/basic-vertical-line-expected.checksum [new file with mode: 0644]
LayoutTests/platform/mac/fast/blockflow/basic-vertical-line-expected.png [new file with mode: 0644]
LayoutTests/platform/mac/fast/blockflow/basic-vertical-line-expected.txt [new file with mode: 0644]
WebCore/ChangeLog
WebCore/rendering/InlineBox.cpp
WebCore/rendering/InlineFlowBox.cpp
WebCore/rendering/InlineFlowBox.h
WebCore/rendering/style/RenderStyle.h

index 3a28670..68c0d35 100644 (file)
@@ -1,3 +1,19 @@
+2010-10-20  David Hyatt  <hyatt@apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        https://bugs.webkit.org/show_bug.cgi?id=48001
+
+        Make boxes place themselves properly in the block direction.  Get basic painting working for spans and add a test that
+        verifies that span painting and replaced element painting (like images) works correctly.
+        
+        Added fast/blockflow/basic-vertical-line.html
+
+        * fast/blockflow/basic-vertical-line.html: Added.
+        * platform/mac/fast/blockflow/basic-vertical-line-expected.checksum: Added.
+        * platform/mac/fast/blockflow/basic-vertical-line-expected.png: Added.
+        * platform/mac/fast/blockflow/basic-vertical-line-expected.txt: Added.
+
 2010-10-20  Beth Dakin  <bdakin@apple.com>
 
         Reviewed by Dave Hyatt.
diff --git a/LayoutTests/fast/blockflow/basic-vertical-line.html b/LayoutTests/fast/blockflow/basic-vertical-line.html
new file mode 100644 (file)
index 0000000..33681b8
--- /dev/null
@@ -0,0 +1,8 @@
+<div style="-webkit-writing-mode: vertical-lr; height:300px; border:2px solid maroon">
+<span style="border-top: 5px solid black; border-bottom:5px solid black; padding-top:5px; padding-bottom:5px"><img style="height:200px;width:100px;background-color:green"></span>
+<br>
+<span style="border-top: 5px solid black; border-bottom:5px solid black; padding-top:5px; padding-bottom:5px"><img style="height:200px;width:100px;background-color:green"></span>
+<br>
+<span style="border-top: 5px solid black; border-bottom:5px solid black; padding-top:5px; padding-bottom:5px"><img style="height:200px;width:100px;background-color:green"></span>
+</div>
+
diff --git a/LayoutTests/platform/mac/fast/blockflow/basic-vertical-line-expected.checksum b/LayoutTests/platform/mac/fast/blockflow/basic-vertical-line-expected.checksum
new file mode 100644 (file)
index 0000000..bc015e4
--- /dev/null
@@ -0,0 +1 @@
+f149a6f8dd8b17bffdc42eb7cbd66e40
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/fast/blockflow/basic-vertical-line-expected.png b/LayoutTests/platform/mac/fast/blockflow/basic-vertical-line-expected.png
new file mode 100644 (file)
index 0000000..914dc2e
Binary files /dev/null and b/LayoutTests/platform/mac/fast/blockflow/basic-vertical-line-expected.png differ
diff --git a/LayoutTests/platform/mac/fast/blockflow/basic-vertical-line-expected.txt b/LayoutTests/platform/mac/fast/blockflow/basic-vertical-line-expected.txt
new file mode 100644 (file)
index 0000000..48d996a
--- /dev/null
@@ -0,0 +1,19 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderBlock {DIV} at (0,0) size 316x304 [border: (2px solid #800000)]
+        RenderInline {SPAN} at (0,0) size 220x18 [border: (5px solid #000000) none (5px solid #000000) none]
+          RenderImage {IMG} at (6,12) size 100x200 [bgcolor=#008000]
+        RenderText {#text} at (2,222) size 4x18
+          text run at (2,222) width 4: " "
+        RenderBR {BR} at (6,226) size 0x0
+        RenderInline {SPAN} at (0,0) size 220x18 [border: (5px solid #000000) none (5px solid #000000) none]
+          RenderImage {IMG} at (110,12) size 100x200 [bgcolor=#008000]
+        RenderText {#text} at (106,222) size 4x18
+          text run at (106,222) width 4: " "
+        RenderBR {BR} at (110,226) size 0x0
+        RenderInline {SPAN} at (0,0) size 220x18 [border: (5px solid #000000) none (5px solid #000000) none]
+          RenderImage {IMG} at (214,12) size 100x200 [bgcolor=#008000]
+        RenderText {#text} at (0,0) size 0x0
index a1b1b6a..d4a7831 100644 (file)
@@ -1,3 +1,29 @@
+2010-10-20  David Hyatt  <hyatt@apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        https://bugs.webkit.org/show_bug.cgi?id=48001
+
+        Make boxes place themselves properly in the block direction.  Get basic painting working for spans and add a test that
+        verifies that span painting and replaced element painting (like images) works correctly.
+        
+        Added fast/blockflow/basic-vertical-line.html
+
+        * rendering/InlineBox.cpp:
+        (WebCore::InlineBox::logicalHeight):
+        * rendering/InlineFlowBox.cpp:
+        (WebCore::InlineFlowBox::placeBoxesInInlineDirection):
+        (WebCore::InlineFlowBox::adjustMaxAscentAndDescent):
+        (WebCore::verticalPositionForBox):
+        (WebCore::InlineFlowBox::computeLogicalBoxHeights):
+        (WebCore::InlineFlowBox::placeBoxesInBlockDirection):
+        (WebCore::InlineFlowBox::flipLinesInBlockDirection):
+        (WebCore::InlineFlowBox::paintBoxDecorations):
+        (WebCore::InlineFlowBox::paintMask):
+        * rendering/InlineFlowBox.h:
+        * rendering/style/RenderStyle.h:
+        (WebCore::InheritedFlags::isFlippedLinesWritingMode):
+
 2010-10-20  Beth Dakin  <bdakin@apple.com>
 
         Reviewed by Dave Hyatt.
index 91cbaff..2028d4e 100644 (file)
@@ -95,14 +95,14 @@ int InlineBox::logicalHeight() const
     if (renderer()->isText())
         return m_isText ? renderer()->style(m_firstLine)->font().height() : 0;
     if (renderer()->isBox() && parent())
-        return toRenderBox(m_renderer)->height();
+        return m_isVertical ? toRenderBox(m_renderer)->width() : toRenderBox(m_renderer)->height();
 
     ASSERT(isInlineFlowBox());
     RenderBoxModelObject* flowObject = boxModelObject();
     const Font& font = renderer()->style(m_firstLine)->font();
     int result = font.height();
     if (parent())
-        result += flowObject->borderAndPaddingHeight();
+        result += flowObject->borderAndPaddingLogicalHeight();
     return result;
 }
 
index 3ecbf66..79c571d 100644 (file)
@@ -332,7 +332,7 @@ int InlineFlowBox::placeBoxesInInlineDirection(int logicalLeft, bool& needsWordS
                 int logicalRightMargin = !isVertical() ? curr->boxModelObject()->marginRight() : curr->boxModelObject()->marginBottom();
                 
                 logicalLeft += logicalLeftMargin;
-                curr->setX(logicalLeft);
+                curr->setLogicalLeft(logicalLeft);
                        
                 RenderBox* box = toRenderBox(curr->renderer());
 
@@ -367,9 +367,9 @@ void InlineFlowBox::adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent,
         // positioned elements
         if (curr->renderer()->isPositioned())
             continue; // Positioned placeholders don't affect calculations.
-        if (curr->y() == PositionTop || curr->y() == PositionBottom) {
+        if (curr->logicalTop() == PositionTop || curr->logicalTop() == PositionBottom) {
             int lineHeight = curr->lineHeight();
-            if (curr->y() == PositionTop) {
+            if (curr->logicalTop() == PositionTop) {
                 if (maxAscent + maxDescent < lineHeight)
                     maxDescent = lineHeight - maxAscent;
             }
@@ -390,7 +390,7 @@ void InlineFlowBox::adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent,
 static int verticalPositionForBox(InlineBox* curr, bool firstLine)
 {
     if (curr->renderer()->isText())
-        return curr->parent()->y();
+        return curr->parent()->logicalTop();
     if (curr->renderer()->isBox())
         return toRenderBox(curr->renderer())->verticalPosition(firstLine);
     return toRenderInline(curr->renderer())->verticalPositionFromCache(firstLine);
@@ -459,15 +459,15 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi
             baseline = curr->baselinePosition();
         }
 
-        curr->setY(verticalPositionForBox(curr, m_firstLine));
-        if (curr->y() == PositionTop) {
+        curr->setLogicalTop(verticalPositionForBox(curr, m_firstLine));
+        if (curr->logicalTop() == PositionTop) {
             if (maxPositionTop < lineHeight)
                 maxPositionTop = lineHeight;
-        } else if (curr->y() == PositionBottom) {
+        } else if (curr->logicalTop() == PositionBottom) {
             if (maxPositionBottom < lineHeight)
                 maxPositionBottom = lineHeight;
         } else if ((!isInlineFlow || static_cast<InlineFlowBox*>(curr)->hasTextChildren()) || curr->boxModelObject()->hasInlineDirectionBordersOrPadding() || strictMode) {
-            int ascent = baseline - curr->y();
+            int ascent = baseline - curr->logicalTop();
             int descent = lineHeight - ascent;
             if (maxAscent < ascent)
                 maxAscent = ascent;
@@ -480,10 +480,10 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi
     }
 }
 
-void InlineFlowBox::placeBoxesInBlockDirection(int yPos, int maxHeight, int maxAscent, bool strictMode, int& selectionTop, int& selectionBottom)
+void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAscent, bool strictMode, int& lineTop, int& lineBottom)
 {
     if (isRootInlineBox())
-        setY(yPos + maxAscent - baselinePosition()); // Place our root box.
+        setLogicalTop(top + maxAscent - baselinePosition()); // Place our root box.
 
     for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
         if (curr->renderer()->isPositioned())
@@ -493,47 +493,70 @@ void InlineFlowBox::placeBoxesInBlockDirection(int yPos, int maxHeight, int maxA
         // line-height).
         bool isInlineFlow = curr->isInlineFlowBox();
         if (isInlineFlow)
-            static_cast<InlineFlowBox*>(curr)->placeBoxesInBlockDirection(yPos, maxHeight, maxAscent, strictMode, selectionTop, selectionBottom);
+            static_cast<InlineFlowBox*>(curr)->placeBoxesInBlockDirection(top, maxHeight, maxAscent, strictMode, lineTop, lineBottom);
 
         bool childAffectsTopBottomPos = true;
-        if (curr->y() == PositionTop)
-            curr->setY(yPos);
-        else if (curr->y() == PositionBottom)
-            curr->setY(yPos + maxHeight - curr->lineHeight());
+        if (curr->logicalTop() == PositionTop)
+            curr->setLogicalTop(top);
+        else if (curr->logicalTop() == PositionBottom)
+            curr->setLogicalTop(top + maxHeight - curr->lineHeight());
         else {
             if ((isInlineFlow && !static_cast<InlineFlowBox*>(curr)->hasTextChildren()) && !curr->boxModelObject()->hasInlineDirectionBordersOrPadding() && !strictMode)
                 childAffectsTopBottomPos = false;
             int posAdjust = maxAscent - curr->baselinePosition();
-            curr->setY(curr->y() + yPos + posAdjust);
+            curr->setLogicalTop(curr->logicalTop() + top + posAdjust);
         }
         
-        int newY = curr->y();
+        int newLogicalTop = curr->logicalTop();
         if (curr->isText() || curr->isInlineFlowBox()) {
             const Font& font = curr->renderer()->style(m_firstLine)->font();
-            newY += curr->baselinePosition() - font.ascent();
-            if (curr->isInlineFlowBox())
-                newY -= curr->boxModelObject()->borderTop() + curr->boxModelObject()->paddingTop();
+            newLogicalTop += curr->baselinePosition() - font.ascent();
+            if (curr->isInlineFlowBox()) {
+                RenderBoxModelObject* boxObject = toRenderBoxModelObject(curr->renderer());
+                newLogicalTop -= boxObject->style(m_firstLine)->isHorizontalWritingMode() ? boxObject->borderTop() + boxObject->paddingTop() : 
+                                 boxObject->borderRight() + boxObject->paddingRight();
+            }
         } else if (!curr->renderer()->isBR()) {
             RenderBox* box = toRenderBox(curr->renderer());
-            newY += box->marginTop();
+            newLogicalTop += box->style(m_firstLine)->isHorizontalWritingMode() ? box->marginTop() : box->marginRight();
         }
 
-        curr->setY(newY);
+        curr->setLogicalTop(newLogicalTop);
 
         if (childAffectsTopBottomPos) {
             int boxHeight = curr->logicalHeight();
-            selectionTop = min(selectionTop, newY);
-            selectionBottom = max(selectionBottom, newY + boxHeight);
+            lineTop = min(lineTop, newLogicalTop);
+            lineBottom = max(lineBottom, newLogicalTop + boxHeight);
         }
     }
 
     if (isRootInlineBox()) {
         const Font& font = renderer()->style(m_firstLine)->font();
-        setY(y() + baselinePosition() - font.ascent());
+        setLogicalTop(logicalTop() + baselinePosition() - font.ascent());
+        
         if (hasTextChildren() || strictMode) {
-            selectionTop = min(selectionTop, y());
-            selectionBottom = max(selectionBottom, y() + logicalHeight());
+            lineTop = min(lineTop, logicalTop());
+            lineBottom = max(lineBottom, logicalTop() + logicalHeight());
         }
+        
+        if (renderer()->style()->isFlippedLinesWritingMode())
+            flipLinesInBlockDirection(lineTop, lineBottom);
+    }
+}
+
+void InlineFlowBox::flipLinesInBlockDirection(int lineTop, int lineBottom)
+{
+    // Flip the box on the line such that the top is now relative to the lineBottom instead of the lineTop.
+    setLogicalTop(lineBottom - (logicalTop() - lineTop) - logicalHeight());
+    
+    for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
+        if (curr->renderer()->isPositioned())
+            continue; // Positioned placeholders aren't affected here.
+        
+        if (curr->isInlineFlowBox())
+            static_cast<InlineFlowBox*>(curr)->flipLinesInBlockDirection(lineTop, lineBottom);
+        else
+            curr->setLogicalTop(lineBottom - (curr->logicalTop() - lineTop) - curr->logicalHeight());
     }
 }
 
@@ -762,16 +785,18 @@ void InlineFlowBox::paintBoxDecorations(PaintInfo& paintInfo, int tx, int ty)
 
     int x = m_x;
     int y = m_y;
-    int w = logicalWidth();
-    int h = logicalHeight();
+    int w = m_isVertical ? logicalHeight() : logicalWidth();
+    int h = m_isVertical ? logicalWidth() : logicalHeight();
 
     // Constrain our background/border painting to the line top and bottom if necessary.
     bool noQuirksMode = renderer()->document()->inNoQuirksMode();
     if (!hasTextChildren() && !noQuirksMode) {
         RootInlineBox* rootBox = root();
-        int bottom = min(rootBox->lineBottom(), y + h);
-        y = max(rootBox->lineTop(), y);
-        h = bottom - y;
+        int& top = m_isVertical ? x : y;
+        int& logicalHeight = m_isVertical ? w : h;
+        int bottom = min(rootBox->lineBottom(), top + logicalHeight);
+        top = max(rootBox->lineTop(), top);
+        logicalHeight = bottom - top;
     }
     
     // Move x/y to our coordinates.
@@ -838,16 +863,18 @@ void InlineFlowBox::paintMask(PaintInfo& paintInfo, int tx, int ty)
 
     int x = m_x;
     int y = m_y;
-    int w = logicalWidth();
-    int h = logicalHeight();
+    int w = m_isVertical ? logicalHeight() : logicalWidth();
+    int h = m_isVertical ? logicalWidth() : logicalHeight();
 
     // Constrain our background/border painting to the line top and bottom if necessary.
     bool noQuirksMode = renderer()->document()->inNoQuirksMode();
     if (!hasTextChildren() && !noQuirksMode) {
         RootInlineBox* rootBox = root();
-        int bottom = min(rootBox->lineBottom(), y + h);
-        y = max(rootBox->lineTop(), y);
-        h = bottom - y;
+        int& top = m_isVertical ? x : y;
+        int& logicalHeight = m_isVertical ? w : h;
+        int bottom = min(rootBox->lineBottom(), top + logicalHeight);
+        top = max(rootBox->lineTop(), top);
+        logicalHeight = bottom - top;
     }
     
     // Move x/y to our coordinates.
index 31072c3..ee16a0f 100644 (file)
@@ -154,12 +154,13 @@ public:
     void determineSpacingForFlowBoxes(bool lastLine, RenderObject* endObject);
     int getFlowSpacingLogicalWidth();
     bool onEndChain(RenderObject* endObject);
-    int placeBoxesInInlineDirection(int x, bool& needsWordSpacing, GlyphOverflowAndFallbackFontsMap&);
+    int placeBoxesInInlineDirection(int logicalLeft, bool& needsWordSpacing, GlyphOverflowAndFallbackFontsMap&);
     void computeLogicalBoxHeights(int& maxPositionTop, int& maxPositionBottom,
                                   int& maxAscent, int& maxDescent, bool strictMode, GlyphOverflowAndFallbackFontsMap&);
     void adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent,
                                    int maxPositionTop, int maxPositionBottom);
-    void placeBoxesInBlockDirection(int y, int maxHeight, int maxAscent, bool strictMode, int& lineTop, int& lineBottom);
+    void placeBoxesInBlockDirection(int logicalTop, int maxHeight, int maxAscent, bool strictMode, int& lineTop, int& lineBottom);
+    void flipLinesInBlockDirection(int lineTop, int lineBottom);
     void computeBlockDirectionOverflow(int lineTop, int lineBottom, bool strictMode, GlyphOverflowAndFallbackFontsMap&);
 
     void removeChild(InlineBox* child);
index 9f39e0f..cd40173 100644 (file)
@@ -751,6 +751,7 @@ public:
 
     WritingMode writingMode() const { return static_cast<WritingMode>(inherited_flags.m_writingMode); }
     bool isHorizontalWritingMode() const { return writingMode() == TopToBottomWritingMode || writingMode() == BottomToTopWritingMode; }
+    bool isFlippedLinesWritingMode() const { return writingMode() == LeftToRightWritingMode || writingMode() == BottomToTopWritingMode; }
 
     ESpeak speak() { return static_cast<ESpeak>(rareInheritedData->speak); }