[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

hyatt at apple.com hyatt at apple.com
Wed Dec 22 16:00:18 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 4a9c625a38991ac9a34b99a1f30f8fb7053d99f1
Author: hyatt at apple.com <hyatt at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Nov 17 20:55:40 2010 +0000

    https://bugs.webkit.org/show_bug.cgi?id=48537
    
    Reviewed by Sam Weinig.
    
    WebCore:
    
    Fonts with no vertical metrics should synthesize baselines when they appear
    on lines that do use fonts with vertical metrics.  Basically we want to make
    sure that English text behaves like vertical-align:middle, i.e., its baseline
    should be treated as though it cuts through the middle of the ascent+descent.
    
    The way this works is that each line in the line box tree is labeled as having
    a baseline type that is either ideographic or alphabetic for the purposes of
    vertical alignment.  A line becomes ideographic if any font with vertical tables
    is either explicitly specified as the primary font or in any of the used fonts
    in the text on that line.
    
    This baselineType is passed down to computeLogicalBoxHeights and placeBoxesInBlockDirection,
    and passed to the ascent and descent methods of the fonts that are examined.
    The underlying Font code selects an appropriate baseline given the type passed in.
    
    This patch also rewrites vertical alignment to lop 4 bytes off all RenderInlines and
    to instead carry around the cached vertical positions for RenderInlines in a new
    VerticalPositionCache object.  This cache only lives for a single layout
    operation, but it does cache information across all the lines built and placed during the
    layout.
    
    This matches the old behavior, since every call to layoutInlineChildren invalidated
    all of the vertical positions in all of the RenderInlines anyway.
    
    The VerticalPositionCache consists of two HashMaps, and it caches vertical alignment
    positions for both alphabetic and ideographic baseline types.
    
    The vertical-align computation has now been moved out of RenderBoxModelObject and
    RenderInline and just placed right into verticalPositionForBox in InlineFlowBox.
    This function has been changed to no longer be recursive when checking parents,
    and it now relies on the fact that the parent vertical alignment computation result
    has already been stored in the logicalTop() of that parent's line box.  By checking
    the line box logicalTop() value instead of recurring, the performance of first lines
    now significantly improves to no longer have O(n^2) behavior in the depth of the line
    box tree on the first line.
    
    All of the baselinePosition functions on the various RenderObjects have been amended
    to take a FontBaseline as the first argument.  This patch does not attempt to fix up
    MathML or form controls yet and just hardcodes AlphabeticBaselines for those renderers.
    
    The RenderTableCell baselinePosition virtual method has been made non-virtual and had
    all arguments removed, since it actually had no real connection with the rest of the
    baseline positioning system.  Cell baseline positioning works by calling firstLineBoxBaseline,
    and that method has been patched to use the cached baselineType for the first line box
    when computing the baseline of that line.
    
    Added fast/blockflow/vertical-baseline-alignment.html and fast/blockflow/vertical-align-table-baseline.html.
    
    * 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:
    * platform/graphics/SimpleFontData.h:
    * rendering/InlineBox.h:
    (WebCore::InlineBox::baselinePosition):
    * rendering/InlineFlowBox.cpp:
    (WebCore::verticalPositionForBox):
    (WebCore::InlineFlowBox::computeLogicalBoxHeights):
    (WebCore::InlineFlowBox::placeBoxesInBlockDirection):
    * rendering/InlineFlowBox.h:
    * rendering/InlineTextBox.cpp:
    (WebCore::InlineTextBox::baselinePosition):
    * rendering/InlineTextBox.h:
    * rendering/RenderBlock.cpp:
    (WebCore::RenderBlock::baselinePosition):
    (WebCore::RenderBlock::firstLineBoxBaseline):
    (WebCore::RenderBlock::lastLineBoxBaseline):
    * rendering/RenderBlock.h:
    * rendering/RenderBlockLineLayout.cpp:
    (WebCore::RenderBlock::computeBlockDirectionPositionsForLine):
    (WebCore::RenderBlock::layoutInlineChildren):
    * rendering/RenderBox.cpp:
    (WebCore::RenderBox::baselinePosition):
    * rendering/RenderBox.h:
    * rendering/RenderBoxModelObject.cpp:
    * rendering/RenderBoxModelObject.h:
    * rendering/RenderFileUploadControl.cpp:
    (WebCore::RenderFileUploadControl::paintObject):
    * rendering/RenderInline.cpp:
    (WebCore::RenderInline::RenderInline):
    (WebCore::RenderInline::baselinePosition):
    * rendering/RenderInline.h:
    * rendering/RenderListBox.cpp:
    (WebCore::RenderListBox::baselinePosition):
    * rendering/RenderListBox.h:
    * rendering/RenderListMarker.cpp:
    (WebCore::RenderListMarker::baselinePosition):
    * rendering/RenderListMarker.h:
    * rendering/RenderSlider.cpp:
    (WebCore::RenderSlider::baselinePosition):
    * rendering/RenderSlider.h:
    * rendering/RenderTableCell.cpp:
    (WebCore::RenderTableCell::baselinePosition):
    * rendering/RenderTableCell.h:
    * rendering/RenderTextControlMultiLine.cpp:
    (WebCore::RenderTextControlMultiLine::baselinePosition):
    * rendering/RenderTextControlMultiLine.h:
    * rendering/RootInlineBox.cpp:
    (WebCore::RootInlineBox::alignBoxesInBlockDirection):
    * rendering/RootInlineBox.h:
    (WebCore::RootInlineBox::baselinePosition):
    * rendering/VerticalPositionCache.h: Added.
    (WebCore::VerticalPositionCache::VerticalPositionCache):
    (WebCore::VerticalPositionCache::get):
    (WebCore::VerticalPositionCache::set):
    * rendering/svg/SVGInlineTextBox.cpp:
    (WebCore::SVGInlineTextBox::calculateBoundaries):
    
    LayoutTests:
    
    Fonts with no vertical metrics should synthesize baselines when they appear
    on lines that do use fonts with vertical metrics.  Basically we want to make
    sure that English text behaves like vertical-align:middle, i.e., its baseline
    should be treated as though it cuts through the middle of the ascent+descent.
    
    The way this works is that each line in the line box tree is labeled as having
    a baseline type that is either ideographic or alphabetic for the purposes of
    vertical alignment.  A line becomes ideographic if any font with vertical tables
    is either explicitly specified as the primary font or in any of the used fonts
    in the text on that line.
    
    This baselineType is passed down to computeLogicalBoxHeights and placeBoxesInBlockDirection,
    and passed to the ascent and descent methods of the fonts that are examined.
    The underlying Font code selects an appropriate baseline given the type passed in.
    
    This patch also rewrites vertical alignment to lop 4 bytes off all RenderInlines and
    to instead carry around the cached vertical positions for RenderInlines in a new
    VerticalPositionCache object.  This cache only lives for a single layout
    operation, but it does cache information across all the lines built and placed during the
    layout.
    
    This matches the old behavior, since every call to layoutInlineChildren invalidated
    all of the vertical positions in all of the RenderInlines anyway.
    
    The VerticalPositionCache consists of two HashMaps, and it caches vertical alignment
    positions for both alphabetic and ideographic baseline types.
    
    The vertical-align computation has now been moved out of RenderBoxModelObject and
    RenderInline and just placed right into verticalPositionForBox in InlineFlowBox.
    This function has been changed to no longer be recursive when checking parents,
    and it now relies on the fact that the parent vertical alignment computation result
    has already been stored in the logicalTop() of that parent's line box.  By checking
    the line box logicalTop() value instead of recurring, the performance of first lines
    now significantly improves to no longer have O(n^2) behavior in the depth of the line
    box tree on the first line.
    
    All of the baselinePosition functions on the various RenderObjects have been amended
    to take a FontBaseline as the first argument.  This patch does not attempt to fix up
    MathML or form controls yet and just hardcodes AlphabeticBaselines for those renderers.
    
    The RenderTableCell baselinePosition virtual method has been made non-virtual and had
    all arguments removed, since it actually had no real connection with the rest of the
    baseline positioning system.  Cell baseline positioning works by calling firstLineBoxBaseline,
    and that method has been patched to use the cached baselineType for the first line box
    when computing the baseline of that line.
    
    Added fast/blockflow/vertical-baseline-alignment.html and fast/blockflow/vertical-align-table-baseline.html
    
    * fast/blockflow/vertical-align-table-baseline.html: Added.
    * fast/blockflow/vertical-baseline-alignment.html: Added.
    * platform/mac/fast/blockflow/vertical-align-table-baseline-expected.checksum: Added.
    * platform/mac/fast/blockflow/vertical-align-table-baseline-expected.png: Added.
    * platform/mac/fast/blockflow/vertical-align-table-baseline-expected.txt: Added.
    * platform/mac/fast/blockflow/vertical-baseline-alignment-expected.checksum: Added.
    * platform/mac/fast/blockflow/vertical-baseline-alignment-expected.png: Added.
    * platform/mac/fast/blockflow/vertical-baseline-alignment-expected.txt: Added.
    * platform/mac/fast/blockflow/vertical-font-fallback-expected.checksum:
    * platform/mac/fast/blockflow/vertical-font-fallback-expected.png:
    * platform/mac/fast/blockflow/vertical-font-fallback-expected.txt:
    * platform/mac/fast/repaint/repaint-across-writing-mode-boundary-expected.checksum:
    * platform/mac/fast/repaint/repaint-across-writing-mode-boundary-expected.png:
    * platform/mac/fast/repaint/repaint-across-writing-mode-boundary-expected.txt:
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@72235 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 2a4be41..005bc48 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,72 @@
+2010-11-17  Dave Hyatt  <hyatt at apple.com>
+
+        Reviewed by Sam Weinig.
+
+        https://bugs.webkit.org/show_bug.cgi?id=48537
+
+        Fonts with no vertical metrics should synthesize baselines when they appear
+        on lines that do use fonts with vertical metrics.  Basically we want to make
+        sure that English text behaves like vertical-align:middle, i.e., its baseline
+        should be treated as though it cuts through the middle of the ascent+descent.
+        
+        The way this works is that each line in the line box tree is labeled as having
+        a baseline type that is either ideographic or alphabetic for the purposes of
+        vertical alignment.  A line becomes ideographic if any font with vertical tables
+        is either explicitly specified as the primary font or in any of the used fonts
+        in the text on that line.
+        
+        This baselineType is passed down to computeLogicalBoxHeights and placeBoxesInBlockDirection,
+        and passed to the ascent and descent methods of the fonts that are examined.
+        The underlying Font code selects an appropriate baseline given the type passed in.
+        
+        This patch also rewrites vertical alignment to lop 4 bytes off all RenderInlines and
+        to instead carry around the cached vertical positions for RenderInlines in a new
+        VerticalPositionCache object.  This cache only lives for a single layout
+        operation, but it does cache information across all the lines built and placed during the
+        layout.
+        
+        This matches the old behavior, since every call to layoutInlineChildren invalidated
+        all of the vertical positions in all of the RenderInlines anyway.
+        
+        The VerticalPositionCache consists of two HashMaps, and it caches vertical alignment
+        positions for both alphabetic and ideographic baseline types.
+        
+        The vertical-align computation has now been moved out of RenderBoxModelObject and
+        RenderInline and just placed right into verticalPositionForBox in InlineFlowBox.
+        This function has been changed to no longer be recursive when checking parents,
+        and it now relies on the fact that the parent vertical alignment computation result
+        has already been stored in the logicalTop() of that parent's line box.  By checking
+        the line box logicalTop() value instead of recurring, the performance of first lines
+        now significantly improves to no longer have O(n^2) behavior in the depth of the line
+        box tree on the first line.
+        
+        All of the baselinePosition functions on the various RenderObjects have been amended
+        to take a FontBaseline as the first argument.  This patch does not attempt to fix up
+        MathML or form controls yet and just hardcodes AlphabeticBaselines for those renderers.
+        
+        The RenderTableCell baselinePosition virtual method has been made non-virtual and had
+        all arguments removed, since it actually had no real connection with the rest of the 
+        baseline positioning system.  Cell baseline positioning works by calling firstLineBoxBaseline,
+        and that method has been patched to use the cached baselineType for the first line box
+        when computing the baseline of that line.
+         
+        Added fast/blockflow/vertical-baseline-alignment.html and fast/blockflow/vertical-align-table-baseline.html
+
+        * fast/blockflow/vertical-align-table-baseline.html: Added.
+        * fast/blockflow/vertical-baseline-alignment.html: Added.
+        * platform/mac/fast/blockflow/vertical-align-table-baseline-expected.checksum: Added.
+        * platform/mac/fast/blockflow/vertical-align-table-baseline-expected.png: Added.
+        * platform/mac/fast/blockflow/vertical-align-table-baseline-expected.txt: Added.
+        * platform/mac/fast/blockflow/vertical-baseline-alignment-expected.checksum: Added.
+        * platform/mac/fast/blockflow/vertical-baseline-alignment-expected.png: Added.
+        * platform/mac/fast/blockflow/vertical-baseline-alignment-expected.txt: Added.
+        * platform/mac/fast/blockflow/vertical-font-fallback-expected.checksum:
+        * platform/mac/fast/blockflow/vertical-font-fallback-expected.png:
+        * platform/mac/fast/blockflow/vertical-font-fallback-expected.txt:
+        * platform/mac/fast/repaint/repaint-across-writing-mode-boundary-expected.checksum:
+        * platform/mac/fast/repaint/repaint-across-writing-mode-boundary-expected.png:
+        * platform/mac/fast/repaint/repaint-across-writing-mode-boundary-expected.txt:
+
 2010-11-17  Martin Robinson  <mrobinson at igalia.com>
 
         Update the skipped list to skip a newly failing geolocation test (requires
diff --git a/LayoutTests/fast/blockflow/vertical-align-table-baseline.html b/LayoutTests/fast/blockflow/vertical-align-table-baseline.html
new file mode 100644
index 0000000..8a8c77d
--- /dev/null
+++ b/LayoutTests/fast/blockflow/vertical-align-table-baseline.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML>
+<html style="-webkit-writing-mode: vertical-lr">
+<head>
+<title>Vertical Font Table Baseline Test</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+  
+<style type="text/css">
+
+body { font-family: "HiraMinPro-W3"; font-size:48px  }
+.large { font-size:96px; }
+td { vertical-align: baseline; }
+
+</style>
+</head>
+<body>
+
+<table border=2 style="" ><tr><td>第一段落
+<td class="large">第二段落 
+</table>
+</body>
+</html>
\ No newline at end of file
diff --git a/LayoutTests/fast/blockflow/vertical-baseline-alignment.html b/LayoutTests/fast/blockflow/vertical-baseline-alignment.html
new file mode 100644
index 0000000..f7806ad
--- /dev/null
+++ b/LayoutTests/fast/blockflow/vertical-baseline-alignment.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html style="-webkit-writing-mode: vertical-rl">
+<head>
+<title>Vertical Font Baseline Test</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+  
+<style type="text/css">
+
+body {  font-size:24px  }
+
+.japanese { font-family: "HiraMinPro-W3"; }
+.english { font-size:48px; text-transform:uppercase }
+
+
+</style>
+</head>
+<body>
+
+<p><span class="japanese">第一段落 </span><span class="english">Paragraph 1
+<br>
+More text. <span style="font-size:12px">Should not be centered.</span>
+</span></p><p><span>第二段落 <span class="english">Paragraph 2
+<img style="background-color:green; width:70px; height:30px;">
+</span></span></p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/fast/blockflow/vertical-align-table-baseline-expected.checksum b/LayoutTests/platform/mac/fast/blockflow/vertical-align-table-baseline-expected.checksum
new file mode 100644
index 0000000..6bc2653
--- /dev/null
+++ b/LayoutTests/platform/mac/fast/blockflow/vertical-align-table-baseline-expected.checksum
@@ -0,0 +1 @@
+cac0a4b3ae891093b271ed0361a026f3
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/fast/blockflow/vertical-align-table-baseline-expected.png b/LayoutTests/platform/mac/fast/blockflow/vertical-align-table-baseline-expected.png
new file mode 100644
index 0000000..107b9ea
Binary files /dev/null and b/LayoutTests/platform/mac/fast/blockflow/vertical-align-table-baseline-expected.png differ
diff --git a/LayoutTests/platform/mac/fast/blockflow/vertical-align-table-baseline-expected.txt b/LayoutTests/platform/mac/fast/blockflow/vertical-align-table-baseline-expected.txt
new file mode 100644
index 0000000..7e47aa4
--- /dev/null
+++ b/LayoutTests/platform/mac/fast/blockflow/vertical-align-table-baseline-expected.txt
@@ -0,0 +1,16 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 316x600
+  RenderBlock {HTML} at (0,0) size 316x600
+    RenderBody {BODY} at (8,8) size 300x584
+      RenderTable {TABLE} at (0,0) size 300x584 [border: (2px outset #808080)]
+        RenderTableSection {TBODY} at (2,2) size 296x580
+          RenderTableRow {TR} at (0,2) size 292x580
+            RenderTableCell {TD} at (2,38) size 292x49 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=1]
+              RenderText {#text} at (50,-34) size 120x146
+                text run at (50,-34) width 146: "\x{7B2C}\x{4E00}\x{6BB5}"
+                text run at (122,-34) width 49: "\x{843D}"
+            RenderTableCell {TD} at (2,197) size 292x381 [border: (1px inset #808080)] [r=0 c=1 rs=1 cs=1]
+              RenderText {#text} at (26,2) size 240x291
+                text run at (26,2) width 291: "\x{7B2C}\x{4E8C}\x{6BB5}"
+                text run at (170,2) width 97: "\x{843D}"
diff --git a/LayoutTests/platform/mac/fast/blockflow/vertical-baseline-alignment-expected.checksum b/LayoutTests/platform/mac/fast/blockflow/vertical-baseline-alignment-expected.checksum
new file mode 100644
index 0000000..0523976
--- /dev/null
+++ b/LayoutTests/platform/mac/fast/blockflow/vertical-baseline-alignment-expected.checksum
@@ -0,0 +1 @@
+339f0a1668c07d9a069f6d88da44eba1
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/fast/blockflow/vertical-baseline-alignment-expected.png b/LayoutTests/platform/mac/fast/blockflow/vertical-baseline-alignment-expected.png
new file mode 100644
index 0000000..8c9395b
Binary files /dev/null and b/LayoutTests/platform/mac/fast/blockflow/vertical-baseline-alignment-expected.png differ
diff --git a/LayoutTests/platform/mac/fast/blockflow/vertical-baseline-alignment-expected.txt b/LayoutTests/platform/mac/fast/blockflow/vertical-baseline-alignment-expected.txt
new file mode 100644
index 0000000..b0cd7f0
--- /dev/null
+++ b/LayoutTests/platform/mac/fast/blockflow/vertical-baseline-alignment-expected.txt
@@ -0,0 +1,28 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (604,0) size 196x600
+  RenderBlock {HTML} at (0,0) size 196x600
+    RenderBody {BODY} at (8,8) size 180x584
+      RenderBlock {P} at (0,24) size 110x536
+        RenderInline {SPAN} at (0,0) size 24x108
+          RenderText {#text} at (16,0) size 24x108
+            text run at (16,0) width 108: "\x{7B2C}\x{4E00}\x{6BB5}\x{843D} "
+        RenderInline {SPAN} at (0,0) size 110x461
+          RenderText {#text} at (0,108) size 55x341
+            text run at (0,108) width 341: "PARAGRAPH 1 "
+          RenderBR {BR} at (0,449) size 55x0
+          RenderText {#text} at (55,0) size 55x297
+            text run at (55,0) width 297: "MORE TEXT. "
+          RenderInline {SPAN} at (0,0) size 14x164
+            RenderText {#text} at (87,297) size 14x164
+              text run at (87,297) width 164: "SHOULD NOT BE CENTERED."
+          RenderText {#text} at (0,0) size 0x0
+      RenderBlock {P} at (110,24) size 70x536
+        RenderInline {SPAN} at (0,0) size 28x477
+          RenderText {#text} at (21,0) size 28x106
+            text run at (21,0) width 106: "\x{7B2C}\x{4E8C}\x{6BB5}\x{843D} "
+          RenderInline {SPAN} at (0,0) size 55x371
+            RenderText {#text} at (7,106) size 55x341
+              text run at (7,106) width 341: "PARAGRAPH 2 "
+            RenderImage {IMG} at (0,447) size 70x30 [bgcolor=#008000]
+            RenderText {#text} at (0,0) size 0x0
diff --git a/LayoutTests/platform/mac/fast/blockflow/vertical-font-fallback-expected.checksum b/LayoutTests/platform/mac/fast/blockflow/vertical-font-fallback-expected.checksum
index 480d8ab..28ad1c9 100644
--- a/LayoutTests/platform/mac/fast/blockflow/vertical-font-fallback-expected.checksum
+++ b/LayoutTests/platform/mac/fast/blockflow/vertical-font-fallback-expected.checksum
@@ -1 +1 @@
-1a38c793aeaed823708cc6bd9330c2d3
\ No newline at end of file
+3c29af017e24ccc90fe35bd1d4377664
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/fast/blockflow/vertical-font-fallback-expected.png b/LayoutTests/platform/mac/fast/blockflow/vertical-font-fallback-expected.png
index 88aaa5a..6fbcdb1 100644
Binary files a/LayoutTests/platform/mac/fast/blockflow/vertical-font-fallback-expected.png and b/LayoutTests/platform/mac/fast/blockflow/vertical-font-fallback-expected.png differ
diff --git a/LayoutTests/platform/mac/fast/blockflow/vertical-font-fallback-expected.txt b/LayoutTests/platform/mac/fast/blockflow/vertical-font-fallback-expected.txt
index fb6232f..ff54513 100644
--- a/LayoutTests/platform/mac/fast/blockflow/vertical-font-fallback-expected.txt
+++ b/LayoutTests/platform/mac/fast/blockflow/vertical-font-fallback-expected.txt
@@ -4,13 +4,13 @@ layer at (0,0) size 800x377
   RenderBlock {HTML} at (0,0) size 800x377
     RenderBody {BODY} at (50,50) size 700x277
       RenderBlock {DIV} at (0,0) size 556x277 [bgcolor=#EEEEEE]
-        RenderBlock {DIV} at (1,1) size 277x127 [bgcolor=#FFEEEE]
-          RenderBlock {P} at (14,28) size 249x22 [bgcolor=#FFAAAA] [border: (20px solid #FF8888) none (20px solid #FF8888)]
-            RenderText {#text} at (21,0) size 181x23
-              text run at (21,0) width 181: "\x{7B2C}\x{4E00}\x{6BB5}\x{843D} paragraph 1"
-          RenderBlock {P} at (14,77) size 249x22 [bgcolor=#FFAAAA] [border: (20px solid #FF8888) none (20px solid #FF8888)]
-            RenderText {#text} at (21,0) size 181x23
-              text run at (21,0) width 181: "\x{7B2C}\x{4E8C}\x{6BB5}\x{843D} paragraph 2"
+        RenderBlock {DIV} at (1,1) size 277x129 [bgcolor=#FFEEEE]
+          RenderBlock {P} at (14,28) size 249x23 [bgcolor=#FFAAAA] [border: (20px solid #FF8888) none (20px solid #FF8888)]
+            RenderText {#text} at (21,1) size 181x23
+              text run at (21,1) width 181: "\x{7B2C}\x{4E00}\x{6BB5}\x{843D} paragraph 1"
+          RenderBlock {P} at (14,78) size 249x23 [bgcolor=#FFAAAA] [border: (20px solid #FF8888) none (20px solid #FF8888)]
+            RenderText {#text} at (21,1) size 181x23
+              text run at (21,1) width 181: "\x{7B2C}\x{4E8C}\x{6BB5}\x{843D} paragraph 2"
         RenderBlock {DIV} at (278,1) size 277x275 [bgcolor=#FFFFEE]
           RenderBlock {P} at (14,28) size 62x219 [bgcolor=#FFAAAA] [border: (20px solid #FF8888) none (20px solid #FF8888)]
             RenderText {#text} at (20,1) size 23x185
diff --git a/LayoutTests/platform/mac/fast/repaint/repaint-across-writing-mode-boundary-expected.checksum b/LayoutTests/platform/mac/fast/repaint/repaint-across-writing-mode-boundary-expected.checksum
index 738f581..5f6d414 100644
--- a/LayoutTests/platform/mac/fast/repaint/repaint-across-writing-mode-boundary-expected.checksum
+++ b/LayoutTests/platform/mac/fast/repaint/repaint-across-writing-mode-boundary-expected.checksum
@@ -1 +1 @@
-7df50cf92359b0a4f0ba95b803db77aa
\ No newline at end of file
+14415853860aa0e125353aa6fcdd7c35
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/fast/repaint/repaint-across-writing-mode-boundary-expected.png b/LayoutTests/platform/mac/fast/repaint/repaint-across-writing-mode-boundary-expected.png
index fe555c6..3c691c1 100644
Binary files a/LayoutTests/platform/mac/fast/repaint/repaint-across-writing-mode-boundary-expected.png and b/LayoutTests/platform/mac/fast/repaint/repaint-across-writing-mode-boundary-expected.png differ
diff --git a/LayoutTests/platform/mac/fast/repaint/repaint-across-writing-mode-boundary-expected.txt b/LayoutTests/platform/mac/fast/repaint/repaint-across-writing-mode-boundary-expected.txt
index 3228eb5..386b570 100644
--- a/LayoutTests/platform/mac/fast/repaint/repaint-across-writing-mode-boundary-expected.txt
+++ b/LayoutTests/platform/mac/fast/repaint/repaint-across-writing-mode-boundary-expected.txt
@@ -4,13 +4,13 @@ layer at (0,0) size 800x377
   RenderBlock {HTML} at (0,0) size 800x377
     RenderBody {BODY} at (50,50) size 700x277
       RenderBlock {DIV} at (0,0) size 556x277 [bgcolor=#EEEEEE]
-        RenderBlock {DIV} at (1,1) size 277x127 [bgcolor=#FFEEEE]
-          RenderBlock {P} at (14,28) size 249x22 [bgcolor=#FFAAAA] [border: (20px solid #FF8888) none (20px solid #FF8888)]
-            RenderText {#text} at (21,0) size 181x23
-              text run at (21,0) width 181: "\x{7B2C}\x{4E00}\x{6BB5}\x{843D} paragraph 1"
-          RenderBlock {P} at (14,77) size 249x22 [bgcolor=#FFAAAA] [border: (20px solid #FF8888) none (20px solid #FF8888)]
-            RenderText {#text} at (21,0) size 181x23
-              text run at (21,0) width 181: "\x{7B2C}\x{4E8C}\x{6BB5}\x{843D} paragraph 2"
+        RenderBlock {DIV} at (1,1) size 277x129 [bgcolor=#FFEEEE]
+          RenderBlock {P} at (14,28) size 249x23 [bgcolor=#FFAAAA] [border: (20px solid #FF8888) none (20px solid #FF8888)]
+            RenderText {#text} at (21,1) size 181x23
+              text run at (21,1) width 181: "\x{7B2C}\x{4E00}\x{6BB5}\x{843D} paragraph 1"
+          RenderBlock {P} at (14,78) size 249x23 [bgcolor=#FFAAAA] [border: (20px solid #FF8888) none (20px solid #FF8888)]
+            RenderText {#text} at (21,1) size 181x23
+              text run at (21,1) width 181: "\x{7B2C}\x{4E8C}\x{6BB5}\x{843D} paragraph 2"
         RenderBlock {DIV} at (278,1) size 277x275 [bgcolor=#FFFFEE]
           RenderBlock {P} at (14,28) size 62x219 [bgcolor=#FFAAAA] [border: (20px solid #FF8888) none (20px solid #FF8888)]
             RenderText {#text} at (20,1) size 23x185
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 9c012c9..909194c 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,130 @@
+2010-11-17  Dave Hyatt  <hyatt at apple.com>
+
+        Reviewed by Sam Weinig.
+
+        https://bugs.webkit.org/show_bug.cgi?id=48537
+
+        Fonts with no vertical metrics should synthesize baselines when they appear
+        on lines that do use fonts with vertical metrics.  Basically we want to make
+        sure that English text behaves like vertical-align:middle, i.e., its baseline
+        should be treated as though it cuts through the middle of the ascent+descent.
+        
+        The way this works is that each line in the line box tree is labeled as having
+        a baseline type that is either ideographic or alphabetic for the purposes of
+        vertical alignment.  A line becomes ideographic if any font with vertical tables
+        is either explicitly specified as the primary font or in any of the used fonts
+        in the text on that line.
+        
+        This baselineType is passed down to computeLogicalBoxHeights and placeBoxesInBlockDirection,
+        and passed to the ascent and descent methods of the fonts that are examined.
+        The underlying Font code selects an appropriate baseline given the type passed in.
+        
+        This patch also rewrites vertical alignment to lop 4 bytes off all RenderInlines and
+        to instead carry around the cached vertical positions for RenderInlines in a new
+        VerticalPositionCache object.  This cache only lives for a single layout
+        operation, but it does cache information across all the lines built and placed during the
+        layout.
+        
+        This matches the old behavior, since every call to layoutInlineChildren invalidated
+        all of the vertical positions in all of the RenderInlines anyway.
+        
+        The VerticalPositionCache consists of two HashMaps, and it caches vertical alignment
+        positions for both alphabetic and ideographic baseline types.
+        
+        The vertical-align computation has now been moved out of RenderBoxModelObject and
+        RenderInline and just placed right into verticalPositionForBox in InlineFlowBox.
+        This function has been changed to no longer be recursive when checking parents,
+        and it now relies on the fact that the parent vertical alignment computation result
+        has already been stored in the logicalTop() of that parent's line box.  By checking
+        the line box logicalTop() value instead of recurring, the performance of first lines
+        now significantly improves to no longer have O(n^2) behavior in the depth of the line
+        box tree on the first line.
+        
+        All of the baselinePosition functions on the various RenderObjects have been amended
+        to take a FontBaseline as the first argument.  This patch does not attempt to fix up
+        MathML or form controls yet and just hardcodes AlphabeticBaselines for those renderers.
+        
+        The RenderTableCell baselinePosition virtual method has been made non-virtual and had
+        all arguments removed, since it actually had no real connection with the rest of the 
+        baseline positioning system.  Cell baseline positioning works by calling firstLineBoxBaseline,
+        and that method has been patched to use the cached baselineType for the first line box
+        when computing the baseline of that line.
+         
+        Added fast/blockflow/vertical-baseline-alignment.html and fast/blockflow/vertical-align-table-baseline.html.
+
+        * 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:
+        * platform/graphics/SimpleFontData.h:
+        * rendering/InlineBox.h:
+        (WebCore::InlineBox::baselinePosition):
+        * rendering/InlineFlowBox.cpp:
+        (WebCore::verticalPositionForBox):
+        (WebCore::InlineFlowBox::computeLogicalBoxHeights):
+        (WebCore::InlineFlowBox::placeBoxesInBlockDirection):
+        * rendering/InlineFlowBox.h:
+        * rendering/InlineTextBox.cpp:
+        (WebCore::InlineTextBox::baselinePosition):
+        * rendering/InlineTextBox.h:
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::baselinePosition):
+        (WebCore::RenderBlock::firstLineBoxBaseline):
+        (WebCore::RenderBlock::lastLineBoxBaseline):
+        * rendering/RenderBlock.h:
+        * rendering/RenderBlockLineLayout.cpp:
+        (WebCore::RenderBlock::computeBlockDirectionPositionsForLine):
+        (WebCore::RenderBlock::layoutInlineChildren):
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::baselinePosition):
+        * rendering/RenderBox.h:
+        * rendering/RenderBoxModelObject.cpp:
+        * rendering/RenderBoxModelObject.h:
+        * rendering/RenderFileUploadControl.cpp:
+        (WebCore::RenderFileUploadControl::paintObject):
+        * rendering/RenderInline.cpp:
+        (WebCore::RenderInline::RenderInline):
+        (WebCore::RenderInline::baselinePosition):
+        * rendering/RenderInline.h:
+        * rendering/RenderListBox.cpp:
+        (WebCore::RenderListBox::baselinePosition):
+        * rendering/RenderListBox.h:
+        * rendering/RenderListMarker.cpp:
+        (WebCore::RenderListMarker::baselinePosition):
+        * rendering/RenderListMarker.h:
+        * rendering/RenderSlider.cpp:
+        (WebCore::RenderSlider::baselinePosition):
+        * rendering/RenderSlider.h:
+        * rendering/RenderTableCell.cpp:
+        (WebCore::RenderTableCell::baselinePosition):
+        * rendering/RenderTableCell.h:
+        * rendering/RenderTextControlMultiLine.cpp:
+        (WebCore::RenderTextControlMultiLine::baselinePosition):
+        * rendering/RenderTextControlMultiLine.h:
+        * rendering/RootInlineBox.cpp:
+        (WebCore::RootInlineBox::alignBoxesInBlockDirection):
+        * rendering/RootInlineBox.h:
+        (WebCore::RootInlineBox::baselinePosition):
+        * rendering/VerticalPositionCache.h: Added.
+        (WebCore::VerticalPositionCache::VerticalPositionCache):
+        (WebCore::VerticalPositionCache::get):
+        (WebCore::VerticalPositionCache::set):
+        * rendering/svg/SVGInlineTextBox.cpp:
+        (WebCore::SVGInlineTextBox::calculateBoundaries):
+
 2010-11-17  Sam Weinig  <sam at webkit.org>
 
         Reviewed by Anders Carlsson.
diff --git a/WebCore/WebCore.xcodeproj/project.pbxproj b/WebCore/WebCore.xcodeproj/project.pbxproj
index f3bd8b6..8ac2d7e 100644
--- a/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -5016,6 +5016,7 @@
 		BC9BC64E0E7C4889008B9849 /* ScrollbarClient.h in Headers */ = {isa = PBXBuildFile; fileRef = BC9BC64C0E7C4889008B9849 /* ScrollbarClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		BCA169A20BFD55B40019CA76 /* JSHTMLTableCaptionElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCA169A00BFD55B40019CA76 /* JSHTMLTableCaptionElement.cpp */; };
 		BCA169A30BFD55B40019CA76 /* JSHTMLTableCaptionElement.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA169A10BFD55B40019CA76 /* JSHTMLTableCaptionElement.h */; };
+		BCA257151293C010007A263D /* VerticalPositionCache.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA257141293C010007A263D /* VerticalPositionCache.h */; };
 		BCA2B061105047600043BD1C /* UserScript.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA2B0601050475F0043BD1C /* UserScript.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		BCA2B08B10505BCD0043BD1C /* UserScriptTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA2B08A10505BCD0043BD1C /* UserScriptTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		BCA83E4F0D7CE1E9003421A8 /* JSClipboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCA83E4D0D7CE1E9003421A8 /* JSClipboard.cpp */; };
@@ -11050,6 +11051,7 @@
 		BC9BC64C0E7C4889008B9849 /* ScrollbarClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollbarClient.h; sourceTree = "<group>"; };
 		BCA169A00BFD55B40019CA76 /* JSHTMLTableCaptionElement.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLTableCaptionElement.cpp; sourceTree = "<group>"; };
 		BCA169A10BFD55B40019CA76 /* JSHTMLTableCaptionElement.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSHTMLTableCaptionElement.h; sourceTree = "<group>"; };
+		BCA257141293C010007A263D /* VerticalPositionCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VerticalPositionCache.h; sourceTree = "<group>"; };
 		BCA2B0601050475F0043BD1C /* UserScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserScript.h; sourceTree = "<group>"; };
 		BCA2B08A10505BCD0043BD1C /* UserScriptTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserScriptTypes.h; sourceTree = "<group>"; };
 		BCA378BA0D15F64200B793D6 /* ScheduledAction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScheduledAction.cpp; sourceTree = "<group>"; };
@@ -18104,6 +18106,7 @@
 				37FC96DA1104ED71003E1FAD /* TrailingFloatsRootInlineBox.h */,
 				0F500AB00F54DB3100EEF928 /* TransformState.cpp */,
 				0F500AAE0F54DB1B00EEF928 /* TransformState.h */,
+				BCA257141293C010007A263D /* VerticalPositionCache.h */,
 			);
 			path = rendering;
 			sourceTree = "<group>";
@@ -21336,6 +21339,7 @@
 				08250939128BD4D800E2ED8E /* SVGAnimatedTransformList.h in Headers */,
 				3888F6EF128C9889000CA8E0 /* InspectorFileSystemAgent.h in Headers */,
 				BCB92D4F1293550B00C8387F /* FontBaseline.h in Headers */,
+				BCA257151293C010007A263D /* VerticalPositionCache.h in Headers */,
 				BCAE1FA712939DB7004CB026 /* ScrollAnimatorMac.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
diff --git a/WebCore/mathml/RenderMathMLFraction.cpp b/WebCore/mathml/RenderMathMLFraction.cpp
index 1000604..1435be7 100644
--- a/WebCore/mathml/RenderMathMLFraction.cpp
+++ b/WebCore/mathml/RenderMathMLFraction.cpp
@@ -167,7 +167,7 @@ void RenderMathMLFraction::paint(PaintInfo& info, int tx, int ty)
     info.context->restore();
 }
 
-int RenderMathMLFraction::baselinePosition(bool firstLine, LineDirectionMode lineDirection, LinePositionMode linePositionMode) const
+int RenderMathMLFraction::baselinePosition(FontBaseline, bool firstLine, LineDirectionMode lineDirection, LinePositionMode linePositionMode) const
 {
     if (firstChild() && firstChild()->isRenderMathMLBlock()) {
         RenderMathMLBlock* numerator = toRenderMathMLBlock(firstChild());
@@ -177,7 +177,7 @@ int RenderMathMLFraction::baselinePosition(bool firstLine, LineDirectionMode lin
         // a good guess.
         return numerator->offsetHeight() + style()->fontSize() / 3;
     }
-    return RenderBlock::baselinePosition(firstLine, lineDirection, linePositionMode);
+    return RenderBlock::baselinePosition(AlphabeticBaseline, firstLine, lineDirection, linePositionMode);
 }
 
 }
diff --git a/WebCore/mathml/RenderMathMLFraction.h b/WebCore/mathml/RenderMathMLFraction.h
index d0f3fe0..8a3a9ed 100644
--- a/WebCore/mathml/RenderMathMLFraction.h
+++ b/WebCore/mathml/RenderMathMLFraction.h
@@ -38,7 +38,7 @@ public:
     RenderMathMLFraction(Element* fraction);
     virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
     virtual void updateFromElement();
-    virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const; 
+    virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const; 
     virtual void paint(PaintInfo&, int tx, int ty);
 protected:
     virtual void layout();
diff --git a/WebCore/mathml/RenderMathMLOperator.cpp b/WebCore/mathml/RenderMathMLOperator.cpp
index 9f35480..72c997b 100644
--- a/WebCore/mathml/RenderMathMLOperator.cpp
+++ b/WebCore/mathml/RenderMathMLOperator.cpp
@@ -332,11 +332,11 @@ RenderBlock* RenderMathMLOperator::createGlyph(UChar glyph, int size, int charRe
     return container;
 }
 
-int RenderMathMLOperator::baselinePosition(bool firstLine, LineDirectionMode lineDirection, LinePositionMode linePositionMode) const
+int RenderMathMLOperator::baselinePosition(FontBaseline, 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, lineDirection, linePositionMode);
+    return RenderBlock::baselinePosition(AlphabeticBaseline, firstLine, lineDirection, linePositionMode);
 }
     
 }
diff --git a/WebCore/mathml/RenderMathMLOperator.h b/WebCore/mathml/RenderMathMLOperator.h
index 7091b34..6501494 100644
--- a/WebCore/mathml/RenderMathMLOperator.h
+++ b/WebCore/mathml/RenderMathMLOperator.h
@@ -41,7 +41,7 @@ public:
     virtual void stretchToHeight(int pixelHeight);
     virtual void updateFromElement(); 
     virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
-    virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+    virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
         
 protected:
     virtual void layout();
diff --git a/WebCore/mathml/RenderMathMLRow.cpp b/WebCore/mathml/RenderMathMLRow.cpp
index ae911fc..ad54846 100644
--- a/WebCore/mathml/RenderMathMLRow.cpp
+++ b/WebCore/mathml/RenderMathMLRow.cpp
@@ -119,15 +119,15 @@ void RenderMathMLRow::layout()
     
 }    
 
-int RenderMathMLRow::baselinePosition(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
+int RenderMathMLRow::baselinePosition(FontBaseline, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
 {
     if (firstChild() && firstChild()->isRenderMathMLBlock()) {
         RenderMathMLBlock* block = toRenderMathMLBlock(firstChild());
         if (block->isRenderMathMLOperator())
-            return block->y() + block->baselinePosition(firstLine, direction, linePositionMode);
+            return block->y() + block->baselinePosition(AlphabeticBaseline, firstLine, direction, linePositionMode);
     }
     
-    return RenderBlock::baselinePosition(firstLine, direction, linePositionMode);
+    return RenderBlock::baselinePosition(AlphabeticBaseline, firstLine, direction, linePositionMode);
 }
     
 }
diff --git a/WebCore/mathml/RenderMathMLRow.h b/WebCore/mathml/RenderMathMLRow.h
index c877561..62a0d09 100644
--- a/WebCore/mathml/RenderMathMLRow.h
+++ b/WebCore/mathml/RenderMathMLRow.h
@@ -37,7 +37,7 @@ public:
     RenderMathMLRow(Node* container);
     virtual bool isRenderMathMLRow() const { return true; }
     virtual int nonOperatorHeight() const;
-    virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;    
+    virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;    
     virtual void stretchToHeight(int) {}
 protected:
     virtual void layout();
diff --git a/WebCore/mathml/RenderMathMLSubSup.cpp b/WebCore/mathml/RenderMathMLSubSup.cpp
index 6c9c6b9..f4ed506 100644
--- a/WebCore/mathml/RenderMathMLSubSup.cpp
+++ b/WebCore/mathml/RenderMathMLSubSup.cpp
@@ -173,7 +173,7 @@ void RenderMathMLSubSup::layout()
     }    
 }
 
-int RenderMathMLSubSup::baselinePosition(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
+int RenderMathMLSubSup::baselinePosition(FontBaseline, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
 {
     RenderObject* base = firstChild();
     if (!base) 
@@ -194,13 +194,13 @@ int RenderMathMLSubSup::baselinePosition(bool firstLine, LineDirectionMode direc
             // 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 + box->baselinePosition(firstLine, direction, linePositionMode) + static_cast<int>((zoomFactor > 1.25 ? 2 : 3) * zoomFactor);
+            return topAdjust + box->baselinePosition(AlphabeticBaseline, firstLine, direction, linePositionMode) + static_cast<int>((zoomFactor > 1.25 ? 2 : 3) * zoomFactor);
         }
         break;
     case Sup: 
     case Sub:
         RenderBoxModelObject* box = toRenderBoxModelObject(base);
-        baseline = box->baselinePosition(firstLine, direction, linePositionMode);
+        baseline = box->baselinePosition(AlphabeticBaseline, firstLine, direction, linePositionMode);
         break;
     }
     
diff --git a/WebCore/mathml/RenderMathMLSubSup.h b/WebCore/mathml/RenderMathMLSubSup.h
index 3e62eb0..7a9d310 100644
--- a/WebCore/mathml/RenderMathMLSubSup.h
+++ b/WebCore/mathml/RenderMathMLSubSup.h
@@ -41,7 +41,7 @@ public:
     virtual bool hasBase() const { return true; }
     virtual int nonOperatorHeight() const;
     virtual void stretchToHeight(int pixelHeight);
-    virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+    virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
 
 protected:
     virtual void layout();
diff --git a/WebCore/mathml/RenderMathMLUnderOver.cpp b/WebCore/mathml/RenderMathMLUnderOver.cpp
index a76f6b1..a3de697 100644
--- a/WebCore/mathml/RenderMathMLUnderOver.cpp
+++ b/WebCore/mathml/RenderMathMLUnderOver.cpp
@@ -158,7 +158,7 @@ void RenderMathMLUnderOver::layout()
             if (!over->firstChild()->isBoxModelObject())
                 break;
             
-            int overSpacing = static_cast<int>(gOverSpacingAdjustment * (getOffsetHeight(over) - toRenderBoxModelObject(over->firstChild())->baselinePosition(true, HorizontalLine)));
+            int overSpacing = static_cast<int>(gOverSpacingAdjustment * (getOffsetHeight(over) - toRenderBoxModelObject(over->firstChild())->baselinePosition(AlphabeticBaseline, true, HorizontalLine)));
             
             // base row wrapper
             base = over->nextSibling();
@@ -188,7 +188,7 @@ void RenderMathMLUnderOver::layout()
             
             // 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 - toRenderBoxModelObject(base)->baselinePosition(true, HorizontalLine);
+            int underSpacing = baseHeight - toRenderBoxModelObject(base)->baselinePosition(AlphabeticBaseline, true, HorizontalLine);
             
             // adjust the base's intrusion into the under
             RenderObject* under = lastChild();
@@ -209,7 +209,7 @@ void RenderMathMLUnderOver::layout()
             // FIXME: bases that ascend higher than the line box intrude into the over
             if (!over->firstChild()->isBoxModelObject())
                 break;
-            int overSpacing = static_cast<int>(gOverSpacingAdjustment * (getOffsetHeight(over) - toRenderBoxModelObject(over->firstChild())->baselinePosition(true, HorizontalLine)));
+            int overSpacing = static_cast<int>(gOverSpacingAdjustment * (getOffsetHeight(over) - toRenderBoxModelObject(over->firstChild())->baselinePosition(AlphabeticBaseline, true, HorizontalLine)));
             
             // base row wrapper
             base = over->nextSibling();
@@ -229,7 +229,7 @@ void RenderMathMLUnderOver::layout()
 
                 // 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 - toRenderBoxModelObject(base)->baselinePosition(true, HorizontalLine);
+                int underSpacing = baseHeight - toRenderBoxModelObject(base)->baselinePosition(AlphabeticBaseline, true, HorizontalLine);
                 
                 RenderObject* under = lastChild();
                 if (under && under->firstChild()->isRenderInline() && underSpacing > 0)
@@ -243,11 +243,11 @@ void RenderMathMLUnderOver::layout()
     RenderBlock::layout();
 }
 
-int RenderMathMLUnderOver::baselinePosition(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
+int RenderMathMLUnderOver::baselinePosition(FontBaseline, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
 {
     RenderObject* current = firstChild();
     if (!current)
-        return RenderBlock::baselinePosition(firstLine, direction, linePositionMode);
+        return RenderBlock::baselinePosition(AlphabeticBaseline, firstLine, direction, linePositionMode);
 
     int baseline = 0;
     switch (m_kind) {
@@ -260,7 +260,7 @@ int RenderMathMLUnderOver::baselinePosition(bool firstLine, LineDirectionMode di
             RenderObject* base = current->firstChild();
             if (!base || !base->isBoxModelObject())
                 break;
-            baseline += toRenderBoxModelObject(base)->baselinePosition(firstLine, HorizontalLine, linePositionMode);
+            baseline += toRenderBoxModelObject(base)->baselinePosition(AlphabeticBaseline, firstLine, HorizontalLine, linePositionMode);
             // added the negative top margin
             baseline += current->style()->marginTop().value();
         }
@@ -268,7 +268,7 @@ int RenderMathMLUnderOver::baselinePosition(bool firstLine, LineDirectionMode di
     case Under:
         RenderObject* base = current->firstChild();
         if (base && base->isBoxModelObject())
-            baseline += toRenderBoxModelObject(base)->baselinePosition(true, HorizontalLine);
+            baseline += toRenderBoxModelObject(base)->baselinePosition(AlphabeticBaseline, true, HorizontalLine);
     }
 
     // FIXME: Where is the extra 2-3px adjusted for zoom coming from?
diff --git a/WebCore/mathml/RenderMathMLUnderOver.h b/WebCore/mathml/RenderMathMLUnderOver.h
index 88edea8..fbab72a 100644
--- a/WebCore/mathml/RenderMathMLUnderOver.h
+++ b/WebCore/mathml/RenderMathMLUnderOver.h
@@ -40,7 +40,7 @@ public:
     virtual void layout();
     virtual bool hasBase() const { return true; }
     virtual int nonOperatorHeight() const;
-    virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;    
+    virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;    
     virtual void stretchToHeight(int pixelHeight);
 private:
     enum UnderOverType { Under, Over, UnderOver };
diff --git a/WebCore/platform/graphics/SimpleFontData.h b/WebCore/platform/graphics/SimpleFontData.h
index 8ff8ead..432a164 100644
--- a/WebCore/platform/graphics/SimpleFontData.h
+++ b/WebCore/platform/graphics/SimpleFontData.h
@@ -80,7 +80,9 @@ public:
 
     SimpleFontData* brokenIdeographFontData() const;
     
-    // vertical metrics
+    // FIXME: Use the actual metrics for fonts with vertical tables instead of just hard-coding.  If the font is horizontally oriented or
+    // a broken ideographic font, then just hard-code to split ascent/descent down the middle.  Otherwise we should actually use the metrics
+    // from the font itself.
     int ascent(FontBaseline baselineType = AlphabeticBaseline) const { return baselineType == AlphabeticBaseline ? m_ascent : height() - height() / 2; }
     int descent(FontBaseline baselineType = AlphabeticBaseline) const { return baselineType == AlphabeticBaseline ? m_descent : height() / 2; }
     int height() const { return m_ascent + m_descent; }
diff --git a/WebCore/rendering/InlineBox.h b/WebCore/rendering/InlineBox.h
index f79330a..c5f1997 100644
--- a/WebCore/rendering/InlineBox.h
+++ b/WebCore/rendering/InlineBox.h
@@ -255,7 +255,7 @@ 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;
 
-    virtual int baselinePosition() const { return boxModelObject()->baselinePosition(m_firstLine, isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingLine); }
+    virtual int baselinePosition(FontBaseline baselineType) const { return boxModelObject()->baselinePosition(baselineType, m_firstLine, isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingLine); }
     virtual int lineHeight() const { return boxModelObject()->lineHeight(m_firstLine, isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingLine); }
     
 
diff --git a/WebCore/rendering/InlineFlowBox.cpp b/WebCore/rendering/InlineFlowBox.cpp
index 756e126..e67c751 100644
--- a/WebCore/rendering/InlineFlowBox.cpp
+++ b/WebCore/rendering/InlineFlowBox.cpp
@@ -35,6 +35,7 @@
 #include "RenderTableCell.h"
 #include "RootInlineBox.h"
 #include "Text.h"
+#include "VerticalPositionCache.h"
 
 #include <math.h>
 
@@ -424,18 +425,76 @@ void InlineFlowBox::adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent,
     }
 }
 
-static int verticalPositionForBox(InlineBox* curr, bool firstLine)
+static int verticalPositionForBox(InlineBox* box, FontBaseline baselineType, bool firstLine, VerticalPositionCache& verticalPositionCache)
 {
-    if (curr->renderer()->isText())
-        return curr->parent()->logicalTop();
-    if (curr->renderer()->isBox())
-        return toRenderBox(curr->renderer())->verticalPosition(firstLine);
-    return toRenderInline(curr->renderer())->verticalPositionFromCache(firstLine);
+    if (box->renderer()->isText())
+        return box->parent()->logicalTop();
+    
+    RenderBoxModelObject* renderer = box->boxModelObject();
+    ASSERT(renderer->isInline());
+    if (!renderer->isInline())
+        return 0;
+
+    // This method determines the vertical position for inline elements.
+    if (firstLine && !renderer->document()->usesFirstLineRules())
+        firstLine = false;
+
+    // Check the cache.
+    bool isRenderInline = renderer->isRenderInline();
+    if (isRenderInline && !firstLine) {
+        int verticalPosition = verticalPositionCache.get(renderer, baselineType);
+        if (verticalPosition != PositionUndefined)
+            return verticalPosition;
+    }
+
+    int verticalPosition = 0;
+    EVerticalAlign verticalAlign = renderer->style()->verticalAlign();
+    if (verticalAlign == TOP)
+        verticalPosition = PositionTop;
+    else if (verticalAlign == BOTTOM)
+        verticalPosition = PositionBottom;
+    else {
+        RenderObject* parent = renderer->parent();
+        if (parent->isRenderInline() && parent->style()->verticalAlign() != TOP && parent->style()->verticalAlign() != BOTTOM)
+            verticalPosition = box->parent()->logicalTop();
+        
+        if (verticalAlign != BASELINE) {
+            const Font& font = parent->style(firstLine)->font();
+            int fontSize = font.pixelSize();
+
+            LineDirectionMode lineDirection = parent->style()->isHorizontalWritingMode() ? HorizontalLine : VerticalLine;
+
+            if (verticalAlign == SUB)
+                verticalPosition += fontSize / 5 + 1;
+            else if (verticalAlign == SUPER)
+                verticalPosition -= fontSize / 3 + 1;
+            else if (verticalAlign == TEXT_TOP)
+                verticalPosition += renderer->baselinePosition(baselineType, firstLine, lineDirection) - font.ascent(baselineType);
+            else if (verticalAlign == MIDDLE)
+                verticalPosition += -static_cast<int>(font.xHeight() / 2) - renderer->lineHeight(firstLine, lineDirection) / 2 + renderer->baselinePosition(baselineType, firstLine, lineDirection);
+            else if (verticalAlign == TEXT_BOTTOM) {
+                verticalPosition += font.descent(baselineType);
+                // lineHeight - baselinePosition is always 0 for replaced elements (except inline blocks), so don't bother wasting time in that case.
+                if (!renderer->isReplaced() || renderer->isInlineBlockOrInlineTable())
+                    verticalPosition -= (renderer->lineHeight(firstLine, lineDirection) - renderer->baselinePosition(baselineType, firstLine, lineDirection));
+            } else if (verticalAlign == BASELINE_MIDDLE)
+                verticalPosition += -renderer->lineHeight(firstLine, lineDirection) / 2 + renderer->baselinePosition(baselineType, firstLine, lineDirection);
+            else if (verticalAlign == LENGTH)
+                verticalPosition -= renderer->style()->verticalAlignLength().calcValue(renderer->lineHeight(firstLine, lineDirection));
+        }
+    }
+
+    // Store the cached value.
+    if (isRenderInline && !firstLine)
+        verticalPositionCache.set(renderer, baselineType, verticalPosition);
+
+    return verticalPosition;
 }
 
 void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositionBottom,
                                              int& maxAscent, int& maxDescent, bool& setMaxAscent, bool& setMaxDescent,
-                                             bool strictMode, GlyphOverflowAndFallbackFontsMap& textBoxDataMap)
+                                             bool strictMode, GlyphOverflowAndFallbackFontsMap& textBoxDataMap,
+                                             FontBaseline baselineType, VerticalPositionCache& verticalPositionCache)
 {
     // The primary purpose of this function is to compute the maximal ascent and descent values for
     // a line.
@@ -450,7 +509,7 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi
     if (isRootInlineBox()) {
         // Examine our root box.
         int height = lineHeight();
-        int baseline = baselinePosition();
+        int baseline = baselinePosition(baselineType);
         if (hasTextChildren() || strictMode) {
             int ascent = baseline;
             int descent = height - ascent;
@@ -480,7 +539,7 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi
         // The verticalPositionForBox function returns the distance between the child box's baseline
         // and the root box's baseline.  The value is negative if the child box's baseline is above the
         // root box's baseline, and it is positive if the child box's baseline is below the root box's baseline.
-        curr->setLogicalTop(verticalPositionForBox(curr, m_firstLine));
+        curr->setLogicalTop(verticalPositionForBox(curr, baselineType, m_firstLine, verticalPositionCache));
         
         int lineHeight;
         int baseline;
@@ -497,8 +556,8 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi
             baseline = 0;
             int baselineToBottom = 0;
             for (size_t i = 0; i < usedFonts->size(); ++i) {
-                int halfLeading = (usedFonts->at(i)->lineSpacing() - usedFonts->at(i)->ascent() - usedFonts->at(i)->descent()) / 2;
-                int usedFontAscent = halfLeading + usedFonts->at(i)->ascent();
+                int halfLeading = (usedFonts->at(i)->lineSpacing() - usedFonts->at(i)->height()) / 2;
+                int usedFontAscent = halfLeading + usedFonts->at(i)->ascent(baselineType);
                 int usedFontDescent = usedFonts->at(i)->lineSpacing() - usedFontAscent;
                 if (!baselineSet) {
                     baselineSet = true;
@@ -512,16 +571,16 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi
             lineHeight = baseline + baselineToBottom;
         } else {
             lineHeight = curr->lineHeight();
-            baseline = curr->baselinePosition();
+            baseline = curr->baselinePosition(baselineType);
             if (curr->isText() || isInlineFlow) {
                 // Examine the font box for inline flows and text boxes to see if any part of it is above the baseline.
                 // If the top of our font box relative to the root box baseline is above the root box baseline, then
                 // we are contributing to the maxAscent value.
-                affectsAscent = curr->renderer()->style(m_firstLine)->font().ascent() - curr->logicalTop() > 0;
+                affectsAscent = curr->renderer()->style(m_firstLine)->font().ascent(baselineType) - curr->logicalTop() > 0;
                 
                 // Descent is similar.  If any part of our font box is below the root box's baseline, then
                 // we contribute to the maxDescent value.
-                affectsDescent = curr->renderer()->style(m_firstLine)->font().descent() + curr->logicalTop() > 0;
+                affectsDescent = curr->renderer()->style(m_firstLine)->font().descent(baselineType) + curr->logicalTop() > 0;
             } else {
                 // Replaced elements always affect both the ascent and descent.
                 affectsAscent = true;
@@ -555,14 +614,16 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi
         }
 
         if (curr->isInlineFlowBox())
-            static_cast<InlineFlowBox*>(curr)->computeLogicalBoxHeights(maxPositionTop, maxPositionBottom, maxAscent, maxDescent, setMaxAscent, setMaxDescent, strictMode, textBoxDataMap);
+            static_cast<InlineFlowBox*>(curr)->computeLogicalBoxHeights(maxPositionTop, maxPositionBottom, maxAscent, maxDescent,
+                                                                        setMaxAscent, setMaxDescent, strictMode, textBoxDataMap,
+                                                                        baselineType, verticalPositionCache);
     }
 }
 
-void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAscent, bool strictMode, int& lineTop, int& lineBottom, bool& setLineTop)
+void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAscent, bool strictMode, int& lineTop, int& lineBottom, bool& setLineTop, FontBaseline baselineType)
 {
     if (isRootInlineBox())
-        setLogicalTop(top + maxAscent - baselinePosition()); // Place our root box.
+        setLogicalTop(top + maxAscent - baselinePosition(baselineType)); // Place our root box.
 
     for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
         if (curr->renderer()->isPositioned())
@@ -572,7 +633,7 @@ void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAs
         // line-height).
         bool isInlineFlow = curr->isInlineFlowBox();
         if (isInlineFlow)
-            static_cast<InlineFlowBox*>(curr)->placeBoxesInBlockDirection(top, maxHeight, maxAscent, strictMode, lineTop, lineBottom, setLineTop);
+            static_cast<InlineFlowBox*>(curr)->placeBoxesInBlockDirection(top, maxHeight, maxAscent, strictMode, lineTop, lineBottom, setLineTop, baselineType);
 
         bool childAffectsTopBottomPos = true;
         if (curr->logicalTop() == PositionTop)
@@ -582,14 +643,14 @@ void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAs
         else {
             if ((isInlineFlow && !static_cast<InlineFlowBox*>(curr)->hasTextChildren()) && !curr->boxModelObject()->hasInlineDirectionBordersOrPadding() && !strictMode)
                 childAffectsTopBottomPos = false;
-            int posAdjust = maxAscent - curr->baselinePosition();
+            int posAdjust = maxAscent - curr->baselinePosition(baselineType);
             curr->setLogicalTop(curr->logicalTop() + top + posAdjust);
         }
         
         int newLogicalTop = curr->logicalTop();
         if (curr->isText() || curr->isInlineFlowBox()) {
             const Font& font = curr->renderer()->style(m_firstLine)->font();
-            newLogicalTop += curr->baselinePosition() - font.ascent();
+            newLogicalTop += curr->baselinePosition(baselineType) - font.ascent(baselineType);
             if (curr->isInlineFlowBox()) {
                 RenderBoxModelObject* boxObject = toRenderBoxModelObject(curr->renderer());
                 newLogicalTop -= boxObject->style(m_firstLine)->isHorizontalWritingMode() ? boxObject->borderTop() + boxObject->paddingTop() : 
@@ -615,7 +676,7 @@ void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAs
 
     if (isRootInlineBox()) {
         const Font& font = renderer()->style(m_firstLine)->font();
-        setLogicalTop(logicalTop() + baselinePosition() - font.ascent());
+        setLogicalTop(logicalTop() + baselinePosition(baselineType) - font.ascent(baselineType));
         
         if (hasTextChildren() || strictMode) {
             if (!setLineTop) {
diff --git a/WebCore/rendering/InlineFlowBox.h b/WebCore/rendering/InlineFlowBox.h
index 69e7604..e3127af 100644
--- a/WebCore/rendering/InlineFlowBox.h
+++ b/WebCore/rendering/InlineFlowBox.h
@@ -30,6 +30,7 @@ class HitTestRequest;
 class HitTestResult;
 class InlineTextBox;
 class RenderLineBoxList;
+class VerticalPositionCache;
 
 typedef HashMap<const InlineTextBox*, pair<Vector<const SimpleFontData*>, GlyphOverflow> > GlyphOverflowAndFallbackFontsMap;
 
@@ -156,10 +157,10 @@ public:
     int placeBoxesInInlineDirection(int logicalLeft, bool& needsWordSpacing, GlyphOverflowAndFallbackFontsMap&);
     void computeLogicalBoxHeights(int& maxPositionTop, int& maxPositionBottom,
                                   int& maxAscent, int& maxDescent, bool& setMaxAscent, bool& setMaxDescent,
-                                  bool strictMode, GlyphOverflowAndFallbackFontsMap&);
+                                  bool strictMode, GlyphOverflowAndFallbackFontsMap&, FontBaseline, VerticalPositionCache&);
     void adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent,
                                    int maxPositionTop, int maxPositionBottom);
-    void placeBoxesInBlockDirection(int logicalTop, int maxHeight, int maxAscent, bool strictMode, int& lineTop, int& lineBottom, bool& setLineTop);
+    void placeBoxesInBlockDirection(int logicalTop, int maxHeight, int maxAscent, bool strictMode, int& lineTop, int& lineBottom, bool& setLineTop, FontBaseline);
     void flipLinesInBlockDirection(int lineTop, int lineBottom);
     void computeBlockDirectionOverflow(int lineTop, int lineBottom, bool strictMode, GlyphOverflowAndFallbackFontsMap&);
     bool requiresIdeographicBaseline(const GlyphOverflowAndFallbackFontsMap&) const;
diff --git a/WebCore/rendering/InlineTextBox.cpp b/WebCore/rendering/InlineTextBox.cpp
index bf865ad..575bdf2 100644
--- a/WebCore/rendering/InlineTextBox.cpp
+++ b/WebCore/rendering/InlineTextBox.cpp
@@ -43,11 +43,11 @@ using namespace std;
 
 namespace WebCore {
 
-int InlineTextBox::baselinePosition() const
+int InlineTextBox::baselinePosition(FontBaseline baselineType) const
 {
     if (!isText() || !parent())
         return 0;
-    return parent()->baselinePosition();
+    return parent()->baselinePosition(baselineType);
 }
     
 int InlineTextBox::lineHeight() const
diff --git a/WebCore/rendering/InlineTextBox.h b/WebCore/rendering/InlineTextBox.h
index e72d625..bc2219b 100644
--- a/WebCore/rendering/InlineTextBox.h
+++ b/WebCore/rendering/InlineTextBox.h
@@ -70,7 +70,7 @@ public:
     static inline bool compareByStart(const InlineTextBox* first, const InlineTextBox* second) { return first->start() < second->start(); }
 
     
-    virtual int baselinePosition() const;
+    virtual int baselinePosition(FontBaseline) const;
     virtual int lineHeight() const;
 
 private:
diff --git a/WebCore/rendering/RenderBlock.cpp b/WebCore/rendering/RenderBlock.cpp
index 902034c..5f73dc4 100644
--- a/WebCore/rendering/RenderBlock.cpp
+++ b/WebCore/rendering/RenderBlock.cpp
@@ -5257,7 +5257,7 @@ int RenderBlock::lineHeight(bool firstLine, LineDirectionMode direction, LinePos
     return m_lineHeight;
 }
 
-int RenderBlock::baselinePosition(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
+int RenderBlock::baselinePosition(FontBaseline baselineType, 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
@@ -5286,11 +5286,11 @@ int RenderBlock::baselinePosition(bool firstLine, LineDirectionMode direction, L
         if (baselinePos != -1 && baselinePos <= bottomOfContent)
             return direction == HorizontalLine ? marginTop() + baselinePos : marginRight() + baselinePos;
             
-        return RenderBox::baselinePosition(firstLine, direction, linePositionMode);
+        return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
     }
 
     const Font& f = style(firstLine)->font();
-    return f.ascent() + (lineHeight(firstLine, direction, linePositionMode) - f.height()) / 2;
+    return f.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - f.height()) / 2;
 }
 
 int RenderBlock::firstLineBoxBaseline() const
@@ -5300,7 +5300,7 @@ int RenderBlock::firstLineBoxBaseline() const
 
     if (childrenInline()) {
         if (firstLineBox())
-            return firstLineBox()->logicalTop() + style(true)->font().ascent();
+            return firstLineBox()->logicalTop() + style(true)->font().ascent(firstRootBox()->baselineType());
         else
             return -1;
     }
@@ -5330,7 +5330,7 @@ int RenderBlock::lastLineBoxBaseline() const
             return f.ascent() + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - f.height()) / 2 + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
         }
         if (lastLineBox())
-            return lastLineBox()->logicalTop() + style(lastLineBox() == firstLineBox())->font().ascent();
+            return lastLineBox()->logicalTop() + style(lastLineBox() == firstLineBox())->font().ascent(lastRootBox()->baselineType());
         return -1;
     } else {
         bool haveNormalFlowChild = false;
diff --git a/WebCore/rendering/RenderBlock.h b/WebCore/rendering/RenderBlock.h
index 1cc89c0..645c0ec 100644
--- a/WebCore/rendering/RenderBlock.h
+++ b/WebCore/rendering/RenderBlock.h
@@ -58,7 +58,7 @@ public:
 
     // These two functions are overridden for inline-block.
     virtual int lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
-    virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+    virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
 
     RenderLineBoxList* lineBoxes() { return &m_lineBoxes; }
     const RenderLineBoxList* lineBoxes() const { return &m_lineBoxes; }
@@ -458,7 +458,7 @@ private:
     RootInlineBox* constructLine(unsigned runCount, BidiRun* firstRun, BidiRun* lastRun, bool firstLine, bool lastLine, RenderObject* endObject);
     InlineFlowBox* createLineBoxes(RenderObject*, bool firstLine);
     void computeInlineDirectionPositionsForLine(RootInlineBox*, bool firstLine, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, GlyphOverflowAndFallbackFontsMap&);
-    void computeBlockDirectionPositionsForLine(RootInlineBox*, BidiRun*, GlyphOverflowAndFallbackFontsMap&);
+    void computeBlockDirectionPositionsForLine(RootInlineBox*, BidiRun*, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&);
     void deleteEllipsisLineBoxes();
     void checkLinesForTextOverflow();
     void addOverflowFromInlineChildren();
diff --git a/WebCore/rendering/RenderBlockLineLayout.cpp b/WebCore/rendering/RenderBlockLineLayout.cpp
index f6951ed..544a1f5 100644
--- a/WebCore/rendering/RenderBlockLineLayout.cpp
+++ b/WebCore/rendering/RenderBlockLineLayout.cpp
@@ -35,6 +35,7 @@
 #include "RenderView.h"
 #include "Settings.h"
 #include "TrailingFloatsRootInlineBox.h"
+#include "VerticalPositionCache.h"
 #include "break_lines.h"
 #include <wtf/AlwaysInline.h>
 #include <wtf/RefCountedLeakCounter.h>
@@ -470,9 +471,10 @@ void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox,
     lineBox->placeBoxesInInlineDirection(logicalLeft, needsWordSpacing, textBoxDataMap);
 }
 
-void RenderBlock::computeBlockDirectionPositionsForLine(RootInlineBox* lineBox, BidiRun* firstRun, GlyphOverflowAndFallbackFontsMap& textBoxDataMap)
+void RenderBlock::computeBlockDirectionPositionsForLine(RootInlineBox* lineBox, BidiRun* firstRun, GlyphOverflowAndFallbackFontsMap& textBoxDataMap,
+                                                        VerticalPositionCache& verticalPositionCache)
 {
-    setLogicalHeight(lineBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap));
+    setLogicalHeight(lineBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, verticalPositionCache));
     lineBox->setBlockLogicalHeight(logicalHeight());
 
     // Now make sure we place replaced render objects correctly.
@@ -567,8 +569,6 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogica
                 if (fullLayout || o->selfNeedsLayout())
                     dirtyLineBoxesForRenderer(o, fullLayout);
                 o->setNeedsLayout(false);
-                if (!o->isText())
-                    toRenderInline(o)->invalidateVerticalPosition(); // FIXME: Should do better here and not always invalidate everything.
             }
             o = bidiNext(this, o, 0, false, &endOfInline);
         }
@@ -648,6 +648,8 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogica
         bool isLineEmpty = true;
         bool paginated = view()->layoutState() && view()->layoutState()->isPaginated();
 
+        VerticalPositionCache verticalPositionCache;
+
         while (!end.atEnd()) {
             // FIXME: Is this check necessary before the first iteration or can it be moved to the end?
             if (checkForEndLineMatch && (endLineMatched = matchedEndLine(resolver, cleanLineStart, cleanLineBidiStatus, endLine, endLineLogicalTop, repaintLogicalBottom, repaintLogicalTop)))
@@ -748,7 +750,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogica
                             computeInlineDirectionPositionsForLine(lineBox, firstLine, resolver.firstRun(), trailingSpaceRun, end.atEnd(), textBoxDataMap);
 
                         // Now position our text runs vertically.
-                        computeBlockDirectionPositionsForLine(lineBox, resolver.firstRun(), textBoxDataMap);
+                        computeBlockDirectionPositionsForLine(lineBox, resolver.firstRun(), textBoxDataMap, verticalPositionCache);
 
 #if ENABLE(SVG)
                         // SVG text layout code computes vertical & horizontal positions on its own.
@@ -878,7 +880,8 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogica
                 m_lineBoxes.appendLineBox(trailingFloatsLineBox);
                 trailingFloatsLineBox->setConstructed();
                 GlyphOverflowAndFallbackFontsMap textBoxDataMap;
-                trailingFloatsLineBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap);
+                VerticalPositionCache verticalPositionCache;
+                trailingFloatsLineBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, verticalPositionCache);
                 trailingFloatsLineBox->setBlockDirectionOverflowPositions(logicalHeight(), bottomLayoutOverflow, logicalHeight(), bottomVisualOverflow);
                 trailingFloatsLineBox->setBlockLogicalHeight(logicalHeight());
             }
diff --git a/WebCore/rendering/RenderBox.cpp b/WebCore/rendering/RenderBox.cpp
index 6b166a2..9bb7765 100644
--- a/WebCore/rendering/RenderBox.cpp
+++ b/WebCore/rendering/RenderBox.cpp
@@ -3189,10 +3189,14 @@ int RenderBox::lineHeight(bool /*firstLine*/, LineDirectionMode direction, LineP
     return 0;
 }
 
-int RenderBox::baselinePosition(bool /*firstLine*/, LineDirectionMode direction, LinePositionMode /*linePositionMode*/) const
+int RenderBox::baselinePosition(FontBaseline baselineType, bool /*firstLine*/, LineDirectionMode direction, LinePositionMode /*linePositionMode*/) const
 {
-    if (isReplaced())
-        return direction == HorizontalLine ? m_marginTop + height() + m_marginBottom : m_marginRight + width() + m_marginLeft;
+    if (isReplaced()) {
+        int result = direction == HorizontalLine ? m_marginTop + height() + m_marginBottom : m_marginRight + width() + m_marginLeft;
+        if (baselineType == AlphabeticBaseline)
+            return result;
+        return result - result / 2;
+    }
     return 0;
 }
 
diff --git a/WebCore/rendering/RenderBox.h b/WebCore/rendering/RenderBox.h
index 36fbede..172a950 100644
--- a/WebCore/rendering/RenderBox.h
+++ b/WebCore/rendering/RenderBox.h
@@ -378,7 +378,7 @@ public:
     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;
+    virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
 
     enum FlippingAdjustment { ChildToParentFlippingAdjustment, ParentToChildFlippingAdjustment };
     IntPoint flipForWritingMode(const RenderBox* child, const IntPoint&, FlippingAdjustment) const;
diff --git a/WebCore/rendering/RenderBoxModelObject.cpp b/WebCore/rendering/RenderBoxModelObject.cpp
index ae89e0a..1580b49 100644
--- a/WebCore/rendering/RenderBoxModelObject.cpp
+++ b/WebCore/rendering/RenderBoxModelObject.cpp
@@ -845,53 +845,6 @@ void RenderBoxModelObject::calculateBackgroundImageGeometry(const FillLayer* fil
     destRect.intersect(IntRect(tx, ty, w, h));
 }
 
-int RenderBoxModelObject::verticalPosition(bool firstLine) const
-{
-    // This method determines the vertical position for inline elements.
-    ASSERT(isInline());
-    if (!isInline())
-        return 0;
-
-    int vpos = 0;
-    EVerticalAlign va = style()->verticalAlign();
-    if (va == TOP)
-        vpos = PositionTop;
-    else if (va == BOTTOM)
-        vpos = PositionBottom;
-    else {
-        bool checkParent = parent()->isRenderInline() && parent()->style()->verticalAlign() != TOP && parent()->style()->verticalAlign() != BOTTOM;
-        vpos = checkParent ? toRenderInline(parent())->verticalPositionFromCache(firstLine) : 0;
-        // don't allow elements nested inside text-top to have a different valignment.
-        if (va == BASELINE)
-            return vpos;
-
-        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, lineDirection) - f.ascent();
-        else if (va == MIDDLE)
-            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, lineDirection) - baselinePosition(firstLine, lineDirection));
-        } else if (va == BASELINE_MIDDLE)
-            vpos += -lineHeight(firstLine, lineDirection) / 2 + baselinePosition(firstLine, lineDirection);
-        else if (va == LENGTH)
-            vpos -= style()->verticalAlignLength().calcValue(lineHeight(firstLine, lineDirection));
-    }
-
-    return vpos;
-}
-
 bool RenderBoxModelObject::paintNinePieceImage(GraphicsContext* graphicsContext, int tx, int ty, int w, int h, const RenderStyle* style,
                                                const NinePieceImage& ninePieceImage, CompositeOperator op)
 {
diff --git a/WebCore/rendering/RenderBoxModelObject.h b/WebCore/rendering/RenderBoxModelObject.h
index 121601f..f502424 100644
--- a/WebCore/rendering/RenderBoxModelObject.h
+++ b/WebCore/rendering/RenderBoxModelObject.h
@@ -28,11 +28,6 @@
 
 namespace WebCore {
 
-// Values for vertical alignment.
-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 };
@@ -113,13 +108,10 @@ public:
     bool paintNinePieceImage(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*, const NinePieceImage&, CompositeOperator = CompositeSourceOver);
     void paintBoxShadow(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*, ShadowStyle, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true);
     void paintFillLayerExtended(const PaintInfo&, const Color&, const FillLayer*, int tx, int ty, int width, int height, InlineFlowBox* = 0, CompositeOperator = CompositeSourceOver, RenderObject* backgroundObject = 0);
-
-    // 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;
+    virtual int baselinePosition(FontBaseline, 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();
diff --git a/WebCore/rendering/RenderFileUploadControl.cpp b/WebCore/rendering/RenderFileUploadControl.cpp
index 3da8530..82bd1fa 100644
--- a/WebCore/rendering/RenderFileUploadControl.cpp
+++ b/WebCore/rendering/RenderFileUploadControl.cpp
@@ -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, HorizontalLine, PositionOnContainingLine);
+            + buttonRenderer->baselinePosition(AlphabeticBaseline, true, HorizontalLine, PositionOnContainingLine);
 
         paintInfo.context->setFillColor(style()->visitedDependentColor(CSSPropertyColor), style()->colorSpace());
         
diff --git a/WebCore/rendering/RenderInline.cpp b/WebCore/rendering/RenderInline.cpp
index 3093f56..8f828f9 100644
--- a/WebCore/rendering/RenderInline.cpp
+++ b/WebCore/rendering/RenderInline.cpp
@@ -48,7 +48,6 @@ RenderInline::RenderInline(Node* node)
     : RenderBoxModelObject(node)
     , m_continuation(0)
     , m_lineHeight(-1)
-    , m_verticalPosition(PositionUndefined)
 {
     setChildrenInline(true);
 }
@@ -903,23 +902,10 @@ int RenderInline::lineHeight(bool firstLine, LineDirectionMode /*direction*/, Li
     return m_lineHeight;
 }
 
-int RenderInline::baselinePosition(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
+int RenderInline::baselinePosition(FontBaseline baselineType, 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.
-        firstLine = document()->usesFirstLineRules();
-    int vpos = m_verticalPosition;
-    if (m_verticalPosition == PositionUndefined || firstLine) {
-        vpos = verticalPosition(firstLine);
-        if (!firstLine)
-            m_verticalPosition = vpos;
-    }
-    return vpos;
+    return f.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - f.height()) / 2;
 }
 
 IntSize RenderInline::relativePositionedInlineOffset(const RenderBox* child) const
diff --git a/WebCore/rendering/RenderInline.h b/WebCore/rendering/RenderInline.h
index 1eb32ff..399a167 100644
--- a/WebCore/rendering/RenderInline.h
+++ b/WebCore/rendering/RenderInline.h
@@ -77,9 +77,6 @@ public:
     virtual void addFocusRingRects(Vector<IntRect>&, int tx, int ty);
     void paintOutline(GraphicsContext*, int tx, int ty);
 
-    int verticalPositionFromCache(bool firstLine) const;
-    void invalidateVerticalPosition() { m_verticalPosition = PositionUndefined; }
-
 protected:
     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
 
@@ -134,7 +131,7 @@ private:
     virtual void dirtyLinesFromChangedChild(RenderObject* child) { m_lineBoxes.dirtyLinesFromChangedChild(this, child); }
 
     virtual int lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
-    virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+    virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
     
     virtual void childBecameNonInline(RenderObject* child);
 
@@ -159,7 +156,6 @@ private:
     RenderBoxModelObject* m_continuation; // Can be either a block or an inline. <b><i><p>Hello</p></i></b>. In this example the <i> will have a block as its continuation but the
                                           // <b> will just have an inline as its continuation.
     mutable int m_lineHeight;
-    mutable int m_verticalPosition;
 };
 
 inline RenderInline* toRenderInline(RenderObject* object)
diff --git a/WebCore/rendering/RenderListBox.cpp b/WebCore/rendering/RenderListBox.cpp
index 532c551..5717871 100644
--- a/WebCore/rendering/RenderListBox.cpp
+++ b/WebCore/rendering/RenderListBox.cpp
@@ -238,9 +238,9 @@ void RenderListBox::computeLogicalHeight()
     }
 }
 
-int RenderListBox::baselinePosition(bool firstLine, LineDirectionMode lineDirection, LinePositionMode linePositionMode) const
+int RenderListBox::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode lineDirection, LinePositionMode linePositionMode) const
 {
-    return RenderBox::baselinePosition(firstLine, lineDirection, linePositionMode) - baselineAdjustment;
+    return RenderBox::baselinePosition(baselineType, firstLine, lineDirection, linePositionMode) - baselineAdjustment;
 }
 
 IntRect RenderListBox::itemBoundingBoxRect(int tx, int ty, int index)
diff --git a/WebCore/rendering/RenderListBox.h b/WebCore/rendering/RenderListBox.h
index 072fc91..69acb57 100644
--- a/WebCore/rendering/RenderListBox.h
+++ b/WebCore/rendering/RenderListBox.h
@@ -71,7 +71,7 @@ private:
     virtual bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1, Node** stopNode = 0);
 
     virtual void computePreferredLogicalWidths();
-    virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+    virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
     virtual void computeLogicalHeight();
 
     virtual void layout();
diff --git a/WebCore/rendering/RenderListMarker.cpp b/WebCore/rendering/RenderListMarker.cpp
index d4a98be..2f33afb 100644
--- a/WebCore/rendering/RenderListMarker.cpp
+++ b/WebCore/rendering/RenderListMarker.cpp
@@ -1530,11 +1530,11 @@ int RenderListMarker::lineHeight(bool firstLine, LineDirectionMode direction, Li
     return RenderBox::lineHeight(firstLine, direction, linePositionMode);
 }
 
-int RenderListMarker::baselinePosition(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
+int RenderListMarker::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
 {
     if (!isImage())
-        return m_listItem->baselinePosition(firstLine, direction, PositionOfInteriorLineBoxes);
-    return RenderBox::baselinePosition(firstLine, direction, linePositionMode);
+        return m_listItem->baselinePosition(baselineType, firstLine, direction, PositionOfInteriorLineBoxes);
+    return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
 }
 
 String RenderListMarker::suffix() const
diff --git a/WebCore/rendering/RenderListMarker.h b/WebCore/rendering/RenderListMarker.h
index fe025c3..d23e674 100644
--- a/WebCore/rendering/RenderListMarker.h
+++ b/WebCore/rendering/RenderListMarker.h
@@ -59,7 +59,7 @@ private:
     virtual InlineBox* createInlineBox();
 
     virtual int lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
-    virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+    virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
 
     bool isImage() const;
     bool isText() const { return !isImage(); }
diff --git a/WebCore/rendering/RenderSlider.cpp b/WebCore/rendering/RenderSlider.cpp
index a996ada..3a698a4 100644
--- a/WebCore/rendering/RenderSlider.cpp
+++ b/WebCore/rendering/RenderSlider.cpp
@@ -155,8 +155,9 @@ RenderSlider::~RenderSlider()
         m_thumb->detach();
 }
 
-int RenderSlider::baselinePosition(bool /*firstLine*/, LineDirectionMode, LinePositionMode) const
+int RenderSlider::baselinePosition(FontBaseline, bool /*firstLine*/, LineDirectionMode, LinePositionMode) const
 {
+    // FIXME: Patch this function for writing-mode.
     return height() + marginTop();
 }
 
diff --git a/WebCore/rendering/RenderSlider.h b/WebCore/rendering/RenderSlider.h
index fa743de..03779a3 100644
--- a/WebCore/rendering/RenderSlider.h
+++ b/WebCore/rendering/RenderSlider.h
@@ -42,7 +42,7 @@ namespace WebCore {
         virtual const char* renderName() const { return "RenderSlider"; }
         virtual bool isSlider() const { return true; }
 
-        virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+        virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
         virtual void computePreferredLogicalWidths();
         virtual void layout();
         virtual void updateFromElement();
diff --git a/WebCore/rendering/RenderTableCell.cpp b/WebCore/rendering/RenderTableCell.cpp
index eec882f..9f6d174 100644
--- a/WebCore/rendering/RenderTableCell.cpp
+++ b/WebCore/rendering/RenderTableCell.cpp
@@ -290,19 +290,15 @@ void RenderTableCell::computeRectForRepaint(RenderBoxModelObject* repaintContain
     RenderBlock::computeRectForRepaint(repaintContainer, r, fixed);
 }
 
-int RenderTableCell::baselinePosition(bool firstLine, LineDirectionMode lineDirection, LinePositionMode linePositionMode) const
+int RenderTableCell::baselinePosition() const
 {
-    // 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
     // is no such line box or table-row, the baseline is the bottom of content edge of the cell box.
     int firstLineBaseline = firstLineBoxBaseline();
     if (firstLineBaseline != -1)
         return firstLineBaseline;
-    return paddingTop() + borderTop() + contentHeight();
+    return paddingBefore() + borderBefore() + contentLogicalHeight();
 }
 
 void RenderTableCell::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
diff --git a/WebCore/rendering/RenderTableCell.h b/WebCore/rendering/RenderTableCell.h
index 15e6bab..281c226 100644
--- a/WebCore/rendering/RenderTableCell.h
+++ b/WebCore/rendering/RenderTableCell.h
@@ -98,7 +98,7 @@ public:
 
     void paintBackgroundsBehindCell(PaintInfo&, int tx, int ty, RenderObject* backgroundObject);
 
-    virtual int baselinePosition(bool firstLine = false, LineDirectionMode = HorizontalLine, LinePositionMode = PositionOnContainingLine) const;
+    int baselinePosition() const;
 
     void setIntrinsicPaddingBefore(int p) { m_intrinsicPaddingBefore = p; }
     void setIntrinsicPaddingAfter(int p) { m_intrinsicPaddingAfter = p; }
diff --git a/WebCore/rendering/RenderTextControlMultiLine.cpp b/WebCore/rendering/RenderTextControlMultiLine.cpp
index 0f2a822..2014830 100644
--- a/WebCore/rendering/RenderTextControlMultiLine.cpp
+++ b/WebCore/rendering/RenderTextControlMultiLine.cpp
@@ -94,9 +94,9 @@ void RenderTextControlMultiLine::adjustControlHeightBasedOnLineHeight(int lineHe
     setHeight(height() + lineHeight * static_cast<HTMLTextAreaElement*>(node())->rows());
 }
 
-int RenderTextControlMultiLine::baselinePosition(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
+int RenderTextControlMultiLine::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
 {
-    return RenderBox::baselinePosition(firstLine, direction, linePositionMode);
+    return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
 }
 
 void RenderTextControlMultiLine::updateFromElement()
diff --git a/WebCore/rendering/RenderTextControlMultiLine.h b/WebCore/rendering/RenderTextControlMultiLine.h
index 2e0ac81..6dc2032 100644
--- a/WebCore/rendering/RenderTextControlMultiLine.h
+++ b/WebCore/rendering/RenderTextControlMultiLine.h
@@ -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, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+    virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
 
     virtual void updateFromElement();
     virtual void cacheSelection(int start, int end);
diff --git a/WebCore/rendering/RootInlineBox.cpp b/WebCore/rendering/RootInlineBox.cpp
index ef79eb4..cdc6525 100644
--- a/WebCore/rendering/RootInlineBox.cpp
+++ b/WebCore/rendering/RootInlineBox.cpp
@@ -215,7 +215,7 @@ void RootInlineBox::childRemoved(InlineBox* box)
     }
 }
 
-int RootInlineBox::alignBoxesInBlockDirection(int heightOfBlock, GlyphOverflowAndFallbackFontsMap& textBoxDataMap)
+int RootInlineBox::alignBoxesInBlockDirection(int heightOfBlock, GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache)
 {
 #if ENABLE(SVG)
     // SVG will handle vertical alignment on its own.
@@ -235,7 +235,8 @@ int RootInlineBox::alignBoxesInBlockDirection(int heightOfBlock, GlyphOverflowAn
 
     m_baselineType = requiresIdeographicBaseline(textBoxDataMap) ? IdeographicBaseline : AlphabeticBaseline;
 
-    computeLogicalBoxHeights(maxPositionTop, maxPositionBottom, maxAscent, maxDescent, setMaxAscent, setMaxDescent, noQuirksMode, textBoxDataMap);
+    computeLogicalBoxHeights(maxPositionTop, maxPositionBottom, maxAscent, maxDescent, setMaxAscent, setMaxDescent, noQuirksMode,
+                             textBoxDataMap, m_baselineType, verticalPositionCache);
 
     if (maxAscent + maxDescent < max(maxPositionTop, maxPositionBottom))
         adjustMaxAscentAndDescent(maxAscent, maxDescent, maxPositionTop, maxPositionBottom);
@@ -244,7 +245,7 @@ int RootInlineBox::alignBoxesInBlockDirection(int heightOfBlock, GlyphOverflowAn
     int lineTop = heightOfBlock;
     int lineBottom = heightOfBlock;
     bool setLineTop = false;
-    placeBoxesInBlockDirection(heightOfBlock, maxHeight, maxAscent, noQuirksMode, lineTop, lineBottom, setLineTop);
+    placeBoxesInBlockDirection(heightOfBlock, maxHeight, maxAscent, noQuirksMode, lineTop, lineBottom, setLineTop, m_baselineType);
     computeBlockDirectionOverflow(lineTop, lineBottom, noQuirksMode, textBoxDataMap);
     setLineTopBottomPositions(lineTop, lineBottom);
 
diff --git a/WebCore/rendering/RootInlineBox.h b/WebCore/rendering/RootInlineBox.h
index e68345f..851b4b1 100644
--- a/WebCore/rendering/RootInlineBox.h
+++ b/WebCore/rendering/RootInlineBox.h
@@ -57,7 +57,7 @@ public:
     int selectionBottom() const;
     int selectionHeight() const { return max(0, selectionBottom() - selectionTop()); }
 
-    int alignBoxesInBlockDirection(int heightOfBlock, GlyphOverflowAndFallbackFontsMap&);
+    int alignBoxesInBlockDirection(int heightOfBlock, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&);
     void setLineTopBottomPositions(int top, int bottom);
 
     virtual RenderLineBoxList* rendererLineBoxes() const;
@@ -88,7 +88,7 @@ public:
 
     virtual void clearTruncation();
 
-    virtual int baselinePosition() const { return boxModelObject()->baselinePosition(m_firstLine, isHorizontal() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes); }
+    virtual int baselinePosition(FontBaseline baselineType) const { return boxModelObject()->baselinePosition(baselineType, m_firstLine, isHorizontal() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes); }
     virtual int lineHeight() const { return boxModelObject()->lineHeight(m_firstLine, isHorizontal() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes); }
 
 #if PLATFORM(MAC)
diff --git a/WebCore/rendering/VerticalPositionCache.h b/WebCore/rendering/VerticalPositionCache.h
new file mode 100644
index 0000000..4deaef5
--- /dev/null
+++ b/WebCore/rendering/VerticalPositionCache.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VerticalPositionCache_h
+#define VerticalPositionCache_h
+
+#include "FontBaseline.h"
+#include <wtf/HashMap.h>
+
+namespace WebCore {
+
+class RenderObject;
+
+// Values for vertical alignment.
+const int PositionTop = -0x7fffffff;
+const int PositionBottom = 0x7fffffff;
+const int PositionUndefined = 0x80000000;
+
+class VerticalPositionCache : public Noncopyable {
+public:
+    VerticalPositionCache()
+    { }
+    
+    int get(RenderObject* renderer, FontBaseline baselineType) const
+    {
+        const HashMap<RenderObject*, int>& mapToCheck = baselineType == AlphabeticBaseline ? m_alphabeticPositions : m_ideographicPositions;
+        const HashMap<RenderObject*, int>::const_iterator it = mapToCheck.find(renderer);
+        if (it == mapToCheck.end())
+            return PositionUndefined;
+        return it->second;
+    }
+    
+    void set(RenderObject* renderer, FontBaseline baselineType, int position)
+    {
+        if (baselineType == AlphabeticBaseline)
+            m_alphabeticPositions.set(renderer, position);
+        else
+            m_ideographicPositions.set(renderer, position);
+    }
+
+private:
+    HashMap<RenderObject*, int> m_alphabeticPositions;
+    HashMap<RenderObject*, int> m_ideographicPositions;
+};
+
+} // namespace WebCore
+
+#endif // VerticalPositionCache_h
diff --git a/WebCore/rendering/svg/SVGInlineTextBox.cpp b/WebCore/rendering/svg/SVGInlineTextBox.cpp
index 699d788..d1f660a 100644
--- a/WebCore/rendering/svg/SVGInlineTextBox.cpp
+++ b/WebCore/rendering/svg/SVGInlineTextBox.cpp
@@ -588,7 +588,7 @@ IntRect SVGInlineTextBox::calculateBoundaries() const
     RenderStyle* style = textRenderer->style();
     ASSERT(style);
 
-    int baseline = baselinePosition();
+    int baseline = baselinePosition(AlphabeticBaseline);
     int heightDifference = baseline - style->font().ascent();
 
     unsigned textFragmentsSize = m_textFragments.size();

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list