svg/text/text-overflow-ellipsis-svgfont-kerning-ligatures.html and svg/css/font-face...
authormmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 1 Apr 2014 20:05:08 +0000 (20:05 +0000)
committermmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 1 Apr 2014 20:05:08 +0000 (20:05 +0000)
https://bugs.webkit.org/show_bug.cgi?id=119747

Reviewed by Simon Fraser.

Source/WebCore:

Even though kerning and ligatures currently don't work with the
simple text path, messing those up is better than creating null
CTRun and CTLine objects.

Rather than calling the badly-named renderingContext() function on TextRun objects
to determine if they are drawn with an SVG font, this patch creates a wrapper function
with a better name and uses that instead.

Test: svg/text/svg-font-hittest.html

* platform/graphics/Font.cpp:
(WebCore::isDrawnWithSVGFont): Wrapper around renderingContext()
(WebCore::Font::drawText): Use wrapper function
(WebCore::Font::drawEmphasisMarks): Use wrapper function
(WebCore::Font::width): Use wrapper function
(WebCore::Font::selectionRectForText): Use wrapper function
(WebCore::Font::offsetForPosition): If we are using an SVG font, use the simple path
instead of the complex one
(WebCore::Font::codePath): Use wrapper function
* platform/graphics/cocoa/FontPlatformDataCocoa.mm:
(WebCore::FontPlatformData::ctFont):

LayoutTests:

Clicking on SVG text used to cause a ComplexTextController to be built
around the SVG text (which is incorrect and would crash). This test
does just that and makes sure there is no crash.

* svg/text/resources/Litherum.svg: Added.
* svg/text/svg-font-hittest-expected.txt: Added.
* svg/text/svg-font-hittest.html: Added.
* LayoutTests/platform/mac/TestExpectations: Unskipped tests

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

LayoutTests/ChangeLog
LayoutTests/platform/mac/TestExpectations
LayoutTests/svg/text/resources/Litherum.svg [new file with mode: 0644]
LayoutTests/svg/text/svg-font-hittest-expected.txt [new file with mode: 0644]
LayoutTests/svg/text/svg-font-hittest.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/Font.cpp
Source/WebCore/platform/graphics/cocoa/FontPlatformDataCocoa.mm

index a4c7ed856fcb24ffebed25c28eb0dac6a18732ee..4137e9098a834016516c0f8580b6ae7b0301639d 100644 (file)
@@ -1,3 +1,19 @@
+2014-04-01  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        svg/text/text-overflow-ellipsis-svgfont-kerning-ligatures.html and svg/css/font-face-crash.html frequently assert in ComplexTextController::offsetForPosition
+        https://bugs.webkit.org/show_bug.cgi?id=119747
+
+        Reviewed by Simon Fraser.
+
+        Clicking on SVG text used to cause a ComplexTextController to be built
+        around the SVG text (which is incorrect and would crash). This test
+        does just that and makes sure there is no crash.
+
+        * svg/text/resources/Litherum.svg: Added.
+        * svg/text/svg-font-hittest-expected.txt: Added.
+        * svg/text/svg-font-hittest.html: Added.
+        * LayoutTests/platform/mac/TestExpectations: Unskipped tests
+
 2014-04-01  Daniel Bates  <dabates@apple.com>
 
         RenderQuote must destroy remaining text renderer before first letter renderer
index c3180ab605b1b19cf8f16a1423f6a2463342ae45..83b39fe28aaf35347ea8cd792c5f84069b047d56 100644 (file)
@@ -1319,9 +1319,6 @@ webkit.org/b/50959 animations/play-state-suspend.html [ Pass Failure ]
 webkit.org/b/122040 animations/combo-transform-translate+scale.html [ Pass Failure ]
 webkit.org/b/128379 animations/suspend-resume-animation.html [ Pass Failure ]
 
-webkit.org/b/119747 [ Debug ] svg/text/text-overflow-ellipsis-svgfont-kerning-ligatures.html [ Skip ]
-webkit.org/b/119747 [ Debug ] svg/css/font-face-crash.html [ Skip ]
-
 # Regressions in svg/clip-path
 webkit.org/b/128499 svg/clip-path/clip-path-content-use-005.svg [ ImageOnlyFailure ]
 webkit.org/b/128499 svg/clip-path/clip-path-precision-001.svg [ ImageOnlyFailure ]
