Diff
Modified: trunk/Source/WebCore/ChangeLog (237286 => 237287)
--- trunk/Source/WebCore/ChangeLog 2018-10-19 15:52:08 UTC (rev 237286)
+++ trunk/Source/WebCore/ChangeLog 2018-10-19 16:31:19 UTC (rev 237287)
@@ -1,5 +1,45 @@
2018-10-19 Zalan Bujtas <za...@apple.com>
+ [LFC][IFC] Add generic inline line breaker
+ https://bugs.webkit.org/show_bug.cgi?id=190698
+
+ Reviewed by Antti Koivisto.
+
+ InlineLineBreaker takes the inline runs and applies the appropriate line breaking rules on them.
+ InlineRunProvider::Run objects ->
+
+ <foobar><image box><hello>< ><world>
+
+ InlineLineBreaker::Run ->
+
+ <foobar><image box><hello world>
+
+ InlineLineBreaker::Run also contains information whether the run is at the beginning or at the end of the line.
+
+ * Sources.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * layout/LayoutContext.h:
+ (WebCore::Layout::LayoutContext::hasDisplayBox const):
+ * layout/inlineformatting/InlineLineBreaker.cpp: Added.
+ (WebCore::Layout::InlineLineBreaker::InlineLineBreaker):
+ (WebCore::Layout::InlineLineBreaker::nextLayoutRun):
+ (WebCore::Layout::InlineLineBreaker::isAtContentEnd const):
+ (WebCore::Layout::InlineLineBreaker::lineBreakingBehavior):
+ (WebCore::Layout::InlineLineBreaker::runWidth const):
+ (WebCore::Layout::InlineLineBreaker::splitRun):
+ (WebCore::Layout::InlineLineBreaker::adjustSplitPositionWithHyphenation const):
+ * layout/inlineformatting/InlineLineBreaker.h: Added.
+ * layout/inlineformatting/textlayout/TextUtil.cpp: Added.
+ (WebCore::Layout::TextUtil::TextUtil):
+ (WebCore::Layout::TextUtil::width const):
+ (WebCore::Layout::TextUtil::hyphenPositionBefore const):
+ (WebCore::Layout::TextUtil::textWidth const):
+ (WebCore::Layout::TextUtil::fixedPitchWidth const):
+ * layout/inlineformatting/textlayout/TextUtil.h: Added.
+ * layout/layouttree/LayoutBox.cpp:
+
+2018-10-19 Zalan Bujtas <za...@apple.com>
+
[LFC][IFC] Add generic inline run generator.
https://bugs.webkit.org/show_bug.cgi?id=190696
Modified: trunk/Source/WebCore/Sources.txt (237286 => 237287)
--- trunk/Source/WebCore/Sources.txt 2018-10-19 15:52:08 UTC (rev 237286)
+++ trunk/Source/WebCore/Sources.txt 2018-10-19 16:31:19 UTC (rev 237287)
@@ -1259,8 +1259,10 @@
layout/inlineformatting/InlineFormattingContext.cpp
layout/inlineformatting/InlineFormattingState.cpp
layout/inlineformatting/InlineInvalidation.cpp
+layout/inlineformatting/InlineLineBreaker.cpp
layout/inlineformatting/InlineRunProvider.cpp
layout/inlineformatting/textlayout/TextContentProvider.cpp
+layout/inlineformatting/textlayout/TextUtil.cpp
layout/inlineformatting/textlayout/simple/SimpleTextRunGenerator.cpp
layout/inlineformatting/textlayout/simple/SimpleLineBreaker.cpp
layout/layouttree/LayoutBlockContainer.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (237286 => 237287)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2018-10-19 15:52:08 UTC (rev 237286)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2018-10-19 16:31:19 UTC (rev 237287)
@@ -2009,6 +2009,8 @@
6F995A381A70833700A735F4 /* JSWebGLTransformFeedback.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F995A2E1A70833700A735F4 /* JSWebGLTransformFeedback.h */; };
6F995A3A1A70833700A735F4 /* JSWebGLVertexArrayObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F995A301A70833700A735F4 /* JSWebGLVertexArrayObject.h */; };
6FA4454E898F2FC168BC38C1 /* JSBeforeUnloadEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 29E04A27BED2F81F98E9022B /* JSBeforeUnloadEvent.h */; };
+ 6FB11B5C21783FD000E2A574 /* TextUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 6FB11B5921783FCF00E2A574 /* TextUtil.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 6FE198172178397C00446F08 /* InlineLineBreaker.h in Headers */ = {isa = PBXBuildFile; fileRef = 6FE198152178397C00446F08 /* InlineLineBreaker.h */; settings = {ATTRIBUTES = (Private, ); }; };
6FE7CFA22177EEF2005B1573 /* InlineItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 6FE7CFA02177EEF1005B1573 /* InlineItem.h */; };
6FE7CFA42177EF10005B1573 /* LayoutLineBreakBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 6FE7CFA32177EF10005B1573 /* LayoutLineBreakBox.h */; settings = {ATTRIBUTES = (Private, ); }; };
6FFDC442212EFF1700A9CA91 /* FloatAvoider.h in Headers */ = {isa = PBXBuildFile; fileRef = 6FFDC440212EFF1600A9CA91 /* FloatAvoider.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -9101,10 +9103,14 @@
6F995A2E1A70833700A735F4 /* JSWebGLTransformFeedback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWebGLTransformFeedback.h; sourceTree = "<group>"; };
6F995A2F1A70833700A735F4 /* JSWebGLVertexArrayObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWebGLVertexArrayObject.cpp; sourceTree = "<group>"; };
6F995A301A70833700A735F4 /* JSWebGLVertexArrayObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWebGLVertexArrayObject.h; sourceTree = "<group>"; };
+ 6FB11B5921783FCF00E2A574 /* TextUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextUtil.h; sourceTree = "<group>"; };
+ 6FB11B5B21783FCF00E2A574 /* TextUtil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextUtil.cpp; sourceTree = "<group>"; };
6FBB860520B464B600DAD938 /* FormattingContextGeometry.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FormattingContextGeometry.cpp; sourceTree = "<group>"; };
6FCD19C120F9727A00FD4529 /* TextContentProvider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TextContentProvider.h; sourceTree = "<group>"; };
6FCD19C720F9727D00FD4529 /* TextContentProvider.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TextContentProvider.cpp; sourceTree = "<group>"; };
6FCF975220F02B3500214960 /* Runs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Runs.h; sourceTree = "<group>"; };
+ 6FE198132178397B00446F08 /* InlineLineBreaker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InlineLineBreaker.cpp; sourceTree = "<group>"; };
+ 6FE198152178397C00446F08 /* InlineLineBreaker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InlineLineBreaker.h; sourceTree = "<group>"; };
6FE7CFA02177EEF1005B1573 /* InlineItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InlineItem.h; sourceTree = "<group>"; };
6FE7CFA32177EF10005B1573 /* LayoutLineBreakBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LayoutLineBreakBox.h; sourceTree = "<group>"; };
6FE7CFA52177F069005B1573 /* LayoutLineBreakBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutLineBreakBox.cpp; sourceTree = "<group>"; };
@@ -16050,6 +16056,8 @@
115CFA9A208BC140001E6991 /* inlineformatting */ = {
isa = PBXGroup;
children = (
+ 6FE198132178397B00446F08 /* InlineLineBreaker.cpp */,
+ 6FE198152178397C00446F08 /* InlineLineBreaker.h */,
6FE7DDDD20EC6E8B008B5B4E /* textlayout */,
6F7CA3C9208C2B2E002F29AB /* InlineFormattingContext.cpp */,
6F7CA3C8208C2B2E002F29AB /* InlineFormattingContext.h */,
@@ -19932,6 +19940,8 @@
6FE7DDDD20EC6E8B008B5B4E /* textlayout */ = {
isa = PBXGroup;
children = (
+ 6FB11B5B21783FCF00E2A574 /* TextUtil.cpp */,
+ 6FB11B5921783FCF00E2A574 /* TextUtil.h */,
6F13A12320F9949C001C025A /* simple */,
6FCF975220F02B3500214960 /* Runs.h */,
6FCD19C720F9727D00FD4529 /* TextContentProvider.cpp */,
@@ -29489,6 +29499,7 @@
A84EBD830CB8C97700079609 /* JSStyleSheetList.h in Headers */,
571F21891DA57C54005C9EFD /* JSSubtleCrypto.h in Headers */,
B20111080AB7740500DB0E68 /* JSSVGAElement.h in Headers */,
+ 6FB11B5C21783FD000E2A574 /* TextUtil.h in Headers */,
24D9129213CA951E00D21915 /* JSSVGAltGlyphDefElement.h in Headers */,
6515EC920D9723FF0063D49A /* JSSVGAltGlyphElement.h in Headers */,
24D9129613CA956100D21915 /* JSSVGAltGlyphItemElement.h in Headers */,
@@ -30137,6 +30148,7 @@
A88DD4870B4629A300C02990 /* PathTraversalState.h in Headers */,
2D5002FC1B56D7990020AAF7 /* PathUtilities.h in Headers */,
A8FA6E5D0E4CFDED00D5CF49 /* Pattern.h in Headers */,
+ 6FE198172178397C00446F08 /* InlineLineBreaker.h in Headers */,
B22279710D00BF220071B782 /* PatternAttributes.h in Headers */,
A1677E08213E024C00A08C34 /* PayerErrorFields.h in Headers */,
1A8A643A1D19FC5300D0E00F /* Payment.h in Headers */,
Modified: trunk/Source/WebCore/layout/LayoutContext.h (237286 => 237287)
--- trunk/Source/WebCore/layout/LayoutContext.h 2018-10-19 15:52:08 UTC (rev 237286)
+++ trunk/Source/WebCore/layout/LayoutContext.h 2018-10-19 16:31:19 UTC (rev 237287)
@@ -82,6 +82,7 @@
FormattingState& createFormattingStateForFormattingRootIfNeeded(const Box& formattingRoot);
Display::Box& displayBoxForLayoutBox(const Box& layoutBox) const;
+ bool hasDisplayBox(const Box& layoutBox) const { return m_layoutToDisplayBox.contains(&layoutBox); }
bool inQuirksMode() const { return m_inQuirksMode; }
// For testing purposes only
Added: trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.cpp (0 => 237287)
--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.cpp (rev 0)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.cpp 2018-10-19 16:31:19 UTC (rev 237287)
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2018 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 "InlineLineBreaker.h"
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include "FontCascade.h"
+#include "Hyphenation.h"
+#include "InlineRunProvider.h"
+#include <wtf/IsoMallocInlines.h>
+
+namespace WebCore {
+namespace Layout {
+
+WTF_MAKE_ISO_ALLOCATED_IMPL(InlineLineBreaker);
+
+InlineLineBreaker::InlineLineBreaker(const LayoutContext& layoutContext, const InlineContent& inlineContent, const Vector<InlineRunProvider::Run>& inlineRuns)
+ : m_layoutContext(layoutContext)
+ , m_textUtil(inlineContent)
+ , m_inlineRuns(inlineRuns)
+{
+}
+
+std::optional<InlineLineBreaker::Run> InlineLineBreaker::nextLayoutRun(LayoutUnit contentLogicalLeft, LayoutUnit availableWidth, bool lineIsEmpty)
+{
+ if (isAtContentEnd())
+ return std::nullopt;
+
+ InlineRunProvider::Run currentInlineRun = m_inlineRuns[m_currentRunIndex];
+ // Adjust the current run if it is split midword.
+ if (m_splitPosition) {
+ ASSERT(currentInlineRun.isText());
+ currentInlineRun.textContext()->setStart(*m_splitPosition);
+ m_splitPosition = std::nullopt;
+ }
+
+ if (currentInlineRun.isLineBreak()) {
+ ++m_currentRunIndex;
+ return Run { Run::Position::LineEnd, currentInlineRun, 0 };
+ }
+
+ auto contentWidth = runWidth(currentInlineRun, contentLogicalLeft);
+ // 1. Plenty of space left.
+ if (contentWidth <= availableWidth) {
+ ++m_currentRunIndex;
+ return Run { lineIsEmpty ? Run::Position::LineBegin : Run::Position::Undetermined, currentInlineRun, contentWidth };
+ }
+
+ // 2. No space left whatsoever.
+ if (availableWidth <= 0) {
+ ++m_currentRunIndex;
+ return Run { Run::Position::LineBegin, currentInlineRun, contentWidth };
+ }
+
+ // 3. Some space left. Let's find out what we need to do with this run.
+ auto breakingBehavior = lineBreakingBehavior(currentInlineRun, lineIsEmpty);
+ if (breakingBehavior == LineBreakingBehavior::Keep) {
+ ++m_currentRunIndex;
+ return Run { lineIsEmpty ? Run::Position::LineBegin : Run::Position::Undetermined, currentInlineRun, contentWidth };
+ }
+
+ if (breakingBehavior == LineBreakingBehavior::WrapToNextLine) {
+ ++m_currentRunIndex;
+ return Run { Run::Position::LineBegin, currentInlineRun, contentWidth };
+ }
+
+ ASSERT(breakingBehavior == LineBreakingBehavior::Break);
+ // Split content.
+ return splitRun(currentInlineRun, contentLogicalLeft, availableWidth, lineIsEmpty);
+}
+
+bool InlineLineBreaker::isAtContentEnd() const
+{
+ return m_currentRunIndex == m_inlineRuns.size();
+}
+
+InlineLineBreaker::LineBreakingBehavior InlineLineBreaker::lineBreakingBehavior(const InlineRunProvider::Run& inlineRun, bool lineIsEmpty)
+{
+ // Line breaking behaviour:
+ // 1. Whitesapce collapse on -> push whitespace to next line.
+ // 2. Whitespace collapse off -> whitespace is split where possible.
+ // 3. Non-whitespace -> first run on the line -> either split or kept on the line. (depends on overflow-wrap)
+ // 4. Non-whitespace -> already content on the line -> either gets split (word-break: break-all) or gets pushed to the next line.
+ // (Hyphenate when possible)
+ // 5. Non-text type -> next line
+ auto& style = inlineRun.style();
+
+ if (inlineRun.isWhitespace())
+ return style.collapseWhiteSpace() ? LineBreakingBehavior::WrapToNextLine : LineBreakingBehavior::Break;
+
+ if (inlineRun.isNonWhitespace()) {
+ auto shouldHypenate = !m_hyphenationIsDisabled && style.hyphens() == Hyphens::Auto && canHyphenate(style.locale());
+ if (shouldHypenate)
+ return LineBreakingBehavior::Break;
+
+ if (style.autoWrap()) {
+ // Break any word
+ if (style.wordBreak() == WordBreak::BreakAll)
+ return LineBreakingBehavior::Break;
+
+ // Break first run on line.
+ if (lineIsEmpty && style.breakWords() && style.preserveNewline())
+ return LineBreakingBehavior::Break;
+ }
+
+ // Non-breakable non-whitespace run.
+ return lineIsEmpty ? LineBreakingBehavior::Keep : LineBreakingBehavior::WrapToNextLine;
+ }
+
+ ASSERT(inlineRun.isBox() || inlineRun.isFloat());
+ // Non-text inline runs.
+ return LineBreakingBehavior::WrapToNextLine;
+}
+
+LayoutUnit InlineLineBreaker::runWidth(const InlineRunProvider::Run& inlineRun, LayoutUnit contentLogicalLeft) const
+{
+ ASSERT(!inlineRun.isLineBreak());
+
+ if (inlineRun.isText()) {
+ auto textContext = inlineRun.textContext();
+ return m_textUtil.width(inlineRun.inlineItem(), textContext->start(), textContext->isCollapsed() ? 1 : textContext->length(), contentLogicalLeft);
+ }
+
+ ASSERT(inlineRun.isBox() || inlineRun.isFloat());
+ auto& layoutBox = inlineRun.inlineItem().layoutBox();
+ ASSERT(m_layoutContext.hasDisplayBox(layoutBox));
+ auto& displayBox = m_layoutContext.displayBoxForLayoutBox(layoutBox);
+ return displayBox.width();
+}
+
+InlineLineBreaker::Run InlineLineBreaker::splitRun(const InlineRunProvider::Run& inlineRun, LayoutUnit, LayoutUnit, bool)
+{
+ return { Run::Position::Undetermined, inlineRun, { } };
+}
+
+std::optional<ItemPosition> InlineLineBreaker::adjustSplitPositionWithHyphenation(const InlineRunProvider::Run&, ItemPosition, LayoutUnit, LayoutUnit, bool) const
+{
+ return { };
+}
+
+}
+}
+#endif
Added: trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.h (0 => 237287)
--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.h (rev 0)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.h 2018-10-19 16:31:19 UTC (rev 237287)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2018 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 "InlineRunProvider.h"
+#include "TextUtil.h"
+#include <wtf/IsoMalloc.h>
+
+namespace WebCore {
+namespace Layout {
+
+class InlineLineBreaker {
+ WTF_MAKE_ISO_ALLOCATED(InlineLineBreaker);
+public:
+ InlineLineBreaker(const LayoutContext&, const InlineContent&, const Vector<InlineRunProvider::Run>&);
+
+ struct Run {
+ enum class Position { Undetermined, LineBegin, LineEnd };
+ Position position;
+ InlineRunProvider::Run inlineRun;
+ LayoutUnit width;
+ };
+ std::optional<Run> nextLayoutRun(LayoutUnit contentLogicalLeft, LayoutUnit availableWidth, bool lineIsEmpty);
+
+private:
+ enum class LineBreakingBehavior { Keep, Break, WrapToNextLine };
+ LineBreakingBehavior lineBreakingBehavior(const InlineRunProvider::Run&, bool lineIsEmpty);
+ bool isAtContentEnd() const;
+ Run splitRun(const InlineRunProvider::Run&, LayoutUnit contentLogicalLeft, LayoutUnit availableWidth, bool lineIsEmpty);
+ LayoutUnit runWidth(const InlineRunProvider::Run&, LayoutUnit contentLogicalLeft) const;
+ std::optional<ItemPosition> adjustSplitPositionWithHyphenation(const InlineRunProvider::Run&, ItemPosition splitPosition, LayoutUnit contentLogicalLeft, LayoutUnit availableWidth, bool isLineEmpty) const;
+
+ const LayoutContext& m_layoutContext;
+ const TextUtil m_textUtil;
+ const Vector<InlineRunProvider::Run>& m_inlineRuns;
+
+ unsigned m_currentRunIndex { 0 };
+ std::optional<ItemPosition> m_splitPosition;
+ bool m_hyphenationIsDisabled { false };
+};
+
+}
+}
+#endif
Added: trunk/Source/WebCore/layout/inlineformatting/textlayout/TextUtil.cpp (0 => 237287)
--- trunk/Source/WebCore/layout/inlineformatting/textlayout/TextUtil.cpp (rev 0)
+++ trunk/Source/WebCore/layout/inlineformatting/textlayout/TextUtil.cpp 2018-10-19 16:31:19 UTC (rev 237287)
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2018 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 "TextUtil.h"
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include "FontCascade.h"
+#include "RenderStyle.h"
+#include <wtf/IsoMallocInlines.h>
+
+namespace WebCore {
+namespace Layout {
+
+WTF_MAKE_ISO_ALLOCATED_IMPL(TextUtil);
+
+TextUtil::TextUtil(const InlineContent& inlineContent)
+ : m_inlineContent(inlineContent)
+{
+}
+
+LayoutUnit TextUtil::width(const InlineItem& inlineItem, ItemPosition from, unsigned length, LayoutUnit contentLogicalLeft) const
+{
+ LayoutUnit width;
+ auto startPosition = from;
+ auto iterator = m_inlineContent.find<const InlineItem&, InlineItemHashTranslator>(inlineItem);
+ auto inlineItemEnd = m_inlineContent.end();
+ while (length) {
+ ASSERT(iterator != inlineItemEnd);
+ auto& currentInlineItem = **iterator;
+ auto endPosition = std::min<ItemPosition>(startPosition + length, currentInlineItem.textContent().length());
+ auto textWidth = this->textWidth(currentInlineItem, startPosition, endPosition, contentLogicalLeft);
+
+ contentLogicalLeft += textWidth;
+ width += textWidth;
+ length -= (endPosition - startPosition);
+
+ startPosition = 0;
+ ++iterator;
+ }
+
+ return width;
+}
+
+std::optional<ItemPosition> TextUtil::hyphenPositionBefore(const InlineItem&, ItemPosition, unsigned) const
+{
+ return std::nullopt;
+}
+
+LayoutUnit TextUtil::textWidth(const InlineItem& inlineTextItem, ItemPosition from, ItemPosition to, LayoutUnit contentLogicalLeft) const
+{
+ auto& style = inlineTextItem.style();
+ auto& font = style.fontCascade();
+ if (!font.size() || from == to)
+ return 0;
+
+ auto text = inlineTextItem.textContent();
+ if (font.isFixedPitch())
+ return fixedPitchWidth(text, style, from, to, contentLogicalLeft);
+
+ auto hasKerningOrLigatures = font.enableKerning() || font.requiresShaping();
+ auto measureWithEndSpace = hasKerningOrLigatures && to < text.length() && text[to] == ' ';
+ if (measureWithEndSpace)
+ ++to;
+ LayoutUnit width;
+ auto tabWidth = style.collapseWhiteSpace() ? 0 : style.tabSize();
+
+ WebCore::TextRun run(StringView(text).substring(from, to - from), contentLogicalLeft);
+ if (tabWidth)
+ run.setTabSize(true, tabWidth);
+ width = font.width(run);
+
+ if (measureWithEndSpace)
+ width -= (font.spaceWidth() + font.wordSpacing());
+
+ return std::max<LayoutUnit>(0, width);
+}
+
+LayoutUnit TextUtil::fixedPitchWidth(String text, const RenderStyle& style, ItemPosition from, ItemPosition to, LayoutUnit contentLogicalLeft) const
+{
+ auto& font = style.fontCascade();
+ auto monospaceCharacterWidth = font.spaceWidth();
+ LayoutUnit width;
+ for (auto i = from; i < to; ++i) {
+ auto character = text[i];
+ if (character >= ' ' || character == '\n')
+ width += monospaceCharacterWidth;
+ else if (character == '\t')
+ width += style.collapseWhiteSpace() ? monospaceCharacterWidth : font.tabWidth(style.tabSize(), contentLogicalLeft + width);
+
+ if (i > from && (character == ' ' || character == '\t' || character == '\n'))
+ width += font.wordSpacing();
+ }
+
+ return width;
+}
+
+}
+}
+#endif
Added: trunk/Source/WebCore/layout/inlineformatting/textlayout/TextUtil.h (0 => 237287)
--- trunk/Source/WebCore/layout/inlineformatting/textlayout/TextUtil.h (rev 0)
+++ trunk/Source/WebCore/layout/inlineformatting/textlayout/TextUtil.h 2018-10-19 16:31:19 UTC (rev 237287)
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2018 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 "InlineItem.h"
+#include <wtf/IsoMalloc.h>
+
+namespace WebCore {
+
+namespace Layout {
+
+class TextUtil {
+ WTF_MAKE_ISO_ALLOCATED(TextUtil);
+public:
+ TextUtil(const InlineContent&);
+
+ LayoutUnit width(const InlineItem&, ItemPosition from, unsigned length, LayoutUnit contentLogicalLeft) const;
+ std::optional<ItemPosition> hyphenPositionBefore(const InlineItem&, ItemPosition from, unsigned length) const;
+
+private:
+ LayoutUnit textWidth(const InlineItem&, ItemPosition from, ItemPosition to, LayoutUnit contentLogicalLeft) const;
+ LayoutUnit fixedPitchWidth(String, const RenderStyle&, ItemPosition from, ItemPosition to, LayoutUnit contentLogicalLeft) const;
+
+ const InlineContent& m_inlineContent;
+};
+
+}
+}
+#endif
Modified: trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp (237286 => 237287)
--- trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp 2018-10-19 15:52:08 UTC (rev 237286)
+++ trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp 2018-10-19 16:31:19 UTC (rev 237287)
@@ -28,6 +28,7 @@
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+#include "LayoutContainer.h"
#include "RenderStyle.h"
#include <wtf/IsoMallocInlines.h>