https://bugs.webkit.org/show_bug.cgi?id=47841
authorhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Oct 2010 18:38:14 +0000 (18:38 +0000)
committerhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Oct 2010 18:38:14 +0000 (18:38 +0000)
Reviewed by Dan Bernstein.

Rework baselinePosition and lineHeight to be writing-mode-aware.  There's a lot of refactoring here to clean up
the method parameters to be more readable and to simplify the subclassing of the various methods in order to
keep the horizontal/vertical querying to a minimum.

* WebCore.xcodeproj/project.pbxproj:
* mathml/RenderMathMLFraction.cpp:
(WebCore::RenderMathMLFraction::baselinePosition):
* mathml/RenderMathMLFraction.h:
* mathml/RenderMathMLOperator.cpp:
(WebCore::RenderMathMLOperator::baselinePosition):
* mathml/RenderMathMLOperator.h:
* mathml/RenderMathMLRow.cpp:
(WebCore::RenderMathMLRow::baselinePosition):
* mathml/RenderMathMLRow.h:
* mathml/RenderMathMLSubSup.cpp:
(WebCore::RenderMathMLSubSup::baselinePosition):
* mathml/RenderMathMLSubSup.h:
* mathml/RenderMathMLUnderOver.cpp:
(WebCore::RenderMathMLUnderOver::layout):
(WebCore::RenderMathMLUnderOver::baselinePosition):
* mathml/RenderMathMLUnderOver.h:
* rendering/InlineBox.h:
(WebCore::InlineBox::baselinePosition):
(WebCore::InlineBox::lineHeight):
* rendering/InlineFlowBox.cpp:
(WebCore::InlineFlowBox::adjustMaxAscentAndDescent):
(WebCore::InlineFlowBox::computeLogicalBoxHeights):
(WebCore::InlineFlowBox::placeBoxesInBlockDirection):
* rendering/InlineTextBox.cpp:
(WebCore::InlineTextBox::baselinePosition):
(WebCore::InlineTextBox::lineHeight):
* rendering/InlineTextBox.h:
* rendering/RenderBR.cpp:
(WebCore::RenderBR::lineHeight):
* rendering/RenderBR.h:
(WebCore::toRenderBR):
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::lineHeight):
(WebCore::RenderBlock::baselinePosition):
(WebCore::RenderBlock::firstLineBoxBaseline):
(WebCore::RenderBlock::lastLineBoxBaseline):
(WebCore::RenderBlock::localCaretRect):
* rendering/RenderBlock.h:
* rendering/RenderBlockLineLayout.cpp:
(WebCore::RenderBlock::layoutInlineChildren):
* rendering/RenderBox.cpp:
(WebCore::RenderBox::lineHeight):
(WebCore::RenderBox::baselinePosition):
* rendering/RenderBox.h:
* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::verticalPosition):
* rendering/RenderBoxModelObject.h:
* rendering/RenderFileUploadControl.cpp:
(WebCore::RenderFileUploadControl::paintObject):
* rendering/RenderFlexibleBox.cpp:
(WebCore::RenderFlexibleBox::layoutHorizontalBox):
(WebCore::RenderFlexibleBox::layoutVerticalBox):
* rendering/RenderInline.cpp:
(WebCore::RenderInline::lineHeight):
(WebCore::RenderInline::baselinePosition):
* rendering/RenderInline.h:
* rendering/RenderListBox.cpp:
(WebCore::RenderListBox::baselinePosition):
* rendering/RenderListBox.h:
* rendering/RenderListMarker.cpp:
(WebCore::RenderListMarker::lineHeight):
(WebCore::RenderListMarker::baselinePosition):
* rendering/RenderListMarker.h:
* rendering/RenderObject.cpp:
* rendering/RenderObject.h:
* rendering/RenderReplaced.cpp:
* rendering/RenderReplaced.h:
* rendering/RenderSVGRoot.cpp:
* rendering/RenderSVGRoot.h:
* rendering/RenderSlider.cpp:
(WebCore::RenderSlider::baselinePosition):
* rendering/RenderSlider.h:
* rendering/RenderTableCell.cpp:
(WebCore::RenderTableCell::baselinePosition):
* rendering/RenderTableCell.h:
* rendering/RenderTableCol.h:
(WebCore::RenderTableCol::isTableCol):
* rendering/RenderTableRow.h:
* rendering/RenderTableSection.h:
* rendering/RenderText.cpp:
* rendering/RenderText.h:
* rendering/RenderTextControl.cpp:
(WebCore::RenderTextControl::computeLogicalHeight):
* rendering/RenderTextControlMultiLine.cpp:
(WebCore::RenderTextControlMultiLine::baselinePosition):
* rendering/RenderTextControlMultiLine.h:
* rendering/RenderTextControlSingleLine.cpp:
(WebCore::RenderTextControlSingleLine::createInnerTextStyle):
* rendering/RootInlineBox.h:
(WebCore::RootInlineBox::baselinePosition):
(WebCore::RootInlineBox::lineHeight):
* rendering/svg/SVGInlineTextBox.cpp:
(WebCore::SVGInlineTextBox::calculateBoundaries):

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

54 files changed:
WebCore/ChangeLog
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/mathml/RenderMathMLFraction.cpp
WebCore/mathml/RenderMathMLFraction.h
WebCore/mathml/RenderMathMLOperator.cpp
WebCore/mathml/RenderMathMLOperator.h
WebCore/mathml/RenderMathMLRow.cpp
WebCore/mathml/RenderMathMLRow.h
WebCore/mathml/RenderMathMLSubSup.cpp
WebCore/mathml/RenderMathMLSubSup.h
WebCore/mathml/RenderMathMLUnderOver.cpp
WebCore/mathml/RenderMathMLUnderOver.h
WebCore/rendering/InlineBox.h
WebCore/rendering/InlineFlowBox.cpp
WebCore/rendering/InlineTextBox.cpp
WebCore/rendering/InlineTextBox.h
WebCore/rendering/RenderBR.cpp
WebCore/rendering/RenderBR.h
WebCore/rendering/RenderBlock.cpp
WebCore/rendering/RenderBlock.h
WebCore/rendering/RenderBlockLineLayout.cpp
WebCore/rendering/RenderBox.cpp
WebCore/rendering/RenderBox.h
WebCore/rendering/RenderBoxModelObject.cpp
WebCore/rendering/RenderBoxModelObject.h
WebCore/rendering/RenderFileUploadControl.cpp
WebCore/rendering/RenderFlexibleBox.cpp
WebCore/rendering/RenderInline.cpp
WebCore/rendering/RenderInline.h
WebCore/rendering/RenderListBox.cpp
WebCore/rendering/RenderListBox.h
WebCore/rendering/RenderListMarker.cpp
WebCore/rendering/RenderListMarker.h
WebCore/rendering/RenderObject.cpp
WebCore/rendering/RenderObject.h
WebCore/rendering/RenderReplaced.cpp
WebCore/rendering/RenderReplaced.h
WebCore/rendering/RenderSVGRoot.cpp
WebCore/rendering/RenderSVGRoot.h
WebCore/rendering/RenderSlider.cpp
WebCore/rendering/RenderSlider.h
WebCore/rendering/RenderTableCell.cpp
WebCore/rendering/RenderTableCell.h
WebCore/rendering/RenderTableCol.h
WebCore/rendering/RenderTableRow.h
WebCore/rendering/RenderTableSection.h
WebCore/rendering/RenderText.cpp
WebCore/rendering/RenderText.h
WebCore/rendering/RenderTextControl.cpp
WebCore/rendering/RenderTextControlMultiLine.cpp
WebCore/rendering/RenderTextControlMultiLine.h
WebCore/rendering/RenderTextControlSingleLine.cpp
WebCore/rendering/RootInlineBox.h
WebCore/rendering/svg/SVGInlineTextBox.cpp

