OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/gfx/render_text_win.h" | 5 #include "ui/gfx/render_text_win.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/i18n/break_iterator.h" | 9 #include "base/i18n/break_iterator.h" |
10 #include "base/i18n/char_iterator.h" | 10 #include "base/i18n/char_iterator.h" |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 } | 257 } |
258 } | 258 } |
259 } | 259 } |
260 | 260 |
261 // Returns true if characters of |block_code| may trigger font fallback. | 261 // Returns true if characters of |block_code| may trigger font fallback. |
262 bool IsUnusualBlockCode(const UBlockCode block_code) { | 262 bool IsUnusualBlockCode(const UBlockCode block_code) { |
263 return block_code == UBLOCK_GEOMETRIC_SHAPES || | 263 return block_code == UBLOCK_GEOMETRIC_SHAPES || |
264 block_code == UBLOCK_MISCELLANEOUS_SYMBOLS; | 264 block_code == UBLOCK_MISCELLANEOUS_SYMBOLS; |
265 } | 265 } |
266 | 266 |
| 267 // Returns the index of the first unusual character after a usual character or |
| 268 // vice versa. Unusual characters are defined by |IsUnusualBlockCode|. |
| 269 size_t FindUnusualCharacter(const base::string16& text, |
| 270 size_t run_start, |
| 271 size_t run_break) { |
| 272 const int32 run_length = static_cast<int32>(run_break - run_start); |
| 273 base::i18n::UTF16CharIterator iter(text.c_str() + run_start, |
| 274 run_length); |
| 275 const UBlockCode first_block_code = ublock_getCode(iter.get()); |
| 276 const bool first_block_unusual = IsUnusualBlockCode(first_block_code); |
| 277 while (iter.Advance() && iter.array_pos() < run_length) { |
| 278 const UBlockCode current_block_code = ublock_getCode(iter.get()); |
| 279 if (current_block_code != first_block_code && |
| 280 (first_block_unusual || IsUnusualBlockCode(current_block_code))) { |
| 281 return run_start + iter.array_pos(); |
| 282 } |
| 283 } |
| 284 return run_break; |
| 285 } |
| 286 |
267 } // namespace | 287 } // namespace |
268 | 288 |
269 namespace internal { | 289 namespace internal { |
270 | 290 |
271 TextRun::TextRun() | 291 TextRun::TextRun() |
272 : font_style(0), | 292 : font_style(0), |
273 strike(false), | 293 strike(false), |
274 diagonal_strike(false), | 294 diagonal_strike(false), |
275 underline(false), | 295 underline(false), |
276 width(0), | 296 width(0), |
(...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
948 if ((run_break - run->range.start()) > max_run_length) { | 968 if ((run_break - run->range.start()) > max_run_length) { |
949 run_break = run->range.start() + max_run_length; | 969 run_break = run->range.start() + max_run_length; |
950 if (!IsValidCodePointIndex(layout_text, run_break)) | 970 if (!IsValidCodePointIndex(layout_text, run_break)) |
951 --run_break; | 971 --run_break; |
952 } | 972 } |
953 | 973 |
954 // Break runs adjacent to character substrings in certain code blocks. | 974 // Break runs adjacent to character substrings in certain code blocks. |
955 // This avoids using their fallback fonts for more characters than needed, | 975 // This avoids using their fallback fonts for more characters than needed, |
956 // in cases like "\x25B6 Media Title", etc. http://crbug.com/278913 | 976 // in cases like "\x25B6 Media Title", etc. http://crbug.com/278913 |
957 if (run_break > run->range.start()) { | 977 if (run_break > run->range.start()) { |
958 const size_t run_start = run->range.start(); | 978 run_break = |
959 const int32 run_length = static_cast<int32>(run_break - run_start); | 979 FindUnusualCharacter(layout_text, run->range.start(), run_break); |
960 base::i18n::UTF16CharIterator iter(layout_text.c_str() + run_start, | |
961 run_length); | |
962 const UBlockCode first_block_code = ublock_getCode(iter.get()); | |
963 const bool first_block_unusual = IsUnusualBlockCode(first_block_code); | |
964 while (iter.Advance() && iter.array_pos() < run_length) { | |
965 const UBlockCode current_block_code = ublock_getCode(iter.get()); | |
966 if (current_block_code != first_block_code && | |
967 (first_block_unusual || IsUnusualBlockCode(current_block_code))) { | |
968 run_break = run_start + iter.array_pos(); | |
969 break; | |
970 } | |
971 } | |
972 } | 980 } |
973 | 981 |
974 DCHECK(IsValidCodePointIndex(layout_text, run_break)); | 982 DCHECK(IsValidCodePointIndex(layout_text, run_break)); |
975 | 983 |
976 style.UpdatePosition(LayoutIndexToTextIndex(run_break)); | 984 style.UpdatePosition(LayoutIndexToTextIndex(run_break)); |
977 if (script_item_break == run_break) | 985 if (script_item_break == run_break) |
978 script_item++; | 986 script_item++; |
979 run->range.set_end(run_break); | 987 run->range.set_end(run_break); |
980 runs_.push_back(run); | 988 runs_.push_back(run); |
981 } | 989 } |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1272 size_t position = LayoutIndexToTextIndex(run->range.end()); | 1280 size_t position = LayoutIndexToTextIndex(run->range.end()); |
1273 position = IndexOfAdjacentGrapheme(position, CURSOR_BACKWARD); | 1281 position = IndexOfAdjacentGrapheme(position, CURSOR_BACKWARD); |
1274 return SelectionModel(position, CURSOR_FORWARD); | 1282 return SelectionModel(position, CURSOR_FORWARD); |
1275 } | 1283 } |
1276 | 1284 |
1277 RenderText* RenderText::CreateNativeInstance() { | 1285 RenderText* RenderText::CreateNativeInstance() { |
1278 return new RenderTextWin; | 1286 return new RenderTextWin; |
1279 } | 1287 } |
1280 | 1288 |
1281 } // namespace gfx | 1289 } // namespace gfx |
OLD | NEW |