Skip to content
Permalink
Browse files
Stop reinterpret_casting UBreakIterators to the undefined type TextBr…
…eakIterator

https://bugs.webkit.org/show_bug.cgi?id=165931

Source/WebCore:

Reviewed by Alex Christensen.

No new tests because there is no behavior change.

* dom/CharacterData.cpp:
(WebCore::CharacterData::parserAppendData):
* editing/TextCheckingHelper.cpp:
(WebCore::findMisspellings):
* editing/VisibleUnits.cpp:
(WebCore::wordBreakIteratorForMinOffsetBoundary):
(WebCore::wordBreakIteratorForMaxOffsetBoundary):
(WebCore::isLogicalStartOfWord):
(WebCore::islogicalEndOfWord):
(WebCore::visualWordPosition):
(WebCore::startSentenceBoundary):
(WebCore::endSentenceBoundary):
(WebCore::previousSentencePositionBoundary):
(WebCore::nextSentencePositionBoundary):
* html/HTMLInputElement.cpp:
* html/HTMLTextAreaElement.cpp:
* html/InputType.cpp:
* html/TextFieldInputType.cpp:
* html/TextInputType.cpp:
* platform/graphics/StringTruncator.cpp:
(WebCore::textBreakAtOrPreceding):
(WebCore::boundedTextBreakFollowing):
(WebCore::rightClipToWordBuffer):
* platform/graphics/mac/ComplexTextController.cpp:
(WebCore::ComplexTextController::offsetForPosition):
* platform/text/TextBoundaries.cpp:
(WebCore::findNextWordFromIndex):
(WebCore::findWordBoundary):
(WebCore::findEndWordBoundary):
* platform/text/mac/TextBoundaries.mm:
(WebCore::findNextWordFromIndex):
* rendering/BreakLines.h:
(WebCore::nextBreakablePositionNonLoosely):
(WebCore::nextBreakablePositionLoosely):
* rendering/RenderBlock.cpp:
* rendering/RenderText.cpp:
(WebCore::makeCapitalized):
(WebCore::RenderText::previousOffset):
(WebCore::RenderText::previousOffsetForBackwardDeletion):
(WebCore::RenderText::nextOffset):
* rendering/SimpleLineLayoutTextFragmentIterator.h:
* rendering/line/LineBreaker.h:

Source/WebKit/ios:

Reviewed by Alex Christensen.

* Misc/WebUIKitSupport.mm:

Source/WTF:

We have a class declaration for TextBreakIterator but no definition for it. When we
create an ICU UBreakIterator, we immediately reinterpret_cast it to this undefined
type, and pass it around our code inside WebCore. Then, whenever we want to actually
use this iterator, we reinterpret_cast it back to UBreakIterator. This is likely due
to some ports historically implementing breaking interators on top of other libraries
other than ICU; however, now, all ports use ICU. Because this internal type is not
helpful and just adds confusion, we should just call our breaking iterators what
they are: UBreakIterators.

This patch is a mechanical replacement of TextBreakIterator to UBreakIterator and
removes the functions we were calling which pass through directly to ubrk_*().

Reviewed by Alex Christensen.

* wtf/text/LineBreakIteratorPoolICU.h:
(WTF::LineBreakIteratorPool::take):
(WTF::LineBreakIteratorPool::put):
* wtf/text/StringView.cpp:
(WTF::StringView::GraphemeClusters::Iterator::Impl::computeIndexEnd):
* wtf/text/TextBreakIterator.cpp:
(WTF::initializeIterator):
(WTF::initializeIteratorWithRules):
(WTF::setTextForIterator):
(WTF::setContextAwareTextForIterator):
(WTF::wordBreakIterator):
(WTF::sentenceBreakIterator):
(WTF::cursorMovementIterator):
(WTF::acquireLineBreakIterator):
(WTF::releaseLineBreakIterator):
(WTF::openLineBreakIterator):
(WTF::closeLineBreakIterator):
(WTF::getNonSharedCharacterBreakIterator):
(WTF::cacheNonSharedCharacterBreakIterator):
(WTF::isWordTextBreak):
(WTF::numGraphemeClusters):
(WTF::numCharactersInGraphemeClusters):
(WTF::textBreakFirst): Deleted.
(WTF::textBreakLast): Deleted.
(WTF::textBreakNext): Deleted.
(WTF::textBreakPrevious): Deleted.
(WTF::textBreakPreceding): Deleted.
(WTF::textBreakFollowing): Deleted.
(WTF::textBreakCurrent): Deleted.
(WTF::isTextBreak): Deleted.
* wtf/text/TextBreakIterator.h:
(WTF::LazyLineBreakIterator::lastCharacter):
(WTF::LazyLineBreakIterator::secondToLastCharacter):
(WTF::LazyLineBreakIterator::setPriorContext):
(WTF::LazyLineBreakIterator::updatePriorContext):
(WTF::LazyLineBreakIterator::resetPriorContext):
(WTF::LazyLineBreakIterator::priorContextLength):
(WTF::LazyLineBreakIterator::get):
(WTF::NonSharedCharacterBreakIterator::operator UBreakIterator*):
(WTF::NonSharedCharacterBreakIterator::operator TextBreakIterator*): Deleted.


