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 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 DCHECK_EQ(segment->x_range.end(), previous_segment->x_range.start()); | 239 DCHECK_EQ(segment->x_range.end(), previous_segment->x_range.start()); |
240 } | 240 } |
241 | 241 |
242 previous_segment = segment; | 242 previous_segment = segment; |
243 previous_segment_line = i; | 243 previous_segment_line = i; |
244 } | 244 } |
245 } | 245 } |
246 } | 246 } |
247 } | 247 } |
248 | 248 |
| 249 // Returns true if characters of |block_code| may trigger font fallback. |
| 250 bool IsUnusualBlockCode(const UBlockCode block_code) { |
| 251 return block_code == UBLOCK_GEOMETRIC_SHAPES || |
| 252 block_code == UBLOCK_MISCELLANEOUS_SYMBOLS; |
| 253 } |
| 254 |
249 } // namespace | 255 } // namespace |
250 | 256 |
251 namespace internal { | 257 namespace internal { |
252 | 258 |
253 TextRun::TextRun() | 259 TextRun::TextRun() |
254 : font_style(0), | 260 : font_style(0), |
255 strike(false), | 261 strike(false), |
256 diagonal_strike(false), | 262 diagonal_strike(false), |
257 underline(false), | 263 underline(false), |
258 width(0), | 264 width(0), |
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
911 run_break = std::min(script_item_break, | 917 run_break = std::min(script_item_break, |
912 TextIndexToLayoutIndex(style.GetRange().end())); | 918 TextIndexToLayoutIndex(style.GetRange().end())); |
913 | 919 |
914 // Clamp run lengths to avoid exceeding the maximum supported glyph count. | 920 // Clamp run lengths to avoid exceeding the maximum supported glyph count. |
915 if ((run_break - run->range.start()) > max_run_length) { | 921 if ((run_break - run->range.start()) > max_run_length) { |
916 run_break = run->range.start() + max_run_length; | 922 run_break = run->range.start() + max_run_length; |
917 if (!IsValidCodePointIndex(layout_text, run_break)) | 923 if (!IsValidCodePointIndex(layout_text, run_break)) |
918 --run_break; | 924 --run_break; |
919 } | 925 } |
920 | 926 |
921 // Break runs adjacent to UBLOCK_GEOMETRIC_SHAPES character substrings. | 927 // Break runs adjacent to character substrings in certain code blocks. |
922 // This avoids using their fallback fonts for more characters than needed, | 928 // This avoids using their fallback fonts for more characters than needed, |
923 // in cases like "\x25B6 Media Title", etc. http://crbug.com/278913 | 929 // in cases like "\x25B6 Media Title", etc. http://crbug.com/278913 |
924 if (run_break > run->range.start()) { | 930 if (run_break > run->range.start()) { |
925 const size_t run_start = run->range.start(); | 931 const size_t run_start = run->range.start(); |
926 const int32 run_length = static_cast<int32>(run_break - run_start); | 932 const int32 run_length = static_cast<int32>(run_break - run_start); |
927 base::i18n::UTF16CharIterator iter(layout_text.c_str() + run_start, | 933 base::i18n::UTF16CharIterator iter(layout_text.c_str() + run_start, |
928 run_length); | 934 run_length); |
929 const UBlockCode first_block_code = ublock_getCode(iter.get()); | 935 const UBlockCode first_block_code = ublock_getCode(iter.get()); |
| 936 const bool first_block_unusual = IsUnusualBlockCode(first_block_code); |
930 while (iter.Advance() && iter.array_pos() < run_length) { | 937 while (iter.Advance() && iter.array_pos() < run_length) { |
931 const UBlockCode current_block_code = ublock_getCode(iter.get()); | 938 const UBlockCode current_block_code = ublock_getCode(iter.get()); |
932 if (current_block_code != first_block_code && | 939 if (current_block_code != first_block_code && |
933 (current_block_code == UBLOCK_GEOMETRIC_SHAPES || | 940 (first_block_unusual || IsUnusualBlockCode(current_block_code))) { |
934 first_block_code == UBLOCK_GEOMETRIC_SHAPES)) { | |
935 run_break = run_start + iter.array_pos(); | 941 run_break = run_start + iter.array_pos(); |
936 break; | 942 break; |
937 } | 943 } |
938 } | 944 } |
939 } | 945 } |
940 | 946 |
941 DCHECK(IsValidCodePointIndex(layout_text, run_break)); | 947 DCHECK(IsValidCodePointIndex(layout_text, run_break)); |
942 | 948 |
943 style.UpdatePosition(LayoutIndexToTextIndex(run_break)); | 949 style.UpdatePosition(LayoutIndexToTextIndex(run_break)); |
944 if (script_item_break == run_break) | 950 if (script_item_break == run_break) |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1239 size_t position = LayoutIndexToTextIndex(run->range.end()); | 1245 size_t position = LayoutIndexToTextIndex(run->range.end()); |
1240 position = IndexOfAdjacentGrapheme(position, CURSOR_BACKWARD); | 1246 position = IndexOfAdjacentGrapheme(position, CURSOR_BACKWARD); |
1241 return SelectionModel(position, CURSOR_FORWARD); | 1247 return SelectionModel(position, CURSOR_FORWARD); |
1242 } | 1248 } |
1243 | 1249 |
1244 RenderText* RenderText::CreateInstance() { | 1250 RenderText* RenderText::CreateInstance() { |
1245 return new RenderTextWin; | 1251 return new RenderTextWin; |
1246 } | 1252 } |
1247 | 1253 |
1248 } // namespace gfx | 1254 } // namespace gfx |
OLD | NEW |