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 run_break = run_start + iter.array_pos(); | |
msw
2014/06/10 18:03:15
Just return run_start + iter.array_pos() here.
ckocagil
2014/06/11 07:49:37
Done.
| |
295 break; | |
296 } | |
297 } | |
298 return run_break; | |
299 } | |
300 | |
280 // If the given scripts match, returns the one that isn't USCRIPT_COMMON or | 301 // 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 | 302 // USCRIPT_INHERITED, i.e. the more specific one. Otherwise returns |
282 // USCRIPT_INVALID_CODE. | 303 // USCRIPT_INVALID_CODE. |
283 UScriptCode ScriptIntersect(UScriptCode first, UScriptCode second) { | 304 UScriptCode ScriptIntersect(UScriptCode first, UScriptCode second) { |
284 if (first == second || | 305 if (first == second || |
285 (second > USCRIPT_INVALID_CODE && second <= USCRIPT_INHERITED)) { | 306 (second > USCRIPT_INVALID_CODE && second <= USCRIPT_INHERITED)) { |
286 return first; | 307 return first; |
287 } | 308 } |
288 if (first > USCRIPT_INVALID_CODE && first <= USCRIPT_INHERITED) | 309 if (first > USCRIPT_INVALID_CODE && first <= USCRIPT_INHERITED) |
289 return second; | 310 return second; |
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
897 script_item_break = ScriptInterval(text, run_break, | 918 script_item_break = ScriptInterval(text, run_break, |
898 script_item_break - run_break, &run->script) + run_break; | 919 script_item_break - run_break, &run->script) + run_break; |
899 | 920 |
900 // Find the next break and advance the iterators as needed. | 921 // Find the next break and advance the iterators as needed. |
901 run_break = std::min(static_cast<size_t>(script_item_break), | 922 run_break = std::min(static_cast<size_t>(script_item_break), |
902 TextIndexToLayoutIndex(style.GetRange().end())); | 923 TextIndexToLayoutIndex(style.GetRange().end())); |
903 | 924 |
904 // Break runs adjacent to character substrings in certain code blocks. | 925 // Break runs adjacent to character substrings in certain code blocks. |
905 // This avoids using their fallback fonts for more characters than needed, | 926 // This avoids using their fallback fonts for more characters than needed, |
906 // in cases like "\x25B6 Media Title", etc. http://crbug.com/278913 | 927 // in cases like "\x25B6 Media Title", etc. http://crbug.com/278913 |
907 if (run_break > run->range.start()) { | 928 if (run_break > run->range.start()) |
908 const size_t run_start = run->range.start(); | 929 run_break = FindUnusualCharacter(text, run->range.start(), run_break); |
909 const int32 run_length = static_cast<int32>(run_break - run_start); | |
910 base::i18n::UTF16CharIterator iter(text.c_str() + run_start, | |
911 run_length); | |
912 const UBlockCode first_block_code = ublock_getCode(iter.get()); | |
913 const bool first_block_unusual = IsUnusualBlockCode(first_block_code); | |
914 while (iter.Advance() && iter.array_pos() < run_length) { | |
915 const UBlockCode current_block_code = ublock_getCode(iter.get()); | |
916 if (current_block_code != first_block_code && | |
917 (first_block_unusual || IsUnusualBlockCode(current_block_code))) { | |
918 run_break = run_start + iter.array_pos(); | |
919 break; | |
920 } | |
921 } | |
922 } | |
923 } | 930 } |
924 | 931 |
925 DCHECK(IsValidCodePointIndex(text, run_break)); | 932 DCHECK(IsValidCodePointIndex(text, run_break)); |
926 style.UpdatePosition(LayoutIndexToTextIndex(run_break)); | 933 style.UpdatePosition(LayoutIndexToTextIndex(run_break)); |
927 run->range.set_end(run_break); | 934 run->range.set_end(run_break); |
928 UBiDiDirection direction = ubidi_getBaseDirection( | 935 UBiDiDirection direction = ubidi_getBaseDirection( |
929 text.c_str() + run->range.start(), run->range.length()); | 936 text.c_str() + run->range.start(), run->range.length()); |
930 if (direction == UBIDI_NEUTRAL) | 937 if (direction == UBIDI_NEUTRAL) |
931 run->is_rtl = is_text_rtl; | 938 run->is_rtl = is_text_rtl; |
932 else | 939 else |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
992 run->positions[i].set(run->width + x_offset, y_offset); | 999 run->positions[i].set(run->width + x_offset, y_offset); |
993 run->width += | 1000 run->width += |
994 SkScalarRoundToInt(SkFixedToScalar(hb_positions[i].x_advance)); | 1001 SkScalarRoundToInt(SkFixedToScalar(hb_positions[i].x_advance)); |
995 } | 1002 } |
996 | 1003 |
997 hb_buffer_destroy(buffer); | 1004 hb_buffer_destroy(buffer); |
998 hb_font_destroy(harfbuzz_font); | 1005 hb_font_destroy(harfbuzz_font); |
999 } | 1006 } |
1000 | 1007 |
1001 } // namespace gfx | 1008 } // namespace gfx |
OLD | NEW |