| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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_harfbuzz.h" | 5 #include "ui/gfx/render_text_harfbuzz.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 | 8 |
| 9 #include "base/i18n/bidi_line_iterator.h" | 9 #include "base/i18n/bidi_line_iterator.h" |
| 10 #include "base/i18n/break_iterator.h" | 10 #include "base/i18n/break_iterator.h" |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 hb_font_make_immutable(harfbuzz_font); | 270 hb_font_make_immutable(harfbuzz_font); |
| 271 return harfbuzz_font; | 271 return harfbuzz_font; |
| 272 } | 272 } |
| 273 | 273 |
| 274 // Returns true if characters of |block_code| may trigger font fallback. | 274 // Returns true if characters of |block_code| may trigger font fallback. |
| 275 bool IsUnusualBlockCode(UBlockCode block_code) { | 275 bool IsUnusualBlockCode(UBlockCode block_code) { |
| 276 return block_code == UBLOCK_GEOMETRIC_SHAPES || | 276 return block_code == UBLOCK_GEOMETRIC_SHAPES || |
| 277 block_code == UBLOCK_MISCELLANEOUS_SYMBOLS; | 277 block_code == UBLOCK_MISCELLANEOUS_SYMBOLS; |
| 278 } | 278 } |
| 279 | 279 |
| 280 // Returns the index of the first unusual character after a usual character or |
| 281 // vice versa. Unusual characters are defined by |IsUnusualBlockCode|. |
| 282 size_t FindUnusualCharacter(const base::string16& text, |
| 283 size_t run_start, |
| 284 size_t run_break) { |
| 285 const int32 run_length = static_cast<int32>(run_break - run_start); |
| 286 base::i18n::UTF16CharIterator iter(text.c_str() + run_start, |
| 287 run_length); |
| 288 const UBlockCode first_block_code = ublock_getCode(iter.get()); |
| 289 const bool first_block_unusual = IsUnusualBlockCode(first_block_code); |
| 290 while (iter.Advance() && iter.array_pos() < run_length) { |
| 291 const UBlockCode current_block_code = ublock_getCode(iter.get()); |
| 292 if (current_block_code != first_block_code && |
| 293 (first_block_unusual || IsUnusualBlockCode(current_block_code))) { |
| 294 return run_start + iter.array_pos(); |
| 295 } |
| 296 } |
| 297 return run_break; |
| 298 } |
| 299 |
| 280 // If the given scripts match, returns the one that isn't USCRIPT_COMMON or | 300 // If the given scripts match, returns the one that isn't USCRIPT_COMMON or |
| 281 // USCRIPT_INHERITED, i.e. the more specific one. Otherwise returns | 301 // USCRIPT_INHERITED, i.e. the more specific one. Otherwise returns |
| 282 // USCRIPT_INVALID_CODE. | 302 // USCRIPT_INVALID_CODE. |
| 283 UScriptCode ScriptIntersect(UScriptCode first, UScriptCode second) { | 303 UScriptCode ScriptIntersect(UScriptCode first, UScriptCode second) { |
| 284 if (first == second || | 304 if (first == second || |
| 285 (second > USCRIPT_INVALID_CODE && second <= USCRIPT_INHERITED)) { | 305 (second > USCRIPT_INVALID_CODE && second <= USCRIPT_INHERITED)) { |
| 286 return first; | 306 return first; |
| 287 } | 307 } |
| 288 if (first > USCRIPT_INVALID_CODE && first <= USCRIPT_INHERITED) | 308 if (first > USCRIPT_INVALID_CODE && first <= USCRIPT_INHERITED) |
| 289 return second; | 309 return second; |
| (...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 901 script_item_break = ScriptInterval(text, run_break, | 921 script_item_break = ScriptInterval(text, run_break, |
| 902 script_item_break - run_break, &run->script) + run_break; | 922 script_item_break - run_break, &run->script) + run_break; |
| 903 | 923 |
| 904 // Find the next break and advance the iterators as needed. | 924 // Find the next break and advance the iterators as needed. |
| 905 run_break = std::min(static_cast<size_t>(script_item_break), | 925 run_break = std::min(static_cast<size_t>(script_item_break), |
| 906 TextIndexToLayoutIndex(style.GetRange().end())); | 926 TextIndexToLayoutIndex(style.GetRange().end())); |
| 907 | 927 |
| 908 // Break runs adjacent to character substrings in certain code blocks. | 928 // Break runs adjacent to character substrings in certain code blocks. |
| 909 // This avoids using their fallback fonts for more characters than needed, | 929 // This avoids using their fallback fonts for more characters than needed, |
| 910 // in cases like "\x25B6 Media Title", etc. http://crbug.com/278913 | 930 // in cases like "\x25B6 Media Title", etc. http://crbug.com/278913 |
| 911 if (run_break > run->range.start()) { | 931 if (run_break > run->range.start()) |
| 912 const size_t run_start = run->range.start(); | 932 run_break = FindUnusualCharacter(text, run->range.start(), run_break); |
| 913 const int32 run_length = static_cast<int32>(run_break - run_start); | |
| 914 base::i18n::UTF16CharIterator iter(text.c_str() + run_start, | |
| 915 run_length); | |
| 916 const UBlockCode first_block_code = ublock_getCode(iter.get()); | |
| 917 const bool first_block_unusual = IsUnusualBlockCode(first_block_code); | |
| 918 while (iter.Advance() && iter.array_pos() < run_length) { | |
| 919 const UBlockCode current_block_code = ublock_getCode(iter.get()); | |
| 920 if (current_block_code != first_block_code && | |
| 921 (first_block_unusual || IsUnusualBlockCode(current_block_code))) { | |
| 922 run_break = run_start + iter.array_pos(); | |
| 923 break; | |
| 924 } | |
| 925 } | |
| 926 } | |
| 927 | 933 |
| 928 DCHECK(IsValidCodePointIndex(text, run_break)); | 934 DCHECK(IsValidCodePointIndex(text, run_break)); |
| 929 style.UpdatePosition(LayoutIndexToTextIndex(run_break)); | 935 style.UpdatePosition(LayoutIndexToTextIndex(run_break)); |
| 930 run->range.set_end(run_break); | 936 run->range.set_end(run_break); |
| 931 | 937 |
| 932 runs_.push_back(run); | 938 runs_.push_back(run); |
| 933 } | 939 } |
| 934 | 940 |
| 935 // Undo the temporarily applied composition underlines and selection colors. | 941 // Undo the temporarily applied composition underlines and selection colors. |
| 936 UndoCompositionAndSelectionStyles(); | 942 UndoCompositionAndSelectionStyles(); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 990 run->positions[i].set(run->width + x_offset, y_offset); | 996 run->positions[i].set(run->width + x_offset, y_offset); |
| 991 run->width += | 997 run->width += |
| 992 SkScalarRoundToInt(SkFixedToScalar(hb_positions[i].x_advance)); | 998 SkScalarRoundToInt(SkFixedToScalar(hb_positions[i].x_advance)); |
| 993 } | 999 } |
| 994 | 1000 |
| 995 hb_buffer_destroy(buffer); | 1001 hb_buffer_destroy(buffer); |
| 996 hb_font_destroy(harfbuzz_font); | 1002 hb_font_destroy(harfbuzz_font); |
| 997 } | 1003 } |
| 998 | 1004 |
| 999 } // namespace gfx | 1005 } // namespace gfx |
| OLD | NEW |