Make line breaking obey the -webkit-locale property
[WebKit-https.git] / Source / WebCore / platform / text / wince / TextBreakIteratorWinCE.cpp
1 /*
2  * Copyright (C) 2006 Lars Knoll <lars@trolltech.com>
3  * Copyright (C) 2007-2009 Torch Mobile, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  */
21
22 #include "config.h"
23 #include "TextBreakIterator.h"
24
25 #include "PlatformString.h"
26 #include <wtf/StdLibExtras.h>
27 #include <wtf/unicode/Unicode.h>
28
29 using namespace std;
30 using namespace WTF::Unicode;
31
32 namespace WebCore {
33
34 // Hack, not entirely correct
35 static inline bool isCharStop(UChar c)
36 {
37     CharCategory charCategory = category(c);
38     return charCategory != Mark_NonSpacing && (charCategory != Other_Surrogate || (c < 0xd800 || c >= 0xdc00));
39 }
40
41 static inline bool isLineStop(UChar c)
42 {
43     return category(c) != Separator_Line;
44 }
45
46 static inline bool isSentenceStop(UChar c)
47 {
48     return isPunct(c);
49 }
50
51 class TextBreakIterator {
52 public:
53     void reset(const UChar* str, int len)
54     {
55         string = str;
56         length = len;
57         currentPos = 0;
58     }
59     int first()
60     {
61         currentPos = 0;
62         return currentPos;
63     }
64     int last()
65     {
66         currentPos = length;
67         return currentPos;
68     }
69     virtual int next() = 0;
70     virtual int previous() = 0;
71     int following(int position)
72     {
73         currentPos = position;
74         return next();
75     }
76     int preceding(int position)
77     {
78         currentPos = position;
79         return previous();
80     }
81
82     int currentPos;
83     const UChar* string;
84     int length;
85 };
86
87 struct WordBreakIterator: TextBreakIterator {
88     virtual int next();
89     virtual int previous();
90 };
91
92 struct CharBreakIterator: TextBreakIterator {
93     virtual int next();
94     virtual int previous();
95 };
96
97 struct LineBreakIterator: TextBreakIterator {
98     virtual int next();
99     virtual int previous();
100 };
101
102 struct SentenceBreakIterator : TextBreakIterator {
103     virtual int next();
104     virtual int previous();
105 };
106
107 int WordBreakIterator::next()
108 {
109     if (currentPos == length) {
110         currentPos = -1;
111         return currentPos;
112     }
113     bool haveSpace = false;
114     while (currentPos < length) {
115         if (haveSpace && !isSpace(string[currentPos]))
116             break;
117         if (isSpace(string[currentPos]))
118             haveSpace = true;
119         ++currentPos;
120     }
121     return currentPos;
122 }
123
124 int WordBreakIterator::previous()
125 {
126     if (!currentPos) {
127         currentPos = -1;
128         return currentPos;
129     }
130     bool haveSpace = false;
131     while (currentPos > 0) {
132         if (haveSpace && !isSpace(string[currentPos]))
133             break;
134         if (isSpace(string[currentPos]))
135             haveSpace = true;
136         --currentPos;
137     }
138     return currentPos;
139 }
140
141 int CharBreakIterator::next()
142 {
143     if (currentPos >= length)
144         return -1;
145     ++currentPos;
146     while (currentPos < length && !isCharStop(string[currentPos]))
147         ++currentPos;
148     return currentPos;
149 }
150
151 int CharBreakIterator::previous()
152 {
153     if (currentPos <= 0)
154         return -1;
155     if (currentPos > length)
156         currentPos = length;
157     --currentPos;
158     while (currentPos > 0 && !isCharStop(string[currentPos]))
159         --currentPos;
160     return currentPos;
161 }
162
163 int LineBreakIterator::next()
164 {
165     if (currentPos == length) {
166         currentPos = -1;
167         return currentPos;
168     }
169     bool haveSpace = false;
170     while (currentPos < length) {
171         if (haveSpace && !isLineStop(string[currentPos]))
172             break;
173         if (isLineStop(string[currentPos]))
174             haveSpace = true;
175         ++currentPos;
176     }
177     return currentPos;
178 }
179
180 int LineBreakIterator::previous()
181 {
182     if (!currentPos) {
183         currentPos = -1;
184         return currentPos;
185     }
186     bool haveSpace = false;
187     while (currentPos > 0) {
188         if (haveSpace && !isLineStop(string[currentPos]))
189             break;
190         if (isLineStop(string[currentPos]))
191             haveSpace = true;
192         --currentPos;
193     }
194     return currentPos;
195 }
196
197 int SentenceBreakIterator::next()
198 {
199     if (currentPos == length) {
200         currentPos = -1;
201         return currentPos;
202     }
203     bool haveSpace = false;
204     while (currentPos < length) {
205         if (haveSpace && !isSentenceStop(string[currentPos]))
206             break;
207         if (isSentenceStop(string[currentPos]))
208             haveSpace = true;
209         ++currentPos;
210     }
211     return currentPos;
212 }
213
214 int SentenceBreakIterator::previous()
215 {
216     if (!currentPos) {
217         currentPos = -1;
218         return currentPos;
219     }
220     bool haveSpace = false;
221     while (currentPos > 0) {
222         if (haveSpace && !isSentenceStop(string[currentPos]))
223             break;
224         if (isSentenceStop(string[currentPos]))
225             haveSpace = true;
226         --currentPos;
227     }
228     return currentPos;
229 }
230
231 TextBreakIterator* wordBreakIterator(const UChar* string, int length)
232 {
233     DEFINE_STATIC_LOCAL(WordBreakIterator, iterator, ());
234     iterator.reset(string, length);
235     return &iterator;
236 }
237
238 TextBreakIterator* characterBreakIterator(const UChar* string, int length)
239 {
240     DEFINE_STATIC_LOCAL(CharBreakIterator, iterator, ());
241     iterator.reset(string, length);
242     return &iterator;
243 }
244
245 static TextBreakIterator* staticLineBreakIterator;
246
247 TextBreakIterator* acquireLineBreakIterator(const UChar* string, int length, const AtomicString&)
248 {
249     TextBreakIterator* lineBreakIterator = 0;
250     if (staticLineBreakIterator) {
251         staticLineBreakIterator->reset(string, length);
252         swap(staticLineBreakIterator, lineBreakIterator);
253     }
254
255     if (!lineBreakIterator && string && length) {
256         lineBreakIterator = new LineBreakIterator;
257         lineBreakIterator->reset(string, length);
258     }
259
260     return lineBreakIterator;
261 }
262
263 void releaseLineBreakIterator(TextBreakIterator* iterator)
264 {
265     ASSERT(iterator);
266
267     if (!staticLineBreakIterator)
268         staticLineBreakIterator = iterator;
269     else
270         delete iterator;
271 }
272
273 TextBreakIterator* sentenceBreakIterator(const UChar* string, int length)
274 {
275     DEFINE_STATIC_LOCAL(SentenceBreakIterator, iterator, ());
276     iterator.reset(string, length);
277     return &iterator;
278 }
279
280 int textBreakFirst(TextBreakIterator* breakIterator)
281 {
282     return breakIterator->first();
283 }
284
285 int textBreakLast(TextBreakIterator* breakIterator)
286 {
287     return breakIterator->last();
288 }
289
290 int textBreakNext(TextBreakIterator* breakIterator)
291 {
292     return breakIterator->next();
293 }
294
295 int textBreakPrevious(TextBreakIterator* breakIterator)
296 {
297     return breakIterator->previous();
298 }
299
300 int textBreakPreceding(TextBreakIterator* breakIterator, int position)
301 {
302     return breakIterator->preceding(position);
303 }
304
305 int textBreakFollowing(TextBreakIterator* breakIterator, int position)
306 {
307     return breakIterator->following(position);
308 }
309
310 int textBreakCurrent(TextBreakIterator* breakIterator)
311 {
312     return breakIterator->currentPos;
313 }
314
315 bool isTextBreak(TextBreakIterator*, int)
316 {
317     return true;
318 }
319
320 TextBreakIterator* cursorMovementIterator(const UChar* string, int length)
321 {
322     return characterBreakIterator(string, length);
323 }
324
325 } // namespace WebCore