18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2006 Lars Knoll <lars@trolltech.com>
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2007 Apple Inc. All rights reserved.
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version.
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful,
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details.
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB.  If not, write to
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA.
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "TextBreakIterator.h"
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "PlatformString.h"
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "TextBreakIteratorInternalICU.h"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <unicode/ubrk.h>
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/Assertions.h>
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochusing namespace std;
3181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic TextBreakIterator* setUpIterator(bool& createdIterator, TextBreakIterator*& iterator,
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UBreakIteratorType type, const UChar* string, int length)
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!string)
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!createdIterator) {
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        UErrorCode openStatus = U_ZERO_ERROR;
42dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        iterator = reinterpret_cast<TextBreakIterator*>(ubrk_open(type, currentTextBreakLocaleID(), 0, 0, &openStatus));
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        createdIterator = true;
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT_WITH_MESSAGE(U_SUCCESS(openStatus), "ICU could not open a break iterator: %s (%d)", u_errorName(openStatus), openStatus);
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!iterator)
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UErrorCode setTextStatus = U_ZERO_ERROR;
50dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    ubrk_setText(reinterpret_cast<UBreakIterator*>(iterator), string, length, &setTextStatus);
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (U_FAILURE(setTextStatus))
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return iterator;
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectTextBreakIterator* characterBreakIterator(const UChar* string, int length)
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static bool createdCharacterBreakIterator = false;
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static TextBreakIterator* staticCharacterBreakIterator;
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return setUpIterator(createdCharacterBreakIterator,
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        staticCharacterBreakIterator, UBRK_CHARACTER, string, length);
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectTextBreakIterator* wordBreakIterator(const UChar* string, int length)
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static bool createdWordBreakIterator = false;
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static TextBreakIterator* staticWordBreakIterator;
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return setUpIterator(createdWordBreakIterator,
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        staticWordBreakIterator, UBRK_WORD, string, length);
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochstatic bool createdLineBreakIterator = false;
7481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochstatic TextBreakIterator* staticLineBreakIterator;
7581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
7681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochTextBreakIterator* acquireLineBreakIterator(const UChar* string, int length)
7781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
7881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    TextBreakIterator* lineBreakIterator = 0;
7981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!createdLineBreakIterator || staticLineBreakIterator) {
8081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        setUpIterator(createdLineBreakIterator, staticLineBreakIterator, UBRK_LINE, string, length);
8181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        swap(staticLineBreakIterator, lineBreakIterator);
8281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
8381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
8481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!lineBreakIterator) {
8581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        bool createdNewLineBreakIterator = false;
8681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        setUpIterator(createdNewLineBreakIterator, lineBreakIterator, UBRK_LINE, string, length);
8781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
8881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
8981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return lineBreakIterator;
9081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
9181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
9281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid releaseLineBreakIterator(TextBreakIterator* iterator)
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ASSERT(createdLineBreakIterator);
9581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ASSERT(iterator);
9681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
9781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!staticLineBreakIterator)
9881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        staticLineBreakIterator = iterator;
9981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    else
10081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        ubrk_close(reinterpret_cast<UBreakIterator*>(iterator));
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectTextBreakIterator* sentenceBreakIterator(const UChar* string, int length)
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static bool createdSentenceBreakIterator = false;
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static TextBreakIterator* staticSentenceBreakIterator;
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return setUpIterator(createdSentenceBreakIterator,
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        staticSentenceBreakIterator, UBRK_SENTENCE, string, length);
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
111dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockint textBreakFirst(TextBreakIterator* iterator)
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
113dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return ubrk_first(reinterpret_cast<UBreakIterator*>(iterator));
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
116dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockint textBreakLast(TextBreakIterator* iterator)
117643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
118dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return ubrk_last(reinterpret_cast<UBreakIterator*>(iterator));
119643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
120643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
121dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockint textBreakNext(TextBreakIterator* iterator)
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
123dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return ubrk_next(reinterpret_cast<UBreakIterator*>(iterator));
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
126dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockint textBreakPrevious(TextBreakIterator* iterator)
127643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
128dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return ubrk_previous(reinterpret_cast<UBreakIterator*>(iterator));
129643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
130643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
131dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockint textBreakPreceding(TextBreakIterator* iterator, int pos)
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
133dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return ubrk_preceding(reinterpret_cast<UBreakIterator*>(iterator), pos);
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
136dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockint textBreakFollowing(TextBreakIterator* iterator, int pos)
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
138dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return ubrk_following(reinterpret_cast<UBreakIterator*>(iterator), pos);
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
141dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockint textBreakCurrent(TextBreakIterator* iterator)
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
143dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return ubrk_current(reinterpret_cast<UBreakIterator*>(iterator));
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
146dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool isTextBreak(TextBreakIterator* iterator, int position)
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
148dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return ubrk_isBoundary(reinterpret_cast<UBreakIterator*>(iterator), position);
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#ifndef BUILDING_ON_TIGER
1528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic TextBreakIterator* setUpIteratorWithRules(bool& createdIterator, TextBreakIterator*& iterator,
1538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    const char* breakRules, const UChar* string, int length)
1548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
1558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!string)
1568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return 0;
1578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!createdIterator) {
1598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        UParseError parseStatus;
1608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        UErrorCode openStatus = U_ZERO_ERROR;
1618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        String rules(breakRules);
162dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        iterator = reinterpret_cast<TextBreakIterator*>(ubrk_openRules(rules.characters(), rules.length(), 0, 0, &parseStatus, &openStatus));
1638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        createdIterator = true;
1648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        ASSERT_WITH_MESSAGE(U_SUCCESS(openStatus), "ICU could not open a break iterator: %s (%d)", u_errorName(openStatus), openStatus);
1658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
1668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!iterator)
1678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return 0;
1688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    UErrorCode setTextStatus = U_ZERO_ERROR;
170dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    ubrk_setText(reinterpret_cast<UBreakIterator*>(iterator), string, length, &setTextStatus);
1718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (U_FAILURE(setTextStatus))
1728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return 0;
1738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return iterator;
1758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
1768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#endif // BUILDING_ON_TIGER
1778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianTextBreakIterator* cursorMovementIterator(const UChar* string, int length)
1798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
1808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#ifdef BUILDING_ON_TIGER
1818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // ICU 3.2 cannot compile the below rules.
1828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return characterBreakIterator(string, length);
1838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#else
1848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // This rule set is based on character-break iterator rules of ICU 4.0
1858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // <http://source.icu-project.org/repos/icu/icu/tags/release-4-0/source/data/brkitr/char.txt>.
1868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // The major differences from the original ones are listed below:
1878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // * Replaced '[\p{Grapheme_Cluster_Break = SpacingMark}]' with '[\p{General_Category = Spacing Mark} - $Extend]' for ICU 3.8 or earlier;
1888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // * Removed rules that prevent a cursor from moving after prepend characters (Bug 24342);
1898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // * Added rules that prevent a cursor from moving after virama signs of Indic languages except Tamil (Bug 15790), and;
1908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // * Added rules that prevent a cursor from moving before Japanese half-width katakara voiced marks.
1918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    static const char* kRules =
1928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$CR      = [\\p{Grapheme_Cluster_Break = CR}];"
1938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$LF      = [\\p{Grapheme_Cluster_Break = LF}];"
1948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Control = [\\p{Grapheme_Cluster_Break = Control}];"
1958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$VoiceMarks = [\\uFF9E\\uFF9F];"  // Japanese half-width katakana voiced marks
1960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        "$Extend  = [\\p{Grapheme_Cluster_Break = Extend} $VoiceMarks - [\\u0E30 \\u0E32 \\u0E45 \\u0EB0 \\u0EB2]];"
1978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$SpacingMark = [[\\p{General_Category = Spacing Mark}] - $Extend];"
1988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$L       = [\\p{Grapheme_Cluster_Break = L}];"
1998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$V       = [\\p{Grapheme_Cluster_Break = V}];"
2008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$T       = [\\p{Grapheme_Cluster_Break = T}];"
2018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$LV      = [\\p{Grapheme_Cluster_Break = LV}];"
2028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$LVT     = [\\p{Grapheme_Cluster_Break = LVT}];"
2038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Hin0    = [\\u0905-\\u0939];"    // Devanagari Letter A,...,Ha
2048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$HinV    = \\u094D;"              // Devanagari Sign Virama
2058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Hin1    = [\\u0915-\\u0939];"    // Devanagari Letter Ka,...,Ha
2068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Ben0    = [\\u0985-\\u09B9];"    // Bengali Letter A,...,Ha
2078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$BenV    = \\u09CD;"              // Bengali Sign Virama
2088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Ben1    = [\\u0995-\\u09B9];"    // Bengali Letter Ka,...,Ha
2098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Pan0    = [\\u0A05-\\u0A39];"    // Gurmukhi Letter A,...,Ha
2108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$PanV    = \\u0A4D;"              // Gurmukhi Sign Virama
2118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Pan1    = [\\u0A15-\\u0A39];"    // Gurmukhi Letter Ka,...,Ha
2128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Guj0    = [\\u0A85-\\u0AB9];"    // Gujarati Letter A,...,Ha
2138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$GujV    = \\u0ACD;"              // Gujarati Sign Virama
2148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Guj1    = [\\u0A95-\\u0AB9];"    // Gujarati Letter Ka,...,Ha
2158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Ori0    = [\\u0B05-\\u0B39];"    // Oriya Letter A,...,Ha
2168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$OriV    = \\u0B4D;"              // Oriya Sign Virama
2178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Ori1    = [\\u0B15-\\u0B39];"    // Oriya Letter Ka,...,Ha
2188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Tel0    = [\\u0C05-\\u0C39];"    // Telugu Letter A,...,Ha
2198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$TelV    = \\u0C4D;"              // Telugu Sign Virama
2208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Tel1    = [\\u0C14-\\u0C39];"    // Telugu Letter Ka,...,Ha
2218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Kan0    = [\\u0C85-\\u0CB9];"    // Kannada Letter A,...,Ha
2228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$KanV    = \\u0CCD;"              // Kannada Sign Virama
2238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Kan1    = [\\u0C95-\\u0CB9];"    // Kannada Letter A,...,Ha
2248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Mal0    = [\\u0D05-\\u0D39];"    // Malayalam Letter A,...,Ha
2258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$MalV    = \\u0D4D;"              // Malayalam Sign Virama
2268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Mal1    = [\\u0D15-\\u0D39];"    // Malayalam Letter A,...,Ha
2278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "!!chain;"
2288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "!!forward;"
2298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$CR $LF;"
2308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$L ($L | $V | $LV | $LVT);"
2318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "($LV | $V) ($V | $T);"
2328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "($LVT | $T) $T;"
2338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "[^$Control $CR $LF] $Extend;"
2348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "[^$Control $CR $LF] $SpacingMark;"
2358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Hin0 $HinV $Hin1;"               // Devanagari Virama (forward)
2368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Ben0 $BenV $Ben1;"               // Bengali Virama (forward)
2378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Pan0 $PanV $Pan1;"               // Gurmukhi Virama (forward)
2388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Guj0 $GujV $Guj1;"               // Gujarati Virama (forward)
2398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Ori0 $OriV $Ori1;"               // Oriya Virama (forward)
2408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Tel0 $TelV $Tel1;"               // Telugu Virama (forward)
2418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Kan0 $KanV $Kan1;"               // Kannada Virama (forward)
2428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Mal0 $MalV $Mal1;"               // Malayalam Virama (forward)
2438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "!!reverse;"
2448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$LF $CR;"
2458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "($L | $V | $LV | $LVT) $L;"
2468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "($V | $T) ($LV | $V);"
2478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$T ($LVT | $T);"
2488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Extend      [^$Control $CR $LF];"
2498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$SpacingMark [^$Control $CR $LF];"
2508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Hin1 $HinV $Hin0;"               // Devanagari Virama (backward)
2518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Ben1 $BenV $Ben0;"               // Bengali Virama (backward)
2528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Pan1 $PanV $Pan0;"               // Gurmukhi Virama (backward)
2538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Guj1 $GujV $Guj0;"               // Gujarati Virama (backward)
2548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Ori1 $OriV $Ori0;"               // Gujarati Virama (backward)
2558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Tel1 $TelV $Tel0;"               // Telugu Virama (backward)
2568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Kan1 $KanV $Kan0;"               // Kannada Virama (backward)
2578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "$Mal1 $MalV $Mal0;"               // Malayalam Virama (backward)
2588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "!!safe_reverse;"
2598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        "!!safe_forward;";
2608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    static bool createdCursorMovementIterator = false;
2618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    static TextBreakIterator* staticCursorMovementIterator;
2628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return setUpIteratorWithRules(createdCursorMovementIterator, staticCursorMovementIterator, kRules, string, length);
2638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#endif // BUILDING_ON_TIGER
2648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
2658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
267