1/* 2 * Copyright (C) 2006 Lars Knoll <lars@trolltech.com> 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Library General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Library General Public License for more details. 13 * 14 * You should have received a copy of the GNU Library General Public License 15 * along with this library; see the file COPYING.LIB. If not, write to 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * Boston, MA 02110-1301, USA. 18 * 19 */ 20 21#include "config.h" 22#include "TextBreakIterator.h" 23 24#include <QtCore/qtextboundaryfinder.h> 25#include <algorithm> 26#include <qdebug.h> 27 28// #define DEBUG_TEXT_ITERATORS 29#ifdef DEBUG_TEXT_ITERATORS 30#define DEBUG qDebug 31#else 32#define DEBUG if (1) {} else qDebug 33#endif 34 35using namespace std; 36 37namespace WebCore { 38 39#if USE(QT_ICU_TEXT_BREAKING) 40const char* currentTextBreakLocaleID() 41{ 42 return QLocale::system().name().toLatin1(); 43} 44#else 45 class TextBreakIterator : public QTextBoundaryFinder { 46 public: 47 TextBreakIterator(QTextBoundaryFinder::BoundaryType type, const QString& string) 48 : QTextBoundaryFinder(type, string) 49 { } 50 TextBreakIterator() 51 : QTextBoundaryFinder() 52 { } 53 }; 54 55 TextBreakIterator* setUpIterator(TextBreakIterator& iterator, QTextBoundaryFinder::BoundaryType type, const UChar* characters, int length) 56 { 57 if (!characters || !length) 58 return 0; 59 60 if (iterator.isValid() && type == iterator.type() && iterator.string() == QString::fromRawData(reinterpret_cast<const QChar*>(characters), length)) { 61 iterator.toStart(); 62 return &iterator; 63 } 64 65 iterator = TextBreakIterator(type, QString(reinterpret_cast<const QChar*>(characters), length)); 66 return &iterator; 67 } 68 69 TextBreakIterator* wordBreakIterator(const UChar* string, int length) 70 { 71 static TextBreakIterator staticWordBreakIterator; 72 return setUpIterator(staticWordBreakIterator, QTextBoundaryFinder::Word, string, length); 73 } 74 75 TextBreakIterator* characterBreakIterator(const UChar* string, int length) 76 { 77 static TextBreakIterator staticCharacterBreakIterator; 78 return setUpIterator(staticCharacterBreakIterator, QTextBoundaryFinder::Grapheme, string, length); 79 } 80 81 TextBreakIterator* cursorMovementIterator(const UChar* string, int length) 82 { 83 return characterBreakIterator(string, length); 84 } 85 86 static TextBreakIterator* staticLineBreakIterator; 87 88 TextBreakIterator* acquireLineBreakIterator(const UChar* string, int length) 89 { 90 TextBreakIterator* lineBreakIterator = 0; 91 if (staticLineBreakIterator) { 92 setUpIterator(*staticLineBreakIterator, QTextBoundaryFinder::Line, string, length); 93 std::swap(staticLineBreakIterator, lineBreakIterator); 94 } 95 96 if (!lineBreakIterator && string && length) 97 lineBreakIterator = new TextBreakIterator(QTextBoundaryFinder::Line, QString(reinterpret_cast<const QChar*>(string), length)); 98 99 return lineBreakIterator; 100 } 101 102 void releaseLineBreakIterator(TextBreakIterator* iterator) 103 { 104 ASSERT(iterator); 105 106 if (!staticLineBreakIterator) 107 staticLineBreakIterator = iterator; 108 else 109 delete iterator; 110 } 111 112 TextBreakIterator* sentenceBreakIterator(const UChar* string, int length) 113 { 114 static TextBreakIterator staticSentenceBreakIterator; 115 return setUpIterator(staticSentenceBreakIterator, QTextBoundaryFinder::Sentence, string, length); 116 117 } 118 119 int textBreakFirst(TextBreakIterator* bi) 120 { 121 bi->toStart(); 122 DEBUG() << "textBreakFirst" << bi->position(); 123 return bi->position(); 124 } 125 126 int textBreakNext(TextBreakIterator* bi) 127 { 128 int pos = bi->toNextBoundary(); 129 DEBUG() << "textBreakNext" << pos; 130 return pos; 131 } 132 133 int textBreakPreceding(TextBreakIterator* bi, int pos) 134 { 135 bi->setPosition(pos); 136 int newpos = bi->toPreviousBoundary(); 137 DEBUG() << "textBreakPreceding" << pos << newpos; 138 return newpos; 139 } 140 141 int textBreakFollowing(TextBreakIterator* bi, int pos) 142 { 143 bi->setPosition(pos); 144 int newpos = bi->toNextBoundary(); 145 DEBUG() << "textBreakFollowing" << pos << newpos; 146 return newpos; 147 } 148 149 int textBreakCurrent(TextBreakIterator* bi) 150 { 151 return bi->position(); 152 } 153 154 bool isTextBreak(TextBreakIterator*, int) 155 { 156 return true; 157 } 158#endif 159 160} 161