https://bugs.webkit.org/show_bug.cgi?id=48537
authorhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 17 Nov 2010 20:55:40 +0000 (20:55 +0000)
committerhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 17 Nov 2010 20:55:40 +0000 (20:55 +0000)
commitfa0e9a6a3cfcd90bb60840f4ec7eff50ba3cd49c
treefdb5efe62d069013e9041191a78425b32c200bf9
parent9d3d8fb1be52b5cd8829d1993c4a975f901f1889
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: https://svn.webkit.org/repository/webkit/trunk@72235 268f45cc-cd09-0410-ab3c-d52691b4dbfc
57 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/blockflow/vertical-align-table-baseline.html [new file with mode: 0644]
LayoutTests/fast/blockflow/vertical-baseline-alignment.html [new file with mode: 0644]
LayoutTests/platform/mac/fast/blockflow/vertical-align-table-baseline-expected.checksum [new file with mode: 0644]
LayoutTests/platform/mac/fast/blockflow/vertical-align-table-baseline-expected.png [new file with mode: 0644]
LayoutTests/platform/mac/fast/blockflow/vertical-align-table-baseline-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/fast/blockflow/vertical-baseline-alignment-expected.checksum [new file with mode: 0644]
LayoutTests/platform/mac/fast/blockflow/vertical-baseline-alignment-expected.png [new file with mode: 0644]
LayoutTests/platform/mac/fast/blockflow/vertical-baseline-alignment-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/fast/blockflow/vertical-font-fallback-expected.checksum
LayoutTests/platform/mac/fast/blockflow/vertical-font-fallback-expected.png
LayoutTests/platform/mac/fast/blockflow/vertical-font-fallback-expected.txt
LayoutTests/platform/mac/fast/repaint/repaint-across-writing-mode-boundary-expected.checksum
LayoutTests/platform/mac/fast/repaint/repaint-across-writing-mode-boundary-expected.png
LayoutTests/platform/mac/fast/repaint/repaint-across-writing-mode-boundary-expected.txt
WebCore/ChangeLog
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/mathml/RenderMathMLFraction.cpp
WebCore/mathml/RenderMathMLFraction.h
WebCore/mathml/RenderMathMLOperator.cpp
WebCore/mathml/RenderMathMLOperator.h
WebCore/mathml/RenderMathMLRow.cpp
WebCore/mathml/RenderMathMLRow.h
WebCore/mathml/RenderMathMLSubSup.cpp
WebCore/mathml/RenderMathMLSubSup.h
WebCore/mathml/RenderMathMLUnderOver.cpp
WebCore/mathml/RenderMathMLUnderOver.h
WebCore/platform/graphics/SimpleFontData.h
WebCore/rendering/InlineBox.h
WebCore/rendering/InlineFlowBox.cpp
WebCore/rendering/InlineFlowBox.h
WebCore/rendering/InlineTextBox.cpp
WebCore/rendering/InlineTextBox.h
WebCore/rendering/RenderBlock.cpp
WebCore/rendering/RenderBlock.h
WebCore/rendering/RenderBlockLineLayout.cpp
WebCore/rendering/RenderBox.cpp
WebCore/rendering/RenderBox.h
WebCore/rendering/RenderBoxModelObject.cpp
WebCore/rendering/RenderBoxModelObject.h
WebCore/rendering/RenderFileUploadControl.cpp
WebCore/rendering/RenderInline.cpp
WebCore/rendering/RenderInline.h
WebCore/rendering/RenderListBox.cpp
WebCore/rendering/RenderListBox.h
WebCore/rendering/RenderListMarker.cpp
WebCore/rendering/RenderListMarker.h
WebCore/rendering/RenderSlider.cpp
WebCore/rendering/RenderSlider.h
WebCore/rendering/RenderTableCell.cpp
WebCore/rendering/RenderTableCell.h
WebCore/rendering/RenderTextControlMultiLine.cpp
WebCore/rendering/RenderTextControlMultiLine.h
WebCore/rendering/RootInlineBox.cpp
WebCore/rendering/RootInlineBox.h
WebCore/rendering/VerticalPositionCache.h [new file with mode: 0644]
WebCore/rendering/svg/SVGInlineTextBox.cpp