Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Side by Side Diff: Source/platform/text/TextBreakIteratorICU.cpp

Issue 23618052: TextBreakIterator should use the C++ icu API instead of the C one (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Downcast to icu::RuleBasedBreakIterator Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/platform/text/TextBreakIterator.h ('k') | Source/web/ContextMenuClientImpl.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006 Lars Knoll <lars@trolltech.com> 2 * Copyright (C) 2006 Lars Knoll <lars@trolltech.com>
3 * Copyright (C) 2007, 2011, 2012 Apple Inc. All rights reserved. 3 * Copyright (C) 2007, 2011, 2012 Apple Inc. All rights reserved.
4 * 4 *
5 * This library is free software; you can redistribute it and/or 5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public 6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either 7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version. 8 * version 2 of the License, or (at your option) any later version.
9 * 9 *
10 * This library is distributed in the hope that it will be useful, 10 * This library is distributed in the hope that it will be useful,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 WTF_MAKE_NONCOPYABLE(LineBreakIteratorPool); 42 WTF_MAKE_NONCOPYABLE(LineBreakIteratorPool);
43 public: 43 public:
44 static LineBreakIteratorPool& sharedPool() 44 static LineBreakIteratorPool& sharedPool()
45 { 45 {
46 static WTF::ThreadSpecific<LineBreakIteratorPool>* pool = new WTF::Threa dSpecific<LineBreakIteratorPool>; 46 static WTF::ThreadSpecific<LineBreakIteratorPool>* pool = new WTF::Threa dSpecific<LineBreakIteratorPool>;
47 return **pool; 47 return **pool;
48 } 48 }
49 49
50 static PassOwnPtr<LineBreakIteratorPool> create() { return adoptPtr(new Line BreakIteratorPool); } 50 static PassOwnPtr<LineBreakIteratorPool> create() { return adoptPtr(new Line BreakIteratorPool); }
51 51
52 UBreakIterator* take(const AtomicString& locale) 52 icu::BreakIterator* take(const AtomicString& locale)
53 { 53 {
54 UBreakIterator* iterator = 0; 54 icu::BreakIterator* iterator = 0;
55 for (size_t i = 0; i < m_pool.size(); ++i) { 55 for (size_t i = 0; i < m_pool.size(); ++i) {
56 if (m_pool[i].first == locale) { 56 if (m_pool[i].first == locale) {
57 iterator = m_pool[i].second; 57 iterator = m_pool[i].second;
58 m_pool.remove(i); 58 m_pool.remove(i);
59 break; 59 break;
60 } 60 }
61 } 61 }
62 62
63 if (!iterator) { 63 if (!iterator) {
64 UErrorCode openStatus = U_ZERO_ERROR; 64 UErrorCode openStatus = U_ZERO_ERROR;
65 bool localeIsEmpty = locale.isEmpty(); 65 bool localeIsEmpty = locale.isEmpty();
66 iterator = ubrk_open(UBRK_LINE, localeIsEmpty ? currentTextBreakLoca leID() : locale.string().utf8().data(), 0, 0, &openStatus); 66 iterator = icu::BreakIterator::createLineInstance(localeIsEmpty ? ic u::Locale(currentTextBreakLocaleID()) : icu::Locale(locale.string().utf8().data( )), openStatus);
67 // locale comes from a web page and it can be invalid, leading ICU 67 // locale comes from a web page and it can be invalid, leading ICU
68 // to fail, in which case we fall back to the default locale. 68 // to fail, in which case we fall back to the default locale.
69 if (!localeIsEmpty && U_FAILURE(openStatus)) { 69 if (!localeIsEmpty && U_FAILURE(openStatus)) {
70 openStatus = U_ZERO_ERROR; 70 openStatus = U_ZERO_ERROR;
71 iterator = ubrk_open(UBRK_LINE, currentTextBreakLocaleID(), 0, 0 , &openStatus); 71 iterator = icu::BreakIterator::createLineInstance(icu::Locale(cu rrentTextBreakLocaleID()), openStatus);
72 } 72 }
73 73
74 if (U_FAILURE(openStatus)) { 74 if (U_FAILURE(openStatus)) {
75 LOG_ERROR("ubrk_open failed with status %d", openStatus); 75 LOG_ERROR("icu::BreakIterator construction failed with status %d ", openStatus);
76 return 0; 76 return 0;
77 } 77 }
78 } 78 }
79 79
80 ASSERT(!m_vendedIterators.contains(iterator)); 80 ASSERT(!m_vendedIterators.contains(iterator));
81 m_vendedIterators.set(iterator, locale); 81 m_vendedIterators.set(iterator, locale);
82 return iterator; 82 return iterator;
83 } 83 }
84 84
85 void put(UBreakIterator* iterator) 85 void put(icu::BreakIterator* iterator)
86 { 86 {
87 ASSERT_ARG(iterator, m_vendedIterators.contains(iterator)); 87 ASSERT_ARG(iterator, m_vendedIterators.contains(iterator));
88 88
89 if (m_pool.size() == capacity) { 89 if (m_pool.size() == capacity) {
90 ubrk_close(m_pool[0].second); 90 delete(m_pool[0].second);
91 m_pool.remove(0); 91 m_pool.remove(0);
92 } 92 }
93 93
94 m_pool.append(Entry(m_vendedIterators.take(iterator), iterator)); 94 m_pool.append(Entry(m_vendedIterators.take(iterator), iterator));
95 } 95 }
96 96
97 private: 97 private:
98 LineBreakIteratorPool() { } 98 LineBreakIteratorPool() { }
99 99
100 static const size_t capacity = 4; 100 static const size_t capacity = 4;
101 101
102 typedef pair<AtomicString, UBreakIterator*> Entry; 102 typedef pair<AtomicString, icu::BreakIterator*> Entry;
103 typedef Vector<Entry, capacity> Pool; 103 typedef Vector<Entry, capacity> Pool;
104 Pool m_pool; 104 Pool m_pool;
105 HashMap<UBreakIterator*, AtomicString> m_vendedIterators; 105 HashMap<icu::BreakIterator*, AtomicString> m_vendedIterators;
106 106
107 friend WTF::ThreadSpecific<LineBreakIteratorPool>::operator LineBreakIterato rPool*(); 107 friend WTF::ThreadSpecific<LineBreakIteratorPool>::operator LineBreakIterato rPool*();
108 }; 108 };
109 109
110 static TextBreakIterator* ensureIterator(bool& createdIterator, TextBreakIterato r*& iterator, UBreakIteratorType type) 110 static TextBreakIterator* ensureIterator(bool& createdIterator, TextBreakIterato r*& iterator, UBreakIteratorType type)
111 { 111 {
112 if (!createdIterator) { 112 if (!createdIterator) {
113 UErrorCode openStatus = U_ZERO_ERROR; 113 UErrorCode openStatus = U_ZERO_ERROR;
114 iterator = reinterpret_cast<TextBreakIterator*>(ubrk_open(type, currentT extBreakLocaleID(), 0, 0, &openStatus)); 114 iterator = reinterpret_cast<TextBreakIterator*>(ubrk_open(type, currentT extBreakLocaleID(), 0, 0, &openStatus));
115 createdIterator = true; 115 createdIterator = true;
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 if (U_FAILURE(*status)) { 479 if (U_FAILURE(*status)) {
480 ASSERT(!text); 480 ASSERT(!text);
481 return 0; 481 return 0;
482 } 482 }
483 textInit(text, &textUTF16Funcs, string, length, priorContext, priorContextLe ngth); 483 textInit(text, &textUTF16Funcs, string, length, priorContext, priorContextLe ngth);
484 return text; 484 return text;
485 } 485 }
486 486
487 static UText emptyText = UTEXT_INITIALIZER; 487 static UText emptyText = UTEXT_INITIALIZER;
488 488
489 static TextBreakIterator* setUpIterator(bool& createdIterator, TextBreakIterator *& iterator, UBreakIteratorType type, const UChar* string, int length) 489 static TextBreakIterator* wordBreakIterator(const LChar* string, int length)
490 { 490 {
491 if (!string) 491 UErrorCode errorCode = U_ZERO_ERROR;
492 return 0; 492 static TextBreakIterator* breakIter = 0;
493 493 if (!breakIter) {
494 iterator = ensureIterator(createdIterator, iterator, type); 494 breakIter = icu::BreakIterator::createWordInstance(icu::Locale(currentTe xtBreakLocaleID()), errorCode);
495 if (!iterator) 495 ASSERT_WITH_MESSAGE(U_SUCCESS(errorCode), "ICU could not open a break it erator: %s (%d)", u_errorName(errorCode), errorCode);
496 return 0; 496 if (!breakIter)
497 497 return 0;
498 UErrorCode setTextStatus = U_ZERO_ERROR; 498 }
499 ubrk_setText(reinterpret_cast<UBreakIterator*>(iterator), string, length, &s etTextStatus);
500 if (U_FAILURE(setTextStatus))
501 return 0;
502
503 return iterator;
504 }
505
506 static TextBreakIterator* setUpIterator(bool& createdIterator, TextBreakIterator *& iterator, UBreakIteratorType type, const LChar* string, int length)
507 {
508 if (!string)
509 return 0;
510
511 iterator = ensureIterator(createdIterator, iterator, type);
512 if (!iterator)
513 return 0;
514 499
515 UTextWithBuffer textLocal; 500 UTextWithBuffer textLocal;
516 textLocal.text = emptyText; 501 textLocal.text = emptyText;
517 textLocal.text.extraSize = sizeof(textLocal.buffer); 502 textLocal.text.extraSize = sizeof(textLocal.buffer);
518 textLocal.text.pExtra = textLocal.buffer; 503 textLocal.text.pExtra = textLocal.buffer;
519 504
520 UErrorCode openStatus = U_ZERO_ERROR; 505 UErrorCode openStatus = U_ZERO_ERROR;
521 UText* text = textOpenLatin1(&textLocal, string, length, 0, 0, &openStatus); 506 UText* text = textOpenLatin1(&textLocal, string, length, 0, 0, &openStatus);
522 if (U_FAILURE(openStatus)) { 507 if (U_FAILURE(openStatus)) {
523 LOG_ERROR("textOpenLatin1 failed with status %d", openStatus); 508 LOG_ERROR("textOpenLatin1 failed with status %d", openStatus);
524 return 0; 509 return 0;
525 } 510 }
526 511
527 UErrorCode setTextStatus = U_ZERO_ERROR; 512 UErrorCode setTextStatus = U_ZERO_ERROR;
528 ubrk_setUText(reinterpret_cast<UBreakIterator*>(iterator), text, &setTextSta tus); 513 breakIter->setText(text, setTextStatus);
529 if (U_FAILURE(setTextStatus)) { 514 if (U_FAILURE(setTextStatus))
530 LOG_ERROR("ubrk_setUText failed with status %d", setTextStatus); 515 LOG_ERROR("BreakIterator::seText failed with status %d", setTextStatus);
531 // FIXME: Do we need to call utext_close(text) here?
532 return 0;
533 }
534 516
535 utext_close(text); 517 utext_close(text);
536 518
537 return iterator; 519 return breakIter;
538 } 520 }
539 521
540 static TextBreakIterator* wordBreakIterator(const LChar* string, int length) 522 static void setText16(TextBreakIterator* iter, const UChar* string, int length)
541 { 523 {
542 static bool createdWordBreakIterator8 = false; 524 UErrorCode errorCode = U_ZERO_ERROR;
543 static TextBreakIterator* staticWordBreakIterator8; 525 UText uText = UTEXT_INITIALIZER;
544 return setUpIterator(createdWordBreakIterator8, 526 utext_openUChars(&uText, string, length, &errorCode);
545 staticWordBreakIterator8, UBRK_WORD, string, length); 527 if (U_FAILURE(errorCode))
528 return;
529 iter->setText(&uText, errorCode);
546 } 530 }
547 531
548 TextBreakIterator* wordBreakIterator(const UChar* string, int length) 532 TextBreakIterator* wordBreakIterator(const UChar* string, int length)
549 { 533 {
550 static bool createdWordBreakIterator16 = false; 534 UErrorCode errorCode = U_ZERO_ERROR;
551 static TextBreakIterator* staticWordBreakIterator16; 535 static TextBreakIterator* breakIter = 0;
552 return setUpIterator(createdWordBreakIterator16, 536 if (!breakIter) {
553 staticWordBreakIterator16, UBRK_WORD, string, length); 537 breakIter = icu::BreakIterator::createWordInstance(icu::Locale(currentTe xtBreakLocaleID()), errorCode);
538 ASSERT_WITH_MESSAGE(U_SUCCESS(errorCode), "ICU could not open a break it erator: %s (%d)", u_errorName(errorCode), errorCode);
539 if (!breakIter)
540 return 0;
541 }
542 setText16(breakIter, string, length);
543 return breakIter;
554 } 544 }
555 545
556 TextBreakIterator* wordBreakIterator(const String& string, int start, int length ) 546 TextBreakIterator* wordBreakIterator(const String& string, int start, int length )
557 { 547 {
558 if (string.isEmpty()) 548 if (string.isEmpty())
559 return 0; 549 return 0;
560 if (string.is8Bit()) 550 if (string.is8Bit())
561 return wordBreakIterator(string.characters8() + start, length); 551 return wordBreakIterator(string.characters8() + start, length);
562 return wordBreakIterator(string.characters16() + start, length); 552 return wordBreakIterator(string.characters16() + start, length);
563 } 553 }
564 554
565 TextBreakIterator* acquireLineBreakIterator(const LChar* string, int length, con st AtomicString& locale, const UChar* priorContext, unsigned priorContextLength) 555 TextBreakIterator* acquireLineBreakIterator(const LChar* string, int length, con st AtomicString& locale, const UChar* priorContext, unsigned priorContextLength)
566 { 556 {
567 UBreakIterator* iterator = LineBreakIteratorPool::sharedPool().take(locale); 557 TextBreakIterator* iterator = LineBreakIteratorPool::sharedPool().take(local e);
568 if (!iterator) 558 if (!iterator)
569 return 0; 559 return 0;
570 560
571 UTextWithBuffer textLocal; 561 UTextWithBuffer textLocal;
572 textLocal.text = emptyText; 562 textLocal.text = emptyText;
573 textLocal.text.extraSize = sizeof(textLocal.buffer); 563 textLocal.text.extraSize = sizeof(textLocal.buffer);
574 textLocal.text.pExtra = textLocal.buffer; 564 textLocal.text.pExtra = textLocal.buffer;
575 565
576 UErrorCode openStatus = U_ZERO_ERROR; 566 UErrorCode openStatus = U_ZERO_ERROR;
577 UText* text = textOpenLatin1(&textLocal, string, length, priorContext, prior ContextLength, &openStatus); 567 UText* text = textOpenLatin1(&textLocal, string, length, priorContext, prior ContextLength, &openStatus);
578 if (U_FAILURE(openStatus)) { 568 if (U_FAILURE(openStatus)) {
579 LOG_ERROR("textOpenLatin1 failed with status %d", openStatus); 569 LOG_ERROR("textOpenLatin1 failed with status %d", openStatus);
580 return 0; 570 return 0;
581 } 571 }
582 572
583 UErrorCode setTextStatus = U_ZERO_ERROR; 573 UErrorCode setTextStatus = U_ZERO_ERROR;
584 ubrk_setUText(iterator, text, &setTextStatus); 574 iterator->setText(text, setTextStatus);
585 if (U_FAILURE(setTextStatus)) { 575 if (U_FAILURE(setTextStatus)) {
586 // FIXME: Do we need to call utext_close(text) here?
587 LOG_ERROR("ubrk_setUText failed with status %d", setTextStatus); 576 LOG_ERROR("ubrk_setUText failed with status %d", setTextStatus);
588 return 0; 577 return 0;
589 } 578 }
590 579
591 utext_close(text); 580 utext_close(text);
592 581
593 return reinterpret_cast<TextBreakIterator*>(iterator); 582 return iterator;
594 } 583 }
595 584
596 TextBreakIterator* acquireLineBreakIterator(const UChar* string, int length, con st AtomicString& locale, const UChar* priorContext, unsigned priorContextLength) 585 TextBreakIterator* acquireLineBreakIterator(const UChar* string, int length, con st AtomicString& locale, const UChar* priorContext, unsigned priorContextLength)
597 { 586 {
598 UBreakIterator* iterator = LineBreakIteratorPool::sharedPool().take(locale); 587 TextBreakIterator* iterator = LineBreakIteratorPool::sharedPool().take(local e);
599 if (!iterator) 588 if (!iterator)
600 return 0; 589 return 0;
601 590
602 UText textLocal = UTEXT_INITIALIZER; 591 UText textLocal = UTEXT_INITIALIZER;
603 592
604 UErrorCode openStatus = U_ZERO_ERROR; 593 UErrorCode openStatus = U_ZERO_ERROR;
605 UText* text = textOpenUTF16(&textLocal, string, length, priorContext, priorC ontextLength, &openStatus); 594 UText* text = textOpenUTF16(&textLocal, string, length, priorContext, priorC ontextLength, &openStatus);
606 if (U_FAILURE(openStatus)) { 595 if (U_FAILURE(openStatus)) {
607 LOG_ERROR("textOpenUTF16 failed with status %d", openStatus); 596 LOG_ERROR("textOpenUTF16 failed with status %d", openStatus);
608 return 0; 597 return 0;
609 } 598 }
610 599
611 UErrorCode setTextStatus = U_ZERO_ERROR; 600 UErrorCode setTextStatus = U_ZERO_ERROR;
612 ubrk_setUText(iterator, text, &setTextStatus); 601 iterator->setText(text, setTextStatus);
613 if (U_FAILURE(setTextStatus)) { 602 if (U_FAILURE(setTextStatus)) {
614 // FIXME: Do we need to call utext_close(text) here?
615 LOG_ERROR("ubrk_setUText failed with status %d", setTextStatus); 603 LOG_ERROR("ubrk_setUText failed with status %d", setTextStatus);
616 return 0; 604 return 0;
617 } 605 }
618 606
619 utext_close(text); 607 utext_close(text);
620 608
621 return reinterpret_cast<TextBreakIterator*>(iterator); 609 return iterator;
622 } 610 }
623 611
624 void releaseLineBreakIterator(TextBreakIterator* iterator) 612 void releaseLineBreakIterator(TextBreakIterator* iterator)
625 { 613 {
626 ASSERT_ARG(iterator, iterator); 614 ASSERT_ARG(iterator, iterator);
627 615
628 LineBreakIteratorPool::sharedPool().put(reinterpret_cast<UBreakIterator*>(it erator)); 616 LineBreakIteratorPool::sharedPool().put(iterator);
629 } 617 }
630 618
631 static TextBreakIterator* nonSharedCharacterBreakIterator; 619 static TextBreakIterator* nonSharedCharacterBreakIterator;
632 620
633 static inline bool compareAndSwapNonSharedCharacterBreakIterator(TextBreakIterat or* expected, TextBreakIterator* newValue) 621 static inline bool compareAndSwapNonSharedCharacterBreakIterator(TextBreakIterat or* expected, TextBreakIterator* newValue)
634 { 622 {
635 DEFINE_STATIC_LOCAL(Mutex, nonSharedCharacterBreakIteratorMutex, ()); 623 DEFINE_STATIC_LOCAL(Mutex, nonSharedCharacterBreakIteratorMutex, ());
636 MutexLocker locker(nonSharedCharacterBreakIteratorMutex); 624 MutexLocker locker(nonSharedCharacterBreakIteratorMutex);
637 if (nonSharedCharacterBreakIterator != expected) 625 if (nonSharedCharacterBreakIterator != expected)
638 return false; 626 return false;
(...skipping 30 matching lines...) Expand all
669 , m_length(0) 657 , m_length(0)
670 , m_iterator(0) 658 , m_iterator(0)
671 { 659 {
672 createIteratorForBuffer(buffer, length); 660 createIteratorForBuffer(buffer, length);
673 } 661 }
674 662
675 void NonSharedCharacterBreakIterator::createIteratorForBuffer(const UChar* buffe r, unsigned length) 663 void NonSharedCharacterBreakIterator::createIteratorForBuffer(const UChar* buffe r, unsigned length)
676 { 664 {
677 m_iterator = nonSharedCharacterBreakIterator; 665 m_iterator = nonSharedCharacterBreakIterator;
678 bool createdIterator = m_iterator && compareAndSwapNonSharedCharacterBreakIt erator(m_iterator, 0); 666 bool createdIterator = m_iterator && compareAndSwapNonSharedCharacterBreakIt erator(m_iterator, 0);
679 m_iterator = setUpIterator(createdIterator, m_iterator, UBRK_CHARACTER, buff er, length); 667 if (!createdIterator) {
668 UErrorCode errorCode = U_ZERO_ERROR;
669 m_iterator = icu::BreakIterator::createCharacterInstance(icu::Locale(cur rentTextBreakLocaleID()), errorCode);
670 ASSERT_WITH_MESSAGE(U_SUCCESS(errorCode), "ICU could not open a break it erator: %s (%d)", u_errorName(errorCode), errorCode);
671 }
672
673 setText16(m_iterator, buffer, length);
680 } 674 }
681 675
682 NonSharedCharacterBreakIterator::~NonSharedCharacterBreakIterator() 676 NonSharedCharacterBreakIterator::~NonSharedCharacterBreakIterator()
683 { 677 {
684 if (m_is8Bit) 678 if (m_is8Bit)
685 return; 679 return;
686 if (!compareAndSwapNonSharedCharacterBreakIterator(0, m_iterator)) 680 if (!compareAndSwapNonSharedCharacterBreakIterator(0, m_iterator))
687 ubrk_close(reinterpret_cast<UBreakIterator*>(m_iterator)); 681 delete m_iterator;
688 } 682 }
689 683
690 int NonSharedCharacterBreakIterator::next() 684 int NonSharedCharacterBreakIterator::next()
691 { 685 {
692 if (!m_is8Bit) 686 if (!m_is8Bit)
693 return textBreakNext(m_iterator); 687 return m_iterator->next();
694 688
695 if (m_offset >= m_length) 689 if (m_offset >= m_length)
696 return TextBreakDone; 690 return TextBreakDone;
697 691
698 m_offset += clusterLengthStartingAt(m_offset); 692 m_offset += clusterLengthStartingAt(m_offset);
699 return m_offset; 693 return m_offset;
700 } 694 }
701 695
702 int NonSharedCharacterBreakIterator::current() 696 int NonSharedCharacterBreakIterator::current()
703 { 697 {
704 if (!m_is8Bit) 698 if (!m_is8Bit)
705 return textBreakCurrent(m_iterator); 699 return m_iterator->current();
706 return m_offset; 700 return m_offset;
707 } 701 }
708 702
709 bool NonSharedCharacterBreakIterator::isBreak(int offset) const 703 bool NonSharedCharacterBreakIterator::isBreak(int offset) const
710 { 704 {
711 if (!m_is8Bit) 705 if (!m_is8Bit)
712 return isTextBreak(m_iterator, offset); 706 return m_iterator->isBoundary(offset);
713 return !isLFAfterCR(offset); 707 return !isLFAfterCR(offset);
714 } 708 }
715 709
716 int NonSharedCharacterBreakIterator::preceding(int offset) const 710 int NonSharedCharacterBreakIterator::preceding(int offset) const
717 { 711 {
718 if (!m_is8Bit) 712 if (!m_is8Bit)
719 return textBreakPreceding(m_iterator, offset); 713 return m_iterator->preceding(offset);
720 if (offset <= 0) 714 if (offset <= 0)
721 return TextBreakDone; 715 return TextBreakDone;
722 if (isLFAfterCR(offset)) 716 if (isLFAfterCR(offset))
723 return offset - 2; 717 return offset - 2;
724 return offset - 1; 718 return offset - 1;
725 } 719 }
726 720
727 int NonSharedCharacterBreakIterator::following(int offset) const 721 int NonSharedCharacterBreakIterator::following(int offset) const
728 { 722 {
729 if (!m_is8Bit) 723 if (!m_is8Bit)
730 return textBreakFollowing(m_iterator, offset); 724 return m_iterator->following(offset);
731 if (static_cast<unsigned>(offset) >= m_length) 725 if (static_cast<unsigned>(offset) >= m_length)
732 return TextBreakDone; 726 return TextBreakDone;
733 return offset + clusterLengthStartingAt(offset); 727 return offset + clusterLengthStartingAt(offset);
734 } 728 }
735 729
736 TextBreakIterator* sentenceBreakIterator(const UChar* string, int length) 730 TextBreakIterator* sentenceBreakIterator(const UChar* string, int length)
737 { 731 {
738 static bool createdSentenceBreakIterator = false; 732 UErrorCode openStatus = U_ZERO_ERROR;
739 static TextBreakIterator* staticSentenceBreakIterator; 733 static TextBreakIterator* iterator = 0;
740 return setUpIterator(createdSentenceBreakIterator, 734 if (!iterator) {
741 staticSentenceBreakIterator, UBRK_SENTENCE, string, length); 735 iterator = icu::BreakIterator::createSentenceInstance(icu::Locale(curre ntTextBreakLocaleID()), openStatus);
742 } 736 ASSERT_WITH_MESSAGE(U_SUCCESS(openStatus), "ICU could not open a break i terator: %s (%d)", u_errorName(openStatus), openStatus);
737 if (!iterator)
738 return 0;
739 }
743 740
744 int textBreakFirst(TextBreakIterator* iterator) 741 setText16(iterator, string, length);
745 { 742 return iterator;
746 return ubrk_first(reinterpret_cast<UBreakIterator*>(iterator));
747 }
748
749 int textBreakLast(TextBreakIterator* iterator)
750 {
751 return ubrk_last(reinterpret_cast<UBreakIterator*>(iterator));
752 }
753
754 int textBreakNext(TextBreakIterator* iterator)
755 {
756 return ubrk_next(reinterpret_cast<UBreakIterator*>(iterator));
757 }
758
759 int textBreakPrevious(TextBreakIterator* iterator)
760 {
761 return ubrk_previous(reinterpret_cast<UBreakIterator*>(iterator));
762 }
763
764 int textBreakPreceding(TextBreakIterator* iterator, int pos)
765 {
766 return ubrk_preceding(reinterpret_cast<UBreakIterator*>(iterator), pos);
767 }
768
769 int textBreakFollowing(TextBreakIterator* iterator, int pos)
770 {
771 return ubrk_following(reinterpret_cast<UBreakIterator*>(iterator), pos);
772 }
773
774 int textBreakCurrent(TextBreakIterator* iterator)
775 {
776 return ubrk_current(reinterpret_cast<UBreakIterator*>(iterator));
777 }
778
779 bool isTextBreak(TextBreakIterator* iterator, int position)
780 {
781 return ubrk_isBoundary(reinterpret_cast<UBreakIterator*>(iterator), position );
782 } 743 }
783 744
784 bool isWordTextBreak(TextBreakIterator* iterator) 745 bool isWordTextBreak(TextBreakIterator* iterator)
785 { 746 {
786 int ruleStatus = ubrk_getRuleStatus(reinterpret_cast<UBreakIterator*>(iterat or)); 747 icu::RuleBasedBreakIterator* ruleBasedBreakIterator = static_cast<icu::RuleB asedBreakIterator*>(iterator);
748 int ruleStatus = ruleBasedBreakIterator->getRuleStatus();
787 return ruleStatus != UBRK_WORD_NONE; 749 return ruleStatus != UBRK_WORD_NONE;
788 } 750 }
789 751
790 static TextBreakIterator* setUpIteratorWithRules(bool& createdIterator, TextBrea kIterator*& iterator, 752 static TextBreakIterator* setUpIteratorWithRules(const char* breakRules, const U Char* string, int length)
791 const char* breakRules, const UChar* string, int length)
792 { 753 {
793 if (!string) 754 if (!string)
794 return 0; 755 return 0;
795 756
796 if (!createdIterator) { 757 static TextBreakIterator* iterator = 0;
758 if (!iterator) {
797 UParseError parseStatus; 759 UParseError parseStatus;
798 UErrorCode openStatus = U_ZERO_ERROR; 760 UErrorCode openStatus = U_ZERO_ERROR;
799 Vector<UChar> rules; 761 Vector<UChar> rules;
800 String(breakRules).appendTo(rules); 762 String(breakRules).appendTo(rules);
801 iterator = reinterpret_cast<TextBreakIterator*>(ubrk_openRules(rules.dat a(), rules.size(), 0, 0, &parseStatus, &openStatus)); 763
802 createdIterator = true; 764 iterator = new icu::RuleBasedBreakIterator(icu::UnicodeString(rules.data (), rules.size()), parseStatus, openStatus);
803 ASSERT_WITH_MESSAGE(U_SUCCESS(openStatus), "ICU could not open a break i terator: %s (%d)", u_errorName(openStatus), openStatus); 765 ASSERT_WITH_MESSAGE(U_SUCCESS(openStatus), "ICU could not open a break i terator: %s (%d)", u_errorName(openStatus), openStatus);
766 if (!iterator)
767 return 0;
804 } 768 }
805 if (!iterator)
806 return 0;
807 769
808 UErrorCode setTextStatus = U_ZERO_ERROR; 770 setText16(iterator, string, length);
809 ubrk_setText(reinterpret_cast<UBreakIterator*>(iterator), string, length, &s etTextStatus);
810 if (U_FAILURE(setTextStatus))
811 return 0;
812
813 return iterator; 771 return iterator;
814 } 772 }
815 773
816 TextBreakIterator* cursorMovementIterator(const UChar* string, int length) 774 TextBreakIterator* cursorMovementIterator(const UChar* string, int length)
817 { 775 {
818 // This rule set is based on character-break iterator rules of ICU 4.0 776 // This rule set is based on character-break iterator rules of ICU 4.0
819 // <http://source.icu-project.org/repos/icu/icu/tags/release-4-0/source/data /brkitr/char.txt>. 777 // <http://source.icu-project.org/repos/icu/icu/tags/release-4-0/source/data /brkitr/char.txt>.
820 // The major differences from the original ones are listed below: 778 // The major differences from the original ones are listed below:
821 // * Replaced '[\p{Grapheme_Cluster_Break = SpacingMark}]' with '[\p{General _Category = Spacing Mark} - $Extend]' for ICU 3.8 or earlier; 779 // * Replaced '[\p{Grapheme_Cluster_Break = SpacingMark}]' with '[\p{General _Category = Spacing Mark} - $Extend]' for ICU 3.8 or earlier;
822 // * Removed rules that prevent a cursor from moving after prepend character s (Bug 24342); 780 // * Removed rules that prevent a cursor from moving after prepend character s (Bug 24342);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
890 "$Hin1 $HinV $Hin0;" // Devanagari Virama (backward) 848 "$Hin1 $HinV $Hin0;" // Devanagari Virama (backward)
891 "$Ben1 $BenV $Ben0;" // Bengali Virama (backward) 849 "$Ben1 $BenV $Ben0;" // Bengali Virama (backward)
892 "$Pan1 $PanV $Pan0;" // Gurmukhi Virama (backward) 850 "$Pan1 $PanV $Pan0;" // Gurmukhi Virama (backward)
893 "$Guj1 $GujV $Guj0;" // Gujarati Virama (backward) 851 "$Guj1 $GujV $Guj0;" // Gujarati Virama (backward)
894 "$Ori1 $OriV $Ori0;" // Gujarati Virama (backward) 852 "$Ori1 $OriV $Ori0;" // Gujarati Virama (backward)
895 "$Tel1 $TelV $Tel0;" // Telugu Virama (backward) 853 "$Tel1 $TelV $Tel0;" // Telugu Virama (backward)
896 "$Kan1 $KanV $Kan0;" // Kannada Virama (backward) 854 "$Kan1 $KanV $Kan0;" // Kannada Virama (backward)
897 "$Mal1 $MalV $Mal0;" // Malayalam Virama (backward) 855 "$Mal1 $MalV $Mal0;" // Malayalam Virama (backward)
898 "!!safe_reverse;" 856 "!!safe_reverse;"
899 "!!safe_forward;"; 857 "!!safe_forward;";
900 static bool createdCursorMovementIterator = false; 858
901 static TextBreakIterator* staticCursorMovementIterator; 859 return setUpIteratorWithRules(kRules, string, length);
902 return setUpIteratorWithRules(createdCursorMovementIterator, staticCursorMov ementIterator, kRules, string, length);
903 } 860 }
904 861
905 } 862 }
OLDNEW
« no previous file with comments | « Source/platform/text/TextBreakIterator.h ('k') | Source/web/ContextMenuClientImpl.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698