diff --git a/LayoutTests/svg/text/resources/Litherum.svg b/LayoutTests/svg/text/resources/Litherum.svg
new file mode 100644 (file)
index 0000000..042c7ed
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata></metadata>
+<defs>
+<font id="Litherum" horiz-adv-x="1024">
+<font-face units-per-em="14" ascent="14" descent="-7"/>
+<glyph unicode="|" horiz-adv-x="14" d="M5 -7v21h4v-21z"/>
+</font>
+</defs>
+</svg>
diff --git a/LayoutTests/svg/text/svg-font-hittest-expected.txt b/LayoutTests/svg/text/svg-font-hittest-expected.txt
new file mode 100644 (file)
index 0000000..c235c1e
--- /dev/null
@@ -0,0 +1,3 @@
+This code triggers the glyph hit-testing code, which should not crash when a glyph is drawn with SVG fonts.
+Pass
+|
diff --git a/LayoutTests/svg/text/svg-font-hittest.html b/LayoutTests/svg/text/svg-font-hittest.html
new file mode 100644 (file)
index 0000000..969cb55
--- /dev/null
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+@font-face {
+    font-family: 'Litherum';
+    src: url("./resources/Litherum.svg") format(svg)
+}
+#p {
+    font: 1000px 'Litherum';
+}
+</style>
+</head>
+<body onload="test()">
+This code triggers the glyph hit-testing code, which should not
+crash when a glyph is drawn with SVG fonts.
+<div id="result"></div>
+<div id="p">|</div>
+<script>
+function test() {
+    if (document.caretRangeFromPoint(400, 300))
+        document.getElementById("result").innerText = "Pass";
+    else
+        document.getElementById("result").innerText = "Fail";
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+}
+// Force layout, so that fonts begin to load before the document finishes loading, and thus delay the load event.
+document.body.offsetTop;
+</script>
+</body>
+</html>
index 6e4c1666257a99c290d66c8bb1390c9039b0bea7..581f5bd6f3185b7c09e3672b319eceb41f16c78d 100644 (file)
@@ -1,3 +1,32 @@
+2014-04-01  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        svg/text/text-overflow-ellipsis-svgfont-kerning-ligatures.html and svg/css/font-face-crash.html frequently assert in ComplexTextController::offsetForPosition
+        https://bugs.webkit.org/show_bug.cgi?id=119747
+
+        Reviewed by Simon Fraser.
+
+        Even though kerning and ligatures currently don't work with the
+        simple text path, messing those up is better than creating null
+        CTRun and CTLine objects.
+
+        Rather than calling the badly-named renderingContext() function on TextRun objects
+        to determine if they are drawn with an SVG font, this patch creates a wrapper function
+        with a better name and uses that instead.
+
+        Test: svg/text/svg-font-hittest.html
+
+        * platform/graphics/Font.cpp:
+        (WebCore::isDrawnWithSVGFont): Wrapper around renderingContext()
+        (WebCore::Font::drawText): Use wrapper function
+        (WebCore::Font::drawEmphasisMarks): Use wrapper function
+        (WebCore::Font::width): Use wrapper function
+        (WebCore::Font::selectionRectForText): Use wrapper function
+        (WebCore::Font::offsetForPosition): If we are using an SVG font, use the simple path
+        instead of the complex one
+        (WebCore::Font::codePath): Use wrapper function
+        * platform/graphics/cocoa/FontPlatformDataCocoa.mm:
+        (WebCore::FontPlatformData::ctFont):
+
 2014-04-01  Daniel Bates  <dabates@apple.com>
 
         RenderQuote must destroy remaining text renderer before first letter renderer
index 51792335e34c8f57172e74ae765c7a92deafa6b8..f88b8b1a5aa274f1bbf1630cee8efbc2a90e05da 100644 (file)
@@ -63,6 +63,11 @@ const uint8_t Font::s_roundingHackCharacterTable[256] = {
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 };
 