Canonical link: https://commits.webkit.org/183543@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@209907 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
litherum committed Dec 16, 2016
1 parent b20b438 commit 0b1bb311d4e9556d9f2ebc60265c550f83772031
Showing with 269 additions and 202 deletions.
  1. +60 −0 Source/WTF/ChangeLog
  2. +1 −1 Source/WTF/wtf/Platform.h
  3. +5 −5 Source/WTF/wtf/text/LineBreakIteratorPoolICU.h
  4. +2 −1 Source/WTF/wtf/text/StringView.cpp
  5. +33 −74 Source/WTF/wtf/text/TextBreakIterator.cpp
  6. +19 −32 Source/WTF/wtf/text/TextBreakIterator.h
  7. +52 −0 Source/WebCore/ChangeLog
  8. +3 −3 Source/WebCore/dom/CharacterData.cpp
  9. +5 −4 Source/WebCore/editing/TextCheckingHelper.cpp
  10. +15 −14 Source/WebCore/editing/VisibleUnits.cpp
  11. +0 −1 Source/WebCore/html/HTMLInputElement.cpp
  12. +0 −1 Source/WebCore/html/HTMLTextAreaElement.cpp
  13. +1 −1 Source/WebCore/html/InputType.cpp
  14. +0 −1 Source/WebCore/html/TextFieldInputType.cpp
  15. +0 −1 Source/WebCore/html/TextInputType.cpp
  16. +9 −8 Source/WebCore/platform/graphics/StringTruncator.cpp
  17. +8 −7 Source/WebCore/platform/graphics/mac/ComplexTextController.cpp
  18. +15 −14 Source/WebCore/platform/text/TextBoundaries.cpp
  19. +4 −3 Source/WebCore/platform/text/enchant/TextCheckerEnchant.cpp
  20. +3 −3 Source/WebCore/platform/text/mac/TextBoundaries.mm
  21. +6 −6 Source/WebCore/rendering/BreakLines.h
  22. +0 −1 Source/WebCore/rendering/RenderBlock.cpp
  23. +10 −10 Source/WebCore/rendering/RenderText.cpp
  24. +0 −1 Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.h
  25. +0 −1 Source/WebCore/rendering/line/LineBreaker.h
  26. +9 −0 Source/WebKit/ios/ChangeLog
  27. +0 −1 Source/WebKit/ios/Misc/WebUIKitSupport.mm
  28. +3 −3 Source/WebKit2/UIProcess/efl/TextCheckerEfl.cpp
  29. +6 −5 Source/WebKit2/UIProcess/gtk/TextCheckerGtk.cpp
@@ -1,3 +1,63 @@
2016-12-15 Myles C. Maxfield <mmaxfield@apple.com>

Stop reinterpret_casting UBreakIterators to the undefined type TextBreakIterator
https://bugs.webkit.org/show_bug.cgi?id=165931

We have a class declaration for TextBreakIterator but no definition for it. When we
create an ICU UBreakIterator, we immediately reinterpret_cast it to this undefined
type, and pass it around our code inside WebCore. Then, whenever we want to actually
use this iterator, we reinterpret_cast it back to UBreakIterator. This is likely due
to some ports historically implementing breaking interators on top of other libraries
other than ICU; however, now, all ports use ICU. Because this internal type is not
helpful and just adds confusion, we should just call our breaking iterators what
they are: UBreakIterators.

This patch is a mechanical replacement of TextBreakIterator to UBreakIterator and
removes the functions we were calling which pass through directly to ubrk_*().