index 5916ac9..039a462 100644 (file)
@@ -1,3 +1,108 @@
+2010-10-19  David Hyatt  <hyatt@apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        https://bugs.webkit.org/show_bug.cgi?id=47841
+
+        Rework baselinePosition and lineHeight to be writing-mode-aware.  There's a lot of refactoring here to clean up
+        the method parameters to be more readable and to simplify the subclassing of the various methods in order to 
+        keep the horizontal/vertical querying to a minimum.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * mathml/RenderMathMLFraction.cpp:
+        (WebCore::RenderMathMLFraction::baselinePosition):
+        * mathml/RenderMathMLFraction.h:
+        * mathml/RenderMathMLOperator.cpp:
+        (WebCore::RenderMathMLOperator::baselinePosition):
+        * mathml/RenderMathMLOperator.h:
+        * mathml/RenderMathMLRow.cpp:
+        (WebCore::RenderMathMLRow::baselinePosition):
+        * mathml/RenderMathMLRow.h:
+        * mathml/RenderMathMLSubSup.cpp:
+        (WebCore::RenderMathMLSubSup::baselinePosition):
+        * mathml/RenderMathMLSubSup.h:
+        * mathml/RenderMathMLUnderOver.cpp:
+        (WebCore::RenderMathMLUnderOver::layout):
+        (WebCore::RenderMathMLUnderOver::baselinePosition):
+        * mathml/RenderMathMLUnderOver.h:
+        * rendering/InlineBox.h:
+        (WebCore::InlineBox::baselinePosition):
+        (WebCore::InlineBox::lineHeight):
+        * rendering/InlineFlowBox.cpp:
+        (WebCore::InlineFlowBox::adjustMaxAscentAndDescent):
+        (WebCore::InlineFlowBox::computeLogicalBoxHeights):
+        (WebCore::InlineFlowBox::placeBoxesInBlockDirection):
+        * rendering/InlineTextBox.cpp:
+        (WebCore::InlineTextBox::baselinePosition):
+        (WebCore::InlineTextBox::lineHeight):
+        * rendering/InlineTextBox.h:
+        * rendering/RenderBR.cpp:
+        (WebCore::RenderBR::lineHeight):
+        * rendering/RenderBR.h:
+        (WebCore::toRenderBR):
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::lineHeight):
+        (WebCore::RenderBlock::baselinePosition):
+        (WebCore::RenderBlock::firstLineBoxBaseline):
+        (WebCore::RenderBlock::lastLineBoxBaseline):
+        (WebCore::RenderBlock::localCaretRect):
+        * rendering/RenderBlock.h:
+        * rendering/RenderBlockLineLayout.cpp:
+        (WebCore::RenderBlock::layoutInlineChildren):
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::lineHeight):
+        (WebCore::RenderBox::baselinePosition):
+        * rendering/RenderBox.h:
+        * rendering/RenderBoxModelObject.cpp:
+        (WebCore::RenderBoxModelObject::verticalPosition):
+        * rendering/RenderBoxModelObject.h:
+        * rendering/RenderFileUploadControl.cpp:
+        (WebCore::RenderFileUploadControl::paintObject):
+        * rendering/RenderFlexibleBox.cpp:
+        (WebCore::RenderFlexibleBox::layoutHorizontalBox):
+        (WebCore::RenderFlexibleBox::layoutVerticalBox):
+        * rendering/RenderInline.cpp:
+        (WebCore::RenderInline::lineHeight):
+        (WebCore::RenderInline::baselinePosition):
+        * rendering/RenderInline.h:
+        * rendering/RenderListBox.cpp:
+        (WebCore::RenderListBox::baselinePosition):
+        * rendering/RenderListBox.h:
+        * rendering/RenderListMarker.cpp:
+        (WebCore::RenderListMarker::lineHeight):
+        (WebCore::RenderListMarker::baselinePosition):
+        * rendering/RenderListMarker.h:
+        * rendering/RenderObject.cpp:
+        * rendering/RenderObject.h:
+        * rendering/RenderReplaced.cpp:
+        * rendering/RenderReplaced.h:
+        * rendering/RenderSVGRoot.cpp:
+        * rendering/RenderSVGRoot.h:
+        * rendering/RenderSlider.cpp:
+        (WebCore::RenderSlider::baselinePosition):
+        * rendering/RenderSlider.h:
+        * rendering/RenderTableCell.cpp:
+        (WebCore::RenderTableCell::baselinePosition):
+        * rendering/RenderTableCell.h:
+        * rendering/RenderTableCol.h:
+        (WebCore::RenderTableCol::isTableCol):
+        * rendering/RenderTableRow.h:
+        * rendering/RenderTableSection.h:
+        * rendering/RenderText.cpp:
+        * rendering/RenderText.h:
+        * rendering/RenderTextControl.cpp:
+        (WebCore::RenderTextControl::computeLogicalHeight):
+        * rendering/RenderTextControlMultiLine.cpp:
+        (WebCore::RenderTextControlMultiLine::baselinePosition):
+        * rendering/RenderTextControlMultiLine.h:
+        * rendering/RenderTextControlSingleLine.cpp:
+        (WebCore::RenderTextControlSingleLine::createInnerTextStyle):
+        * rendering/RootInlineBox.h:
+        (WebCore::RootInlineBox::baselinePosition):
+        (WebCore::RootInlineBox::lineHeight):
+        * rendering/svg/SVGInlineTextBox.cpp:
+        (WebCore::SVGInlineTextBox::calculateBoundaries):
+
 2010-10-19  Jia Pu  <jpu@apple.com>
 
         Reviewed by Adele Peterson.
index 0429a2f..323ffca 100644 (file)
                BCEA4861097D93020094C9E4 /* RenderBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEA4822097D93020094C9E4 /* RenderBox.cpp */; };
                BCEA4862097D93020094C9E4 /* RenderBox.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEA4823097D93020094C9E4 /* RenderBox.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BCEA4863097D93020094C9E4 /* RenderBR.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEA4824097D93020094C9E4 /* RenderBR.cpp */; };
-               BCEA4864097D93020094C9E4 /* RenderBR.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEA4825097D93020094C9E4 /* RenderBR.h */; };
+               BCEA4864097D93020094C9E4 /* RenderBR.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEA4825097D93020094C9E4 /* RenderBR.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BCEA4865097D93020094C9E4 /* RenderButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEA4826097D93020094C9E4 /* RenderButton.cpp */; };
                BCEA4866097D93020094C9E4 /* RenderButton.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEA4827097D93020094C9E4 /* RenderButton.h */; };
                BCEA4867097D93020094C9E4 /* RenderView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEA4828097D93020094C9E4 /* RenderView.cpp */; };
index 914f6fe..7d48e62 100644 (file)
@@ -174,7 +174,7 @@ void RenderMathMLFraction::paint(PaintInfo& info, int tx, int ty)
     info.context->restore();
 }
 
-int RenderMathMLFraction::baselinePosition(bool firstLine, bool isRootLineBox) const
+int RenderMathMLFraction::baselinePosition(bool firstLine, LineDirectionMode lineDirection, LinePositionMode linePositionMode) const
 {
     if (firstChild() && firstChild()->isRenderMathMLBlock()) {
         RenderMathMLBlock* numerator = toRenderMathMLBlock(firstChild());
@@ -184,7 +184,7 @@ int RenderMathMLFraction::baselinePosition(bool firstLine, bool isRootLineBox) c
         // a good guess.
         return numerator->offsetHeight() + style()->fontSize() / 3;
     }
-    return RenderBlock::baselinePosition(firstLine, isRootLineBox);
+    return RenderBlock::baselinePosition(firstLine, lineDirection, linePositionMode);
 }
 
 }
index c8c1cb8..d0f3fe0 100644 (file)
@@ -38,7 +38,7 @@ public:
     RenderMathMLFraction(Element* fraction);
     virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
     virtual void updateFromElement();
-    virtual int baselinePosition(bool , bool) const; 
+    virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const; 
     virtual void paint(PaintInfo&, int tx, int ty);
 protected:
     virtual void layout();
