Diff
Modified: trunk/LayoutTests/ChangeLog (281730 => 281731)
--- trunk/LayoutTests/ChangeLog 2021-08-28 02:09:00 UTC (rev 281730)
+++ trunk/LayoutTests/ChangeLog 2021-08-28 03:20:21 UTC (rev 281731)
@@ -1,3 +1,13 @@
+2021-08-27 Myles C. Maxfield <[email protected]>
+
+ The simple text codepath does not handle unpaired surrogates
+ https://bugs.webkit.org/show_bug.cgi?id=229392
+
+ Reviewed by Alan Bujtas.
+
+ * fast/text/unpaired-surrogate-expected-mismatch.html: Added.
+ * fast/text/unpaired-surrogate.html: Added.
+
2021-08-27 Eric Carlson <[email protected]>
[ Catalina EWS ] media/track/track-disabled-addcue.html is flaky crashing
Added: trunk/LayoutTests/fast/text/unpaired-surrogate-expected-mismatch.html (0 => 281731)
--- trunk/LayoutTests/fast/text/unpaired-surrogate-expected-mismatch.html (rev 0)
+++ trunk/LayoutTests/fast/text/unpaired-surrogate-expected-mismatch.html 2021-08-28 03:20:21 UTC (rev 281731)
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+<div id="target" style="font-size: 100px;">a</div>
+</body>
+</html>
Added: trunk/LayoutTests/fast/text/unpaired-surrogate.html (0 => 281731)
--- trunk/LayoutTests/fast/text/unpaired-surrogate.html (rev 0)
+++ trunk/LayoutTests/fast/text/unpaired-surrogate.html 2021-08-28 03:20:21 UTC (rev 281731)
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+<div id="target" style="font-size: 100px;"></div>
+<script>
+let target = document.getElementById("target");
+target.textContent = 'a\uD800b';
+</script>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (281730 => 281731)
--- trunk/Source/WebCore/ChangeLog 2021-08-28 02:09:00 UTC (rev 281730)
+++ trunk/Source/WebCore/ChangeLog 2021-08-28 03:20:21 UTC (rev 281731)
@@ -1,3 +1,43 @@
+2021-08-27 Myles C. Maxfield <[email protected]>
+
+ The simple text codepath does not handle unpaired surrogates
+ https://bugs.webkit.org/show_bug.cgi?id=229392
+
+ Reviewed by Alan Bujtas.
+
+ The simple text codepath was taking an early return if it encountered an unpaired surrogate.
+ This essentially ends up being data loss, because everything after that surrogate is just gone.
+ The other browsers render the unpaired surrogate, and the text after it too.
+
+ Removing the early return uncovered a preexisting bug, where word-break: break-all would cause
+ both RenderText::computePreferredLogicalWidths() and BreakingContext::handleText() to try to
+ break in between two adjacent joining surrogates.
+
+ Because both fixes depend on each other to be observable, this patch does both together.
+
+ Test: fast/text/unpaired-surrogate.html
+
+ * Sources.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * WebCore.xcodeproj/xcshareddata/xcschemes/WebCore.xcscheme:
+ * platform/graphics/FontCascade.cpp:
+ (WebCore::FontCascade::getEmphasisMarkGlyphData const):
+ * platform/graphics/SurrogatePairAwareTextIterator.cpp: Removed.
+ * platform/graphics/SurrogatePairAwareTextIterator.h:
+ (WebCore::SurrogatePairAwareTextIterator::SurrogatePairAwareTextIterator):
+ (WebCore::SurrogatePairAwareTextIterator::consume):
+ (WebCore::SurrogatePairAwareTextIterator::currentIndex const):
+ (WebCore::SurrogatePairAwareTextIterator::characters const): Deleted.
+ * platform/graphics/WidthIterator.cpp:
+ (WebCore::WidthIterator::advanceInternal):
+ * platform/graphics/freetype/SimpleFontDataFreeType.cpp:
+ * rendering/InlineIterator.h:
+ (WebCore::InlineIterator::incrementByCodePointInTextNode):
+ * rendering/RenderText.cpp:
+ (WebCore::RenderText::computePreferredLogicalWidths):
+ * rendering/line/BreakingContext.h:
+ (WebCore::BreakingContext::handleText):
+
2021-08-27 Simon Fraser <[email protected]>
Define ENABLE_CONTENT_CHANGE_OBSERVER for IOS_FAMILY and use it to wrap content observation code
Modified: trunk/Source/WebCore/Sources.txt (281730 => 281731)
--- trunk/Source/WebCore/Sources.txt 2021-08-28 02:09:00 UTC (rev 281730)
+++ trunk/Source/WebCore/Sources.txt 2021-08-28 03:20:21 UTC (rev 281731)
@@ -1959,7 +1959,6 @@
platform/graphics/ShadowBlur.cpp
platform/graphics/SourceBufferPrivate.cpp
platform/graphics/StringTruncator.cpp
-platform/graphics/SurrogatePairAwareTextIterator.cpp
platform/graphics/TextRun.cpp
platform/graphics/TextTrackRepresentation.cpp
platform/graphics/TrackPrivateBase.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (281730 => 281731)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-08-28 02:09:00 UTC (rev 281730)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-08-28 03:20:21 UTC (rev 281731)
@@ -262,7 +262,6 @@
08641D4812142F7D008DE9F6 /* RenderImageResourceStyleImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 08641D4612142F7D008DE9F6 /* RenderImageResourceStyleImage.h */; settings = {ATTRIBUTES = (Private, ); }; };
086BBD0F136039C2008B15D8 /* Glyph.h in Headers */ = {isa = PBXBuildFile; fileRef = 086BBD0E136039C2008B15D8 /* Glyph.h */; settings = {ATTRIBUTES = (Private, ); }; };
0873B86B136064EA00A522C2 /* GlyphPage.h in Headers */ = {isa = PBXBuildFile; fileRef = 0873B86A136064EA00A522C2 /* GlyphPage.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 087558C613B4A57D00F49307 /* SurrogatePairAwareTextIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = 087558C413B4A57D00F49307 /* SurrogatePairAwareTextIterator.h */; settings = {ATTRIBUTES = (Private, ); }; };
0885067F11DA045B00182B98 /* PaintInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0885067D11DA045B00182B98 /* PaintInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
0885068011DA045B00182B98 /* PaintPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0885067E11DA045B00182B98 /* PaintPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
088A0E0C126EF1DB00978F7A /* SVGPropertyTraits.h in Headers */ = {isa = PBXBuildFile; fileRef = 088A0E03126EF1DB00978F7A /* SVGPropertyTraits.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -6073,7 +6072,6 @@
08641D4612142F7D008DE9F6 /* RenderImageResourceStyleImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderImageResourceStyleImage.h; sourceTree = "<group>"; };
086BBD0E136039C2008B15D8 /* Glyph.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Glyph.h; sourceTree = "<group>"; };
0873B86A136064EA00A522C2 /* GlyphPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GlyphPage.h; sourceTree = "<group>"; };
- 087558C313B4A57D00F49307 /* SurrogatePairAwareTextIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SurrogatePairAwareTextIterator.cpp; sourceTree = "<group>"; };
087558C413B4A57D00F49307 /* SurrogatePairAwareTextIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SurrogatePairAwareTextIterator.h; sourceTree = "<group>"; };
0885067D11DA045B00182B98 /* PaintInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PaintInfo.h; sourceTree = "<group>"; };
0885067E11DA045B00182B98 /* PaintPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PaintPhase.h; sourceTree = "<group>"; };
@@ -26743,7 +26741,6 @@
7C83DE851D04CBD400FEBCF3 /* SpringSolver.h */,
B23540F00D00782E002382FA /* StringTruncator.cpp */,
B23540F10D00782E002382FA /* StringTruncator.h */,
- 087558C313B4A57D00F49307 /* SurrogatePairAwareTextIterator.cpp */,
087558C413B4A57D00F49307 /* SurrogatePairAwareTextIterator.h */,
3BB6B80F22A7D311003A2A69 /* TabSize.h */,
376DCCE013B4F966002EBEFC /* TextRun.cpp */,
@@ -34768,7 +34765,6 @@
93B2D8160F9920D2006AE6B2 /* SuddenTermination.h in Headers */,
97C078501165D5BE003A32EF /* SuffixTree.h in Headers */,
97627B9814FB5424002CDCA1 /* Supplementable.h in Headers */,
- 087558C613B4A57D00F49307 /* SurrogatePairAwareTextIterator.h in Headers */,
62C1217D11AB9E77003C462C /* SuspendableTimer.h in Headers */,
B22279740D00BF220071B782 /* SVGAElement.h in Headers */,
24D912B113CA9A1F00D21915 /* SVGAltGlyphDefElement.h in Headers */,
Modified: trunk/Source/WebCore/platform/graphics/FontCascade.cpp (281730 => 281731)
--- trunk/Source/WebCore/platform/graphics/FontCascade.cpp 2021-08-28 02:09:00 UTC (rev 281730)
+++ trunk/Source/WebCore/platform/graphics/FontCascade.cpp 2021-08-28 03:20:21 UTC (rev 281731)
@@ -33,7 +33,6 @@
#include "GraphicsContext.h"
#include "InMemoryDisplayList.h"
#include "LayoutRect.h"
-#include "SurrogatePairAwareTextIterator.h"
#include "TextRun.h"
#include "WidthIterator.h"
#include <wtf/MainThread.h>
@@ -1194,10 +1193,9 @@
UChar32 character;
if (!mark.is8Bit()) {
- SurrogatePairAwareTextIterator iterator(mark.characters16(), 0, mark.length(), mark.length());
- unsigned clusterLength;
- if (!iterator.consume(character, clusterLength))
- return std::nullopt;
+ size_t i = 0;
+ U16_NEXT(mark.characters16(), i, mark.length(), character);
+ ASSERT(U16_IS_SINGLE(character)); // The CSS parser replaces unpaired surrogates with the object replacement character.
} else
character = mark[0];
Deleted: trunk/Source/WebCore/platform/graphics/SurrogatePairAwareTextIterator.cpp (281730 => 281731)
--- trunk/Source/WebCore/platform/graphics/SurrogatePairAwareTextIterator.cpp 2021-08-28 02:09:00 UTC (rev 281730)
+++ trunk/Source/WebCore/platform/graphics/SurrogatePairAwareTextIterator.cpp 2021-08-28 03:20:21 UTC (rev 281731)
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2003-2019 Apple Inc. All rights reserved.
- * Copyright (C) 2008 Holger Hans Peter Freyther
- * Copyright (C) Research In Motion Limited 2011. 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.
- *
- */
-
-#include "config.h"
-#include "SurrogatePairAwareTextIterator.h"
-
-#include <unicode/unorm2.h>
-
-namespace WebCore {
-
-SurrogatePairAwareTextIterator::SurrogatePairAwareTextIterator(const UChar* characters, unsigned currentIndex, unsigned lastIndex, unsigned endIndex)
- : m_characters(characters)
- , m_currentIndex(currentIndex)
- , m_lastIndex(lastIndex)
- , m_endIndex(endIndex)
-{
-}
-
-bool SurrogatePairAwareTextIterator::consumeSlowCase(UChar32& character, unsigned& clusterLength)
-{
- ASSERT(U16_IS_SURROGATE(character));
-
- // If we have a surrogate pair, make sure it starts with the high part.
- if (!U16_IS_SURROGATE_LEAD(character))
- return false;
-
- // Do we have a surrogate pair? If so, determine the full Unicode (32 bit) code point before glyph lookup.
- // Make sure we have another character and it's a low surrogate.
- if (m_currentIndex + 1 >= m_endIndex)
- return false;
-
- UChar low = m_characters[1];
- if (!U16_IS_TRAIL(low))
- return false;
-
- character = U16_GET_SUPPLEMENTARY(character, low);
- clusterLength = 2;
- return true;
-}
-
-UChar32 SurrogatePairAwareTextIterator::normalizeVoicingMarks()
-{
- // According to http://www.unicode.org/Public/UNIDATA/UCD.html#Canonical_Combining_Class_Values
- static constexpr uint8_t hiraganaKatakanaVoicingMarksCombiningClass = 8;
-
- if (m_currentIndex + 1 >= m_endIndex)
- return 0;
-
- if (u_getCombiningClass(m_characters[1]) == hiraganaKatakanaVoicingMarksCombiningClass) {
- UErrorCode status = U_ZERO_ERROR;
- const UNormalizer2* normalizer = unorm2_getNFCInstance(&status);
- ASSERT(U_SUCCESS(status));
- auto composedCharacter = unorm2_composePair(normalizer, m_characters[0], m_characters[1]);
- if (composedCharacter > 0)
- return composedCharacter;
- }
-
- return 0;
-}
-
-}
Modified: trunk/Source/WebCore/platform/graphics/SurrogatePairAwareTextIterator.h (281730 => 281731)
--- trunk/Source/WebCore/platform/graphics/SurrogatePairAwareTextIterator.h 2021-08-28 02:09:00 UTC (rev 281730)
+++ trunk/Source/WebCore/platform/graphics/SurrogatePairAwareTextIterator.h 2021-08-28 03:20:21 UTC (rev 281731)
@@ -18,10 +18,9 @@
*
*/
-#ifndef SurrogatePairAwareTextIterator_h
-#define SurrogatePairAwareTextIterator_h
+#pragma once
-#include <wtf/unicode/CharacterNames.h>
+#include <unicode/utf16.h>
#include <wtf/text/WTFString.h>
namespace WebCore {
@@ -28,22 +27,24 @@
class SurrogatePairAwareTextIterator {
public:
- // The passed in UChar pointer starts at 'currentIndex'. The iterator operatoes on the range [currentIndex, lastIndex].
+ // The passed in UChar pointer starts at 'currentIndex'. The iterator operates on the range [currentIndex, lastIndex].
// 'endIndex' denotes the maximum length of the UChar array, which might exceed 'lastIndex'.
- SurrogatePairAwareTextIterator(const UChar*, unsigned currentIndex, unsigned lastIndex, unsigned endIndex);
+ SurrogatePairAwareTextIterator(const UChar* characters, unsigned currentIndex, unsigned lastIndex, unsigned endIndex)
+ : m_characters(characters)
+ , m_currentIndex(currentIndex)
+ , m_lastIndex(lastIndex)
+ , m_endIndex(endIndex)
+ {
+ }
- inline bool consume(UChar32& character, unsigned& clusterLength)
+ bool consume(UChar32& character, unsigned& clusterLength)
{
if (m_currentIndex >= m_lastIndex)
return false;
- character = *m_characters;
- clusterLength = 1;
-
- if (!U16_IS_SURROGATE(character))
- return true;
-
- return consumeSlowCase(character, clusterLength);
+ clusterLength = 0;
+ U16_NEXT(m_characters, clusterLength, m_endIndex - m_currentIndex, character);
+ return true;
}
void advance(unsigned advanceLength)
@@ -53,18 +54,12 @@
}
unsigned currentIndex() const { return m_currentIndex; }
- const UChar* characters() const { return m_characters; }
private:
- bool consumeSlowCase(UChar32&, unsigned&);
- UChar32 normalizeVoicingMarks();
-
- const UChar* m_characters;
- unsigned m_currentIndex;
- unsigned m_lastIndex;
- unsigned m_endIndex;
+ const UChar* m_characters { nullptr };
+ unsigned m_currentIndex { 0 };
+ unsigned m_lastIndex { 0 };
+ unsigned m_endIndex { 0 };
};
}
-
-#endif
Modified: trunk/Source/WebCore/platform/graphics/WidthIterator.cpp (281730 => 281731)
--- trunk/Source/WebCore/platform/graphics/WidthIterator.cpp 2021-08-28 02:09:00 UTC (rev 281730)
+++ trunk/Source/WebCore/platform/graphics/WidthIterator.cpp 2021-08-28 03:20:21 UTC (rev 281731)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 - 2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2003 - 2021 Apple Inc. All rights reserved.
* Copyright (C) 2008 Holger Hans Peter Freyther
*
* This library is free software; you can redistribute it and/or
@@ -278,6 +278,8 @@
float widthOfCurrentFontRange = 0;
// We are iterating in string order, not glyph order. Compare this to ComplexTextController::adjustGlyphsAndAdvances()
while (textIterator.consume(character, clusterLength)) {
+ // FIXME: Should we replace unpaired surrogates with the object replacement character?
+ // Should we do this before or after shaping? What does a shaper do with an unpaired surrogate?
m_containsTabs |= character == tabCharacter;
currentCharacterIndex = textIterator.currentIndex();
unsigned advanceLength = clusterLength;
Modified: trunk/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp (281730 => 281731)
--- trunk/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp 2021-08-28 02:09:00 UTC (rev 281730)
+++ trunk/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp 2021-08-28 03:20:21 UTC (rev 281731)
@@ -42,7 +42,6 @@
#include "GlyphBuffer.h"
#include "OpenTypeTypes.h"
#include "RefPtrCairo.h"
-#include "SurrogatePairAwareTextIterator.h"
#include "UTF16UChar32Iterator.h"
#include <cairo-ft.h>
#include <cairo.h>
Modified: trunk/Source/WebCore/rendering/InlineIterator.h (281730 => 281731)
--- trunk/Source/WebCore/rendering/InlineIterator.h 2021-08-28 02:09:00 UTC (rev 281730)
+++ trunk/Source/WebCore/rendering/InlineIterator.h 2021-08-28 03:20:21 UTC (rev 281731)
@@ -92,6 +92,7 @@
void setRefersToEndOfPreviousNode();
void fastIncrementInTextNode();
+ void incrementByCodePointInTextNode();
void increment(InlineBidiResolver* = nullptr);
void fastDecrement();
bool atEnd() const;
@@ -346,6 +347,19 @@
++m_pos;
}
+inline void InlineIterator::incrementByCodePointInTextNode()
+{
+ ASSERT(m_renderer);
+ const auto& text = downcast<RenderText>(*m_renderer).text();
+ ASSERT(m_pos < text.length());
+ if (text.is8Bit()) {
+ ++m_pos;
+ return;
+ }
+ UChar32 character;
+ U16_NEXT(text.characters16(), m_pos, text.length(), character);
+}
+
inline void InlineIterator::setOffset(unsigned position)
{
ASSERT(position <= UINT_MAX - 10); // Sanity check
Modified: trunk/Source/WebCore/rendering/RenderText.cpp (281730 => 281731)
--- trunk/Source/WebCore/rendering/RenderText.cpp 2021-08-28 02:09:00 UTC (rev 281730)
+++ trunk/Source/WebCore/rendering/RenderText.cpp 2021-08-28 03:20:21 UTC (rev 281731)
@@ -1069,13 +1069,19 @@
bool betweenWords = true;
unsigned j = i;
while (c != '\n' && !isSpaceAccordingToStyle(c, style) && c != '\t' && (c != softHyphen || style.hyphens() == Hyphens::None)) {
+ UChar previousCharacter = c;
j++;
if (j == length)
break;
c = string[j];
+ if (U_IS_LEAD(previousCharacter) && U_IS_TRAIL(c))
+ continue;
if (isBreakable(breakIterator, j, nextBreakable, breakNBSP, canUseLineBreakShortcut, keepAllWords, breakAnywhere) && characterAt(j - 1) != softHyphen)
break;
if (breakAll) {
+ // FIXME: This code is ultra wrong.
+ // The spec says "word-break: break-all: Any typographic letter units are treated as ID(“ideographic characters”) for the purpose of line-breaking."
+ // The spec describes how a "typographic letter unit" is a cluster, not a code point: https://drafts.csswg.org/css-text-3/#typographic-character-unit
betweenWords = false;
break;
}
Modified: trunk/Source/WebCore/rendering/line/BreakingContext.h (281730 => 281731)
--- trunk/Source/WebCore/rendering/line/BreakingContext.h 2021-08-28 02:09:00 UTC (rev 281730)
+++ trunk/Source/WebCore/rendering/line/BreakingContext.h 2021-08-28 03:20:21 UTC (rev 281731)
@@ -738,11 +738,11 @@
// words with their trailing space, then subtract its width.
TextLayout* textLayout = m_renderTextInfo.layout.get();
WordTrailingSpace wordTrailingSpace(style, !textLayout);
- for (; m_current.offset() < renderer.text().length(); m_current.fastIncrementInTextNode()) {
+ for (; m_current.offset() < renderer.text().length(); m_current.incrementByCodePointInTextNode()) {
ASSERT(&renderer == m_current.renderer());
bool previousCharacterIsSpace = m_currentCharacterIsSpace;
bool previousCharacterIsWS = m_currentCharacterIsWS;
- UChar c = m_current.current();
+ UChar c = m_current.current(); // FIXME: It's silly to pull out a single surrogate from the content and attempt to do anything useful with it.
m_currentCharacterIsSpace = c == ' ' || c == '\t' || (!m_preservesNewline && (c == '\n'));
// A single preserved leading white-space doesn't fulfill the 'betweenWords' condition, however it's indeed a
@@ -776,6 +776,9 @@
m_currentCharacterIsWS = m_currentCharacterIsSpace || (breakNBSP && c == noBreakSpace);
if (canBreakMidWord && !midWordBreak && (!m_currentCharacterIsSpace || m_atStart || style.whiteSpace() != WhiteSpace::PreWrap)) {
+ // FIXME: This code is ultra wrong.
+ // The spec says "word-break: break-all: Any typographic letter units are treated as ID(“ideographic characters”) for the purpose of line-breaking."
+ // The spec describes how a "typographic letter unit" is a cluster, not a code point: https://drafts.csswg.org/css-text-3/#typographic-character-unit
wrapW += charWidth;
bool midWordBreakIsBeforeSurrogatePair = U16_IS_LEAD(c) && U16_IS_TRAIL(renderer.characterAt(m_current.offset() + 1));
charWidth = textWidth(renderer, m_current.offset(), midWordBreakIsBeforeSurrogatePair ? 2 : 1, font, m_width.committedWidth() + wrapW, isFixedPitch, m_collapseWhiteSpace, fallbackFonts, textLayout);
@@ -783,7 +786,7 @@
}
std::optional<unsigned> nextBreakablePosition = m_current.nextBreakablePosition();
- bool betweenWords = c == '\n' || (m_currWS != WhiteSpace::Pre && !m_atStart && isBreakable(m_renderTextInfo.lineBreakIterator, m_current.offset(), nextBreakablePosition, breakNBSP, canUseLineBreakShortcut, keepAllWords, breakAnywhere)
+ bool betweenWords = c == newlineCharacter || (m_currWS != WhiteSpace::Pre && !m_atStart && isBreakable(m_renderTextInfo.lineBreakIterator, m_current.offset(), nextBreakablePosition, breakNBSP, canUseLineBreakShortcut, keepAllWords, breakAnywhere)
&& (style.hyphens() != Hyphens::None || (m_current.previousInSameNode() != softHyphen)));
m_current.setNextBreakablePosition(nextBreakablePosition);
@@ -931,7 +934,7 @@
}
}
- if (c == '\n' && m_preservesNewline) {
+ if (c == newlineCharacter && m_preservesNewline) {
if (!stoppedIgnoringSpaces && m_current.offset())
ensureCharacterGetsLineBox(m_lineWhitespaceCollapsingState, m_current);
commitLineBreakAtCurrentWidth(renderer, m_current.offset(), m_current.nextBreakablePosition());