Simple line layout: Bail out from Simple Line Layout when the primary font is insuffi...
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 4 Feb 2017 01:42:12 +0000 (01:42 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 4 Feb 2017 01:42:12 +0000 (01:42 +0000)
https://bugs.webkit.org/show_bug.cgi?id=167820
Source/WebCore:

<rdar://problem/30359685>

Reviewed by Myles C. Maxfield.

Currently simple line layout requires the primary font to have all the glyps for the content.

Test: fast/text/simple-line-layout-do-not-support-unicode-range.html

* rendering/SimpleLineLayout.cpp:
(WebCore::SimpleLineLayout::canUseForText):
(WebCore::SimpleLineLayout::canUseForFontAndText):
(WebCore::SimpleLineLayout::printReason):

LayoutTests:

Reviewed by Myles C. Maxfield.

* fast/text/simple-line-layout-do-not-support-unicode-range-expected.html: Added.
* fast/text/simple-line-layout-do-not-support-unicode-range.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/fast/text/simple-line-layout-do-not-support-unicode-range-expected.html [new file with mode: 0644]
LayoutTests/fast/text/simple-line-layout-do-not-support-unicode-range.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/SimpleLineLayout.cpp

index 52d9dce..44a567d 100644 (file)
@@ -1,3 +1,13 @@
+2017-02-03  Zalan Bujtas  <zalan@apple.com>
+
+        Simple line layout: Bail out from Simple Line Layout when the primary font is insufficient.
+        https://bugs.webkit.org/show_bug.cgi?id=167820
+
+        Reviewed by Myles C. Maxfield.
+
+        * fast/text/simple-line-layout-do-not-support-unicode-range-expected.html: Added.
+        * fast/text/simple-line-layout-do-not-support-unicode-range.html: Added.
+
 2017-02-03  Jer Noble  <jer.noble@apple.com>
 
         ASSERT in HTMLMediaElement::~HTMLMediaElement
diff --git a/LayoutTests/fast/text/simple-line-layout-do-not-support-unicode-range-expected.html b/LayoutTests/fast/text/simple-line-layout-do-not-support-unicode-range-expected.html
new file mode 100644 (file)
index 0000000..4a79f9d
--- /dev/null
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Simple line layout can't work with insufficient primary font.</title>
+<style>
+@font-face {
+    font-family: Monaco;
+    unicode-range: U+0060-0080;
+    src: local(Times);
+}
+</style>
+<script>
+if (window.internals) {
+    internals.settings.setSimpleLineLayoutDebugBordersEnabled(true);
+    internals.settings.setSimpleLineLayoutEnabled(false);
+}
+</script>
+</head>
+<body>
+<p style="font-family: Monaco;">THIS SHOULD NOT HAVE GREEN simple line layout borders.</p>
+</body>
+</html>
diff --git a/LayoutTests/fast/text/simple-line-layout-do-not-support-unicode-range.html b/LayoutTests/fast/text/simple-line-layout-do-not-support-unicode-range.html
new file mode 100644 (file)
index 0000000..022bd8b
--- /dev/null
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Simple line layout can't work with insufficient primary font.</title>
+<style>
+@font-face {
+    font-family: Monaco;
+    unicode-range: U+0060-0080;
+    src: local(Times);
+}
+</style>
+<script>
+if (window.internals) {
+    internals.settings.setSimpleLineLayoutDebugBordersEnabled(true);
+    internals.settings.setSimpleLineLayoutEnabled(true);
+}
+</script>
+</head>
+<body>
+<p style="font-family: Monaco;">THIS SHOULD NOT HAVE GREEN simple line layout borders.</p>
+</body>
+</html>
index 6d7301a..2adbe04 100644 (file)
@@ -1,3 +1,20 @@
+2017-02-03  Zalan Bujtas  <zalan@apple.com>
+
+        Simple line layout: Bail out from Simple Line Layout when the primary font is insufficient.
+        https://bugs.webkit.org/show_bug.cgi?id=167820
+        <rdar://problem/30359685>
+
+        Reviewed by Myles C. Maxfield.
+
+        Currently simple line layout requires the primary font to have all the glyps for the content.
+
+        Test: fast/text/simple-line-layout-do-not-support-unicode-range.html
+
+        * rendering/SimpleLineLayout.cpp:
+        (WebCore::SimpleLineLayout::canUseForText):
+        (WebCore::SimpleLineLayout::canUseForFontAndText):
+        (WebCore::SimpleLineLayout::printReason):
+
 2017-02-03  Jer Noble  <jer.noble@apple.com>
 
         ASSERT in HTMLMediaElement::~HTMLMediaElement
index b6257a2..0736aeb 100644 (file)
@@ -100,7 +100,7 @@ enum AvoidanceReason_ : uint64_t {
     FlowTextHasSoftHyphen                 = 1LLU  << 34,
     FlowTextHasDirectionCharacter         = 1LLU  << 35,
     FlowIsMissingPrimaryFont              = 1LLU  << 36,
-    FlowFontIsMissingGlyph                = 1LLU  << 37,
+    FlowPrimaryFontIsInsufficient         = 1LLU  << 37,
     FlowTextIsCombineText                 = 1LLU  << 38,
     FlowTextIsRenderCounter               = 1LLU  << 39,
     FlowTextIsRenderQuote                 = 1LLU  << 40,
@@ -137,10 +137,11 @@ enum class IncludeReasons { First , All };
 #endif
 
 template <typename CharacterType>
-static AvoidanceReasonFlags canUseForText(const CharacterType* text, unsigned length, const Font& font, std::optional<float> lineHeightConstraint,
+static AvoidanceReasonFlags canUseForText(const CharacterType* text, unsigned length, const FontCascade& fontCascade, std::optional<float> lineHeightConstraint,
     bool textIsJustified, IncludeReasons includeReasons)
 {
     AvoidanceReasonFlags reasons = { };
+    auto& primaryFont = fontCascade.primaryFont();
     // FIXME: <textarea maxlength=0> generates empty text node.
     if (!length)
         SET_REASON_AND_RETURN_IF_NEEDED(FlowTextIsEmpty, reasons, includeReasons);
@@ -168,20 +169,21 @@ static AvoidanceReasonFlags canUseForText(const CharacterType* text, unsigned le
             || direction == U_POP_DIRECTIONAL_FORMAT || direction == U_BOUNDARY_NEUTRAL)
             SET_REASON_AND_RETURN_IF_NEEDED(FlowTextHasDirectionCharacter, reasons, includeReasons);
 
-        auto glyph = font.glyphForCharacter(character);
-        if (!glyph)
-            SET_REASON_AND_RETURN_IF_NEEDED(FlowFontIsMissingGlyph, reasons, includeReasons);
-        if (lineHeightConstraint && font.boundsForGlyph(glyph).height() > *lineHeightConstraint)
+        auto glyphData = fontCascade.glyphDataForCharacter(character, false);
+        if (!glyphData.isValid() || glyphData.font != &primaryFont)
+            SET_REASON_AND_RETURN_IF_NEEDED(FlowPrimaryFontIsInsufficient, reasons, includeReasons);
+
+        if (lineHeightConstraint && primaryFont.boundsForGlyph(glyphData.glyph).height() > *lineHeightConstraint)
             SET_REASON_AND_RETURN_IF_NEEDED(FlowFontHasOverflowGlyph, reasons, includeReasons);
     }
     return reasons;
 }
 
-static AvoidanceReasonFlags canUseForText(const RenderText& textRenderer, const Font& font, std::optional<float> lineHeightConstraint, bool textIsJustified, IncludeReasons includeReasons)
+static AvoidanceReasonFlags canUseForText(const RenderText& textRenderer, const FontCascade& fontCascade, std::optional<float> lineHeightConstraint, bool textIsJustified, IncludeReasons includeReasons)
 {
     if (textRenderer.is8Bit())
-        return canUseForText(textRenderer.characters8(), textRenderer.textLength(), font, lineHeightConstraint, false, includeReasons);
-    return canUseForText(textRenderer.characters16(), textRenderer.textLength(), font, lineHeightConstraint, textIsJustified, includeReasons);
+        return canUseForText(textRenderer.characters8(), textRenderer.textLength(), fontCascade, lineHeightConstraint, false, includeReasons);
+    return canUseForText(textRenderer.characters16(), textRenderer.textLength(), fontCascade, lineHeightConstraint, textIsJustified, includeReasons);
 }
 
 static AvoidanceReasonFlags canUseForFontAndText(const RenderBlockFlow& flow, IncludeReasons includeReasons)
@@ -189,8 +191,8 @@ static AvoidanceReasonFlags canUseForFontAndText(const RenderBlockFlow& flow, In
     AvoidanceReasonFlags reasons = { };
     // We assume that all lines have metrics based purely on the primary font.
     const auto& style = flow.style();
-    auto& primaryFont = style.fontCascade().primaryFont();
-    if (primaryFont.isLoading())
+    auto& fontCascade = style.fontCascade();
+    if (fontCascade.primaryFont().isLoading())
         SET_REASON_AND_RETURN_IF_NEEDED(FlowIsMissingPrimaryFont, reasons, includeReasons);
     std::optional<float> lineHeightConstraint;
     if (style.lineBoxContain() & LineBoxContainGlyphs)
@@ -210,7 +212,7 @@ static AvoidanceReasonFlags canUseForFontAndText(const RenderBlockFlow& flow, In
         if (style.fontCascade().codePath(TextRun(textRenderer.text())) != FontCascade::Simple)
             SET_REASON_AND_RETURN_IF_NEEDED(FlowFontIsNotSimple, reasons, includeReasons);
 
-        auto textReasons = canUseForText(textRenderer, primaryFont, lineHeightConstraint, flowIsJustified, includeReasons);
+        auto textReasons = canUseForText(textRenderer, fontCascade, lineHeightConstraint, flowIsJustified, includeReasons);
         if (textReasons != NoReason)
             SET_REASON_AND_RETURN_IF_NEEDED(textReasons, reasons, includeReasons);
     }
@@ -1031,8 +1033,8 @@ static void printReason(AvoidanceReason reason, TextStream& stream)
     case FlowIsMissingPrimaryFont:
         stream << "missing primary font";
         break;
-    case FlowFontIsMissingGlyph:
-        stream << "missing glyph";
+    case FlowPrimaryFontIsInsufficient:
+        stream << "missing glyph or glyph needs another font";
         break;
     case FlowTextIsCombineText:
         stream << "text is combine";