index 9b28888..1e3b429 100644 (file)
@@ -333,12 +333,11 @@ RenderBlock* RenderMathMLOperator::createGlyph(UChar glyph, int size, int charRe
     return container;
 }
 
-int RenderMathMLOperator::baselinePosition(bool firstLine, bool isRootLineBox) const
+int RenderMathMLOperator::baselinePosition(bool firstLine, LineDirectionMode lineDirection, LinePositionMode linePositionMode) const
 {
     if (m_isStacked)
-        return m_stretchHeight * 2 / 3 - (m_stretchHeight - static_cast<int>(m_stretchHeight / gOperatorExpansion)) / 2;
-    
-    return RenderBlock::baselinePosition(firstLine, isRootLineBox);
+        return m_stretchHeight * 2 / 3 - (m_stretchHeight - static_cast<int>(m_stretchHeight / gOperatorExpansion)) / 2;    
+    return RenderBlock::baselinePosition(firstLine, lineDirection, linePositionMode);
 }
     
 }
index 7df5d49..7091b34 100644 (file)
@@ -41,8 +41,8 @@ public:
     virtual void stretchToHeight(int pixelHeight);
     virtual void updateFromElement(); 
     virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
-    virtual int baselinePosition(bool , bool) const;    
-    
+    virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+        
 protected:
     virtual void layout();
     virtual RefPtr<RenderStyle> createStackableStyle(int size, int topRelative);
index d2dbe3e..632b794 100644 (file)
@@ -145,15 +145,15 @@ void RenderMathMLRow::layout()
     RenderBlock::layout();
 }    
 
-int RenderMathMLRow::baselinePosition(bool firstLine, bool isRootLineBox) const
+int RenderMathMLRow::baselinePosition(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
 {
     if (firstChild() && firstChild()->isRenderMathMLBlock()) {
         RenderMathMLBlock* block = toRenderMathMLBlock(firstChild());
         if (block->isRenderMathMLOperator())
-            return block->y() + block->baselinePosition(firstLine, isRootLineBox);
+            return block->y() + block->baselinePosition(firstLine, direction, linePositionMode);
     }
     
-    return RenderBlock::baselinePosition(firstLine, isRootLineBox);
+    return RenderBlock::baselinePosition(firstLine, direction, linePositionMode);
 }
     
 }
index 83c6832..b363b1b 100644 (file)
@@ -37,7 +37,7 @@ public:
     RenderMathMLRow(Node* container);
     virtual bool isRenderMathMLRow() const { return true; }
     virtual int nonOperatorHeight() const;
-    virtual int baselinePosition(bool , bool) const;    
+    virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;    
 protected:
     virtual void layout();
 };
index 4cda36f..8add254 100644 (file)
@@ -173,49 +173,47 @@ void RenderMathMLSubSup::layout()
     }    
 }
 
