Title: [267468] trunk/Source/WebCore
Revision
267468
Author
[email protected]
Date
2020-09-23 05:03:57 -0700 (Wed, 23 Sep 2020)

Log Message

[LFC][Integration] Add canUseFor functions
https://bugs.webkit.org/show_bug.cgi?id=216869

Reviewed by Zalan Bujtas.

Copy the SLL canUseFor code.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* layout/integration/LayoutIntegrationCoverage.cpp: Added.
(WebCore::LayoutIntegration::canUseForCharacter):
(WebCore::LayoutIntegration::canUseForText):
(WebCore::LayoutIntegration::canUseForFontAndText):
(WebCore::LayoutIntegration::canUseForStyle):
(WebCore::LayoutIntegration::canUseForLineLayoutWithReason):
(WebCore::LayoutIntegration::canUseForLineLayout):
(WebCore::LayoutIntegration::canUseForLineLayoutAfterStyleChange):
* layout/integration/LayoutIntegrationCoverage.h: Added.

Also switch to OptionSet.

* layout/integration/LayoutIntegrationLineLayout.cpp:
(WebCore::LayoutIntegration::LineLayout::isEnabled):
(WebCore::LayoutIntegration::LineLayout::canUseFor):
(WebCore::LayoutIntegration::LineLayout::canUseForAfterStyleChange):
* layout/integration/LayoutIntegrationLineLayout.h:
(WebCore::LayoutIntegration::LineLayout::canUseFor): Deleted.
* rendering/RenderBlockFlow.cpp:
(WebCore::RenderBlockFlow::layoutInlineChildren):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (267467 => 267468)


--- trunk/Source/WebCore/ChangeLog	2020-09-23 10:27:14 UTC (rev 267467)
+++ trunk/Source/WebCore/ChangeLog	2020-09-23 12:03:57 UTC (rev 267468)
@@ -1,3 +1,35 @@
+2020-09-23  Antti Koivisto  <[email protected]>
+
+        [LFC][Integration] Add canUseFor functions
+        https://bugs.webkit.org/show_bug.cgi?id=216869
+
+        Reviewed by Zalan Bujtas.
+
+        Copy the SLL canUseFor code.
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * layout/integration/LayoutIntegrationCoverage.cpp: Added.
+        (WebCore::LayoutIntegration::canUseForCharacter):
+        (WebCore::LayoutIntegration::canUseForText):
+        (WebCore::LayoutIntegration::canUseForFontAndText):
+        (WebCore::LayoutIntegration::canUseForStyle):
+        (WebCore::LayoutIntegration::canUseForLineLayoutWithReason):
+        (WebCore::LayoutIntegration::canUseForLineLayout):
+        (WebCore::LayoutIntegration::canUseForLineLayoutAfterStyleChange):
+        * layout/integration/LayoutIntegrationCoverage.h: Added.
+
+        Also switch to OptionSet.
+
+        * layout/integration/LayoutIntegrationLineLayout.cpp:
+        (WebCore::LayoutIntegration::LineLayout::isEnabled):
+        (WebCore::LayoutIntegration::LineLayout::canUseFor):
+        (WebCore::LayoutIntegration::LineLayout::canUseForAfterStyleChange):
+        * layout/integration/LayoutIntegrationLineLayout.h:
+        (WebCore::LayoutIntegration::LineLayout::canUseFor): Deleted.
+        * rendering/RenderBlockFlow.cpp:
+        (WebCore::RenderBlockFlow::layoutInlineChildren):
+
 2020-09-23  Zalan Bujtas  <[email protected]>
 
         [LFC][IFC] Remove redundant RuntimeEnabledFeatures::layoutFormattingContextIntegrationEnabled from Line::Run::hasTrailingLetterSpacing

Modified: trunk/Source/WebCore/Sources.txt (267467 => 267468)


--- trunk/Source/WebCore/Sources.txt	2020-09-23 10:27:14 UTC (rev 267467)
+++ trunk/Source/WebCore/Sources.txt	2020-09-23 12:03:57 UTC (rev 267468)
@@ -1455,6 +1455,7 @@
 layout/inlineformatting/InlineTextItem.cpp
 layout/inlineformatting/text/TextUtil.cpp
 layout/integration/LayoutIntegrationBoxTree.cpp
+layout/integration/LayoutIntegrationCoverage.cpp
 layout/integration/LayoutIntegrationLineLayout.cpp
 layout/integration/LayoutIntegrationPagination.cpp
 layout/invalidation/InvalidationContext.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (267467 => 267468)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2020-09-23 10:27:14 UTC (rev 267467)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2020-09-23 12:03:57 UTC (rev 267468)
