REGRESSION: missing underline under CJK text
authormmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 9 Jun 2014 21:18:07 +0000 (21:18 +0000)
committermmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 9 Jun 2014 21:18:07 +0000 (21:18 +0000)
commit00f26f7d17025999f6137e99b94e1efb6ab874a3
tree6240cab8c784f2094e92fc0eb96af1de6d9eb302
parentea8637d9fa936ec7f3cd9e1e09ea452c0160dbb3
REGRESSION: missing underline under CJK text
https://bugs.webkit.org/show_bug.cgi?id=128145

Reviewed by Darin Adler.

Source/WebCore:
This patch refactors the GlyphToPathTranslator which is used to find intersections of
glyphs and underlines. It was modified to allow for querying these pieces of
information:
1) The extents of the glyph. This can be used to make the underlines skip an entire
glyph, wholesale
2) What kind of skipping behavior should be used
3) The Path which represents the glyph
There are three skipping behaviors:
1) (SkipDescenders) The previous behavior
2) (SkipGlyph) Make the underline skip over the entire glyph, using the extents() function
3) (DrawOverGlyph) Make the underline plow through the glyph, ignoring any descenders

Calculating which underlining behavior to use depends on what the base codepoint that
originated that glyph is. This means that we have to map from glyphs to characters,
something which is nontrivial to do. In order to solve this problem, this patch adds
an optional vector to GlyphBuffer which represents the location in the original string
from which a particular glyph originated. Then, when our WidthIterator code adds
glyphs to the GlyphBuffer, we can include the extra information about where we are
in the input string. Once this data is available, the GlyphPathTranslator can look up
the base codepoint from which this glyph originates, and can run ICU functions on that
codepoint.

We can use the ICU ublock_getCode() function to find which Unicode block a particular
codepoint comes from. If the codepoint comes from a CJK block, we will use
DrawOverGlyph; otherwise, we will use SkipDescenders.

Test: fast/css3-text/css3-text-decoration/text-decoration-skip/text-decoration-skip-ink-cjk.html

* platform/graphics/Font.cpp:
(WebCore::sharedUnderlineType): Look up the base codepoint from which this glyph
originates, call ublock_getCode to get its Unicode block, then return
a GlyphUnderlineType accordingly. This code is shared between SVG and non-SVG.
* platform/graphics/Font.h: New virtual functions in GlyphToPathTranslator, as well as
function signatures for the above two functions.
* platform/graphics/GlyphBuffer.h: Add an optional instance member for the location
from within the original string from which a particular glyph originates.
(WebCore::GlyphBuffer::clear): Updated for new member.
(WebCore::GlyphBuffer::add): Ditto.
(WebCore::GlyphBuffer::saveOffsetsInString): Opt-in to using the new variable
(WebCore::GlyphBuffer::offsetInString): New variable accessor.
* platform/graphics/TextRun.h: SVG needs the TextRun to use sharedUnderlineType.
* platform/graphics/WidthIterator.cpp:
(WebCore::WidthIterator::advanceInternal): Use GlyphBuffer's new variable (if present).
* platform/graphics/mac/ComplexTextController.cpp:
(WebCore::ComplexTextController::advance): Use GlyphBuffer's new variable (if present).
* platform/graphics/mac/FontMac.mm: Implement new GlyphToPathTranslator functions.
(WebCore::MacGlyphToPathTranslator::path):
(WebCore::MacGlyphToPathTranslator::extents):
(WebCore::MacGlyphToPathTranslator::underlineType): Calls sharedUnderlineType().
(WebCore::MacGlyphToPathTranslator::moveToNextValidGlyph):
(WebCore::MacGlyphToPathTranslator::increment):
(WebCore::Font::dashesForIntersectionsWithRect): Ask the translator what kind of underline
behavior should be used. React accordingly.
(WebCore::MacGlyphToPathTranslator::nextPath): Deleted.
(WebCore::MacGlyphToPathTranslator::incrementIndex): Deleted.
* platform/graphics/win/UniscribeController.cpp:
(WebCore::UniscribeController::shapeAndPlaceItem): Update to new signature of GlyphBuffer::add()
* rendering/svg/SVGTextRunRenderingContext.cpp: Implement new GlyphToPathTranslator functions.
(WebCore::SVGGlyphToPathTranslator::SVGGlyphToPathTranslator):
(WebCore::SVGGlyphToPathTranslator::getCurrentTransform):
(WebCore::SVGGlyphToPathTranslator::path):
(WebCore::SVGGlyphToPathTranslator::extents):
(WebCore::MacGlyphToPathTranslator::underlineType): Calls sharedUnderlineType().
(WebCore::SVGGlyphToPathTranslator::moveToNextValidGlyph):
(WebCore::SVGGlyphToPathTranslator::increment):
(WebCore::SVGTextRunRenderingContext::createGlyphToPathTranslator):
(WebCore::SVGTextRunRenderingContext::drawSVGGlyphs):
(WebCore::SVGGlyphToPathTranslator::nextPath): Deleted.
(WebCore::SVGGlyphToPathTranslator::incrementIndex): Deleted.
* rendering/svg/SVGTextRunRenderingContext.h: SVG needs the TextRun to use sharedUnderlineType.

LayoutTests:
This test makes sure that underlines under CJK text don't skip over descenders.

* fast/css3-text/css3-text-decoration/text-decoration-skip/text-decoration-skip-ink-cjk-expected.html: Added.
* fast/css3-text/css3-text-decoration/text-decoration-skip/text-decoration-skip-ink-cjk.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@169715 268f45cc-cd09-0410-ab3c-d52691b4dbfc
15 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-skip/resources/Litherum.svg
LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-skip/text-decoration-skip-ink-cjk-expected.html [new file with mode: 0644]
LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-skip/text-decoration-skip-ink-cjk.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/Font.cpp
Source/WebCore/platform/graphics/Font.h
Source/WebCore/platform/graphics/GlyphBuffer.h
Source/WebCore/platform/graphics/TextRun.h
Source/WebCore/platform/graphics/WidthIterator.cpp
Source/WebCore/platform/graphics/mac/ComplexTextController.cpp
Source/WebCore/platform/graphics/mac/FontMac.mm
Source/WebCore/platform/graphics/win/UniscribeController.cpp
Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp
Source/WebCore/rendering/svg/SVGTextRunRenderingContext.h