| OLD | NEW |
| 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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 // letters/numbers except some south east asians'. | 73 // letters/numbers except some south east asians'. |
| 74 }; | 74 }; |
| 75 | 75 |
| 76 class PLATFORM_EXPORT LazyLineBreakIterator final { | 76 class PLATFORM_EXPORT LazyLineBreakIterator final { |
| 77 STACK_ALLOCATED(); | 77 STACK_ALLOCATED(); |
| 78 | 78 |
| 79 public: | 79 public: |
| 80 LazyLineBreakIterator() | 80 LazyLineBreakIterator() |
| 81 : iterator_(0), | 81 : iterator_(0), |
| 82 cached_prior_context_(0), | 82 cached_prior_context_(0), |
| 83 cached_prior_context_length_(0) { | 83 cached_prior_context_length_(0), |
| 84 break_type_(LineBreakType::kNormal) { |
| 84 ResetPriorContext(); | 85 ResetPriorContext(); |
| 85 } | 86 } |
| 86 | 87 |
| 87 LazyLineBreakIterator(String string, | 88 LazyLineBreakIterator(String string, |
| 88 const AtomicString& locale = AtomicString()) | 89 const AtomicString& locale = AtomicString(), |
| 90 LineBreakType break_type = LineBreakType::kNormal) |
| 89 : string_(string), | 91 : string_(string), |
| 90 locale_(locale), | 92 locale_(locale), |
| 91 iterator_(0), | 93 iterator_(0), |
| 92 cached_prior_context_(0), | 94 cached_prior_context_(0), |
| 93 cached_prior_context_length_(0) { | 95 cached_prior_context_length_(0), |
| 96 break_type_(break_type) { |
| 94 ResetPriorContext(); | 97 ResetPriorContext(); |
| 95 } | 98 } |
| 96 | 99 |
| 97 ~LazyLineBreakIterator() { | 100 ~LazyLineBreakIterator() { |
| 98 if (iterator_) | 101 if (iterator_) |
| 99 ReleaseLineBreakIterator(iterator_); | 102 ReleaseLineBreakIterator(iterator_); |
| 100 } | 103 } |
| 101 | 104 |
| 102 String GetString() const { return string_; } | 105 String GetString() const { return string_; } |
| 103 | 106 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 if (prior_context_[0]) | 146 if (prior_context_[0]) |
| 144 ++prior_context_length; | 147 ++prior_context_length; |
| 145 } | 148 } |
| 146 return prior_context_length; | 149 return prior_context_length; |
| 147 } | 150 } |
| 148 | 151 |
| 149 // Obtain text break iterator, possibly previously cached, where this iterator | 152 // Obtain text break iterator, possibly previously cached, where this iterator |
| 150 // is (or has been) initialized to use the previously stored string as the | 153 // is (or has been) initialized to use the previously stored string as the |
| 151 // primary breaking context and using previously stored prior context if | 154 // primary breaking context and using previously stored prior context if |
| 152 // non-empty. | 155 // non-empty. |
| 153 TextBreakIterator* Get(unsigned prior_context_length) { | 156 TextBreakIterator* Get(unsigned prior_context_length) const { |
| 154 DCHECK(prior_context_length <= kPriorContextCapacity); | 157 DCHECK(prior_context_length <= kPriorContextCapacity); |
| 155 const UChar* prior_context = | 158 const UChar* prior_context = |
| 156 prior_context_length | 159 prior_context_length |
| 157 ? &prior_context_[kPriorContextCapacity - prior_context_length] | 160 ? &prior_context_[kPriorContextCapacity - prior_context_length] |
| 158 : 0; | 161 : 0; |
| 159 if (!iterator_) { | 162 if (!iterator_) { |
| 160 if (string_.Is8Bit()) | 163 if (string_.Is8Bit()) |
| 161 iterator_ = AcquireLineBreakIterator( | 164 iterator_ = AcquireLineBreakIterator( |
| 162 string_.Characters8(), string_.length(), locale_, prior_context, | 165 string_.Characters8(), string_.length(), locale_, prior_context, |
| 163 prior_context_length); | 166 prior_context_length); |
| 164 else | 167 else |
| 165 iterator_ = AcquireLineBreakIterator( | 168 iterator_ = AcquireLineBreakIterator( |
| 166 string_.Characters16(), string_.length(), locale_, prior_context, | 169 string_.Characters16(), string_.length(), locale_, prior_context, |
| 167 prior_context_length); | 170 prior_context_length); |
| 168 cached_prior_context_ = prior_context; | 171 cached_prior_context_ = prior_context; |
| 169 cached_prior_context_length_ = prior_context_length; | 172 cached_prior_context_length_ = prior_context_length; |
| 170 } else if (prior_context != cached_prior_context_ || | 173 } else if (prior_context != cached_prior_context_ || |
| 171 prior_context_length != cached_prior_context_length_) { | 174 prior_context_length != cached_prior_context_length_) { |
| 172 this->ResetStringAndReleaseIterator(string_, locale_); | 175 ReleaseIterator(); |
| 173 return this->Get(prior_context_length); | 176 return Get(prior_context_length); |
| 174 } | 177 } |
| 175 return iterator_; | 178 return iterator_; |
| 176 } | 179 } |
| 177 | 180 |
| 178 void ResetStringAndReleaseIterator(String string, | 181 void ResetStringAndReleaseIterator(String string, |
| 179 const AtomicString& locale) { | 182 const AtomicString& locale) { |
| 180 if (iterator_) | |
| 181 ReleaseLineBreakIterator(iterator_); | |
| 182 | |
| 183 string_ = string; | 183 string_ = string; |
| 184 locale_ = locale; | 184 locale_ = locale; |
| 185 iterator_ = 0; | 185 |
| 186 cached_prior_context_ = 0; | 186 ReleaseIterator(); |
| 187 cached_prior_context_length_ = 0; | |
| 188 } | 187 } |
| 189 | 188 |
| 190 inline bool IsBreakable( | 189 void SetLocale(const AtomicString& locale) { |
| 191 int pos, | 190 if (locale == locale_) |
| 192 int& next_breakable, | 191 return; |
| 193 LineBreakType line_break_type = LineBreakType::kNormal) { | 192 locale_ = locale; |
| 193 ReleaseIterator(); |
| 194 } |
| 195 |
| 196 void SetBreakType(LineBreakType break_type) { break_type_ = break_type; } |
| 197 |
| 198 inline bool IsBreakable(int pos, |
| 199 int& next_breakable, |
| 200 LineBreakType line_break_type) const { |
| 194 if (pos > next_breakable) { | 201 if (pos > next_breakable) { |
| 195 switch (line_break_type) { | 202 switch (line_break_type) { |
| 196 case LineBreakType::kBreakAll: | 203 case LineBreakType::kBreakAll: |
| 197 next_breakable = NextBreakablePositionBreakAll(pos); | 204 next_breakable = NextBreakablePositionBreakAll(pos); |
| 198 break; | 205 break; |
| 199 case LineBreakType::kKeepAll: | 206 case LineBreakType::kKeepAll: |
| 200 next_breakable = NextBreakablePositionKeepAll(pos); | 207 next_breakable = NextBreakablePositionKeepAll(pos); |
| 201 break; | 208 break; |
| 202 default: | 209 default: |
| 203 next_breakable = NextBreakablePositionIgnoringNBSP(pos); | 210 next_breakable = NextBreakablePositionIgnoringNBSP(pos); |
| 204 } | 211 } |
| 205 } | 212 } |
| 206 return pos == next_breakable; | 213 return pos == next_breakable; |
| 207 } | 214 } |
| 208 | 215 |
| 216 inline bool IsBreakable(int pos, int& next_breakable) const { |
| 217 return IsBreakable(pos, next_breakable, break_type_); |
| 218 } |
| 219 |
| 220 // Returns the break opportunity at or after |offset|. |
| 221 unsigned NextBreakOpportunity(unsigned offset) const; |
| 222 |
| 223 // Returns the break opportunity at or before |offset|. |
| 224 unsigned PreviousBreakOpportunity(unsigned offset, unsigned min = 0) const; |
| 225 |
| 209 private: | 226 private: |
| 210 int NextBreakablePositionIgnoringNBSP(int pos); | 227 void ReleaseIterator() const { |
| 211 int NextBreakablePositionBreakAll(int pos); | 228 if (iterator_) |
| 212 int NextBreakablePositionKeepAll(int pos); | 229 ReleaseLineBreakIterator(iterator_); |
| 230 iterator_ = 0; |
| 231 cached_prior_context_ = 0; |
| 232 cached_prior_context_length_ = 0; |
| 233 } |
| 234 |
| 235 int NextBreakablePositionIgnoringNBSP(int pos) const; |
| 236 int NextBreakablePositionBreakAll(int pos) const; |
| 237 int NextBreakablePositionKeepAll(int pos) const; |
| 213 | 238 |
| 214 static const unsigned kPriorContextCapacity = 2; | 239 static const unsigned kPriorContextCapacity = 2; |
| 215 String string_; | 240 String string_; |
| 216 AtomicString locale_; | 241 AtomicString locale_; |
| 217 TextBreakIterator* iterator_; | 242 mutable TextBreakIterator* iterator_; |
| 218 UChar prior_context_[kPriorContextCapacity]; | 243 UChar prior_context_[kPriorContextCapacity]; |
| 219 const UChar* cached_prior_context_; | 244 mutable const UChar* cached_prior_context_; |
| 220 unsigned cached_prior_context_length_; | 245 mutable unsigned cached_prior_context_length_; |
| 246 LineBreakType break_type_; |
| 221 }; | 247 }; |
| 222 | 248 |
| 223 // Iterates over "extended grapheme clusters", as defined in UAX #29. | 249 // Iterates over "extended grapheme clusters", as defined in UAX #29. |
| 224 // Note that platform implementations may be less sophisticated - e.g. ICU prior | 250 // Note that platform implementations may be less sophisticated - e.g. ICU prior |
| 225 // to version 4.0 only supports "legacy grapheme clusters". Use this for | 251 // to version 4.0 only supports "legacy grapheme clusters". Use this for |
| 226 // general text processing, e.g. string truncation. | 252 // general text processing, e.g. string truncation. |
| 227 | 253 |
| 228 class PLATFORM_EXPORT NonSharedCharacterBreakIterator final { | 254 class PLATFORM_EXPORT NonSharedCharacterBreakIterator final { |
| 229 STACK_ALLOCATED(); | 255 STACK_ALLOCATED(); |
| 230 WTF_MAKE_NONCOPYABLE(NonSharedCharacterBreakIterator); | 256 WTF_MAKE_NONCOPYABLE(NonSharedCharacterBreakIterator); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 }; | 302 }; |
| 277 | 303 |
| 278 // Counts the number of grapheme clusters. A surrogate pair or a sequence | 304 // Counts the number of grapheme clusters. A surrogate pair or a sequence |
| 279 // of a non-combining character and following combining characters is | 305 // of a non-combining character and following combining characters is |
| 280 // counted as 1 grapheme cluster. | 306 // counted as 1 grapheme cluster. |
| 281 PLATFORM_EXPORT unsigned NumGraphemeClusters(const String&); | 307 PLATFORM_EXPORT unsigned NumGraphemeClusters(const String&); |
| 282 | 308 |
| 283 } // namespace blink | 309 } // namespace blink |
| 284 | 310 |
| 285 #endif | 311 #endif |
| OLD | NEW |