@@ -4975,6 +4975,8 @@
 		E3FA38641D71812D00AA5950 /* PendingScriptClient.h in Headers */ = {isa = PBXBuildFile; fileRef = E3FA38611D716E7600AA5950 /* PendingScriptClient.h */; };
 		E401C27517CE53EC00C41A35 /* ElementIteratorAssertions.h in Headers */ = {isa = PBXBuildFile; fileRef = E401C27417CE53EC00C41A35 /* ElementIteratorAssertions.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E401E0A41C3C0B8300F34D10 /* StyleChange.h in Headers */ = {isa = PBXBuildFile; fileRef = E401E0A31C3C0B8300F34D10 /* StyleChange.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		E403B7A2251B11930019E800 /* LayoutIntegrationCoverage.h in Headers */ = {isa = PBXBuildFile; fileRef = E403B7A1251B11930019E800 /* LayoutIntegrationCoverage.h */; };
+		E403B7A3251B11C10019E800 /* LayoutIntegrationPagination.h in Headers */ = {isa = PBXBuildFile; fileRef = E4312AB724B3265600678349 /* LayoutIntegrationPagination.h */; };
 		E418025523D4549B00FFB071 /* LayoutIntegrationBoxTree.h in Headers */ = {isa = PBXBuildFile; fileRef = E418025323D4549A00FFB071 /* LayoutIntegrationBoxTree.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E419041F1CC6486B00C35F5D /* FontSelectorClient.h in Headers */ = {isa = PBXBuildFile; fileRef = E419041E1CC6486B00C35F5D /* FontSelectorClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E42050172141901B0066EF3B /* ProcessWarming.h in Headers */ = {isa = PBXBuildFile; fileRef = E42050142141901A0066EF3B /* ProcessWarming.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -15814,6 +15816,8 @@
 		E401C27417CE53EC00C41A35 /* ElementIteratorAssertions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElementIteratorAssertions.h; sourceTree = "<group>"; };
 		E401E0A31C3C0B8300F34D10 /* StyleChange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleChange.h; sourceTree = "<group>"; };
 		E401E0A51C3C0CF700F34D10 /* StyleChange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleChange.cpp; sourceTree = "<group>"; };
+		E403B79F251B118B0019E800 /* LayoutIntegrationCoverage.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutIntegrationCoverage.cpp; sourceTree = "<group>"; };
+		E403B7A1251B11930019E800 /* LayoutIntegrationCoverage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LayoutIntegrationCoverage.h; sourceTree = "<group>"; };
 		E406F3FB1198307D009D59D6 /* ColorData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ColorData.cpp; path = DerivedSources/WebCore/ColorData.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
 		E418025323D4549A00FFB071 /* LayoutIntegrationBoxTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LayoutIntegrationBoxTree.h; sourceTree = "<group>"; };
 		E418025623D454B500FFB071 /* LayoutIntegrationBoxTree.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutIntegrationBoxTree.cpp; sourceTree = "<group>"; };
@@ -28443,12 +28447,14 @@
 		E4FB4B1E2395356F003C336A /* integration */ = {
 			isa = PBXGroup;
 			children = (
-				E4312AB524B3265600678349 /* LayoutIntegrationPagination.cpp */,
-				E4312AB724B3265600678349 /* LayoutIntegrationPagination.h */,
 				E418025623D454B500FFB071 /* LayoutIntegrationBoxTree.cpp */,
 				E418025323D4549A00FFB071 /* LayoutIntegrationBoxTree.h */,
+				E403B79F251B118B0019E800 /* LayoutIntegrationCoverage.cpp */,
+				E403B7A1251B11930019E800 /* LayoutIntegrationCoverage.h */,
 				E4ABABDE2360893D00FA4345 /* LayoutIntegrationLineLayout.cpp */,
 				E4ABABDB236088FD00FA4345 /* LayoutIntegrationLineLayout.h */,
+				E4312AB524B3265600678349 /* LayoutIntegrationPagination.cpp */,
+				E4312AB724B3265600678349 /* LayoutIntegrationPagination.h */,
 			);
 			path = integration;
 			sourceTree = "<group>";
@@ -32783,6 +32789,7 @@
 				B22279650D00BF220071B782 /* LinearGradientAttributes.h in Headers */,
 				AB31C91E10AE1B8E000C7B92 /* LineClampValue.h in Headers */,
 				FFEFAB2A18380DA000514534 /* LineLayoutState.h in Headers */,
+				E403B7A2251B11930019E800 /* LayoutIntegrationCoverage.h in Headers */,
 				E484A33E23055325009ADE6A /* LineLayoutTraversal.h in Headers */,
 				E4343D252392779000EBBB66 /* LineLayoutTraversalComplexPath.h in Headers */,
 				E451C628239293EC00993190 /* LineLayoutTraversalDisplayRunPath.h in Headers */,
@@ -33651,6 +33658,7 @@
 				228C284510D82500009D0D0E /* ScriptWrappable.h in Headers */,
 				1400D7A817136EA70077CE05 /* ScriptWrappableInlines.h in Headers */,
 				BC8AE34F12EA096A00EB3AE6 /* ScrollableArea.h in Headers */,
+				E403B7A3251B11C10019E800 /* LayoutIntegrationPagination.h in Headers */,
 				5D925B680F64D4DD00B847F0 /* ScrollAlignment.h in Headers */,
 				CA3BF67E10D99BAE00E6CE53 /* ScrollAnimator.h in Headers */,
 				0F1774801378B772009DA76A /* ScrollAnimatorIOS.h in Headers */,

Added: trunk/Source/WebCore/layout/integration/LayoutIntegrationCoverage.cpp (0 => 267468)


--- trunk/Source/WebCore/layout/integration/LayoutIntegrationCoverage.cpp	                        (rev 0)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationCoverage.cpp	2020-09-23 12:03:57 UTC (rev 267468)
@@ -0,0 +1,376 @@
+/*
+ * Copyright (C) 2013-2020 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.
+ */
+
+#include "config.h"
+#include "LayoutIntegrationCoverage.h"
+
+#include "DocumentMarkerController.h"
+#include "HTMLTextFormControlElement.h"
+#include "Logging.h"
+#include "RenderBlockFlow.h"
+#include "RenderMultiColumnFlow.h"
+#include "RenderTextControl.h"
+#include "RenderView.h"
+#include "RuntimeEnabledFeatures.h"
+#include "Settings.h"
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#ifndef NDEBUG
+#define SET_REASON_AND_RETURN_IF_NEEDED(reason, reasons, includeReasons) { \
+        reasons.add(AvoidanceReason::reason); \
+        if (includeReasons == IncludeReasons::First) \
+            return reasons; \
+    }
+#else
+#define SET_REASON_AND_RETURN_IF_NEEDED(reason, reasons, includeReasons) { \
+        ASSERT_UNUSED(includeReasons, includeReasons == IncludeReasons::First); \
+        reasons.add(AvoidanceReason::reason); \
+        return reasons; \
+    }
+#endif
+
+#ifndef NDEBUG
+#define ADD_REASONS_AND_RETURN_IF_NEEDED(newReasons, reasons, includeReasons) { \
+        reasons.add(newReasons); \
+        if (includeReasons == IncludeReasons::First) \
+            return reasons; \
+    }
+#else
+#define ADD_REASONS_AND_RETURN_IF_NEEDED(newReasons, reasons, includeReasons) { \
+        ASSERT_UNUSED(includeReasons, includeReasons == IncludeReasons::First); \
+        reasons.add(newReasons); \
+        return reasons; \
+    }
+#endif
+
+namespace WebCore {
+namespace LayoutIntegration {
+
+template <typename CharacterType> OptionSet<AvoidanceReason> canUseForCharacter(CharacterType, bool textIsJustified, IncludeReasons);
+
+template<> OptionSet<AvoidanceReason> canUseForCharacter(UChar character, bool textIsJustified, IncludeReasons includeReasons)
+{
+    OptionSet<AvoidanceReason> reasons;
+    if (textIsJustified) {
+        // Include characters up to Latin Extended-B and some punctuation range when text is justified.
+        bool isLatinIncludingExtendedB = character <= 0x01FF;
+        bool isPunctuationRange = character >= 0x2010 && character <= 0x2027;
+        if (!(isLatinIncludingExtendedB || isPunctuationRange))
+            SET_REASON_AND_RETURN_IF_NEEDED(FlowHasJustifiedNonLatinText, reasons, includeReasons);
+    }
+
+    if (U16_IS_SURROGATE(character))
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowTextHasSurrogatePair, reasons, includeReasons);
+
+    UCharDirection direction = u_charDirection(character);
+    if (direction == U_RIGHT_TO_LEFT || direction == U_RIGHT_TO_LEFT_ARABIC
+        || direction == U_RIGHT_TO_LEFT_EMBEDDING || direction == U_RIGHT_TO_LEFT_OVERRIDE
+        || direction == U_LEFT_TO_RIGHT_EMBEDDING || direction == U_LEFT_TO_RIGHT_OVERRIDE
+        || direction == U_POP_DIRECTIONAL_FORMAT || direction == U_BOUNDARY_NEUTRAL)
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowTextHasDirectionCharacter, reasons, includeReasons);
+
+    return reasons;
+}
+
+template<> OptionSet<AvoidanceReason> canUseForCharacter(LChar, bool, IncludeReasons)
+{
+    return { };
+}
+
+template <typename CharacterType>
+static OptionSet<AvoidanceReason> canUseForText(const CharacterType* text, unsigned length, const FontCascade& fontCascade, Optional<float> lineHeightConstraint,
+    bool textIsJustified, IncludeReasons includeReasons)
+{
+    OptionSet<AvoidanceReason> reasons;
+    auto& primaryFont = fontCascade.primaryFont();
+    auto& fontMetrics = primaryFont.fontMetrics();
+    auto availableSpaceForGlyphAscent = fontMetrics.ascent();
+    auto availableSpaceForGlyphDescent = fontMetrics.descent();
+    if (lineHeightConstraint) {
+        auto lineHeightPadding = *lineHeightConstraint - fontMetrics.height();
+        availableSpaceForGlyphAscent += lineHeightPadding / 2;
+        availableSpaceForGlyphDescent += lineHeightPadding / 2;
+    }
+
+    for (unsigned i = 0; i < length; ++i) {
+        auto character = text[i];
+        if (FontCascade::treatAsSpace(character))
+            continue;
+
+        if (character == softHyphen)
+            SET_REASON_AND_RETURN_IF_NEEDED(FlowTextHasSoftHyphen, reasons, includeReasons);
+
+        auto characterReasons = canUseForCharacter(character, textIsJustified, includeReasons);
+        if (characterReasons)
+            ADD_REASONS_AND_RETURN_IF_NEEDED(characterReasons, reasons, includeReasons);
+
+        auto glyphData = fontCascade.glyphDataForCharacter(character, false);
+        if (!glyphData.isValid() || glyphData.font != &primaryFont)
+            SET_REASON_AND_RETURN_IF_NEEDED(FlowPrimaryFontIsInsufficient, reasons, includeReasons);
+
+        if (lineHeightConstraint) {
+            auto bounds = primaryFont.boundsForGlyph(glyphData.glyph);
+            if (ceilf(-bounds.y()) > availableSpaceForGlyphAscent || ceilf(bounds.maxY()) > availableSpaceForGlyphDescent)
+                SET_REASON_AND_RETURN_IF_NEEDED(FlowFontHasOverflowGlyph, reasons, includeReasons);
+        }
+    }
+    return reasons;
+}
+
+static OptionSet<AvoidanceReason> canUseForText(StringView text, const FontCascade& fontCascade, Optional<float> lineHeightConstraint, bool textIsJustified, IncludeReasons includeReasons)
+{
+    if (text.is8Bit())
+        return canUseForText(text.characters8(), text.length(), fontCascade, lineHeightConstraint, textIsJustified, includeReasons);
+    return canUseForText(text.characters16(), text.length(), fontCascade, lineHeightConstraint, textIsJustified, includeReasons);
+}
+
+static OptionSet<AvoidanceReason> canUseForFontAndText(const RenderBlockFlow& flow, IncludeReasons includeReasons)
+{
+    OptionSet<AvoidanceReason> reasons;
+    // We assume that all lines have metrics based purely on the primary font.
+    const auto& style = flow.style();
+    auto& fontCascade = style.fontCascade();
+    if (fontCascade.primaryFont().isInterstitial())
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowIsMissingPrimaryFont, reasons, includeReasons);
+    Optional<float> lineHeightConstraint;
+    if (style.lineBoxContain().contains(LineBoxContain::Glyphs))
+        lineHeightConstraint = flow.lineHeight(false, HorizontalLine, PositionOfInteriorLineBoxes).toFloat();
+    bool flowIsJustified = style.textAlign() == TextAlignMode::Justify;
+    for (const auto& textRenderer : childrenOfType<RenderText>(flow)) {
+        // FIXME: Do not return until after checking all children.
+        if (textRenderer.text().isEmpty())
+            SET_REASON_AND_RETURN_IF_NEEDED(FlowTextIsEmpty, reasons, includeReasons);
+        if (textRenderer.isCombineText())
+            SET_REASON_AND_RETURN_IF_NEEDED(FlowTextIsCombineText, reasons, includeReasons);
+        if (textRenderer.isCounter())
+            SET_REASON_AND_RETURN_IF_NEEDED(FlowTextIsRenderCounter, reasons, includeReasons);
+        if (textRenderer.isQuote())
+            SET_REASON_AND_RETURN_IF_NEEDED(FlowTextIsRenderQuote, reasons, includeReasons);
+        if (textRenderer.isTextFragment())
+            SET_REASON_AND_RETURN_IF_NEEDED(FlowTextIsTextFragment, reasons, includeReasons);
+        if (textRenderer.isSVGInlineText())
+            SET_REASON_AND_RETURN_IF_NEEDED(FlowTextIsSVGInlineText, reasons, includeReasons);
+        if (!textRenderer.canUseSimpleFontCodePath()) {
+            // No need to check the code path at this point. We already know it can't be simple.
+            SET_REASON_AND_RETURN_IF_NEEDED(FlowHasComplexFontCodePath, reasons, includeReasons);
+        } else {
+            TextRun run(String(textRenderer.text()));
+            run.setCharacterScanForCodePath(false);
+            if (style.fontCascade().codePath(run) != FontCascade::Simple)
+                SET_REASON_AND_RETURN_IF_NEEDED(FlowHasComplexFontCodePath, reasons, includeReasons);
+        }
+
+        auto textReasons = canUseForText(textRenderer.stringView(), fontCascade, lineHeightConstraint, flowIsJustified, includeReasons);
+        if (textReasons)
+            ADD_REASONS_AND_RETURN_IF_NEEDED(textReasons, reasons, includeReasons);
+    }
+    return reasons;
+}
+
+static OptionSet<AvoidanceReason> canUseForStyle(const RenderStyle& style, IncludeReasons includeReasons)
+{
+    OptionSet<AvoidanceReason> reasons;
+    if (style.textOverflow() == TextOverflow::Ellipsis)
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasTextOverflow, reasons, includeReasons);
+    if (style.textUnderlinePosition() != TextUnderlinePosition::Auto || !style.textUnderlineOffset().isAuto() || !style.textDecorationThickness().isAuto())
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasUnsupportedUnderlineDecoration, reasons, includeReasons);
+    // Non-visible overflow should be pretty easy to support.
+    if (style.overflowX() != Overflow::Visible || style.overflowY() != Overflow::Visible)
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasOverflowNotVisible, reasons, includeReasons);
+    if (!style.isLeftToRightDirection())
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowIsNotLTR, reasons, includeReasons);
+    if (!(style.lineBoxContain().contains(LineBoxContain::Block)))
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasLineBoxContainProperty, reasons, includeReasons);
+    if (style.writingMode() != WritingMode::TopToBottom)
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowIsNotTopToBottom, reasons, includeReasons);
+    if (style.lineBreak() != LineBreak::Auto)
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasLineBreak, reasons, includeReasons);
+    if (style.unicodeBidi() != UBNormal)
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasNonNormalUnicodeBiDi, reasons, includeReasons);
+    if (style.rtlOrdering() != Order::Logical)
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasRTLOrdering, reasons, includeReasons);
+    if (style.lineAlign() != LineAlign::None)
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasLineAlignEdges, reasons, includeReasons);
+    if (style.lineSnap() != LineSnap::None)
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasLineSnap, reasons, includeReasons);
+    if (style.textEmphasisFill() != TextEmphasisFill::Filled || style.textEmphasisMark() != TextEmphasisMark::None)
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasTextEmphasisFillOrMark, reasons, includeReasons);
+    if (style.textShadow())
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasTextShadow, reasons, includeReasons);
+    if (style.hasPseudoStyle(PseudoId::FirstLine))
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasPseudoFirstLine, reasons, includeReasons);
+    if (style.hasPseudoStyle(PseudoId::FirstLetter))
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasPseudoFirstLetter, reasons, includeReasons);
+    if (style.hasTextCombine())
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasTextCombine, reasons, includeReasons);
+    if (style.backgroundClip() == FillBox::Text)
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasTextFillBox, reasons, includeReasons);
+    if (style.borderFit() == BorderFit::Lines)
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasBorderFitLines, reasons, includeReasons);
+    if (style.lineBreak() != LineBreak::Auto)
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasNonAutoLineBreak, reasons, includeReasons);
+    if (style.nbspMode() != NBSPMode::Normal)
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasWebKitNBSPMode, reasons, includeReasons);
+    // Special handling of text-security:disc is not yet implemented in the simple line layout code path.
+    // See RenderBlock::updateSecurityDiscCharacters.
+    if (style.textSecurity() != TextSecurity::None)
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasTextSecurity, reasons, includeReasons);
+    if (style.hyphens() == Hyphens::Auto) {
+        auto textReasons = canUseForText(style.hyphenString(), style.fontCascade(), WTF::nullopt, false, includeReasons);
+        if (textReasons)
+            ADD_REASONS_AND_RETURN_IF_NEEDED(textReasons, reasons, includeReasons);
+    }
+    return reasons;
+}
+
+OptionSet<AvoidanceReason> canUseForLineLayoutWithReason(const RenderBlockFlow& flow, IncludeReasons includeReasons)
+{
+    OptionSet<AvoidanceReason> reasons;
+    // FIXME: For tests that disable SLL and expect to get CLL.
+    if (!flow.settings().simpleLineLayoutEnabled())
+        SET_REASON_AND_RETURN_IF_NEEDED(FeatureIsDisabled, reasons, includeReasons);
+    if (!flow.parent())
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasNoParent, reasons, includeReasons);
+    if (!flow.firstChild())
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasNoChild, reasons, includeReasons);
+    if (flow.fragmentedFlowState() != RenderObject::NotInsideFragmentedFlow) {
+        auto* fragmentedFlow = flow.enclosingFragmentedFlow();
+        if (!is<RenderMultiColumnFlow>(fragmentedFlow))
+            SET_REASON_AND_RETURN_IF_NEEDED(FlowIsInsideANonMultiColumnThread, reasons, includeReasons);
+        auto& columnThread = downcast<RenderMultiColumnFlow>(*fragmentedFlow);
+        if (columnThread.parent() != &flow.view())
+            SET_REASON_AND_RETURN_IF_NEEDED(MultiColumnFlowIsNotTopLevel, reasons, includeReasons);
+        if (columnThread.hasColumnSpanner())
+            SET_REASON_AND_RETURN_IF_NEEDED(MultiColumnFlowHasColumnSpanner, reasons, includeReasons);
+        auto& style = flow.style();
+        if (style.verticalAlign() != VerticalAlign::Baseline)
+            SET_REASON_AND_RETURN_IF_NEEDED(MultiColumnFlowVerticalAlign, reasons, includeReasons);
+        if (style.isFloating())
+            SET_REASON_AND_RETURN_IF_NEEDED(MultiColumnFlowIsFloating, reasons, includeReasons);
+    }
+    if (!flow.isHorizontalWritingMode())
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasHorizonalWritingMode, reasons, includeReasons);
+    if (flow.hasOutline())
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasOutline, reasons, includeReasons);
+    if (flow.isRubyText() || flow.isRubyBase())
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowIsRuby, reasons, includeReasons);
+    if (!flow.style().hangingPunctuation().isEmpty())
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasHangingPunctuation, reasons, includeReasons);
+
+    // Printing does pagination without a flow thread.
+    if (flow.document().paginated())
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowIsPaginated, reasons, includeReasons);
+    if (flow.firstLineBlock())
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasPseudoFirstLine, reasons, includeReasons);
+    if (flow.isAnonymousBlock() && flow.parent()->style().textOverflow() == TextOverflow::Ellipsis)
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasTextOverflow, reasons, includeReasons);
+    if (flow.parent()->isDeprecatedFlexibleBox())
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowIsDepricatedFlexBox, reasons, includeReasons);
+    // FIXME: Placeholders do something strange.
+    if (is<RenderTextControl>(*flow.parent()) && downcast<RenderTextControl>(*flow.parent()).textFormControlElement().placeholderElement())
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowParentIsPlaceholderElement, reasons, includeReasons);
+    // FIXME: Implementation of wrap=hard looks into lineboxes.
+    if (flow.parent()->isTextArea() && flow.parent()->element()->hasAttributeWithoutSynchronization(HTMLNames::wrapAttr))
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowParentIsTextAreaWithWrapping, reasons, includeReasons);
+    // This currently covers <blockflow>#text</blockflow>, <blockflow>#text<br></blockflow> and mutiple (sibling) RenderText cases.
+    // The <blockflow><inline>#text</inline></blockflow> case is also popular and should be relatively easy to cover.
+    for (const auto* child = flow.firstChild(); child;) {
+        if (child->selectionState() != RenderObject::HighlightState::None)
+            SET_REASON_AND_RETURN_IF_NEEDED(FlowChildIsSelected, reasons, includeReasons);
+        if (is<RenderText>(*child)) {
+            const auto& renderText = downcast<RenderText>(*child);
+            if (renderText.textNode() && !renderText.document().markers().markersFor(*renderText.textNode()).isEmpty())
+                SET_REASON_AND_RETURN_IF_NEEDED(FlowIncludesDocumentMarkers, reasons, includeReasons);
+            child = child->nextSibling();
+            continue;
+        }
+        if (is<RenderLineBreak>(child) && !downcast<RenderLineBreak>(*child).isWBR() && child->style().clear() == Clear::None) {
+            child = child->nextSibling();
+            continue;
+        }
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasNonSupportedChild, reasons, includeReasons);
+        break;
+    }
+    auto styleReasons = canUseForStyle(flow.style(), includeReasons);
+    if (styleReasons)
+        ADD_REASONS_AND_RETURN_IF_NEEDED(styleReasons, reasons, includeReasons);
+    // We can't use the code path if any lines would need to be shifted below floats. This is because we don't keep per-line y coordinates.
+    if (flow.containsFloats()) {
+        float minimumWidthNeeded = std::numeric_limits<float>::max();
+        for (const auto& textRenderer : childrenOfType<RenderText>(flow)) {
+            minimumWidthNeeded = std::min(minimumWidthNeeded, textRenderer.minLogicalWidth());
+
+            for (auto& floatingObject : *flow.floatingObjectSet()) {
+                ASSERT(floatingObject);
+                // if a float has a shape, we cannot tell if content will need to be shifted until after we lay it out,
+                // since the amount of space is not uniform for the height of the float.
+                if (floatingObject->renderer().shapeOutsideInfo())
+                    SET_REASON_AND_RETURN_IF_NEEDED(FlowHasUnsupportedFloat, reasons, includeReasons);
+                float availableWidth = flow.availableLogicalWidthForLine(floatingObject->y(), DoNotIndentText);
+                if (availableWidth < minimumWidthNeeded)
+                    SET_REASON_AND_RETURN_IF_NEEDED(FlowHasUnsupportedFloat, reasons, includeReasons);
+            }
+        }
+    }
+    auto fontAndTextReasons = canUseForFontAndText(flow, includeReasons);
+    if (fontAndTextReasons)
+        ADD_REASONS_AND_RETURN_IF_NEEDED(fontAndTextReasons, reasons, includeReasons);
+    return reasons;
+}
+
+bool canUseForLineLayout(const RenderBlockFlow& flow)
+{
+    return canUseForLineLayoutWithReason(flow, IncludeReasons::First).isEmpty();
+}
+
+bool canUseForLineLayoutAfterStyleChange(const RenderBlockFlow& blockContainer, StyleDifference diff)
+{
+    switch (diff) {
+    case StyleDifference::Equal:
+    case StyleDifference::RecompositeLayer:
+        return true;
+    case StyleDifference::Repaint:
+    case StyleDifference::RepaintIfTextOrBorderOrOutline:
+    case StyleDifference::RepaintLayer:
+        // FIXME: We could do a more focused style check by matching RendererStyle::changeRequiresRepaint&co.
+        return canUseForStyle(blockContainer.style(), IncludeReasons::First).isEmpty();
+    case StyleDifference::LayoutPositionedMovementOnly:
+        return true;
+    case StyleDifference::SimplifiedLayout:
+    case StyleDifference::SimplifiedLayoutAndPositionedMovement:
+        return canUseForStyle(blockContainer.style(), IncludeReasons::First).isEmpty();
+    case StyleDifference::Layout:
+    case StyleDifference::NewStyle:
+        return canUseForLineLayout(blockContainer);
+    }
+    ASSERT_NOT_REACHED();
+    return canUseForLineLayout(blockContainer);
+}
+
+}
+}
+
+#endif