+static bool isDrawnWithSVGFont(const TextRun& run)
+{
+    return run.renderingContext();
+}
+
 static bool useBackslashAsYenSignForFamily(const AtomicString& family)
 {
     if (family.isEmpty())
@@ -336,7 +341,7 @@ float Font::drawText(GraphicsContext* context, const TextRun& run, const FloatPo
 
     CodePath codePathToUse = codePath(run);
     // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050
-    if (codePathToUse != Complex && typesettingFeatures() && (from || to != run.length()) && !run.renderingContext())
+    if (codePathToUse != Complex && typesettingFeatures() && (from || to != run.length()) && !isDrawnWithSVGFont(run))
         codePathToUse = Complex;
 
     if (codePathToUse != Complex)
@@ -355,7 +360,7 @@ void Font::drawEmphasisMarks(GraphicsContext* context, const TextRun& run, const
 
     CodePath codePathToUse = codePath(run);
     // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050
-    if (codePathToUse != Complex && typesettingFeatures() && (from || to != run.length()) && !run.renderingContext())
+    if (codePathToUse != Complex && typesettingFeatures() && (from || to != run.length()) && !isDrawnWithSVGFont(run))
         codePathToUse = Complex;
 
     if (codePathToUse != Complex)
@@ -400,8 +405,8 @@ float Font::width(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFo
 float Font::width(const TextRun& run, int& charsConsumed, String& glyphName) const
 {
 #if ENABLE(SVG_FONTS)
-    if (TextRun::RenderingContext* renderingContext = run.renderingContext())
-        return renderingContext->floatWidthUsingSVGFont(*this, run, charsConsumed, glyphName);
+    if (isDrawnWithSVGFont(run))
+        return run.renderingContext()->floatWidthUsingSVGFont(*this, run, charsConsumed, glyphName);
 #endif
 
     charsConsumed = run.length();
@@ -508,7 +513,7 @@ FloatRect Font::selectionRectForText(const TextRun& run, const FloatPoint& point
 
     CodePath codePathToUse = codePath(run);
     // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050
-    if (codePathToUse != Complex && typesettingFeatures() && (from || to != run.length()) && !run.renderingContext())
+    if (codePathToUse != Complex && typesettingFeatures() && (from || to != run.length()) && !isDrawnWithSVGFont(run))
         codePathToUse = Complex;
 
     if (codePathToUse != Complex)
@@ -520,7 +525,7 @@ FloatRect Font::selectionRectForText(const TextRun& run, const FloatPoint& point
 int Font::offsetForPosition(const TextRun& run, float x, bool includePartialGlyphs) const
 {
     // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050
-    if (codePath(run) != Complex && !typesettingFeatures())
+    if (codePath(run) != Complex && (!typesettingFeatures() || isDrawnWithSVGFont(run)))
         return offsetForPositionForSimpleText(run, x, includePartialGlyphs);
 
     return offsetForPositionForComplexText(run, x, includePartialGlyphs);
@@ -587,7 +592,7 @@ Font::CodePath Font::codePath(const TextRun& run) const
         return s_codePath;
 
 #if ENABLE(SVG_FONTS)
-    if (run.renderingContext())
+    if (isDrawnWithSVGFont(run))
         return Simple;
 #endif
 
index e8d84b1ee16e4fa7e7a73812b5677116e2f69fd7..2e7fdd9e861189b68bb19601113c1b0077c4e336 100644 (file)
@@ -308,6 +308,7 @@ CTFontRef FontPlatformData::ctFont() const
     if (m_CTFont)
         return m_CTFont.get();
 
+    ASSERT(m_cgFont.get());
 #if !PLATFORM(IOS)
     m_CTFont = toCTFontRef(m_font);
     if (m_CTFont) {
@@ -319,10 +320,8 @@ CTFontRef FontPlatformData::ctFont() const
         else
             fontDescriptor = cascadeToLastResortFontDescriptor();
         m_CTFont = adoptCF(CTFontCreateCopyWithAttributes(m_CTFont.get(), m_size, 0, fontDescriptor));
-    } else {
-        ASSERT(m_cgFont.get());
+    } else
         m_CTFont = adoptCF(CTFontCreateWithGraphicsFont(m_cgFont.get(), m_size, 0, cascadeToLastResortFontDescriptor()));
-    }
 #else
     // Apple Color Emoji size is adjusted (and then re-adjusted by Core Text) and capped.
     CGFloat size = !m_isEmoji ? m_size : m_size <= 15 ? 4 * (m_size + 2) / static_cast<CGFloat>(5) : 16;