Diff
Modified: trunk/Source/WebCore/ChangeLog (158917 => 158918)
--- trunk/Source/WebCore/ChangeLog 2013-11-08 12:16:33 UTC (rev 158917)
+++ trunk/Source/WebCore/ChangeLog 2013-11-08 12:53:19 UTC (rev 158918)
@@ -1,3 +1,45 @@
+2013-11-08 Antti Koivisto <[email protected]>
+
+ Templated LChar/UChar paths for simple line layout
+ https://bugs.webkit.org/show_bug.cgi?id=124035
+
+ Reviewed by Andreas Kling.
+
+ * rendering/SimpleLineLayout.cpp:
+ (WebCore::SimpleLineLayout::canUseForText):
+ (WebCore::SimpleLineLayout::canUseFor):
+
+ Use a templated function to check for illegal characters.
+
+ (WebCore::SimpleLineLayout::skipWhitespaces):
+
+ Make a template function.
+
+ (WebCore::SimpleLineLayout::textWidth):
+
+ Make a template function plus some argument changes.
+
+ (WebCore::SimpleLineLayout::createTextRuns):
+
+ Template function for creating runs while operating with either LChars or UChar.
+ Also simplified line breaking and text width measuring logic.
+
+ (WebCore::SimpleLineLayout::create):
+
+ Pick the template.
+
+ * rendering/break_lines.cpp:
+ * rendering/break_lines.h:
+
+ Move the implementation to the header (except for the table) so we can use the template
+ versions directly.
+
+ (WebCore::isBreakableSpace):
+ (WebCore::shouldBreakAfter):
+ (WebCore::needsLineBreakIterator):
+ (WebCore::nextBreakablePosition):
+ (WebCore::nextBreakablePositionIgnoringNBSP):
+
2013-11-08 Mario Sanchez Prada <[email protected]>
AX: [ATK] <span> elements exposed through ATK when not needed
Modified: trunk/Source/WebCore/rendering/SimpleLineLayout.cpp (158917 => 158918)
--- trunk/Source/WebCore/rendering/SimpleLineLayout.cpp 2013-11-08 12:16:33 UTC (rev 158917)
+++ trunk/Source/WebCore/rendering/SimpleLineLayout.cpp 2013-11-08 12:53:19 UTC (rev 158918)
@@ -49,11 +49,40 @@
namespace WebCore {
namespace SimpleLineLayout {
-static inline bool isWhitespace(UChar character)
+template <typename CharacterType>
+static bool canUseForText(const CharacterType* text, unsigned length, const SimpleFontData& fontData)
{
- return character == ' ' || character == '\t' || character == '\n';
+ for (unsigned i = 0; i < length; ++i) {
+ UChar character = text[i];
+ if (character == ' ')
+ continue;
+
+ // These would be easy to support.
+ if (character == noBreakSpace)
+ return false;
+ if (character == softHyphen)
+ return false;
+
+ 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)
+ return false;
+
+ if (!fontData.glyphForCharacter(character))
+ return false;
+ }
+ return true;
}
+static bool canUseForText(const RenderText& textRenderer, const SimpleFontData& fontData)
+{
+ if (textRenderer.is8Bit())
+ return canUseForText(textRenderer.characters8(), textRenderer.textLength(), fontData);
+ return canUseForText(textRenderer.characters16(), textRenderer.textLength(), fontData);
+}
+
bool canUseFor(const RenderBlockFlow& flow)
{
#if !PLATFORM(MAC) && !PLATFORM(GTK) && !PLATFORM(EFL)
@@ -162,51 +191,38 @@
auto& primaryFontData = *style.font().primaryFont();
if (primaryFontData.isLoading())
return false;
+ if (!canUseForText(textRenderer, primaryFontData))
+ return false;
- unsigned length = textRenderer.textLength();
- for (unsigned i = 0; i < length; ++i) {
- UChar character = textRenderer.characterAt(i);
- if (character == ' ')
- continue;
-
- // These would be easy to support.
- if (character == noBreakSpace)
- return false;
- if (character == softHyphen)
- return false;
-
- 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)
- return false;
-
- if (!primaryFontData.glyphForCharacter(character))
- return false;
- }
return true;
}
-static inline unsigned skipWhitespaces(const RenderText& textRenderer, unsigned offset, unsigned length)
+static inline bool isWhitespace(UChar character)
{
+ return character == ' ' || character == '\t' || character == '\n';
+}
+
+template <typename CharacterType>
+static inline unsigned skipWhitespaces(const CharacterType* text, unsigned offset, unsigned length)
+{
for (; offset < length; ++offset) {
- if (!isWhitespace(textRenderer.characterAt(offset)))
- break;
+ if (!isWhitespace(text[offset]))
+ return offset;
}
- return offset;
+ return length;
}
-static float textWidth(const RenderText& text, unsigned from, unsigned length, float xPosition, const RenderStyle& style)
+template <typename CharacterType>
+static float textWidth(const RenderText& renderText, const CharacterType* text, unsigned textLength, unsigned from, unsigned to, float xPosition, const RenderStyle& style)
{
- if (style.font().isFixedPitch() || (!from && length == text.textLength()))
- return text.width(from, length, style.font(), xPosition, nullptr, nullptr);
+ if (style.font().isFixedPitch() || (!from && to == textLength))
+ return renderText.width(from, to - from, style.font(), xPosition, nullptr, nullptr);
// FIXME: Add templated UChar/LChar paths.
- TextRun run = text.is8Bit() ? TextRun(text.characters8() + from, length) : TextRun(text.characters16() + from, length);
- run.setCharactersLength(text.textLength() - from);
+ TextRun run(text + from, to - from);
+ run.setXPos(xPosition);
+ run.setCharactersLength(textLength - from);
ASSERT(run.charactersLength() >= run.length());
- run.setXPos(xPosition);
return style.font().width(run);
}
@@ -240,77 +256,68 @@
}
}
-std::unique_ptr<Layout> create(RenderBlockFlow& flow)
+template <typename CharacterType>
+void createTextRuns(Layout::RunVector& runs, unsigned& lineCount, RenderBlockFlow& flow, RenderText& textRenderer)
{
- RenderText& textRenderer = toRenderText(*flow.firstChild());
- ASSERT(!textRenderer.firstTextBox());
-
const RenderStyle& style = flow.style();
- const unsigned textLength = textRenderer.textLength();
ETextAlign textAlign = style.textAlign();
float wordTrailingSpaceWidth = style.font().width(TextRun(&space, 1));
+ const CharacterType* text = textRenderer.text()->getCharacters<CharacterType>();
+ const unsigned textLength = textRenderer.textLength();
+
LazyLineBreakIterator lineBreakIterator(textRenderer.text(), style.locale());
- int nextBreakable = -1;
- Layout::RunVector runs;
- unsigned lineCount = 0;
-
- unsigned lineEndOffset = 0;
- while (lineEndOffset < textLength) {
- lineEndOffset = skipWhitespaces(textRenderer, lineEndOffset, textLength);
- unsigned lineStartOffset = lineEndOffset;
- unsigned wordEndOffset = lineEndOffset;
+ unsigned lineEnd = 0;
+ while (lineEnd < textLength) {
+ lineEnd = skipWhitespaces(text, lineEnd, textLength);
+ unsigned lineStart = lineEnd;
+ unsigned wordEnd = lineEnd;
LineWidth lineWidth(flow, false, DoNotIndentText);
Vector<Run, 4> lineRuns;
- lineRuns.uncheckedAppend(Run(lineStartOffset, 0));
+ lineRuns.uncheckedAppend(Run(lineStart, 0));
- while (wordEndOffset < textLength) {
- ASSERT(!isWhitespace(textRenderer.characterAt(wordEndOffset)));
+ while (wordEnd < textLength) {
+ ASSERT(!isWhitespace(text[wordEnd]));
- bool previousWasSpaceBetweenWords = wordEndOffset > lineStartOffset && isWhitespace(textRenderer.characterAt(wordEndOffset - 1));
- unsigned wordStartOffset = previousWasSpaceBetweenWords ? wordEndOffset - 1 : wordEndOffset;
+ bool wordIsPrecededByWhitespace = wordEnd > lineStart && isWhitespace(text[wordEnd - 1]);
+ unsigned wordStart = wordIsPrecededByWhitespace ? wordEnd - 1 : wordEnd;
- ++wordEndOffset;
- while (wordEndOffset < textLength) {
- if (wordEndOffset > lineStartOffset && isBreakable(lineBreakIterator, wordEndOffset, nextBreakable, false))
- break;
- ++wordEndOffset;
- }
+ wordEnd = nextBreakablePosition<CharacterType, false>(lineBreakIterator, text, textLength, wordEnd + 1);
- unsigned wordLength = wordEndOffset - wordStartOffset;
- bool includeEndSpace = wordEndOffset < textLength && textRenderer.characterAt(wordEndOffset) == ' ';
- float wordWidth;
- if (includeEndSpace)
- wordWidth = textWidth(textRenderer, wordStartOffset, wordLength + 1, lineWidth.committedWidth(), style) - wordTrailingSpaceWidth;
- else
- wordWidth = textWidth(textRenderer, wordStartOffset, wordLength, lineWidth.committedWidth(), style);
+ bool measureWithEndSpace = wordEnd < textLength && text[wordEnd] == ' ';
+ unsigned wordMeasureEnd = measureWithEndSpace ? wordEnd + 1 : wordEnd;
+ float wordWidth = textWidth(textRenderer, text, textLength, wordStart, wordMeasureEnd, lineWidth.committedWidth(), style);
+
+ if (measureWithEndSpace)
+ wordWidth -= wordTrailingSpaceWidth;
+
lineWidth.addUncommittedWidth(wordWidth);
// Move to the next line if the current one is full and we have something on it.
if (!lineWidth.fitsOnLine() && lineWidth.committedWidth())
break;
- if (wordStartOffset > lineEndOffset) {
+ if (wordStart > lineEnd) {
// There were more than one consecutive whitespace.
- ASSERT(previousWasSpaceBetweenWords);
+ ASSERT(wordIsPrecededByWhitespace);
// Include space to the end of the previous run.
lineRuns.last().textLength++;
lineRuns.last().right += wordTrailingSpaceWidth;
// Start a new run on the same line.
- lineRuns.append(Run(wordStartOffset + 1, lineRuns.last().right));
+ lineRuns.append(Run(wordStart + 1, lineRuns.last().right));
}
lineWidth.commit();
lineRuns.last().right = lineWidth.committedWidth();
- lineRuns.last().textLength = wordEndOffset - lineRuns.last().textOffset;
+ lineRuns.last().textLength = wordEnd - lineRuns.last().textOffset;
- lineEndOffset = wordEndOffset;
- wordEndOffset = skipWhitespaces(textRenderer, wordEndOffset, textLength);
+ lineEnd = wordEnd;
+ wordEnd = skipWhitespaces(text, wordEnd, textLength);
if (!lineWidth.fitsOnLine()) {
// The first run on the line overflows.
@@ -318,7 +325,7 @@
break;
}
}
- if (lineStartOffset == lineEndOffset)
+ if (lineStart == lineEnd)
continue;
adjustRunOffsets(lineRuns, textAlign, lineWidth.committedWidth(), lineWidth.availableWidth());
@@ -329,7 +336,21 @@
runs.last().isEndOfLine = true;
++lineCount;
}
+}
+std::unique_ptr<Layout> create(RenderBlockFlow& flow)
+{
+ Layout::RunVector runs;
+ unsigned lineCount = 0;
+
+ RenderText& textRenderer = toRenderText(*flow.firstChild());
+ ASSERT(!textRenderer.firstTextBox());
+
+ if (textRenderer.is8Bit())
+ createTextRuns<LChar>(runs, lineCount, flow, textRenderer);
+ else
+ createTextRuns<UChar>(runs, lineCount, flow, textRenderer);
+
textRenderer.clearNeedsLayout();
return Layout::create(runs, lineCount);
Modified: trunk/Source/WebCore/rendering/break_lines.cpp (158917 => 158918)
--- trunk/Source/WebCore/rendering/break_lines.cpp 2013-11-08 12:16:33 UTC (rev 158917)
+++ trunk/Source/WebCore/rendering/break_lines.cpp 2013-11-08 12:53:19 UTC (rev 158918)
@@ -38,24 +38,6 @@
namespace WebCore {
-template<bool treatNoBreakSpaceAsBreak>
-static inline bool isBreakableSpace(UChar ch)
-{
- switch (ch) {
- case ' ':
- case '\n':
- case '\t':
- return true;
- case noBreakSpace:
- return treatNoBreakSpaceAsBreak;
- default:
- return false;
- }
-}
-
-static const UChar asciiLineBreakTableFirstChar = '!';
-static const UChar asciiLineBreakTableLastChar = 127;
-
// Pack 8 bits into one byte
#define B(a, b, c, d, e, f, g, h) \
((a) | ((b) << 1) | ((c) << 2) | ((d) << 3) | ((e) << 4) | ((f) << 5) | ((g) << 6) | ((h) << 7))
@@ -73,7 +55,7 @@
// - after '-' and '?' (backward-compatible, and compatible with Internet Explorer).
// Please refer to <https://bugs.webkit.org/show_bug.cgi?id=37698> for line breaking matrixes of different browsers
// and the ICU standard.
-static const unsigned char asciiLineBreakTable[][(asciiLineBreakTableLastChar - asciiLineBreakTableFirstChar) / 8 + 1] = {
+const unsigned char asciiLineBreakTable[][asciiLineBreakTableColumnCount] = {
// ! " # $ % & ' ( ) * + , - . / 0 1-8 9 : ; < = > ? @ A-X Y Z [ \ ] ^ _ ` a-x y z { | } ~ DEL
{ B(0, 0, 0, 0, 0, 0, 0, 1), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 1, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0) }, // !
{ B(0, 0, 0, 0, 0, 0, 0, 1), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 1, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0) }, // "
@@ -120,85 +102,4 @@
COMPILE_ASSERT(WTF_ARRAY_LENGTH(asciiLineBreakTable) == asciiLineBreakTableLastChar - asciiLineBreakTableFirstChar + 1, TestLineBreakTableConsistency);
-static inline bool shouldBreakAfter(UChar lastCh, UChar ch, UChar nextCh)
-{
- // Don't allow line breaking between '-' and a digit if the '-' may mean a minus sign in the context,
- // while allow breaking in 'ABCD-1234' and '1234-5678' which may be in long URLs.
- if (ch == '-' && isASCIIDigit(nextCh))
- return isASCIIAlphanumeric(lastCh);
-
- // If both ch and nextCh are ASCII characters, use a lookup table for enhanced speed and for compatibility
- // with other browsers (see comments for asciiLineBreakTable for details).
- if (ch >= asciiLineBreakTableFirstChar && ch <= asciiLineBreakTableLastChar
- && nextCh >= asciiLineBreakTableFirstChar && nextCh <= asciiLineBreakTableLastChar) {
- const unsigned char* tableRow = asciiLineBreakTable[ch - asciiLineBreakTableFirstChar];
- int nextChIndex = nextCh - asciiLineBreakTableFirstChar;
- return tableRow[nextChIndex / 8] & (1 << (nextChIndex % 8));
- }
- // Otherwise defer to the Unicode algorithm by returning false.
- return false;
-}
-
-template<bool treatNoBreakSpaceAsBreak>
-inline bool needsLineBreakIterator(UChar ch)
-{
- if (treatNoBreakSpaceAsBreak)
- return ch > asciiLineBreakTableLastChar;
- return ch > asciiLineBreakTableLastChar && ch != noBreakSpace;
-}
-
-template<typename CharacterType, bool treatNoBreakSpaceAsBreak>
-static inline int nextBreakablePosition(LazyLineBreakIterator& lazyBreakIterator, const CharacterType* str, unsigned length, int pos)
-{
- int len = static_cast<int>(length);
- int nextBreak = -1;
-
- CharacterType lastLastCh = pos > 1 ? str[pos - 2] : static_cast<CharacterType>(lazyBreakIterator.secondToLastCharacter());
- CharacterType lastCh = pos > 0 ? str[pos - 1] : static_cast<CharacterType>(lazyBreakIterator.lastCharacter());
- unsigned priorContextLength = lazyBreakIterator.priorContextLength();
- for (int i = pos; i < len; i++) {
- CharacterType ch = str[i];
-
- if (isBreakableSpace<treatNoBreakSpaceAsBreak>(ch) || shouldBreakAfter(lastLastCh, lastCh, ch))
- return i;
-
- if (needsLineBreakIterator<treatNoBreakSpaceAsBreak>(ch) || needsLineBreakIterator<treatNoBreakSpaceAsBreak>(lastCh)) {
- if (nextBreak < i) {
- // Don't break if positioned at start of primary context and there is no prior context.
- if (i || priorContextLength) {
- TextBreakIterator* breakIterator = lazyBreakIterator.get(priorContextLength);
- if (breakIterator) {
- nextBreak = textBreakFollowing(breakIterator, i - 1 + priorContextLength);
- if (nextBreak >= 0)
- nextBreak -= priorContextLength;
- }
- }
- }
- if (i == nextBreak && !isBreakableSpace<treatNoBreakSpaceAsBreak>(lastCh))
- return i;
- }
-
- lastLastCh = lastCh;
- lastCh = ch;
- }
-
- return len;
-}
-
-int nextBreakablePositionIgnoringNBSP(LazyLineBreakIterator& lazyBreakIterator, int pos)
-{
- String string = lazyBreakIterator.string();
- if (string.is8Bit())
- return nextBreakablePosition<LChar, false>(lazyBreakIterator, string.characters8(), string.length(), pos);
- return nextBreakablePosition<UChar, false>(lazyBreakIterator, string.characters16(), string.length(), pos);
-}
-
-int nextBreakablePosition(LazyLineBreakIterator& lazyBreakIterator, int pos)
-{
- String string = lazyBreakIterator.string();
- if (string.is8Bit())
- return nextBreakablePosition<LChar, true>(lazyBreakIterator, string.characters8(), string.length(), pos);
- return nextBreakablePosition<UChar, true>(lazyBreakIterator, string.characters16(), string.length(), pos);
-}
-
} // namespace WebCore
Modified: trunk/Source/WebCore/rendering/break_lines.h (158917 => 158918)
--- trunk/Source/WebCore/rendering/break_lines.h 2013-11-08 12:16:33 UTC (rev 158917)
+++ trunk/Source/WebCore/rendering/break_lines.h 2013-11-08 12:53:19 UTC (rev 158918)
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2005 Apple Computer, Inc.
+ * Copyright (C) 2005, 2007, 2010, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Google 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
@@ -21,15 +22,118 @@
#ifndef break_lines_h
#define break_lines_h
+#include "TextBreakIterator.h"
+#include <wtf/ASCIICType.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/unicode/CharacterNames.h>
#include <wtf/unicode/Unicode.h>
namespace WebCore {
-class LazyLineBreakIterator;
+static const UChar asciiLineBreakTableFirstChar = '!';
+static const UChar asciiLineBreakTableLastChar = 127;
+static const unsigned asciiLineBreakTableColumnCount = (asciiLineBreakTableLastChar - asciiLineBreakTableFirstChar) / 8 + 1;
+extern const unsigned char asciiLineBreakTable[][asciiLineBreakTableColumnCount];
+
int nextBreakablePositionIgnoringNBSP(LazyLineBreakIterator&, int pos);
int nextBreakablePosition(LazyLineBreakIterator&, int pos);
+template<bool treatNoBreakSpaceAsBreak>
+static inline bool isBreakableSpace(UChar ch)
+{
+ switch (ch) {
+ case ' ':
+ case '\n':
+ case '\t':
+ return true;
+ case noBreakSpace:
+ return treatNoBreakSpaceAsBreak;
+ default:
+ return false;
+ }
+}
+
+inline bool shouldBreakAfter(UChar lastCh, UChar ch, UChar nextCh)
+{
+ // Don't allow line breaking between '-' and a digit if the '-' may mean a minus sign in the context,
+ // while allow breaking in 'ABCD-1234' and '1234-5678' which may be in long URLs.
+ if (ch == '-' && isASCIIDigit(nextCh))
+ return isASCIIAlphanumeric(lastCh);
+
+ // If both ch and nextCh are ASCII characters, use a lookup table for enhanced speed and for compatibility
+ // with other browsers (see comments for asciiLineBreakTable for details).
+ if (ch >= asciiLineBreakTableFirstChar && ch <= asciiLineBreakTableLastChar && nextCh >= asciiLineBreakTableFirstChar && nextCh <= asciiLineBreakTableLastChar) {
+ const unsigned char* tableRow = asciiLineBreakTable[ch - asciiLineBreakTableFirstChar];
+ int nextChIndex = nextCh - asciiLineBreakTableFirstChar;
+ return tableRow[nextChIndex / 8] & (1 << (nextChIndex % 8));
+ }
+ // Otherwise defer to the Unicode algorithm by returning false.
+ return false;
+}
+
+template<bool treatNoBreakSpaceAsBreak>
+inline bool needsLineBreakIterator(UChar ch)
+{
+ if (treatNoBreakSpaceAsBreak)
+ return ch > asciiLineBreakTableLastChar;
+ return ch > asciiLineBreakTableLastChar && ch != noBreakSpace;
+}
+
+template<typename CharacterType, bool treatNoBreakSpaceAsBreak>
+inline int nextBreakablePosition(LazyLineBreakIterator& lazyBreakIterator, const CharacterType* str, unsigned length, int pos)
+{
+ int len = static_cast<int>(length);
+ int nextBreak = -1;
+
+ CharacterType lastLastCh = pos > 1 ? str[pos - 2] : static_cast<CharacterType>(lazyBreakIterator.secondToLastCharacter());
+ CharacterType lastCh = pos > 0 ? str[pos - 1] : static_cast<CharacterType>(lazyBreakIterator.lastCharacter());
+ unsigned priorContextLength = lazyBreakIterator.priorContextLength();
+ for (int i = pos; i < len; i++) {
+ CharacterType ch = str[i];
+
+ if (isBreakableSpace<treatNoBreakSpaceAsBreak>(ch) || shouldBreakAfter(lastLastCh, lastCh, ch))
+ return i;
+
+ if (needsLineBreakIterator<treatNoBreakSpaceAsBreak>(ch) || needsLineBreakIterator<treatNoBreakSpaceAsBreak>(lastCh)) {
+ if (nextBreak < i) {
+ // Don't break if positioned at start of primary context and there is no prior context.
+ if (i || priorContextLength) {
+ TextBreakIterator* breakIterator = lazyBreakIterator.get(priorContextLength);
+ if (breakIterator) {
+ nextBreak = textBreakFollowing(breakIterator, i - 1 + priorContextLength);
+ if (nextBreak >= 0)
+ nextBreak -= priorContextLength;
+ }
+ }
+ }
+ if (i == nextBreak && !isBreakableSpace<treatNoBreakSpaceAsBreak>(lastCh))
+ return i;
+ }
+
+ lastLastCh = lastCh;
+ lastCh = ch;
+ }
+
+ return len;
+}
+
+inline int nextBreakablePositionIgnoringNBSP(LazyLineBreakIterator& lazyBreakIterator, int pos)
+{
+ String string = lazyBreakIterator.string();
+ if (string.is8Bit())
+ return nextBreakablePosition<LChar, false>(lazyBreakIterator, string.characters8(), string.length(), pos);
+ return nextBreakablePosition<UChar, false>(lazyBreakIterator, string.characters16(), string.length(), pos);
+}
+
+inline int nextBreakablePosition(LazyLineBreakIterator& lazyBreakIterator, int pos)
+{
+ String string = lazyBreakIterator.string();
+ if (string.is8Bit())
+ return nextBreakablePosition<LChar, true>(lazyBreakIterator, string.characters8(), string.length(), pos);
+ return nextBreakablePosition<UChar, true>(lazyBreakIterator, string.characters16(), string.length(), pos);
+}
+
inline bool isBreakable(LazyLineBreakIterator& lazyBreakIterator, int pos, int& nextBreakable, bool breakNBSP)
{
if (pos > nextBreakable) {