-int RenderMathMLSubSup::baselinePosition(bool firstLine, bool isRootLineBox) const
+int RenderMathMLSubSup::baselinePosition(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
 {
     RenderObject* base = firstChild();
     if (!base) 
         return offsetHeight();
     base = base->firstChild();
-    if (!base) 
-        return offsetHeight();
     
     int baseline = offsetHeight();
-    
+    if (!base || !base->isBoxModelObject()) 
+        return baseline;
+
+    RenderBoxModelObject* box = toRenderBoxModelObject(base);
+
     switch (m_kind) {
     case SubSup:
         if (m_scripts) {
-            int topAdjust = 0;
-            if (base->isBoxModelObject()) {
-                RenderBoxModelObject* box = toRenderBoxModelObject(base);
-                topAdjust = (m_scripts->offsetHeight() - box->offsetHeight()) / 2;
-            }
+            int topAdjust = (m_scripts->offsetHeight() - box->offsetHeight()) / 2;
+        
             // FIXME: The last bit of this calculation should be more exact.  Why is the 2-3px scaled for zoom necessary?
             // The baseline is top spacing of the base + the baseline of the base + adjusted space for zoom
             float zoomFactor = style()->effectiveZoom();
-            return topAdjust + base->baselinePosition(firstLine, isRootLineBox) + static_cast<int>((zoomFactor > 1.25 ? 2 : 3) * zoomFactor);
+            return topAdjust + box->baselinePosition(firstLine, direction, linePositionMode) + static_cast<int>((zoomFactor > 1.25 ? 2 : 3) * zoomFactor);
         }
         break;
-    case Sup:
-        if (base) {
-            baseline = base->baselinePosition(firstLine, isRootLineBox) + 4;
-            // FIXME: The extra amount of the superscript ascending above the base's box
-            // isn't taken into account.  This should be calculated in a more reliable
-            // way.
-            RenderObject* sup = base->nextSibling();
-            if (sup && sup->isBoxModelObject()) {
-                RenderBoxModelObject* box = toRenderBoxModelObject(sup);
-                // we'll take half of the sup's box height into account in the baseline
-                baseline += static_cast<int>(box->offsetHeight() * 0.5);
-            }
-            baseline++;
+    case Sup: {
+        baseline = box->baselinePosition(firstLine, direction, linePositionMode) + 4;
+        // FIXME: The extra amount of the superscript ascending above the base's box
+        // isn't taken into account.  This should be calculated in a more reliable
+        // way.
+        RenderObject* sup = base->nextSibling();
+        if (sup && sup->isBoxModelObject()) {
+            RenderBoxModelObject* box = toRenderBoxModelObject(sup);
+            // we'll take half of the sup's box height into account in the baseline
+            baseline += static_cast<int>(box->offsetHeight() * 0.5);
         }
+        baseline++;
         break;
+    }
     case Sub:
-        if (base) 
-            baseline = base->baselinePosition(true) + 4;
+        baseline = box->baselinePosition(true, direction) + 4;
+        break;
     }
     
     return baseline;
index 037ef89..3e62eb0 100644 (file)
@@ -41,7 +41,7 @@ public:
     virtual bool hasBase() const { return true; }
     virtual int nonOperatorHeight() const;
     virtual void stretchToHeight(int pixelHeight);
-    virtual int baselinePosition(bool, bool) const;    
+    virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
 
 protected:
     virtual void layout();
index f015054..69f2c57 100644 (file)
@@ -157,7 +157,10 @@ void RenderMathMLUnderOver::layout()
         if (over) {
             // FIXME: descending glyphs intrude into base (e.g. lowercase y over base)
             // FIXME: bases that ascend higher than the line box intrude into the over
-            int overSpacing = static_cast<int>(gOverSpacingAdjustment * (getOffsetHeight(over) - over->firstChild()->baselinePosition(true)));
+            if (!over->firstChild()->isBoxModelObject())
+                break;
+            
+            int overSpacing = static_cast<int>(gOverSpacingAdjustment * (getOffsetHeight(over) - toRenderBoxModelObject(over->firstChild())->baselinePosition(true, HorizontalLine)));
             
             // base row wrapper
             base = over->nextSibling();
@@ -182,9 +185,12 @@ void RenderMathMLUnderOver::layout()
             int baseHeight = getOffsetHeight(base);
             // actual base
             base = base->firstChild();
+            if (!base->isBoxModelObject())
+                break;
+            
             // FIXME: We need to look at the space between a single maximum height of
             //        the line boxes and the baseline and squeeze them together
-            int underSpacing = baseHeight - base->baselinePosition(true);
+            int underSpacing = baseHeight - toRenderBoxModelObject(base)->baselinePosition(true, HorizontalLine);
             
             // adjust the base's intrusion into the under
             RenderObject* under = lastChild();
@@ -203,7 +209,9 @@ void RenderMathMLUnderOver::layout()
         if (over) {
             // FIXME: descending glyphs intrude into base (e.g. lowercase y over base)
             // FIXME: bases that ascend higher than the line box intrude into the over
-            int overSpacing = static_cast<int>(gOverSpacingAdjustment * (getOffsetHeight(over) - over->firstChild()->baselinePosition(true)));
+            if (!over->firstChild()->isBoxModelObject())
+                break;
+            int overSpacing = static_cast<int>(gOverSpacingAdjustment * (getOffsetHeight(over) - toRenderBoxModelObject(over->firstChild())->baselinePosition(true, HorizontalLine)));
             
             // base row wrapper
             base = over->nextSibling();
@@ -218,9 +226,12 @@ void RenderMathMLUnderOver::layout()
                 int baseHeight = getOffsetHeight(base);
                 // actual base
                 base = base->firstChild();
+                if (!base->isBoxModelObject())
+                    break;
+
                 // FIXME: We need to look at the space between a single maximum height of
                 //        the line boxes and the baseline and squeeze them together
-                int underSpacing = baseHeight - base->baselinePosition(true);
+                int underSpacing = baseHeight - toRenderBoxModelObject(base)->baselinePosition(true, HorizontalLine);
                 
                 RenderObject* under = lastChild();
                 if (under && under->firstChild()->isRenderInline() && underSpacing > 0)
@@ -234,11 +245,11 @@ void RenderMathMLUnderOver::layout()
     RenderBlock::layout();
 }
 
-int RenderMathMLUnderOver::baselinePosition(bool firstLine, bool isRootLineBox) const
+int RenderMathMLUnderOver::baselinePosition(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
 {
     RenderObject* current = firstChild();
     if (!current)
-        return RenderBlock::baselinePosition(firstLine, isRootLineBox);
+        return RenderBlock::baselinePosition(firstLine, direction, linePositionMode);
 
     int baseline = 0;
     switch (m_kind) {
@@ -249,17 +260,17 @@ int RenderMathMLUnderOver::baselinePosition(bool firstLine, bool isRootLineBox)
         if (current) {
             // actual base
             RenderObject* base = current->firstChild();
-            if (!base)
+            if (!base || !base->isBoxModelObject())
                 break;
-            baseline += base->baselinePosition(firstLine, isRootLineBox);
+            baseline += toRenderBoxModelObject(base)->baselinePosition(firstLine, HorizontalLine, linePositionMode);
             // added the negative top margin
             baseline += current->style()->marginTop().value();
         }
         break;
     case Under:
         RenderObject* base = current->firstChild();
-        if (base)
-            baseline += base->baselinePosition(true);
+        if (base && base->isBoxModelObject())
+            baseline += toRenderBoxModelObject(base)->baselinePosition(true, HorizontalLine);
     }
 
     // FIXME: Where is the extra 2-3px adjusted for zoom coming from?
index 5917126..88edea8 100644 (file)
@@ -40,7 +40,7 @@ public:
     virtual void layout();
     virtual bool hasBase() const { return true; }
     virtual int nonOperatorHeight() const;
-    virtual int baselinePosition(bool , bool) const;    
+    virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;    
     virtual void stretchToHeight(int pixelHeight);
 private:
     enum UnderOverType { Under, Over, UnderOver };
index 0afd1df..38a7805 100644 (file)
@@ -21,6 +21,7 @@
 #ifndef InlineBox_h
 #define InlineBox_h
 
+#include "RenderBR.h"
 #include "RenderBoxModelObject.h"
 #include "TextDirection.h"
 
@@ -243,8 +244,9 @@ public:
     // The logical height is our extent in the block flow direction, i.e., height for horizontal text and width for vertical text.
     int logicalHeight() const;
 
-    inline int baselinePosition(bool isRootLineBox) const { return renderer()->baselinePosition(m_firstLine, isRootLineBox); }
-    inline int lineHeight(bool isRootLineBox) const { return renderer()->lineHeight(m_firstLine, isRootLineBox); }
+    virtual int baselinePosition() const { return boxModelObject()->baselinePosition(m_firstLine, m_isVertical ? VerticalLine : HorizontalLine, PositionOnContainingLine); }
+    virtual int lineHeight() const { return boxModelObject()->lineHeight(m_firstLine, m_isVertical ? VerticalLine : HorizontalLine, PositionOnContainingLine); }
+    
 
     virtual int caretMinOffset() const;
     virtual int caretMaxOffset() const;
index fead06d..3ecbf66 100644 (file)
@@ -368,7 +368,7 @@ void InlineFlowBox::adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent,
         if (curr->renderer()->isPositioned())
             continue; // Positioned placeholders don't affect calculations.
         if (curr->y() == PositionTop || curr->y() == PositionBottom) {
-            int lineHeight = curr->lineHeight(false);
+            int lineHeight = curr->lineHeight();
             if (curr->y() == PositionTop) {
                 if (maxAscent + maxDescent < lineHeight)
                     maxDescent = lineHeight - maxAscent;
@@ -401,8 +401,8 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi
 {
     if (isRootInlineBox()) {
         // Examine our root box.
-        int height = lineHeight(true);
-        int baseline = baselinePosition(true);
+        int height = lineHeight();
+        int baseline = baselinePosition();
         if (hasTextChildren() || strictMode) {
             int ascent = baseline;
             int descent = height - ascent;
@@ -455,8 +455,8 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi
                 }
             }
         } else {
-            lineHeight = curr->lineHeight(false);
-            baseline = curr->baselinePosition(false);
+            lineHeight = curr->lineHeight();
+            baseline = curr->baselinePosition();
         }
 
         curr->setY(verticalPositionForBox(curr, m_firstLine));
@@ -483,7 +483,7 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi
 void InlineFlowBox::placeBoxesInBlockDirection(int yPos, int maxHeight, int maxAscent, bool strictMode, int& selectionTop, int& selectionBottom)
 {
     if (isRootInlineBox())
-        setY(yPos + maxAscent - baselinePosition(true)); // Place our root box.
+        setY(yPos + maxAscent - baselinePosition()); // Place our root box.
 
     for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
         if (curr->renderer()->isPositioned())
@@ -499,18 +499,18 @@ void InlineFlowBox::placeBoxesInBlockDirection(int yPos, int maxHeight, int maxA
         if (curr->y() == PositionTop)
             curr->setY(yPos);
         else if (curr->y() == PositionBottom)
-            curr->setY(yPos + maxHeight - curr->lineHeight(false));
+            curr->setY(yPos + maxHeight - curr->lineHeight());
         else {
             if ((isInlineFlow && !static_cast<InlineFlowBox*>(curr)->hasTextChildren()) && !curr->boxModelObject()->hasInlineDirectionBordersOrPadding() && !strictMode)
                 childAffectsTopBottomPos = false;
-            int posAdjust = maxAscent - curr->baselinePosition(false);
+            int posAdjust = maxAscent - curr->baselinePosition();
             curr->setY(curr->y() + yPos + posAdjust);
         }
         
         int newY = curr->y();
         if (curr->isText() || curr->isInlineFlowBox()) {
             const Font& font = curr->renderer()->style(m_firstLine)->font();
-            newY += curr->baselinePosition(false) - font.ascent();
+            newY += curr->baselinePosition() - font.ascent();
             if (curr->isInlineFlowBox())
                 newY -= curr->boxModelObject()->borderTop() + curr->boxModelObject()->paddingTop();
         } else if (!curr->renderer()->isBR()) {
@@ -529,7 +529,7 @@ void InlineFlowBox::placeBoxesInBlockDirection(int yPos, int maxHeight, int maxA
 
     if (isRootInlineBox()) {
         const Font& font = renderer()->style(m_firstLine)->font();
-        setY(y() + baselinePosition(true) - font.ascent());
+        setY(y() + baselinePosition() - font.ascent());
         if (hasTextChildren() || strictMode) {
             selectionTop = min(selectionTop, y());
             selectionBottom = max(selectionBottom, y() + logicalHeight());
index dd1d5a6..cf100e0 100644 (file)
@@ -43,6 +43,22 @@ using namespace std;
 
 namespace WebCore {
 
+int InlineTextBox::baselinePosition() const
+{
+    if (!isText() || !parent())
+        return 0;
+    return parent()->baselinePosition();
+}
+    
+int InlineTextBox::lineHeight() const
+{
+    if (!isText() || !parent())
+        return 0;
+    if (m_renderer->isBR())
+        return toRenderBR(m_renderer)->lineHeight(m_firstLine);
+    return parent()->lineHeight();
+}
+
 int InlineTextBox::selectionTop()
 {
     return root()->selectionTop();
index 0da2e6e..f010c39 100644 (file)
@@ -69,6 +69,10 @@ public:
     void setHasHyphen(bool hasHyphen) { m_hasEllipsisBoxOrHyphen = hasHyphen; }
     static inline bool compareByStart(const InlineTextBox* first, const InlineTextBox* second) { return first->start() < second->start(); }
 
+    
+    virtual int baselinePosition() const;
+    virtual int lineHeight() const;
+
 private:
     virtual int selectionTop();
     virtual int selectionHeight();
index 340d6b7..fb136a4 100644 (file)
@@ -38,36 +38,17 @@ RenderBR::~RenderBR()
 {
 }
 
-int RenderBR::baselinePosition(bool firstLine, bool isRootLineBox) const
+int RenderBR::lineHeight(bool firstLine) const
 {
-    if (firstTextBox() && !firstTextBox()->isText())
-        return 0;
-    return RenderText::baselinePosition(firstLine, isRootLineBox);
-}
-
-int RenderBR::lineHeight(bool firstLine, bool /*isRootLineBox*/) const
-{
-    if (firstTextBox() && !firstTextBox()->isText())
-        return 0;
-
-    if (firstLine) {
+    if (firstLine && document()->usesFirstLineRules()) {
         RenderStyle* s = style(firstLine);
-        Length lh = s->lineHeight();
-        if (lh.isNegative()) {
-            if (s == style()) {
-                if (m_lineHeight == -1)
-                    m_lineHeight = RenderObject::lineHeight(false);
-                return m_lineHeight;
-            }
-            return s->font().lineSpacing();
-        }
-        if (lh.isPercent())
-            return lh.calcMinValue(s->fontSize());
-        return lh.value();
+        if (s != style())
+            return s->computedLineHeight();
     }
-
+    
     if (m_lineHeight == -1)
-        m_lineHeight = RenderObject::lineHeight(false);
+        m_lineHeight = style()->computedLineHeight();
+    
     return m_lineHeight;
 }
 
index 8850d46..7216b5a 100644 (file)
@@ -43,8 +43,7 @@ public:
     virtual unsigned width(unsigned /*from*/, unsigned /*len*/, const Font&, int /*xpos*/) const { return 0; }
     virtual unsigned width(unsigned /*from*/, unsigned /*len*/, int /*xpos*/, bool /*firstLine = false*/) const { return 0; }
 
-    virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const;
-    virtual int baselinePosition(bool firstLine, bool isRootLineBox = false) const;
+    int lineHeight(bool firstLine) const;
 
     // overrides
     virtual bool isBR() const { return true; }
@@ -62,6 +61,22 @@ private:
     mutable int m_lineHeight;
 };
 
+
+inline RenderBR* toRenderBR(RenderObject* object)
+{ 
+    ASSERT(!object || object->isBR());
+    return static_cast<RenderBR*>(object);
+}
+
+inline const RenderBR* toRenderBR(const RenderObject* object)
+{ 
+    ASSERT(!object || object->isBR());
+    return static_cast<const RenderBR*>(object);
+}
+
+// This will catch anyone doing an unnecessary cast.
+void toRenderBR(const RenderBR*);
+
 } // namespace WebCore
 
 #endif // RenderBR_h
index 10218b2..41347e2 100644 (file)
@@ -5164,15 +5164,15 @@ bool RenderBlock::hasLineIfEmpty() const
     return false;
 }
 
-int RenderBlock::lineHeight(bool firstLine, bool isRootLineBox) const
+int RenderBlock::lineHeight(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
 {
     // Inline blocks are replaced elements. Otherwise, just pass off to
     // the base class.  If we're being queried as though we're the root line
     // box, then the fact that we're an inline-block is irrelevant, and we behave
     // just like a block.
-    if (isReplaced() && !isRootLineBox)
-        return height() + marginTop() + marginBottom();
-    
+    if (isReplaced() && linePositionMode == PositionOnContainingLine)
+        return RenderBox::lineHeight(firstLine, direction, linePositionMode);
+
     if (firstLine && document()->usesFirstLineRules()) {
         RenderStyle* s = style(firstLine);
         if (s != style())
@@ -5185,16 +5185,17 @@ int RenderBlock::lineHeight(bool firstLine, bool isRootLineBox) const
     return m_lineHeight;
 }
 
-int RenderBlock::baselinePosition(bool b, bool isRootLineBox) const
+int RenderBlock::baselinePosition(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
 {
     // Inline blocks are replaced elements. Otherwise, just pass off to
     // the base class.  If we're being queried as though we're the root line
     // box, then the fact that we're an inline-block is irrelevant, and we behave
     // just like a block.
-    if (isReplaced() && !isRootLineBox) {
+    if (isReplaced() && linePositionMode == PositionOnContainingLine) {
         // For "leaf" theme objects, let the theme decide what the baseline position is.
         // FIXME: Might be better to have a custom CSS property instead, so that if the theme
         // is turned off, checkboxes/radios will still have decent baselines.
+        // FIXME: Need to patch form controls to deal with vertical lines.
         if (style()->hasAppearance() && !theme()->isControlContainer(style()->appearance()))
             return theme()->baselinePosition(this);
             
@@ -5204,22 +5205,29 @@ int RenderBlock::baselinePosition(bool b, bool isRootLineBox) const
         // We also give up on finding a baseline if we have a vertical scrollbar, or if we are scrolled
         // vertically (e.g., an overflow:hidden block that has had scrollTop moved) or if the baseline is outside
         // of our content box.
-        int baselinePos = (layer() && (layer()->marquee() || layer()->verticalScrollbar() || layer()->scrollYOffset() != 0)) ? -1 : lastLineBoxBaseline();
-        if (baselinePos != -1 && baselinePos <= borderTop() + paddingTop() + contentHeight())
-            return marginTop() + baselinePos;
-        return height() + marginTop() + marginBottom();
+        bool ignoreBaseline = (layer() && (layer()->marquee() || (direction == HorizontalLine ? (layer()->verticalScrollbar() || layer()->scrollYOffset() != 0)
+            : (layer()->horizontalScrollbar() || layer()->scrollXOffset() != 0)))) || isWritingModeRoot();
+        int baselinePos = ignoreBaseline ? -1 : lastLineBoxBaseline();
+        
+        int bottomOfContent = direction == HorizontalLine ? borderTop() + paddingTop() + contentHeight() : borderRight() + paddingRight() + contentWidth();
+        if (baselinePos != -1 && baselinePos <= bottomOfContent)
+            return direction == HorizontalLine ? marginTop() + baselinePos : marginRight() + baselinePos;
+            
+        return RenderBox::baselinePosition(firstLine, direction, linePositionMode);
     }
-    return RenderBox::baselinePosition(b, isRootLineBox);
+
+    const Font& f = style(firstLine)->font();
+    return f.ascent() + (lineHeight(firstLine, direction, linePositionMode) - f.height()) / 2;
 }
 
 int RenderBlock::firstLineBoxBaseline() const
 {
-    if (!isBlockFlow())
+    if (!isBlockFlow() || isWritingModeRoot())
         return -1;
 
     if (childrenInline()) {
         if (firstLineBox())
-            return firstLineBox()->y() + style(true)->font().ascent();
+            return firstLineBox()->logicalTop() + style(true)->font().ascent();
         else
             return -1;
     }
@@ -5228,7 +5236,7 @@ int RenderBlock::firstLineBoxBaseline() const
             if (!curr->isFloatingOrPositioned()) {
                 int result = curr->firstLineBoxBaseline();
                 if (result != -1)
-                    return curr->y() + result; // Translate to our coordinate space.
+                    return curr->logicalTop() + result; // Translate to our coordinate space.
             }
         }
     }
@@ -5238,28 +5246,33 @@ int RenderBlock::firstLineBoxBaseline() const
 
 int RenderBlock::lastLineBoxBaseline() const
 {
-    if (!isBlockFlow())
+    if (!isBlockFlow() || isWritingModeRoot())
         return -1;
 
+    LineDirectionMode lineDirection = style()->isHorizontalWritingMode() ? HorizontalLine : VerticalLine;
+
     if (childrenInline()) {
-        if (!firstLineBox() && hasLineIfEmpty())
-            return RenderBox::baselinePosition(true, true) + borderTop() + paddingTop();
+        if (!firstLineBox() && hasLineIfEmpty()) {
+            const Font& f = firstLineStyle()->font();
+            return f.ascent() + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - f.height()) / 2 + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
+        }
         if (lastLineBox())
-            return lastLineBox()->y() + style(lastLineBox() == firstLineBox())->font().ascent();
+            return lastLineBox()->logicalTop() + style(lastLineBox() == firstLineBox())->font().ascent();
         return -1;
-    }
-    else {
+    } else {
         bool haveNormalFlowChild = false;
         for (RenderBox* curr = lastChildBox(); curr; curr = curr->previousSiblingBox()) {
             if (!curr->isFloatingOrPositioned()) {
                 haveNormalFlowChild = true;
                 int result = curr->lastLineBoxBaseline();
                 if (result != -1)
-                    return curr->y() + result; // Translate to our coordinate space.
+                    return curr->logicalTop() + result; // Translate to our coordinate space.
             }
         }
-        if (!haveNormalFlowChild && hasLineIfEmpty())
-            return RenderBox::baselinePosition(true, true) + borderTop() + paddingTop();
+        if (!haveNormalFlowChild && hasLineIfEmpty()) {
+            const Font& f = firstLineStyle()->font();
+            return f.ascent() + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - f.height()) / 2 + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
+        }
     }
 
     return -1;
@@ -5804,7 +5817,7 @@ IntRect RenderBlock::localCaretRect(InlineBox* inlineBox, int caretOffset, int*
     // constructed and this kludge is not called any more. So only the caret size
     // of an empty :first-line'd block is wrong. I think we can live with that.
     RenderStyle* currentStyle = firstLineStyle();
-    int height = lineHeight(true);
+    int height = lineHeight(true, currentStyle->isHorizontalWritingMode() ? HorizontalLine : VerticalLine);
 
     enum CaretAlignment { alignLeft, alignRight, alignCenter };
 
index 961f0fe..c467289 100644 (file)
@@ -57,8 +57,8 @@ public:
     virtual void destroy();
 
     // These two functions are overridden for inline-block.
-    virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const;
-    virtual int baselinePosition(bool firstLine, bool isRootLineBox = false) const;
+    virtual int lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+    virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
 
     RenderLineBoxList* lineBoxes() { return &m_lineBoxes; }
     const RenderLineBoxList* lineBoxes() const { return &m_lineBoxes; }
index 95625df..4d4333b 100644 (file)
@@ -908,7 +908,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogica
     setLogicalHeight(logicalHeight() + borderAfter() + paddingAfter() + scrollbarLogicalHeight());
 
     if (!firstLineBox() && hasLineIfEmpty())
-        setLogicalHeight(logicalHeight() + lineHeight(true, true));
+        setLogicalHeight(logicalHeight() + lineHeight(true, style()->isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes));
 
     // See if we have any lines that spill out of our block.  If we do, then we will possibly need to
     // truncate text.
index 06393b5..a5ba19a 100644 (file)
@@ -3136,4 +3136,18 @@ void RenderBox::clearLayoutOverflow()
     m_overflow->resetLayoutOverflow(borderBoxRect());
 }
 
+int RenderBox::lineHeight(bool /*firstLine*/, LineDirectionMode direction, LinePositionMode /*linePositionMode*/) const
+{
+    if (isReplaced())
+        return direction == HorizontalLine ? m_marginTop + height() + m_marginBottom : m_marginRight + width() + m_marginLeft;
+    return 0;
+}
+
+int RenderBox::baselinePosition(bool /*firstLine*/, LineDirectionMode direction, LinePositionMode /*linePositionMode*/) const
+{
+    if (isReplaced())
+        return direction == HorizontalLine ? m_marginTop + height() + m_marginBottom : m_marginRight + width() + m_marginLeft;
+    return 0;
+}
+
 } // namespace WebCore
index 9ded12c..30a96c0 100644 (file)
@@ -366,6 +366,9 @@ public:
     virtual void markForPaginationRelayoutIfNeeded() { }
 
     bool isWritingModeRoot() const { return !parent() || parent()->style()->writingMode() != style()->writingMode(); }
+    
+    virtual int lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+    virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
 
 protected:
     virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
index 9b8cab9..ec065a6 100644 (file)
@@ -855,23 +855,25 @@ int RenderBoxModelObject::verticalPosition(bool firstLine) const
         const Font& f = parent()->style(firstLine)->font();
         int fontsize = f.pixelSize();
 
+        LineDirectionMode lineDirection = parent()->style()->isHorizontalWritingMode() ? HorizontalLine : VerticalLine;
+
         if (va == SUB)
             vpos += fontsize / 5 + 1;
         else if (va == SUPER)
             vpos -= fontsize / 3 + 1;
         else if (va == TEXT_TOP)
-            vpos += baselinePosition(firstLine) - f.ascent();
+            vpos += baselinePosition(firstLine, lineDirection) - f.ascent();
         else if (va == MIDDLE)
-            vpos += -static_cast<int>(f.xHeight() / 2) - lineHeight(firstLine) / 2 + baselinePosition(firstLine);
+            vpos += -static_cast<int>(f.xHeight() / 2) - lineHeight(firstLine, lineDirection) / 2 + baselinePosition(firstLine, lineDirection);
         else if (va == TEXT_BOTTOM) {
             vpos += f.descent();
             // lineHeight - baselinePosition is always 0 for replaced elements (except inline blocks), so don't bother wasting time in that case.
             if (!isReplaced() || style()->display() == INLINE_BLOCK)
-                vpos -= (lineHeight(firstLine) - baselinePosition(firstLine));
+                vpos -= (lineHeight(firstLine, lineDirection) - baselinePosition(firstLine, lineDirection));
         } else if (va == BASELINE_MIDDLE)
-            vpos += -lineHeight(firstLine) / 2 + baselinePosition(firstLine);
+            vpos += -lineHeight(firstLine, lineDirection) / 2 + baselinePosition(firstLine, lineDirection);
         else if (va == LENGTH)
-            vpos -= style()->verticalAlignLength().calcValue(lineHeight(firstLine));
+            vpos -= style()->verticalAlignLength().calcValue(lineHeight(firstLine, lineDirection));
     }
 
     return vpos;
index 08dfd3c..33d7ca2 100644 (file)
@@ -33,6 +33,10 @@ const int PositionTop = -0x7fffffff;
 const int PositionBottom = 0x7fffffff;
 const int PositionUndefined = 0x80000000;
 
+// Modes for some of the line-related functions.
+enum LinePositionMode { PositionOnContainingLine, PositionOfInteriorLineBoxes };
+enum LineDirectionMode { HorizontalLine, VerticalLine };
+
 // This class is the base for all objects that adhere to the CSS box model as described
 // at http://www.w3.org/TR/CSS21/box.html
 
@@ -112,6 +116,10 @@ public:
 
     // The difference between this inline's baseline position and the line's baseline position.
     int verticalPosition(bool firstLine) const;
+    
+    // Overridden by subclasses to determine line height and baseline position.
+    virtual int lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const = 0;
+    virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const = 0;
 
     // Called by RenderObject::destroy() (and RenderWidget::destroy()) and is the only way layers should ever be destroyed
     void destroyLayer();
index ccbcf44..3da8530 100644 (file)
@@ -231,7 +231,7 @@ void RenderFileUploadControl::paintObject(PaintInfo& paintInfo, int tx, int ty)
         RenderButton* buttonRenderer = toRenderButton(m_button->renderer());
         int textY = buttonRenderer->absoluteBoundingBoxRect().y()
             + buttonRenderer->marginTop() + buttonRenderer->borderTop() + buttonRenderer->paddingTop()
-            + buttonRenderer->baselinePosition(true, false);
+            + buttonRenderer->baselinePosition(true, HorizontalLine, PositionOnContainingLine);
 
         paintInfo.context->setFillColor(style()->visitedDependentColor(CSSPropertyColor), style()->colorSpace());
         
index 38454fa..da4a6fa 100644 (file)
@@ -394,7 +394,7 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren)
         }
         
         if (!iterator.first() && hasLineIfEmpty())
-            setHeight(height() + lineHeight(true, true));
+            setHeight(height() + lineHeight(true, style()->isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes));
         
         setHeight(height() + toAdd);
         
@@ -737,7 +737,7 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren)
         yPos = height();
         
         if (!iterator.first() && hasLineIfEmpty())
-            setHeight(height() + lineHeight(true, true));
+            setHeight(height() + lineHeight(true, style()->isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes));
     
         setHeight(height() + toAdd);
 
index 22310af..4b28268 100644 (file)
@@ -879,7 +879,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);
@@ -893,6 +893,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.
index 34b29d7..1eb32ff 100644 (file)
@@ -133,7 +133,8 @@ private:
 
     virtual void dirtyLinesFromChangedChild(RenderObject* child) { m_lineBoxes.dirtyLinesFromChangedChild(this, child); }
 
-    virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const;
+    virtual int lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+    virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
     
     virtual void childBecameNonInline(RenderObject* child);
 
index caf82a2..532c551 100644 (file)
@@ -238,9 +238,9 @@ void RenderListBox::computeLogicalHeight()
     }
 }
 
-int RenderListBox::baselinePosition(bool, bool) const
+int RenderListBox::baselinePosition(bool firstLine, LineDirectionMode lineDirection, LinePositionMode linePositionMode) const
 {
-    return height() + marginTop() + marginBottom() - baselineAdjustment;
+    return RenderBox::baselinePosition(firstLine, lineDirection, linePositionMode) - baselineAdjustment;
 }
 
 IntRect RenderListBox::itemBoundingBoxRect(int tx, int ty, int index)
index c69f205..072fc91 100644 (file)
@@ -71,7 +71,7 @@ private:
     virtual bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1, Node** stopNode = 0);
 
     virtual void computePreferredLogicalWidths();
-    virtual int baselinePosition(bool firstLine, bool isRootLineBox) const;
+    virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
     virtual void computeLogicalHeight();
 
     virtual void layout();
index b82d41b..e6250c7 100644 (file)
@@ -1505,20 +1505,18 @@ void RenderListMarker::updateMargins()
     style()->setMarginRight(Length(marginRight, Fixed));
 }
 
-int RenderListMarker::lineHeight(bool, bool) const
+int RenderListMarker::lineHeight(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
 {
     if (!isImage())
-        return m_listItem->lineHeight(false, true);
-    return height();
+        return m_listItem->lineHeight(firstLine, direction, PositionOfInteriorLineBoxes);
+    return RenderBox::lineHeight(firstLine, direction, linePositionMode);
 }
 
-int RenderListMarker::baselinePosition(bool, bool) const
+int RenderListMarker::baselinePosition(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
 {
-    if (!isImage()) {
-        const Font& font = style()->font();
-        return font.ascent() + (lineHeight(false) - font.height())/2;
-    }
-    return height();
+    if (!isImage())
+        return m_listItem->baselinePosition(firstLine, direction, PositionOfInteriorLineBoxes);
+    return RenderBox::baselinePosition(firstLine, direction, linePositionMode);
 }
 
 String RenderListMarker::suffix() const
index 1e55898..fe025c3 100644 (file)
@@ -58,8 +58,8 @@ private:
 
     virtual InlineBox* createInlineBox();
 
-    virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const;
-    virtual int baselinePosition(bool firstLine, bool isRootLineBox = false) const;
+    virtual int lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+    virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
 
     bool isImage() const;
     bool isText() const { return !isImage(); }
index d4ff8ce..1941d31 100644 (file)
@@ -2277,17 +2277,6 @@ bool RenderObject::nodeAtPoint(const HitTestRequest&, HitTestResult&, int /*x*/,
     return false;
 }
 
-int RenderObject::lineHeight(bool firstLine, bool /*isRootLineBox*/) const
-{
-    return style(firstLine)->computedLineHeight();
-}
-
-int RenderObject::baselinePosition(bool firstLine, bool isRootLineBox) const
-{
-    const Font& f = style(firstLine)->font();
-    return f.ascent() + (lineHeight(firstLine, isRootLineBox) - f.height()) / 2;
-}
-
 void RenderObject::scheduleRelayout()
 {
     if (isRenderView()) {
index ac92da4..9c29ce1 100644 (file)
@@ -485,11 +485,6 @@ public:
     void updateFillImages(const FillLayer*, const FillLayer*);
     void updateImage(StyleImage*, StyleImage*);
 
-    // for discussion of lineHeight see CSS2 spec
-    virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const;
-    // for the vertical-align property of inline elements
-    // the offset of baseline from the top of the object.
-    virtual int baselinePosition(bool firstLine, bool isRootLineBox = false) const;
     virtual void paint(PaintInfo&, int tx, int ty);
 
     // Recursive function that computes the size and position of this object and all its descendants.
index 7690ac9..a087038 100644 (file)
@@ -269,16 +269,6 @@ void RenderReplaced::computePreferredLogicalWidths()
     setPreferredLogicalWidthsDirty(false);
 }
 
-int RenderReplaced::lineHeight(bool, bool) const
-{
-    return height() + marginTop() + marginBottom();
-}
-
-int RenderReplaced::baselinePosition(bool, bool) const
-{
-    return height() + marginTop() + marginBottom();
-}
-
 unsigned RenderReplaced::caretMaxRenderedOffset() const
 {
     return 1; 
index 044ee81..fbc5151 100644 (file)
@@ -60,9 +60,6 @@ private:
 
     virtual bool canHaveChildren() const { return false; }
 
-    virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const;
-    virtual int baselinePosition(bool firstLine, bool isRootLineBox = false) const;
-
     virtual void computePreferredLogicalWidths();
 
     int calcAspectRatioLogicalWidth() const;
index a71454c..215aac7 100644 (file)
@@ -57,16 +57,6 @@ RenderSVGRoot::~RenderSVGRoot()
 {
 }
 
-int RenderSVGRoot::lineHeight(bool, bool) const
-{
-    return height() + marginTop() + marginBottom();
-}
-
-int RenderSVGRoot::baselinePosition(bool, bool) const
-{
-    return height() + marginTop() + marginBottom();
-}
-
 void RenderSVGRoot::computePreferredLogicalWidths()
 {
     ASSERT(preferredLogicalWidthsDirty());
index 0f723be..1b6aa22 100644 (file)
@@ -52,8 +52,6 @@ private:
     virtual bool isSVGRoot() const { return true; }
     virtual const char* renderName() const { return "RenderSVGRoot"; }
 
-    virtual int lineHeight(bool b, bool isRootLineBox = false) const;
-    virtual int baselinePosition(bool b, bool isRootLineBox = false) const;
     virtual void computePreferredLogicalWidths();
     virtual int computeReplacedLogicalWidth(bool includeMaxWidth = true) const;
     virtual int computeReplacedLogicalHeight() const;
index 40cffc1..240278d 100644 (file)
@@ -155,7 +155,7 @@ RenderSlider::~RenderSlider()
         m_thumb->detach();
 }
 
-int RenderSlider::baselinePosition(bool, bool) const
+int RenderSlider::baselinePosition(bool /*firstLine*/, LineDirectionMode, LinePositionMode) const
 {
     return height() + marginTop();
 }
index d214e41..fa743de 100644 (file)
@@ -42,7 +42,7 @@ namespace WebCore {
         virtual const char* renderName() const { return "RenderSlider"; }
         virtual bool isSlider() const { return true; }
 
-        virtual int baselinePosition(bool, bool) const;
+        virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
         virtual void computePreferredLogicalWidths();
         virtual void layout();
         virtual void updateFromElement();
index 005d8df..69d63cf 100644 (file)
@@ -291,10 +291,11 @@ void RenderTableCell::computeRectForRepaint(RenderBoxModelObject* repaintContain
     RenderBlock::computeRectForRepaint(repaintContainer, r, fixed);
 }
 
-int RenderTableCell::baselinePosition(bool firstLine, bool isRootLineBox) const
+int RenderTableCell::baselinePosition(bool firstLine, LineDirectionMode lineDirection, LinePositionMode linePositionMode) const
 {
-    if (isRootLineBox)
-        return RenderBox::baselinePosition(firstLine, isRootLineBox);
+    // FIXME: This function still needs to be patched for writing-mode.
+    if (linePositionMode == PositionOfInteriorLineBoxes)
+        return RenderBlock::baselinePosition(firstLine, lineDirection, linePositionMode);
 
     // <http://www.w3.org/TR/2007/CR-CSS21-20070719/tables.html#height-layout>: The baseline of a cell is the baseline of
     // the first in-flow line box in the cell, or the first in-flow table-row in the cell, whichever comes first. If there
index d803f05..31879d6 100644 (file)
@@ -88,7 +88,7 @@ public:
 
     void paintBackgroundsBehindCell(PaintInfo&, int tx, int ty, RenderObject* backgroundObject);
 
-    virtual int baselinePosition(bool firstLine = false, bool isRootLineBox = false) const;
+    virtual int baselinePosition(bool firstLine = false, LineDirectionMode = HorizontalLine, LinePositionMode = PositionOnContainingLine) const;
 
     void setIntrinsicPaddingBefore(int p) { m_intrinsicPaddingBefore = p; }
     void setIntrinsicPaddingAfter(int p) { m_intrinsicPaddingAfter = p; }
index 5fb4128..8255937 100644 (file)
@@ -50,7 +50,6 @@ private:
 
     virtual const char* renderName() const { return "RenderTableCol"; }
     virtual bool isTableCol() const { return true; }
-    virtual int lineHeight(bool) const { return 0; }
     virtual void updateFromElement();
 
     virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
index 3059060..20aa424 100644 (file)
@@ -50,7 +50,6 @@ private:
     virtual void destroy();
 
     virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
-    virtual int lineHeight(bool, bool) const { return 0; }
     virtual void layout();
     virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
     virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
index 0393aae..119ff9d 100644 (file)
@@ -149,8 +149,6 @@ private:
 
     virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
 
-    virtual int lineHeight(bool, bool) const { return 0; }
-
     bool ensureRows(int);
     void clearGrid();
 
index bc7e396..510d830 100644 (file)
@@ -1139,12 +1139,6 @@ String RenderText::textWithoutTranscoding() const
     return text;
 }
 
-int RenderText::lineHeight(bool firstLine, bool) const
-{
-    // Always use the interior line height of the parent (e.g., if our parent is an inline block).
-    return parent()->lineHeight(firstLine, true);
-}
-
 void RenderText::dirtyLineBoxes(bool fullLayout)
 {
     if (fullLayout)
index e3a6997..964a1d3 100644 (file)
@@ -74,8 +74,6 @@ public:
     virtual unsigned width(unsigned from, unsigned len, const Font&, int xPos, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
     virtual unsigned width(unsigned from, unsigned len, int xPos, bool firstLine = false, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
 
-    virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const;
-
     virtual int minPreferredLogicalWidth() const;
     virtual int maxPreferredLogicalWidth() const;
 
index 7cfe7c9..4855bab 100644 (file)
@@ -409,7 +409,7 @@ void RenderTextControl::computeLogicalHeight()
               m_innerText->renderBox()->paddingTop() + m_innerText->renderBox()->paddingBottom() +
               m_innerText->renderBox()->marginTop() + m_innerText->renderBox()->marginBottom());
 
-    adjustControlHeightBasedOnLineHeight(m_innerText->renderer()->lineHeight(true, true));
+    adjustControlHeightBasedOnLineHeight(m_innerText->renderBox()->lineHeight(true, HorizontalLine, PositionOfInteriorLineBoxes));
     setHeight(height() + borderAndPaddingHeight());
 
     // We are able to have a horizontal scrollbar if the overflow style is scroll, or if its auto and there's no word wrap.
index bf7abb0..64293fe 100644 (file)
@@ -99,9 +99,9 @@ void RenderTextControlMultiLine::adjustControlHeightBasedOnLineHeight(int lineHe
     setHeight(height() + lineHeight * static_cast<HTMLTextAreaElement*>(node())->rows());
 }
 
-int RenderTextControlMultiLine::baselinePosition(bool, bool) const
+int RenderTextControlMultiLine::baselinePosition(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
 {
-    return height() + marginTop() + marginBottom();
+    return RenderBox::baselinePosition(firstLine, direction, linePositionMode);
 }
 
 void RenderTextControlMultiLine::updateFromElement()
index fbca308..e061e89 100644 (file)
@@ -43,7 +43,7 @@ private:
     virtual float getAvgCharWidth(AtomicString family);
     virtual int preferredContentWidth(float charWidth) const;
     virtual void adjustControlHeightBasedOnLineHeight(int lineHeight);
-    virtual int baselinePosition(bool firstLine, bool isRootLineBox) const;
+    virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
 
     virtual void updateFromElement();
     virtual void cacheSelection(int start, int end);
index 2211110..85efae8 100644 (file)
@@ -726,7 +726,7 @@ PassRefPtr<RenderStyle> RenderTextControlSingleLine::createInnerTextStyle(const
     textBlockStyle->setOverflowY(OHIDDEN);
 
     // Do not allow line-height to be smaller than our default.
-    if (textBlockStyle->font().lineSpacing() > lineHeight(true, true))
+    if (textBlockStyle->font().lineSpacing() > lineHeight(true, HorizontalLine, PositionOfInteriorLineBoxes))
         textBlockStyle->setLineHeight(Length(-100.0f, Percent));
 
     WebCore::EDisplay display = (m_innerBlock || inputElement()->hasSpinButton() ? INLINE_BLOCK : BLOCK);
index 3f64b45..4a0b485 100644 (file)
@@ -88,6 +88,9 @@ public:
 
     virtual void clearTruncation();
 
+    virtual int baselinePosition() const { return boxModelObject()->baselinePosition(m_firstLine, m_isVertical ? VerticalLine : HorizontalLine, PositionOfInteriorLineBoxes); }
+    virtual int lineHeight() const { return boxModelObject()->lineHeight(m_firstLine, m_isVertical ? VerticalLine : HorizontalLine, PositionOfInteriorLineBoxes); }
+
 #if PLATFORM(MAC)
     void addHighlightOverflow();
     void paintCustomHighlight(PaintInfo&, int tx, int ty, const AtomicString& highlightType);
index 72f15dd..0458af5 100644 (file)
@@ -588,7 +588,7 @@ IntRect SVGInlineTextBox::calculateBoundaries() const
     RenderStyle* style = textRenderer->style();
     ASSERT(style);
 
-    int baseline = baselinePosition(true);
+    int baseline = baselinePosition();
     int heightDifference = baseline - style->font().ascent();
 
     unsigned textFragmentsSize = m_textFragments.size();