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" |
11 #include "base/i18n/rtl.h" | 11 #include "base/i18n/rtl.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
14 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
15 #include "base/win/windows_version.h" | 15 #include "base/win/windows_version.h" |
16 #include "third_party/icu/source/common/unicode/uchar.h" | 16 #include "third_party/icu/source/common/unicode/uchar.h" |
17 #include "ui/base/text/utf16_indexing.h" | |
18 #include "ui/gfx/canvas.h" | 17 #include "ui/gfx/canvas.h" |
19 #include "ui/gfx/font_fallback_win.h" | 18 #include "ui/gfx/font_fallback_win.h" |
20 #include "ui/gfx/font_smoothing_win.h" | 19 #include "ui/gfx/font_smoothing_win.h" |
21 #include "ui/gfx/platform_font_win.h" | 20 #include "ui/gfx/platform_font_win.h" |
| 21 #include "ui/gfx/utf16_indexing.h" |
22 | 22 |
23 namespace gfx { | 23 namespace gfx { |
24 | 24 |
25 namespace { | 25 namespace { |
26 | 26 |
27 // The maximum length of text supported for Uniscribe layout and display. | 27 // The maximum length of text supported for Uniscribe layout and display. |
28 // This empirically chosen value should prevent major performance degradations. | 28 // This empirically chosen value should prevent major performance degradations. |
29 // TODO(msw): Support longer text, partial layout/painting, etc. | 29 // TODO(msw): Support longer text, partial layout/painting, etc. |
30 const size_t kMaxUniscribeTextLength = 10000; | 30 const size_t kMaxUniscribeTextLength = 10000; |
31 | 31 |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 bounds.pop_back(); | 406 bounds.pop_back(); |
407 } | 407 } |
408 bounds.push_back(rect); | 408 bounds.push_back(rect); |
409 } | 409 } |
410 } | 410 } |
411 return bounds; | 411 return bounds; |
412 } | 412 } |
413 | 413 |
414 size_t RenderTextWin::TextIndexToLayoutIndex(size_t index) const { | 414 size_t RenderTextWin::TextIndexToLayoutIndex(size_t index) const { |
415 DCHECK_LE(index, text().length()); | 415 DCHECK_LE(index, text().length()); |
416 ptrdiff_t i = obscured() ? ui::UTF16IndexToOffset(text(), 0, index) : index; | 416 ptrdiff_t i = obscured() ? gfx::UTF16IndexToOffset(text(), 0, index) : index; |
417 CHECK_GE(i, 0); | 417 CHECK_GE(i, 0); |
418 // Clamp layout indices to the length of the text actually used for layout. | 418 // Clamp layout indices to the length of the text actually used for layout. |
419 return std::min<size_t>(GetLayoutText().length(), i); | 419 return std::min<size_t>(GetLayoutText().length(), i); |
420 } | 420 } |
421 | 421 |
422 size_t RenderTextWin::LayoutIndexToTextIndex(size_t index) const { | 422 size_t RenderTextWin::LayoutIndexToTextIndex(size_t index) const { |
423 if (!obscured()) | 423 if (!obscured()) |
424 return index; | 424 return index; |
425 | 425 |
426 DCHECK_LE(index, GetLayoutText().length()); | 426 DCHECK_LE(index, GetLayoutText().length()); |
427 const size_t text_index = ui::UTF16OffsetToIndex(text(), 0, index); | 427 const size_t text_index = gfx::UTF16OffsetToIndex(text(), 0, index); |
428 DCHECK_LE(text_index, text().length()); | 428 DCHECK_LE(text_index, text().length()); |
429 return text_index; | 429 return text_index; |
430 } | 430 } |
431 | 431 |
432 bool RenderTextWin::IsCursorablePosition(size_t position) { | 432 bool RenderTextWin::IsCursorablePosition(size_t position) { |
433 if (position == 0 || position == text().length()) | 433 if (position == 0 || position == text().length()) |
434 return true; | 434 return true; |
435 EnsureLayout(); | 435 EnsureLayout(); |
436 | 436 |
437 // Check that the index is at a valid code point (not mid-surrgate-pair), | 437 // Check that the index is at a valid code point (not mid-surrgate-pair), |
438 // that it is not truncated from layout text (its glyph is shown on screen), | 438 // that it is not truncated from layout text (its glyph is shown on screen), |
439 // and that its glyph has distinct bounds (not mid-multi-character-grapheme). | 439 // and that its glyph has distinct bounds (not mid-multi-character-grapheme). |
440 // An example of a multi-character-grapheme that is not a surrogate-pair is: | 440 // An example of a multi-character-grapheme that is not a surrogate-pair is: |
441 // \x0915\x093f - (ki) - one of many Devanagari biconsonantal conjuncts. | 441 // \x0915\x093f - (ki) - one of many Devanagari biconsonantal conjuncts. |
442 return ui::IsValidCodePointIndex(text(), position) && | 442 return gfx::IsValidCodePointIndex(text(), position) && |
443 position < LayoutIndexToTextIndex(GetLayoutText().length()) && | 443 position < LayoutIndexToTextIndex(GetLayoutText().length()) && |
444 GetGlyphBounds(position) != GetGlyphBounds(position - 1); | 444 GetGlyphBounds(position) != GetGlyphBounds(position - 1); |
445 } | 445 } |
446 | 446 |
447 void RenderTextWin::ResetLayout() { | 447 void RenderTextWin::ResetLayout() { |
448 // Layout is performed lazily as needed for drawing/metrics. | 448 // Layout is performed lazily as needed for drawing/metrics. |
449 needs_layout_ = true; | 449 needs_layout_ = true; |
450 } | 450 } |
451 | 451 |
452 void RenderTextWin::EnsureLayout() { | 452 void RenderTextWin::EnsureLayout() { |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
592 run->script_analysis = script_item->a; | 592 run->script_analysis = script_item->a; |
593 | 593 |
594 // Find the next break and advance the iterators as needed. | 594 // Find the next break and advance the iterators as needed. |
595 const size_t script_item_break = (script_item + 1)->iCharPos; | 595 const size_t script_item_break = (script_item + 1)->iCharPos; |
596 run_break = std::min(script_item_break, | 596 run_break = std::min(script_item_break, |
597 TextIndexToLayoutIndex(style.GetRange().end())); | 597 TextIndexToLayoutIndex(style.GetRange().end())); |
598 | 598 |
599 // Clamp run lengths to avoid exceeding the maximum supported glyph count. | 599 // Clamp run lengths to avoid exceeding the maximum supported glyph count. |
600 if ((run_break - run->range.start()) > max_run_length) { | 600 if ((run_break - run->range.start()) > max_run_length) { |
601 run_break = run->range.start() + max_run_length; | 601 run_break = run->range.start() + max_run_length; |
602 if (!ui::IsValidCodePointIndex(layout_text, run_break)) | 602 if (!gfx::IsValidCodePointIndex(layout_text, run_break)) |
603 --run_break; | 603 --run_break; |
604 } | 604 } |
605 | 605 |
606 // Break runs between characters in different code blocks. This avoids using | 606 // Break runs between characters in different code blocks. This avoids using |
607 // fallback fonts for more characters than needed. http://crbug.com/278913 | 607 // fallback fonts for more characters than needed. http://crbug.com/278913 |
608 if (run_break > run->range.start()) { | 608 if (run_break > run->range.start()) { |
609 const size_t run_start = run->range.start(); | 609 const size_t run_start = run->range.start(); |
610 const int32 run_length = static_cast<int32>(run_break - run_start); | 610 const int32 run_length = static_cast<int32>(run_break - run_start); |
611 base::i18n::UTF16CharIterator iter(layout_text.c_str() + run_start, | 611 base::i18n::UTF16CharIterator iter(layout_text.c_str() + run_start, |
612 run_length); | 612 run_length); |
613 const UBlockCode first_block_code = ublock_getCode(iter.get()); | 613 const UBlockCode first_block_code = ublock_getCode(iter.get()); |
614 while (iter.Advance() && iter.array_pos() < run_length) { | 614 while (iter.Advance() && iter.array_pos() < run_length) { |
615 if (ublock_getCode(iter.get()) != first_block_code) { | 615 if (ublock_getCode(iter.get()) != first_block_code) { |
616 run_break = run_start + iter.array_pos(); | 616 run_break = run_start + iter.array_pos(); |
617 break; | 617 break; |
618 } | 618 } |
619 } | 619 } |
620 } | 620 } |
621 | 621 |
622 DCHECK(ui::IsValidCodePointIndex(layout_text, run_break)); | 622 DCHECK(gfx::IsValidCodePointIndex(layout_text, run_break)); |
623 | 623 |
624 style.UpdatePosition(LayoutIndexToTextIndex(run_break)); | 624 style.UpdatePosition(LayoutIndexToTextIndex(run_break)); |
625 if (script_item_break == run_break) | 625 if (script_item_break == run_break) |
626 script_item++; | 626 script_item++; |
627 run->range.set_end(run_break); | 627 run->range.set_end(run_break); |
628 runs_.push_back(run); | 628 runs_.push_back(run); |
629 } | 629 } |
630 | 630 |
631 // Undo the temporarily applied composition underlines and selection colors. | 631 // Undo the temporarily applied composition underlines and selection colors. |
632 UndoCompositionAndSelectionStyles(); | 632 UndoCompositionAndSelectionStyles(); |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
922 size_t position = LayoutIndexToTextIndex(run->range.end()); | 922 size_t position = LayoutIndexToTextIndex(run->range.end()); |
923 position = IndexOfAdjacentGrapheme(position, CURSOR_BACKWARD); | 923 position = IndexOfAdjacentGrapheme(position, CURSOR_BACKWARD); |
924 return SelectionModel(position, CURSOR_FORWARD); | 924 return SelectionModel(position, CURSOR_FORWARD); |
925 } | 925 } |
926 | 926 |
927 RenderText* RenderText::CreateInstance() { | 927 RenderText* RenderText::CreateInstance() { |
928 return new RenderTextWin; | 928 return new RenderTextWin; |
929 } | 929 } |
930 | 930 |
931 } // namespace gfx | 931 } // namespace gfx |
OLD | NEW |