Added: trunk/Source/WebCore/layout/integration/LayoutIntegrationCoverage.h (0 => 267468)


--- trunk/Source/WebCore/layout/integration/LayoutIntegrationCoverage.h	                        (rev 0)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationCoverage.h	2020-09-23 12:03:57 UTC (rev 267468)
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#pragma once
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include "RenderStyleConstants.h"
+
+namespace WebCore {
+
+class RenderBlockFlow;
+
+namespace LayoutIntegration {
+
+enum class AvoidanceReason : uint64_t {
+    FlowIsInsideANonMultiColumnThread     = 1LLU  << 0,
+    FlowHasHorizonalWritingMode           = 1LLU  << 1,
+    FlowHasOutline                        = 1LLU  << 2,
+    FlowIsRuby                            = 1LLU  << 3,
+    FlowIsPaginated                       = 1LLU  << 4,
+    FlowHasTextOverflow                   = 1LLU  << 5,
+    FlowIsDepricatedFlexBox               = 1LLU  << 6,
+    FlowParentIsPlaceholderElement        = 1LLU  << 7,
+    FlowParentIsTextAreaWithWrapping      = 1LLU  << 8,
+    FlowHasNonSupportedChild              = 1LLU  << 9,
+    FlowHasUnsupportedFloat               = 1LLU  << 10,
+    FlowHasUnsupportedUnderlineDecoration = 1LLU  << 11,
+    FlowHasJustifiedNonLatinText          = 1LLU  << 12,
+    FlowHasOverflowNotVisible             = 1LLU  << 13,
+    FlowHasWebKitNBSPMode                 = 1LLU  << 14,
+    FlowIsNotLTR                          = 1LLU  << 15,
+    FlowHasLineBoxContainProperty         = 1LLU  << 16,
+    FlowIsNotTopToBottom                  = 1LLU  << 17,
+    FlowHasLineBreak                      = 1LLU  << 18,
+    FlowHasNonNormalUnicodeBiDi           = 1LLU  << 19,
+    FlowHasRTLOrdering                    = 1LLU  << 20,
+    FlowHasLineAlignEdges                 = 1LLU  << 21,
+    FlowHasLineSnap                       = 1LLU  << 22,
+    FlowHasTextEmphasisFillOrMark         = 1LLU  << 23,
+    FlowHasTextShadow                     = 1LLU  << 24,
+    FlowHasPseudoFirstLine                = 1LLU  << 25,
+    FlowHasPseudoFirstLetter              = 1LLU  << 26,
+    FlowHasTextCombine                    = 1LLU  << 27,
+    FlowHasTextFillBox                    = 1LLU  << 28,
+    FlowHasBorderFitLines                 = 1LLU  << 29,
+    FlowHasNonAutoLineBreak               = 1LLU  << 30,
+    FlowHasTextSecurity                   = 1LLU  << 31,
+    FlowHasSVGFont                        = 1LLU  << 32,
+    FlowTextIsEmpty                       = 1LLU  << 33,
+    FlowTextHasSoftHyphen                 = 1LLU  << 34,
+    FlowTextHasDirectionCharacter         = 1LLU  << 35,
+    FlowIsMissingPrimaryFont              = 1LLU  << 36,
+    FlowPrimaryFontIsInsufficient         = 1LLU  << 37,
+    FlowTextIsCombineText                 = 1LLU  << 38,
+    FlowTextIsRenderCounter               = 1LLU  << 39,
+    FlowTextIsRenderQuote                 = 1LLU  << 40,
+    FlowTextIsTextFragment                = 1LLU  << 41,
+    FlowTextIsSVGInlineText               = 1LLU  << 42,
+    FlowHasComplexFontCodePath            = 1LLU  << 43,
+    FeatureIsDisabled                     = 1LLU  << 44,
+    FlowHasNoParent                       = 1LLU  << 45,
+    FlowHasNoChild                        = 1LLU  << 46,
+    FlowChildIsSelected                   = 1LLU  << 47,
+    FlowHasHangingPunctuation             = 1LLU  << 48,
+    FlowFontHasOverflowGlyph              = 1LLU  << 49,
+    FlowTextHasSurrogatePair              = 1LLU  << 50,
+    MultiColumnFlowIsNotTopLevel          = 1LLU  << 51,
+    MultiColumnFlowHasColumnSpanner       = 1LLU  << 52,
+    MultiColumnFlowVerticalAlign          = 1LLU  << 53,
+    MultiColumnFlowIsFloating             = 1LLU  << 54,
+    FlowIncludesDocumentMarkers           = 1LLU  << 55,
+    EndOfReasons                          = 1LLU  << 56
+};
+
+bool canUseForLineLayout(const RenderBlockFlow&);
+bool canUseForLineLayoutAfterStyleChange(const RenderBlockFlow&, StyleDifference);
+
+enum class IncludeReasons { First , All };
+OptionSet<AvoidanceReason> canUseForLineLayoutWithReason(const RenderBlockFlow&, IncludeReasons);
+
+}
+}
+
+#endif

Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.cpp (267467 => 267468)


--- trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.cpp	2020-09-23 10:27:14 UTC (rev 267467)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.cpp	2020-09-23 12:03:57 UTC (rev 267468)
@@ -37,6 +37,7 @@
 #include "InlineFormattingState.h"
 #include "InvalidationState.h"
 #include "LayoutBoxGeometry.h"
+#include "LayoutIntegrationCoverage.h"
 #include "LayoutIntegrationPagination.h"
 #include "LayoutTreeBuilder.h"
 #include "PaintInfo.h"
@@ -65,23 +66,23 @@
 
 LineLayout::~LineLayout() = default;
 
-bool LineLayout::canUseFor(const RenderBlockFlow& flow, Optional<bool> couldUseSimpleLineLayout)
+bool LineLayout::isEnabled()
 {
-    if (!RuntimeEnabledFeatures::sharedFeatures().layoutFormattingContextIntegrationEnabled())
+    return RuntimeEnabledFeatures::sharedFeatures().layoutFormattingContextIntegrationEnabled();
+}
+
+bool LineLayout::canUseFor(const RenderBlockFlow& flow)
+{
+    if (!isEnabled())
         return false;
 
-    // Initially only a subset of SLL features is supported.
-    auto passesSimpleLineLayoutTest = valueOrCompute(couldUseSimpleLineLayout, [&] {
-        return SimpleLineLayout::canUseFor(flow);
-    });
-
-    return passesSimpleLineLayoutTest;
+    return canUseForLineLayout(flow);
 }
 
 bool LineLayout::canUseForAfterStyleChange(const RenderBlockFlow& flow, StyleDifference diff)
 {
-    ASSERT(RuntimeEnabledFeatures::sharedFeatures().layoutFormattingContextIntegrationEnabled());
-    return SimpleLineLayout::canUseForAfterStyleChange(flow, diff);
+    ASSERT(isEnabled());
+    return canUseForLineLayoutAfterStyleChange(flow, diff);
 }
 
 void LineLayout::updateStyle()

Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.h (267467 => 267468)


--- trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.h	2020-09-23 10:27:14 UTC (rev 267467)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.h	2020-09-23 12:03:57 UTC (rev 267468)
@@ -55,7 +55,8 @@
     LineLayout(const RenderBlockFlow&);
     ~LineLayout();
 
-    static bool canUseFor(const RenderBlockFlow&, Optional<bool> couldUseSimpleLineLayout = { });
+    static bool isEnabled();
+    static bool canUseFor(const RenderBlockFlow&);
     static bool canUseForAfterStyleChange(const RenderBlockFlow&, StyleDifference);
 
     void updateStyle();

Modified: trunk/Source/WebCore/rendering/RenderBlockFlow.cpp (267467 => 267468)


--- trunk/Source/WebCore/rendering/RenderBlockFlow.cpp	2020-09-23 10:27:14 UTC (rev 267467)
+++ trunk/Source/WebCore/rendering/RenderBlockFlow.cpp	2020-09-23 12:03:57 UTC (rev 267468)
@@ -669,12 +669,13 @@
 void RenderBlockFlow::layoutInlineChildren(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom)
 {
     auto computeLineLayoutPath = [&] {
-        bool canUseSimpleLines = SimpleLineLayout::canUseFor(*this);
+        bool isIntegrationEnabled = false;
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
-        if (LayoutIntegration::LineLayout::canUseFor(*this, canUseSimpleLines))
+        if (LayoutIntegration::LineLayout::canUseFor(*this))
             return LayoutFormattingContextPath;
+        isIntegrationEnabled = LayoutIntegration::LineLayout::isEnabled();
 #endif
-        if (canUseSimpleLines)
+        if (!isIntegrationEnabled && SimpleLineLayout::canUseFor(*this))
             return SimpleLinesPath;
 
         return LineBoxesPath;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to