Reviewed by Alex Christensen.

* wtf/text/LineBreakIteratorPoolICU.h:
(WTF::LineBreakIteratorPool::take):
(WTF::LineBreakIteratorPool::put):
* wtf/text/StringView.cpp:
(WTF::StringView::GraphemeClusters::Iterator::Impl::computeIndexEnd):
* wtf/text/TextBreakIterator.cpp:
(WTF::initializeIterator):
(WTF::initializeIteratorWithRules):
(WTF::setTextForIterator):
(WTF::setContextAwareTextForIterator):
(WTF::wordBreakIterator):
(WTF::sentenceBreakIterator):
(WTF::cursorMovementIterator):
(WTF::acquireLineBreakIterator):
(WTF::releaseLineBreakIterator):
(WTF::openLineBreakIterator):
(WTF::closeLineBreakIterator):
(WTF::getNonSharedCharacterBreakIterator):
(WTF::cacheNonSharedCharacterBreakIterator):
(WTF::isWordTextBreak):
(WTF::numGraphemeClusters):
(WTF::numCharactersInGraphemeClusters):
(WTF::textBreakFirst): Deleted.
(WTF::textBreakLast): Deleted.
(WTF::textBreakNext): Deleted.
(WTF::textBreakPrevious): Deleted.
(WTF::textBreakPreceding): Deleted.
(WTF::textBreakFollowing): Deleted.
(WTF::textBreakCurrent): Deleted.
(WTF::isTextBreak): Deleted.
* wtf/text/TextBreakIterator.h:
(WTF::LazyLineBreakIterator::lastCharacter):
(WTF::LazyLineBreakIterator::secondToLastCharacter):
(WTF::LazyLineBreakIterator::setPriorContext):
(WTF::LazyLineBreakIterator::updatePriorContext):
(WTF::LazyLineBreakIterator::resetPriorContext):
(WTF::LazyLineBreakIterator::priorContextLength):
(WTF::LazyLineBreakIterator::get):
(WTF::NonSharedCharacterBreakIterator::operator UBreakIterator*):
(WTF::NonSharedCharacterBreakIterator::operator TextBreakIterator*): Deleted.

2016-12-15 Myles C. Maxfield <mmaxfield@apple.com>

Sort Xcode project files
@@ -1208,7 +1208,7 @@
#endif

#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 101201 && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200
#define HAVE_TOUCH_BAR 1
#define HAVE_TOUCH_BAR 0
#define HAVE_ADVANCED_SPELL_CHECKING 1

#if defined(__LP64__)
@@ -60,11 +60,11 @@ class LineBreakIteratorPool {
return locale;
}

