Diff
Modified: trunk/Source/WebCore/ChangeLog (287205 => 287206)
--- trunk/Source/WebCore/ChangeLog 2021-12-17 21:51:19 UTC (rev 287205)
+++ trunk/Source/WebCore/ChangeLog 2021-12-17 22:09:16 UTC (rev 287206)
@@ -1,3 +1,49 @@
+2021-12-17 Myles C. Maxfield <[email protected]>
+
+ Deduplicate code in RenderText::computePreferredLogicalWidths()
+ https://bugs.webkit.org/show_bug.cgi?id=234424
+
+ Reviewed by Alan Bujtas.
+
+ We have 3 places with code of this form:
+
+ float result;
+ std::optional<float> wordTrailingSpaceWidth;
+ if (currentCharacterIsSpace)
+ wordTrailingSpaceWidth = wordTrailingSpace.width(fallbackFonts);
+ if (wordTrailingSpaceWidth)
+ result = measureText(startingCharacterIndex, length + 1) - wordTrailingSpaceWidth.value();
+ else
+ result = measureText(startingCharacterIndex, length);
+
+ This patch simply deduplicates this logic, and puts it into a single function:
+ RenderText::measureTextConsideringPossibleTrailingSpace(). Because the different places which call it
+ use different text measurement functions, this function accepts a "measure text" callback.
+
+ No new tests because there is no behavior change.
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * rendering/RenderText.cpp:
+ (WebCore::RenderText::widthFromCacheConsideringPossibleTrailingSpace const):
+ (WebCore::RenderText::maxWordFragmentWidth):
+ (WebCore::RenderText::computePreferredLogicalWidths):
+ * rendering/RenderText.h:
+ * rendering/RenderTextInlines.h: Added. This function needs to be able to see into WordTrailingSpace,
+ but we shouldn't be adding any more #includes to RenderText.h because doing so will increase the build time.
+ So, instead, we can move this templated function to a new Inlines header, and have callers include that
+ header.
+ (WebCore::RenderText::measureTextConsideringPossibleTrailingSpace):
+ * rendering/line/BreakingContext.h:
+ (WebCore::BreakingContext::textWidthConsideringPossibleTrailingSpace):
+ (WebCore::BreakingContext::computeAdditionalBetweenWordsWidth):
+ (WebCore::WordTrailingSpace::WordTrailingSpace): Deleted.
+ (WebCore::WordTrailingSpace::width): Deleted.
+ * rendering/line/WordTrailingSpace.h: Added. BreakingContext.h defines WordTrailingSpace, but it needs
+ to be able to call measureTextConsideringPossibleTrailingSpace(), which needs to be able to see inside
+ WordTrailingSpace. Avoid the circular dependency by splitting out WordTrailingSpace into its own file.
+ (WebCore::WordTrailingSpace::WordTrailingSpace):
+ (WebCore::WordTrailingSpace::width):
+
2021-12-17 Alan Bujtas <[email protected]>
[LFC][IFC] Use the inline box's direction to decide if start/end decorations should be applied on first/last box
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (287205 => 287206)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-12-17 21:51:19 UTC (rev 287205)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-12-17 22:09:16 UTC (rev 287206)
@@ -7067,6 +7067,8 @@
1C0939E91A13E12900B788E5 /* CachedSVGFont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedSVGFont.h; sourceTree = "<group>"; };
1C09D04B1E31C32800725F18 /* PAL.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = PAL.xcodeproj; path = PAL/PAL.xcodeproj; sourceTree = "<group>"; };
1C0AA16A21940DC700896829 /* StyleColorScheme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleColorScheme.h; sourceTree = "<group>"; };
+ 1C0BE943276C60BC005FB6C1 /* RenderTextInlines.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RenderTextInlines.h; sourceTree = "<group>"; };
+ 1C0BE947276C6603005FB6C1 /* WordTrailingSpace.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WordTrailingSpace.h; sourceTree = "<group>"; };
1C12AC281EE778AE0079E0A0 /* FontFamilySpecificationCoreText.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FontFamilySpecificationCoreText.cpp; sourceTree = "<group>"; };
1C12AC291EE778AE0079E0A0 /* FontFamilySpecificationCoreText.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FontFamilySpecificationCoreText.h; sourceTree = "<group>"; };
1C12AC2C1EE779950079E0A0 /* FontDescriptionCocoa.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FontDescriptionCocoa.cpp; sourceTree = "<group>"; };
@@ -31943,6 +31945,7 @@
083DAEA50F01A7FB00342754 /* RenderTextControlSingleLine.h */,
BCEA484E097D93020094C9E4 /* RenderTextFragment.cpp */,
BCEA484F097D93020094C9E4 /* RenderTextFragment.h */,
+ 1C0BE943276C60BC005FB6C1 /* RenderTextInlines.h */,
E4C91A17180999FB00A17F6D /* RenderTextLineBoxes.cpp */,
E4C91A15180999F100A17F6D /* RenderTextLineBoxes.h */,
BCEA484A097D93020094C9E4 /* RenderTheme.cpp */,
@@ -33084,6 +33087,7 @@
FFDBC045183D27B700407109 /* LineWidth.h */,
FFAC30FD184FB145008C4F1E /* TrailingObjects.cpp */,
FFAC30FC184FB145008C4F1E /* TrailingObjects.h */,
+ 1C0BE947276C6603005FB6C1 /* WordTrailingSpace.h */,
);
path = line;
sourceTree = "<group>";
Modified: trunk/Source/WebCore/rendering/RenderText.cpp (287205 => 287206)
--- trunk/Source/WebCore/rendering/RenderText.cpp 2021-12-17 21:51:19 UTC (rev 287205)
+++ trunk/Source/WebCore/rendering/RenderText.cpp 2021-12-17 22:09:16 UTC (rev 287206)
@@ -1,7 +1,7 @@
/*
* (C) 1999 Lars Knoll ([email protected])
* (C) 2000 Dirk Mueller ([email protected])
- * Copyright (C) 2004-2019 Apple Inc. All rights reserved.
+ * Copyright (C) 2004-2021 Apple Inc. All rights reserved.
* Copyright (C) 2006 Andrew Wellington ([email protected])
* Copyright (C) 2006 Graham Dennis ([email protected])
*
@@ -47,6 +47,7 @@
#include "RenderCombineText.h"
#include "RenderInline.h"
#include "RenderLayer.h"
+#include "RenderTextInlines.h"
#include "RenderView.h"
#include "RenderedDocumentMarker.h"
#include "SVGElementTypeHelpers.h"
@@ -717,6 +718,13 @@
return f.width(run, fallbackFonts, glyphOverflow);
}
+ALWAYS_INLINE float RenderText::widthFromCacheConsideringPossibleTrailingSpace(const RenderStyle& style, const FontCascade& font, unsigned startIndex, unsigned wordLen, float xPos, bool currentCharacterIsSpace, WordTrailingSpace& wordTrailingSpace, HashSet<const Font*>& fallbackFonts, GlyphOverflow& glyphOverflow) const
+{
+ return measureTextConsideringPossibleTrailingSpace(currentCharacterIsSpace, startIndex, wordLen, wordTrailingSpace, fallbackFonts, [&] (unsigned from, unsigned len) {
+ return widthFromCache(font, from, len, xPos, &fallbackFonts, &glyphOverflow, style);
+ });
+}
+
inline bool isHangablePunctuationAtLineStart(UChar c)
{
return U_GET_GC_MASK(c) & (U_GC_PS_MASK | U_GC_PI_MASK | U_GC_PF_MASK);
@@ -973,15 +981,7 @@
return entireWordWidth;
}
- float suffixWidth;
- std::optional<float> wordTrailingSpaceWidth;
- if (currentCharacterIsSpace)
- wordTrailingSpaceWidth = wordTrailingSpace.width(fallbackFonts);
- if (wordTrailingSpaceWidth)
- suffixWidth = widthFromCache(font, characterIndex + suffixStart, word.length() - suffixStart + 1, xPos, 0, 0, style) - wordTrailingSpaceWidth.value();
- else
- suffixWidth = widthFromCache(font, characterIndex + suffixStart, word.length() - suffixStart, xPos, 0, 0, style);
-
+ auto suffixWidth = widthFromCacheConsideringPossibleTrailingSpace(style, font, characterIndex + suffixStart, word.length() - suffixStart, xPos, currentCharacterIsSpace, wordTrailingSpace, fallbackFonts, glyphOverflow);
return std::max(maxFragmentWidth, suffixWidth);
}
@@ -1115,17 +1115,9 @@
if (wordLen) {
float currMinWidth = 0;
bool isSpace = (j < length) && isSpaceAccordingToStyle(c, style);
- float w;
- std::optional<float> wordTrailingSpaceWidth;
- if (isSpace)
- wordTrailingSpaceWidth = wordTrailingSpace.width(fallbackFonts);
- if (wordTrailingSpaceWidth)
- w = widthFromCache(font, i, wordLen + 1, leadWidth + currMaxWidth, &fallbackFonts, &glyphOverflow, style) - wordTrailingSpaceWidth.value();
- else {
- w = widthFromCache(font, i, wordLen, leadWidth + currMaxWidth, &fallbackFonts, &glyphOverflow, style);
- if (c == softHyphen && style.hyphens() != Hyphens::None)
- currMinWidth = hyphenWidth(*this, font);
- }
+ float w = widthFromCacheConsideringPossibleTrailingSpace(style, font, i, wordLen, leadWidth + currMaxWidth, isSpace, wordTrailingSpace, fallbackFonts, glyphOverflow);
+ if (c == softHyphen && style.hyphens() != Hyphens::None)
+ currMinWidth = hyphenWidth(*this, font);
if (w > maxWordWidth) {
auto maxFragmentWidth = maxWordFragmentWidth(style, font, StringView(string).substring(i, wordLen), minimumPrefixLength, minimumSuffixLength, isSpace, i, leadWidth + currMaxWidth, w, wordTrailingSpace, fallbackFonts, glyphOverflow);
Modified: trunk/Source/WebCore/rendering/RenderText.h (287205 => 287206)
--- trunk/Source/WebCore/rendering/RenderText.h 2021-12-17 21:51:19 UTC (rev 287205)
+++ trunk/Source/WebCore/rendering/RenderText.h 2021-12-17 22:09:16 UTC (rev 287206)
@@ -1,7 +1,7 @@
/*
* (C) 1999 Lars Knoll ([email protected])
* (C) 2000 Dirk Mueller ([email protected])
- * Copyright (C) 2004-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2004-2021 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -183,6 +183,9 @@
static RenderText* findByDisplayContentsInlineWrapperCandidate(RenderElement&);
+ template <typename MeasureTextCallback>
+ static float measureTextConsideringPossibleTrailingSpace(bool currentCharacterIsSpace, unsigned startIndex, unsigned wordLength, WordTrailingSpace&, HashSet<const Font*>& fallbackFonts, MeasureTextCallback&&);
+
protected:
virtual void computePreferredLogicalWidths(float leadWidth);
void willBeDestroyed() override;
@@ -224,6 +227,7 @@
void container(const RenderLayerModelObject&, bool&) const = delete; // Use parent() instead.
float maxWordFragmentWidth(const RenderStyle&, const FontCascade&, StringView word, unsigned minimumPrefixLength, unsigned minimumSuffixLength, bool currentCharacterIsSpace, unsigned characterIndex, float xPos, float entireWordWidth, WordTrailingSpace&, HashSet<const Font*>& fallbackFonts, GlyphOverflow&);
+ float widthFromCacheConsideringPossibleTrailingSpace(const RenderStyle&, const FontCascade&, unsigned startIndex, unsigned wordLen, float xPos, bool currentCharacterIsSpace, WordTrailingSpace&, HashSet<const Font*>& fallbackFonts, GlyphOverflow&) const;
// We put the bitfield first to minimize padding on 64-bit.
unsigned m_hasBreakableChar : 1; // Whether or not we can be broken into multiple lines.
Added: trunk/Source/WebCore/rendering/RenderTextInlines.h (0 => 287206)
--- trunk/Source/WebCore/rendering/RenderTextInlines.h (rev 0)
+++ trunk/Source/WebCore/rendering/RenderTextInlines.h 2021-12-17 22:09:16 UTC (rev 287206)
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#pragma once
+
+#include "RenderText.h"
+#include "WordTrailingSpace.h"
+
+namespace WebCore {
+
+template <typename MeasureTextCallback>
+float RenderText::measureTextConsideringPossibleTrailingSpace(bool currentCharacterIsSpace, unsigned startIndex, unsigned wordLength, WordTrailingSpace& wordTrailingSpace, HashSet<const Font*>& fallbackFonts, MeasureTextCallback&& callback)
+{
+ std::optional<float> wordTrailingSpaceWidth;
+ if (currentCharacterIsSpace)
+ wordTrailingSpaceWidth = wordTrailingSpace.width(fallbackFonts);
+ if (wordTrailingSpaceWidth)
+ return callback(startIndex, wordLength + 1) - wordTrailingSpaceWidth.value();
+ return callback(startIndex, wordLength);
+}
+
+} // namespace WebCore
Modified: trunk/Source/WebCore/rendering/line/BreakingContext.h (287205 => 287206)
--- trunk/Source/WebCore/rendering/line/BreakingContext.h 2021-12-17 21:51:19 UTC (rev 287205)
+++ trunk/Source/WebCore/rendering/line/BreakingContext.h 2021-12-17 22:09:16 UTC (rev 287206)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2000 Lars Knoll ([email protected])
- * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All right reserved.
+ * Copyright (C) 2003-2021 Apple Inc. All right reserved.
* Copyright (C) 2010 Google Inc. All rights reserved.
* Copyright (C) 2013 ChangSeok Oh <[email protected]>
* Copyright (C) 2013 Adobe Systems Inc. All right reserved.
@@ -38,7 +38,9 @@
#include "RenderListMarker.h"
#include "RenderRubyRun.h"
#include "RenderSVGInlineText.h"
+#include "RenderTextInlines.h"
#include "TrailingObjects.h"
+#include "WordTrailingSpace.h"
#include <wtf/Function.h>
#include <wtf/text/StringView.h>
#include <wtf/unicode/CharacterNames.h>
@@ -64,32 +66,6 @@
HashSet<const Font*> fallbackFonts;
};
-struct WordTrailingSpace {
- WordTrailingSpace(const RenderStyle& style, bool measuringWithTrailingWhitespaceEnabled = true)
- : m_style(style)
- {
- if (!measuringWithTrailingWhitespaceEnabled || !m_style.fontCascade().enableKerning())
- m_state = WordTrailingSpaceState::Initialized;
- }
-
- std::optional<float> width(HashSet<const Font*>& fallbackFonts)
- {
- if (m_state == WordTrailingSpaceState::Initialized)
- return m_width;
-
- auto& font = m_style.fontCascade();
- m_width = font.width(RenderBlock::constructTextRun(&space, 1, m_style), &fallbackFonts) + font.wordSpacing();
- m_state = WordTrailingSpaceState::Initialized;
- return m_width;
- }
-
-private:
- enum class WordTrailingSpaceState { Uninitialized, Initialized };
- const RenderStyle& m_style;
- WordTrailingSpaceState m_state { WordTrailingSpaceState::Uninitialized };
- std::optional<float> m_width;
-};
-
class BreakingContext {
public:
BreakingContext(LineBreaker& lineBreaker, InlineBidiResolver& resolver, LineInfo& inLineInfo, LineWidth& lineWidth, RenderTextInfo& inRenderTextInfo, FloatingObject* inLastFloatFromPreviousLine, bool appliedStartWidth, RenderBlockFlow& block)
@@ -151,6 +127,7 @@
LegacyInlineIterator handleEndOfLine();
float computeAdditionalBetweenWordsWidth(RenderText&, TextLayout*, UChar, WordTrailingSpace&, HashSet<const Font*>& fallbackFonts, WordMeasurements&, const FontCascade&, bool isFixedPitch, unsigned lastSpace, float lastSpaceWordSpacing, float wordSpacingForWordMeasurement, unsigned offset);
+ float textWidthConsideringPossibleTrailingSpace(RenderText&, TextLayout*, UChar currentCharacter, WordTrailingSpace&, HashSet<const Font*>& fallbackFonts, HashSet<const Font*>& wordMeasurementFallbackFonts, const FontCascade&, bool isFixedPitch, unsigned lastSpace, unsigned offset);
void clearLineBreakIfFitsOnLine(bool ignoringTrailingSpace = false)
{
@@ -631,6 +608,13 @@
hyphenated = true;
}
+inline float BreakingContext::textWidthConsideringPossibleTrailingSpace(RenderText& renderText, TextLayout* textLayout, UChar currentCharacter, WordTrailingSpace& wordTrailingSpace, HashSet<const Font*>& fallbackFonts, HashSet<const Font*>& wordMeasurementFallbackFonts, const FontCascade& font, bool isFixedPitch, unsigned lastSpace, unsigned offset)
+{
+ return RenderText::measureTextConsideringPossibleTrailingSpace(currentCharacter == space, lastSpace, offset - lastSpace, wordTrailingSpace, fallbackFonts, [&] (unsigned from, unsigned len) {
+ return textWidth(renderText, from, len, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace, wordMeasurementFallbackFonts, textLayout);
+ });
+}
+
inline float BreakingContext::computeAdditionalBetweenWordsWidth(RenderText& renderText, TextLayout* textLayout, UChar currentCharacter, WordTrailingSpace& wordTrailingSpace, HashSet<const Font*>& fallbackFonts, WordMeasurements& wordMeasurements, const FontCascade& font, bool isFixedPitch, unsigned lastSpace, float lastSpaceWordSpacing, float wordSpacingForWordMeasurement, unsigned offset)
{
wordMeasurements.grow(wordMeasurements.size() + 1);
@@ -640,14 +624,7 @@
wordMeasurement.endOffset = offset;
wordMeasurement.startOffset = lastSpace;
- float additionalTempWidth = 0;
- std::optional<float> wordTrailingSpaceWidth;
- if (currentCharacter == ' ')
- wordTrailingSpaceWidth = wordTrailingSpace.width(fallbackFonts);
- if (wordTrailingSpaceWidth)
- additionalTempWidth = textWidth(renderText, lastSpace, offset + 1 - lastSpace, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace, wordMeasurement.fallbackFonts, textLayout) - wordTrailingSpaceWidth.value();
- else
- additionalTempWidth = textWidth(renderText, lastSpace, offset - lastSpace, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace, wordMeasurement.fallbackFonts, textLayout);
+ float additionalTempWidth = textWidthConsideringPossibleTrailingSpace(renderText, textLayout, currentCharacter, wordTrailingSpace, fallbackFonts, wordMeasurement.fallbackFonts, font, isFixedPitch, lastSpace, offset);
if (wordMeasurement.fallbackFonts.isEmpty() && !fallbackFonts.isEmpty())
wordMeasurement.fallbackFonts.swap(fallbackFonts);
@@ -1252,4 +1229,4 @@
return m_lineBreak;
}
-}
+} // namespace WebCore
Added: trunk/Source/WebCore/rendering/line/WordTrailingSpace.h (0 => 287206)
--- trunk/Source/WebCore/rendering/line/WordTrailingSpace.h (rev 0)
+++ trunk/Source/WebCore/rendering/line/WordTrailingSpace.h 2021-12-17 22:09:16 UTC (rev 287206)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2000 Lars Knoll ([email protected])
+ * Copyright (C) 2003-2021 Apple Inc. All right reserved.
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2013 ChangSeok Oh <[email protected]>
+ * Copyright (C) 2013 Adobe Systems Inc. All right reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#pragma once
+
+#include "FontCascade.h"
+#include "RenderBlock.h"
+#include "RenderStyle.h"
+#include <optional>
+#include <wtf/HashSet.h>
+
+namespace WebCore {
+
+struct WordTrailingSpace {
+ WordTrailingSpace(const RenderStyle& style, bool measuringWithTrailingWhitespaceEnabled = true)
+ : m_style(style)
+ {
+ if (!measuringWithTrailingWhitespaceEnabled || !m_style.fontCascade().enableKerning())
+ m_state = WordTrailingSpaceState::Initialized;
+ }
+
+ std::optional<float> width(HashSet<const Font*>& fallbackFonts)
+ {
+ if (m_state == WordTrailingSpaceState::Initialized)
+ return m_width;
+
+ auto& font = m_style.fontCascade();
+ m_width = font.width(RenderBlock::constructTextRun(&space, 1, m_style), &fallbackFonts) + font.wordSpacing();
+ m_state = WordTrailingSpaceState::Initialized;
+ return m_width;
+ }
+
+private:
+ enum class WordTrailingSpaceState { Uninitialized, Initialized };
+ const RenderStyle& m_style;
+ WordTrailingSpaceState m_state { WordTrailingSpaceState::Uninitialized };
+ std::optional<float> m_width;
+};
+
+} // namespace WebCore