Modified: trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.cpp (210455 => 210456)
--- trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.cpp 2017-01-06 20:46:24 UTC (rev 210455)
+++ trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.cpp 2017-01-06 23:29:09 UTC (rev 210456)
@@ -41,6 +41,8 @@
, wrapLines(style.autoWrap())
, breakAnyWordOnOverflow(style.wordBreak() == BreakAllWordBreak && wrapLines)
, breakFirstWordOnOverflow(breakAnyWordOnOverflow || (style.breakWords() && (wrapLines || preserveNewline)))
+ , breakNBSP(wrapLines && style.nbspMode() == SPACE)
+ , keepAllWordsForCJK(style.wordBreak() == KeepAllWordBreak)
, spaceWidth(font.width(TextRun(StringView(&space, 1))))
, wordSpacing(font.wordSpacing())
, tabWidth(collapseWhitespace ? 0 : style.tabSize())
@@ -110,7 +112,25 @@
m_atEndOfSegment = false;
}
-template <typename CharacterType>
+static unsigned nextBreakablePositionInSegment(LazyLineBreakIterator& lineBreakIterator, unsigned startPosition, bool breakNBSP, bool keepAllWordsForCJK)
+{
+ if (keepAllWordsForCJK) {
+ if (breakNBSP)
+ return nextBreakablePositionKeepingAllWords(lineBreakIterator, startPosition);
+ return nextBreakablePositionKeepingAllWordsIgnoringNBSP(lineBreakIterator, startPosition);
+ }
+
+ if (lineBreakIterator.isLooseCJKMode()) {
+ if (breakNBSP)
+ return nextBreakablePositionLoose(lineBreakIterator, startPosition);
+ return nextBreakablePositionIgnoringNBSPLoose(lineBreakIterator, startPosition);
+ }
+
+ if (breakNBSP)
+ return WebCore::nextBreakablePosition(lineBreakIterator, startPosition);
+ return nextBreakablePositionIgnoringNBSP(lineBreakIterator, startPosition);
+}
+
unsigned TextFragmentIterator::nextBreakablePosition(const FlowContents::Segment& segment, unsigned startPosition)
{
ASSERT(startPosition < segment.end);
@@ -123,10 +143,8 @@
m_lineBreakIterator.setPriorContext(lastCharacter, secondToLastCharacter);
m_lineBreakIterator.resetStringAndReleaseIterator(segment.text, m_style.locale, LineBreakIteratorMode::Default);
}
- const auto* characters = segment.text.characters<CharacterType>();
- unsigned segmentLength = segment.end - segment.start;
unsigned segmentPosition = startPosition - segment.start;
- return segment.start + nextBreakablePositionNonLoosely<CharacterType, NonBreakingSpaceBehavior::IgnoreNonBreakingSpace>(m_lineBreakIterator, characters, segmentLength, segmentPosition);
+ return segment.start + nextBreakablePositionInSegment(m_lineBreakIterator, segmentPosition, m_style.breakNBSP, m_style.keepAllWordsForCJK);
}
template <typename CharacterType>
@@ -165,7 +183,7 @@
if (positionType == NonWhitespace)
nextPosition = m_currentSegment->text.is8Bit() ? nextNonWhitespacePosition<LChar>(*m_currentSegment, currentPosition) : nextNonWhitespacePosition<UChar>(*m_currentSegment, currentPosition);
else if (positionType == Breakable) {
- nextPosition = m_currentSegment->text.is8Bit() ? nextBreakablePosition<LChar>(*m_currentSegment, currentPosition) : nextBreakablePosition<UChar>(*m_currentSegment, currentPosition);
+ nextPosition = nextBreakablePosition(*m_currentSegment, currentPosition);
// nextBreakablePosition returns the same position for certain characters such as hyphens. Call next again with modified position unless we are at the end of the segment.
bool skipCurrentPosition = nextPosition == currentPosition;
if (skipCurrentPosition) {
@@ -174,13 +192,13 @@
if (currentPosition == m_currentSegment->end - 1)
nextPosition = m_currentSegment->end;
else
- nextPosition = m_currentSegment->text.is8Bit() ? nextBreakablePosition<LChar>(*m_currentSegment, currentPosition + 1) : nextBreakablePosition<UChar>(*m_currentSegment, currentPosition + 1);
+ nextPosition = nextBreakablePosition(*m_currentSegment, currentPosition + 1);
}
// We need to know whether the word actually finishes at the end of this renderer or not.
if (nextPosition == m_currentSegment->end) {
const auto nextSegment = m_currentSegment + 1;
if (nextSegment != m_flowContents.end() && !isHardLineBreak(nextSegment))
- overlappingFragment = nextPosition < (nextSegment->text.is8Bit() ? nextBreakablePosition<LChar>(*nextSegment, nextPosition) : nextBreakablePosition<UChar>(*nextSegment, nextPosition));
+ overlappingFragment = nextPosition < nextBreakablePosition(*nextSegment, nextPosition);
}
}
width = 0;
Modified: trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.h (210455 => 210456)
--- trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.h 2017-01-06 20:46:24 UTC (rev 210455)
+++ trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.h 2017-01-06 23:29:09 UTC (rev 210456)
@@ -103,6 +103,8 @@
bool wrapLines;
bool breakAnyWordOnOverflow;
bool breakFirstWordOnOverflow;
+ bool breakNBSP;
+ bool keepAllWordsForCJK;
float spaceWidth;
float wordSpacing;
unsigned tabWidth;
@@ -116,7 +118,7 @@
unsigned skipToNextPosition(PositionType, unsigned startPosition, float& width, float xPosition, bool& overlappingFragment);
bool isSoftLineBreak(unsigned position) const;
bool isHardLineBreak(const FlowContents::Iterator& segment) const;
- template <typename CharacterType> unsigned nextBreakablePosition(const FlowContents::Segment&, unsigned startPosition);
+ unsigned nextBreakablePosition(const FlowContents::Segment&, unsigned startPosition);
template <typename CharacterType> unsigned nextNonWhitespacePosition(const FlowContents::Segment&, unsigned startPosition);
float runWidth(const FlowContents::Segment&, unsigned startPosition, unsigned endPosition, float xPosition) const;