TextBreakIteratorICU.cpp [plain text]
#include "config.h"
#include "TextBreakIterator.h"
#include "PlatformString.h"
#include "TextBreakIteratorInternalICU.h"
#include <unicode/ubrk.h>
#include <wtf/Assertions.h>
namespace WebCore {
static TextBreakIterator* setUpIterator(bool& createdIterator, TextBreakIterator*& iterator,
UBreakIteratorType type, const UChar* string, int length)
{
if (!string)
return 0;
if (!createdIterator) {
UErrorCode openStatus = U_ZERO_ERROR;
iterator = reinterpret_cast<TextBreakIterator*>(ubrk_open(type, currentTextBreakLocaleID(), 0, 0, &openStatus));
createdIterator = true;
ASSERT_WITH_MESSAGE(U_SUCCESS(openStatus), "ICU could not open a break iterator: %s (%d)", u_errorName(openStatus), openStatus);
}
if (!iterator)
return 0;
UErrorCode setTextStatus = U_ZERO_ERROR;
ubrk_setText(reinterpret_cast<UBreakIterator*>(iterator), string, length, &setTextStatus);
if (U_FAILURE(setTextStatus))
return 0;
return iterator;
}
TextBreakIterator* characterBreakIterator(const UChar* string, int length)
{
static bool createdCharacterBreakIterator = false;
static TextBreakIterator* staticCharacterBreakIterator;
return setUpIterator(createdCharacterBreakIterator,
staticCharacterBreakIterator, UBRK_CHARACTER, string, length);
}
TextBreakIterator* wordBreakIterator(const UChar* string, int length)
{
static bool createdWordBreakIterator = false;
static TextBreakIterator* staticWordBreakIterator;
return setUpIterator(createdWordBreakIterator,
staticWordBreakIterator, UBRK_WORD, string, length);
}
TextBreakIterator* lineBreakIterator(const UChar* string, int length)
{
static bool createdLineBreakIterator = false;
static TextBreakIterator* staticLineBreakIterator;
return setUpIterator(createdLineBreakIterator,
staticLineBreakIterator, UBRK_LINE, string, length);
}
TextBreakIterator* sentenceBreakIterator(const UChar* string, int length)
{
static bool createdSentenceBreakIterator = false;
static TextBreakIterator* staticSentenceBreakIterator;
return setUpIterator(createdSentenceBreakIterator,
staticSentenceBreakIterator, UBRK_SENTENCE, string, length);
}
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);
}
#ifndef BUILDING_ON_TIGER
static TextBreakIterator* setUpIteratorWithRules(bool& createdIterator, TextBreakIterator*& iterator,
const char* breakRules, const UChar* string, int length)
{
if (!string)
return 0;
if (!createdIterator) {
UParseError parseStatus;
UErrorCode openStatus = U_ZERO_ERROR;
String rules(breakRules);
iterator = reinterpret_cast<TextBreakIterator*>(ubrk_openRules(rules.characters(), rules.length(), 0, 0, &parseStatus, &openStatus));
createdIterator = true;
ASSERT_WITH_MESSAGE(U_SUCCESS(openStatus), "ICU could not open a break iterator: %s (%d)", u_errorName(openStatus), openStatus);
}
if (!iterator)
return 0;
UErrorCode setTextStatus = U_ZERO_ERROR;
ubrk_setText(reinterpret_cast<UBreakIterator*>(iterator), string, length, &setTextStatus);
if (U_FAILURE(setTextStatus))
return 0;
return iterator;
}
#endif // BUILDING_ON_TIGER
TextBreakIterator* cursorMovementIterator(const UChar* string, int length)
{
#ifdef BUILDING_ON_TIGER
return characterBreakIterator(string, length);
#else
static const char* kRules =
"$CR = [\\p{Grapheme_Cluster_Break = CR}];"
"$LF = [\\p{Grapheme_Cluster_Break = LF}];"
"$Control = [\\p{Grapheme_Cluster_Break = Control}];"
"$VoiceMarks = [\\uFF9E\\uFF9F];" "$Extend = [\\p{Grapheme_Cluster_Break = Extend} $VoiceMarks - [\\u0E30 \\u0E32 \\u0E45 \\u0EB0 \\u0EB2]];"
"$SpacingMark = [[\\p{General_Category = Spacing Mark}] - $Extend];"
"$L = [\\p{Grapheme_Cluster_Break = L}];"
"$V = [\\p{Grapheme_Cluster_Break = V}];"
"$T = [\\p{Grapheme_Cluster_Break = T}];"
"$LV = [\\p{Grapheme_Cluster_Break = LV}];"
"$LVT = [\\p{Grapheme_Cluster_Break = LVT}];"
"$Hin0 = [\\u0905-\\u0939];" "$HinV = \\u094D;" "$Hin1 = [\\u0915-\\u0939];" "$Ben0 = [\\u0985-\\u09B9];" "$BenV = \\u09CD;" "$Ben1 = [\\u0995-\\u09B9];" "$Pan0 = [\\u0A05-\\u0A39];" "$PanV = \\u0A4D;" "$Pan1 = [\\u0A15-\\u0A39];" "$Guj0 = [\\u0A85-\\u0AB9];" "$GujV = \\u0ACD;" "$Guj1 = [\\u0A95-\\u0AB9];" "$Ori0 = [\\u0B05-\\u0B39];" "$OriV = \\u0B4D;" "$Ori1 = [\\u0B15-\\u0B39];" "$Tel0 = [\\u0C05-\\u0C39];" "$TelV = \\u0C4D;" "$Tel1 = [\\u0C14-\\u0C39];" "$Kan0 = [\\u0C85-\\u0CB9];" "$KanV = \\u0CCD;" "$Kan1 = [\\u0C95-\\u0CB9];" "$Mal0 = [\\u0D05-\\u0D39];" "$MalV = \\u0D4D;" "$Mal1 = [\\u0D15-\\u0D39];" "!!chain;"
"!!forward;"
"$CR $LF;"
"$L ($L | $V | $LV | $LVT);"
"($LV | $V) ($V | $T);"
"($LVT | $T) $T;"
"[^$Control $CR $LF] $Extend;"
"[^$Control $CR $LF] $SpacingMark;"
"$Hin0 $HinV $Hin1;" "$Ben0 $BenV $Ben1;" "$Pan0 $PanV $Pan1;" "$Guj0 $GujV $Guj1;" "$Ori0 $OriV $Ori1;" "$Tel0 $TelV $Tel1;" "$Kan0 $KanV $Kan1;" "$Mal0 $MalV $Mal1;" "!!reverse;"
"$LF $CR;"
"($L | $V | $LV | $LVT) $L;"
"($V | $T) ($LV | $V);"
"$T ($LVT | $T);"
"$Extend [^$Control $CR $LF];"
"$SpacingMark [^$Control $CR $LF];"
"$Hin1 $HinV $Hin0;" "$Ben1 $BenV $Ben0;" "$Pan1 $PanV $Pan0;" "$Guj1 $GujV $Guj0;" "$Ori1 $OriV $Ori0;" "$Tel1 $TelV $Tel0;" "$Kan1 $KanV $Kan0;" "$Mal1 $MalV $Mal0;" "!!safe_reverse;"
"!!safe_forward;";
static bool createdCursorMovementIterator = false;
static TextBreakIterator* staticCursorMovementIterator;
return setUpIteratorWithRules(createdCursorMovementIterator, staticCursorMovementIterator, kRules, string, length);
#endif // BUILDING_ON_TIGER
}
}