TextBreakIterator* take(const AtomicString& locale, LineBreakIteratorMode mode, bool isCJK)
UBreakIterator* take(const AtomicString& locale, LineBreakIteratorMode mode, bool isCJK)
{
auto localeWithOptionalBreakKeyword = makeLocaleWithBreakKeyword(locale, mode);

TextBreakIterator* iterator = nullptr;
UBreakIterator* iterator = nullptr;
for (size_t i = 0; i < m_pool.size(); ++i) {
if (m_pool[i].first == localeWithOptionalBreakKeyword) {
iterator = m_pool[i].second;
@@ -84,7 +84,7 @@ class LineBreakIteratorPool {
return iterator;
}

void put(TextBreakIterator* iterator)
void put(UBreakIterator* iterator)
{
ASSERT(m_vendedIterators.contains(iterator));
if (m_pool.size() == capacity) {
@@ -97,8 +97,8 @@ class LineBreakIteratorPool {
private:
static constexpr size_t capacity = 4;

Vector<std::pair<AtomicString, TextBreakIterator*>, capacity> m_pool;
HashMap<TextBreakIterator*, AtomicString> m_vendedIterators;
Vector<std::pair<AtomicString, UBreakIterator*>, capacity> m_pool;
HashMap<UBreakIterator*, AtomicString> m_vendedIterators;

friend WTF::ThreadSpecific<LineBreakIteratorPool>::operator LineBreakIteratorPool*();
};
@@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "StringView.h"

#include <mutex>
#include <unicode/ubrk.h>
#include <wtf/HashMap.h>
#include <wtf/Lock.h>
#include <wtf/NeverDestroyed.h>
@@ -131,7 +132,7 @@ class StringView::GraphemeClusters::Iterator::Impl {
return 0;
if (m_index == m_stringView.length())
return m_index;
return textBreakFollowing(m_iterator.value(), m_index);
return ubrk_following(m_iterator.value(), m_index);
}

private:
@@ -38,23 +38,23 @@ namespace WTF {

// Iterator initialization

static TextBreakIterator* initializeIterator(UBreakIteratorType type, const char* locale = currentTextBreakLocaleID())
static UBreakIterator* initializeIterator(UBreakIteratorType type, const char* locale = currentTextBreakLocaleID())
{
UErrorCode openStatus = U_ZERO_ERROR;
TextBreakIterator* iterator = reinterpret_cast<TextBreakIterator*>(ubrk_open(type, locale, 0, 0, &openStatus));
UBreakIterator* iterator = ubrk_open(type, locale, 0, 0, &openStatus);
ASSERT_WITH_MESSAGE(U_SUCCESS(openStatus), "ICU could not open a break iterator: %s (%d)", u_errorName(openStatus), openStatus);
return iterator;
}

#if !PLATFORM(IOS)

static TextBreakIterator* initializeIteratorWithRules(const char* breakRules)
static UBreakIterator* initializeIteratorWithRules(const char* breakRules)
{
UParseError parseStatus;
UErrorCode openStatus = U_ZERO_ERROR;
unsigned length = strlen(breakRules);
auto upconvertedCharacters = StringView(reinterpret_cast<const LChar*>(breakRules), length).upconvertedCharacters();
TextBreakIterator* iterator = reinterpret_cast<TextBreakIterator*>(ubrk_openRules(upconvertedCharacters, length, 0, 0, &parseStatus, &openStatus));
UBreakIterator* iterator = ubrk_openRules(upconvertedCharacters, length, 0, 0, &parseStatus, &openStatus);
ASSERT_WITH_MESSAGE(U_SUCCESS(openStatus), "ICU could not open a break iterator: %s (%d)", u_errorName(openStatus), openStatus);
return iterator;
}
@@ -64,7 +64,7 @@ static TextBreakIterator* initializeIteratorWithRules(const char* breakRules)

// Iterator text setting

static TextBreakIterator* setTextForIterator(TextBreakIterator& iterator, StringView string)
static UBreakIterator* setTextForIterator(UBreakIterator& iterator, StringView string)
{
if (string.is8Bit()) {
UTextWithBuffer textLocal;
@@ -80,7 +80,7 @@ static TextBreakIterator* setTextForIterator(TextBreakIterator& iterator, String
}

UErrorCode setTextStatus = U_ZERO_ERROR;
ubrk_setUText(reinterpret_cast<UBreakIterator*>(&iterator), text, &setTextStatus);
ubrk_setUText(&iterator, text, &setTextStatus);
if (U_FAILURE(setTextStatus)) {
LOG_ERROR("ubrk_setUText failed with status %d", setTextStatus);
return nullptr;
@@ -89,15 +89,15 @@ static TextBreakIterator* setTextForIterator(TextBreakIterator& iterator, String
utext_close(text);
} else {
UErrorCode setTextStatus = U_ZERO_ERROR;
ubrk_setText(reinterpret_cast<UBreakIterator*>(&iterator), string.characters16(), string.length(), &setTextStatus);
ubrk_setText(&iterator, string.characters16(), string.length(), &setTextStatus);
if (U_FAILURE(setTextStatus))
return nullptr;
}

return &iterator;
}

static TextBreakIterator* setContextAwareTextForIterator(TextBreakIterator& iterator, StringView string, const UChar* priorContext, unsigned priorContextLength)
static UBreakIterator* setContextAwareTextForIterator(UBreakIterator& iterator, StringView string, const UChar* priorContext, unsigned priorContextLength)
{
if (string.is8Bit()) {
UTextWithBuffer textLocal;
@@ -113,7 +113,7 @@ static TextBreakIterator* setContextAwareTextForIterator(TextBreakIterator& iter
}

UErrorCode setTextStatus = U_ZERO_ERROR;
ubrk_setUText(reinterpret_cast<UBreakIterator*>(&iterator), text, &setTextStatus);
ubrk_setUText(&iterator, text, &setTextStatus);
if (U_FAILURE(setTextStatus)) {
LOG_ERROR("ubrk_setUText failed with status %d", setTextStatus);
return nullptr;
@@ -131,7 +131,7 @@ static TextBreakIterator* setContextAwareTextForIterator(TextBreakIterator& iter
}

UErrorCode setTextStatus = U_ZERO_ERROR;
ubrk_setUText(reinterpret_cast<UBreakIterator*>(&iterator), text, &setTextStatus);
ubrk_setUText(&iterator, text, &setTextStatus);
if (U_FAILURE(setTextStatus)) {
LOG_ERROR("ubrk_setUText failed with status %d", setTextStatus);
return nullptr;
@@ -146,25 +146,25 @@ static TextBreakIterator* setContextAwareTextForIterator(TextBreakIterator& iter

// Static iterators

TextBreakIterator* wordBreakIterator(StringView string)
UBreakIterator* wordBreakIterator(StringView string)
{
static TextBreakIterator* staticWordBreakIterator = initializeIterator(UBRK_WORD);
static UBreakIterator* staticWordBreakIterator = initializeIterator(UBRK_WORD);
if (!staticWordBreakIterator)
return nullptr;

return setTextForIterator(*staticWordBreakIterator, string);
}

TextBreakIterator* sentenceBreakIterator(StringView string)
UBreakIterator* sentenceBreakIterator(StringView string)
{
static TextBreakIterator* staticSentenceBreakIterator = initializeIterator(UBRK_SENTENCE);
static UBreakIterator* staticSentenceBreakIterator = initializeIterator(UBRK_SENTENCE);
if (!staticSentenceBreakIterator)
return nullptr;

return setTextForIterator(*staticSentenceBreakIterator, string);
}

TextBreakIterator* cursorMovementIterator(StringView string)
UBreakIterator* cursorMovementIterator(StringView string)
{
#if !PLATFORM(IOS)
// This rule set is based on character-break iterator rules of ICU 57
@@ -291,10 +291,10 @@ TextBreakIterator* cursorMovementIterator(StringView string)
"!!safe_reverse;"
"!!safe_forward;";
#endif
static TextBreakIterator* staticCursorMovementIterator = initializeIteratorWithRules(kRules);
static UBreakIterator* staticCursorMovementIterator = initializeIteratorWithRules(kRules);
#else // PLATFORM(IOS)
// Use the special Thai character break iterator for all locales
static TextBreakIterator* staticCursorMovementIterator = initializeIterator(UBRK_CHARACTER, "th");
static UBreakIterator* staticCursorMovementIterator = initializeIterator(UBRK_CHARACTER, "th");
#endif // !PLATFORM(IOS)

if (!staticCursorMovementIterator)
@@ -303,16 +303,16 @@ TextBreakIterator* cursorMovementIterator(StringView string)
return setTextForIterator(*staticCursorMovementIterator, string);
}

TextBreakIterator* acquireLineBreakIterator(StringView string, const AtomicString& locale, const UChar* priorContext, unsigned priorContextLength, LineBreakIteratorMode mode, bool isCJK)
UBreakIterator* acquireLineBreakIterator(StringView string, const AtomicString& locale, const UChar* priorContext, unsigned priorContextLength, LineBreakIteratorMode mode, bool isCJK)
{
TextBreakIterator* iterator = LineBreakIteratorPool::sharedPool().take(locale, mode, isCJK);
UBreakIterator* iterator = LineBreakIteratorPool::sharedPool().take(locale, mode, isCJK);
if (!iterator)
return nullptr;

return setContextAwareTextForIterator(*iterator, string, priorContext, priorContextLength);
}

void releaseLineBreakIterator(TextBreakIterator* iterator)
void releaseLineBreakIterator(UBreakIterator* iterator)
{
ASSERT_ARG(iterator, iterator);

@@ -780,7 +780,7 @@ bool isCJKLocale(const AtomicString& locale)
return false;
}

TextBreakIterator* openLineBreakIterator(const AtomicString& locale, LineBreakIteratorMode mode, bool isCJK)
UBreakIterator* openLineBreakIterator(const AtomicString& locale, LineBreakIteratorMode mode, bool isCJK)
{
UBreakIterator* ubrkIter;
UErrorCode openStatus = U_ZERO_ERROR;
@@ -804,30 +804,30 @@ TextBreakIterator* openLineBreakIterator(const AtomicString& locale, LineBreakIt
return nullptr;
}

return reinterpret_cast<TextBreakIterator*>(ubrkIter);
return ubrkIter;
}

void closeLineBreakIterator(TextBreakIterator*& iterator)
void closeLineBreakIterator(UBreakIterator*& iterator)
{
UBreakIterator* ubrkIter = reinterpret_cast<UBreakIterator*>(iterator);
UBreakIterator* ubrkIter = iterator;
ASSERT(ubrkIter);
ubrk_close(ubrkIter);
iterator = nullptr;
}

static std::atomic<TextBreakIterator*> nonSharedCharacterBreakIterator = ATOMIC_VAR_INIT(nullptr);
static std::atomic<UBreakIterator*> nonSharedCharacterBreakIterator = ATOMIC_VAR_INIT(nullptr);

static inline TextBreakIterator* getNonSharedCharacterBreakIterator()
static inline UBreakIterator* getNonSharedCharacterBreakIterator()
{
if (auto *res = nonSharedCharacterBreakIterator.exchange(nullptr, std::memory_order_acquire))
return res;
return initializeIterator(UBRK_CHARACTER);
}

static inline void cacheNonSharedCharacterBreakIterator(TextBreakIterator* cacheMe)
static inline void cacheNonSharedCharacterBreakIterator(UBreakIterator* cacheMe)
{
if (auto *old = nonSharedCharacterBreakIterator.exchange(cacheMe, std::memory_order_release))
ubrk_close(reinterpret_cast<UBreakIterator*>(old));
ubrk_close(old);
}

NonSharedCharacterBreakIterator::NonSharedCharacterBreakIterator(StringView string)
@@ -848,52 +848,11 @@ NonSharedCharacterBreakIterator::NonSharedCharacterBreakIterator(NonSharedCharac
std::swap(m_iterator, other.m_iterator);
}


// Iterator implemenation.

int textBreakFirst(TextBreakIterator* iterator)
{
return ubrk_first(reinterpret_cast<UBreakIterator*>(iterator));
}

int textBreakLast(TextBreakIterator* iterator)
{
return ubrk_last(reinterpret_cast<UBreakIterator*>(iterator));
}

int textBreakNext(TextBreakIterator* iterator)
{
return ubrk_next(reinterpret_cast<UBreakIterator*>(iterator));
}

int textBreakPrevious(TextBreakIterator* iterator)
{
return ubrk_previous(reinterpret_cast<UBreakIterator*>(iterator));
}

int textBreakPreceding(TextBreakIterator* iterator, int pos)
{
return ubrk_preceding(reinterpret_cast<UBreakIterator*>(iterator), pos);
}

int textBreakFollowing(TextBreakIterator* iterator, int pos)
{
return ubrk_following(reinterpret_cast<UBreakIterator*>(iterator), pos);
}

int textBreakCurrent(TextBreakIterator* iterator)
{
return ubrk_current(reinterpret_cast<UBreakIterator*>(iterator));
}

bool isTextBreak(TextBreakIterator* iterator, int position)
{
return ubrk_isBoundary(reinterpret_cast<UBreakIterator*>(iterator), position);
}

bool isWordTextBreak(TextBreakIterator* iterator)
bool isWordTextBreak(UBreakIterator* iterator)
{
int ruleStatus = ubrk_getRuleStatus(reinterpret_cast<UBreakIterator*>(iterator));
int ruleStatus = ubrk_getRuleStatus(iterator);
return ruleStatus != UBRK_WORD_NONE;
}

@@ -920,7 +879,7 @@ unsigned numGraphemeClusters(StringView string)
}

unsigned numGraphemeClusters = 0;
while (textBreakNext(iterator) != TextBreakDone)
while (ubrk_next(iterator) != UBRK_DONE)
++numGraphemeClusters;
return numGraphemeClusters;
}
@@ -948,10 +907,10 @@ unsigned numCharactersInGraphemeClusters(StringView string, unsigned numGrapheme
}

for (unsigned i = 0; i < numGraphemeClusters; ++i) {
if (textBreakNext(iterator) == TextBreakDone)
if (ubrk_next(iterator) == UBRK_DONE)
return stringLength;
}
return textBreakCurrent(iterator);
return ubrk_current(iterator);
}

} // namespace WTF

0 comments on commit 0b1bb31

Please sign in to comment.