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.h" | 5 #include "ui/gfx/render_text.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/logging.h" | 10 #include "base/logging.h" |
11 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
12 #include "third_party/skia/include/core/SkTypeface.h" | 12 #include "third_party/skia/include/core/SkTypeface.h" |
13 #include "third_party/skia/include/effects/SkGradientShader.h" | 13 #include "third_party/skia/include/effects/SkGradientShader.h" |
14 #include "ui/base/text/utf16_indexing.h" | 14 #include "ui/base/text/utf16_indexing.h" |
15 #include "ui/gfx/canvas.h" | 15 #include "ui/gfx/canvas.h" |
16 #include "ui/gfx/insets.h" | 16 #include "ui/gfx/insets.h" |
17 #include "ui/gfx/skia_util.h" | 17 #include "ui/gfx/skia_util.h" |
| 18 #include "ui/gfx/text_constants.h" |
18 | 19 |
19 namespace { | 20 namespace { |
20 | 21 |
21 // All chars are replaced by this char when the password style is set. | 22 // All chars are replaced by this char when the password style is set. |
22 // TODO(benrg): GTK uses the first of U+25CF, U+2022, U+2731, U+273A, '*' | 23 // TODO(benrg): GTK uses the first of U+25CF, U+2022, U+2731, U+273A, '*' |
23 // that's available in the font (find_invisible_char() in gtkentry.c). | 24 // that's available in the font (find_invisible_char() in gtkentry.c). |
24 const char16 kPasswordReplacementChar = '*'; | 25 const char16 kPasswordReplacementChar = '*'; |
25 | 26 |
26 // Default color used for the cursor. | 27 // Default color used for the cursor. |
27 const SkColor kDefaultCursorColor = SK_ColorBLACK; | 28 const SkColor kDefaultCursorColor = SK_ColorBLACK; |
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 } | 388 } |
388 #ifndef NDEBUG | 389 #ifndef NDEBUG |
389 CheckStyleRanges(style_ranges_, text_.length()); | 390 CheckStyleRanges(style_ranges_, text_.length()); |
390 #endif | 391 #endif |
391 cached_bounds_and_offset_valid_ = false; | 392 cached_bounds_and_offset_valid_ = false; |
392 | 393 |
393 // Reset selection model. SetText should always followed by SetSelectionModel | 394 // Reset selection model. SetText should always followed by SetSelectionModel |
394 // or SetCursorPosition in upper layer. | 395 // or SetCursorPosition in upper layer. |
395 SetSelectionModel(SelectionModel()); | 396 SetSelectionModel(SelectionModel()); |
396 | 397 |
| 398 // Invalidate the cached text direction if it depends on the text contents. |
| 399 if (directionality_mode_ == DIRECTIONALITY_FROM_TEXT) |
| 400 text_direction_ = base::i18n::UNKNOWN_DIRECTION; |
| 401 |
397 ResetLayout(); | 402 ResetLayout(); |
398 } | 403 } |
399 | 404 |
400 void RenderText::SetHorizontalAlignment(HorizontalAlignment alignment) { | 405 void RenderText::SetHorizontalAlignment(HorizontalAlignment alignment) { |
401 if (horizontal_alignment_ != alignment) { | 406 if (horizontal_alignment_ != alignment) { |
402 horizontal_alignment_ = alignment; | 407 horizontal_alignment_ = alignment; |
403 display_offset_ = Point(); | 408 display_offset_ = Point(); |
404 cached_bounds_and_offset_valid_ = false; | 409 cached_bounds_and_offset_valid_ = false; |
405 } | 410 } |
406 } | 411 } |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
589 | 594 |
590 void RenderText::ApplyDefaultStyle() { | 595 void RenderText::ApplyDefaultStyle() { |
591 style_ranges_.clear(); | 596 style_ranges_.clear(); |
592 StyleRange style = StyleRange(default_style_); | 597 StyleRange style = StyleRange(default_style_); |
593 style.range.set_end(text_.length()); | 598 style.range.set_end(text_.length()); |
594 style_ranges_.push_back(style); | 599 style_ranges_.push_back(style); |
595 cached_bounds_and_offset_valid_ = false; | 600 cached_bounds_and_offset_valid_ = false; |
596 ResetLayout(); | 601 ResetLayout(); |
597 } | 602 } |
598 | 603 |
| 604 void RenderText::SetDirectionalityMode(DirectionalityMode mode) { |
| 605 if (mode == directionality_mode_) |
| 606 return; |
| 607 |
| 608 directionality_mode_ = mode; |
| 609 text_direction_ = base::i18n::UNKNOWN_DIRECTION; |
| 610 ResetLayout(); |
| 611 } |
| 612 |
| 613 base::i18n::TextDirection RenderText::GetTextDirection() { |
| 614 if (text_direction_ == base::i18n::UNKNOWN_DIRECTION) { |
| 615 switch (directionality_mode_) { |
| 616 case DIRECTIONALITY_FROM_TEXT: |
| 617 // Derive the direction from the display text, which differs from text() |
| 618 // in the case of obscured (password) textfields. |
| 619 text_direction_ = |
| 620 base::i18n::GetFirstStrongCharacterDirection(GetDisplayText()); |
| 621 break; |
| 622 case DIRECTIONALITY_FROM_UI: |
| 623 text_direction_ = base::i18n::IsRTL() ? base::i18n::RIGHT_TO_LEFT : |
| 624 base::i18n::LEFT_TO_RIGHT; |
| 625 break; |
| 626 case DIRECTIONALITY_FORCE_LTR: |
| 627 text_direction_ = base::i18n::LEFT_TO_RIGHT; |
| 628 break; |
| 629 case DIRECTIONALITY_FORCE_RTL: |
| 630 text_direction_ = base::i18n::RIGHT_TO_LEFT; |
| 631 break; |
| 632 default: |
| 633 NOTREACHED(); |
| 634 } |
| 635 } |
| 636 |
| 637 return text_direction_; |
| 638 } |
| 639 |
599 VisualCursorDirection RenderText::GetVisualDirectionOfLogicalEnd() { | 640 VisualCursorDirection RenderText::GetVisualDirectionOfLogicalEnd() { |
600 return GetTextDirection() == base::i18n::LEFT_TO_RIGHT ? | 641 return GetTextDirection() == base::i18n::LEFT_TO_RIGHT ? |
601 CURSOR_RIGHT : CURSOR_LEFT; | 642 CURSOR_RIGHT : CURSOR_LEFT; |
602 } | 643 } |
603 | 644 |
604 void RenderText::Draw(Canvas* canvas) { | 645 void RenderText::Draw(Canvas* canvas) { |
605 EnsureLayout(); | 646 EnsureLayout(); |
606 | 647 |
607 if (clip_to_display_rect()) { | 648 if (clip_to_display_rect()) { |
608 gfx::Rect clip_rect(display_rect()); | 649 gfx::Rect clip_rect(display_rect()); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
694 return SelectionModel(sel.start(), | 735 return SelectionModel(sel.start(), |
695 sel.is_reversed() ? CURSOR_BACKWARD : CURSOR_FORWARD); | 736 sel.is_reversed() ? CURSOR_BACKWARD : CURSOR_FORWARD); |
696 } | 737 } |
697 | 738 |
698 void RenderText::SetTextShadows(const ShadowValues& shadows) { | 739 void RenderText::SetTextShadows(const ShadowValues& shadows) { |
699 text_shadows_ = shadows; | 740 text_shadows_ = shadows; |
700 } | 741 } |
701 | 742 |
702 RenderText::RenderText() | 743 RenderText::RenderText() |
703 : horizontal_alignment_(base::i18n::IsRTL() ? ALIGN_RIGHT : ALIGN_LEFT), | 744 : horizontal_alignment_(base::i18n::IsRTL() ? ALIGN_RIGHT : ALIGN_LEFT), |
| 745 directionality_mode_(DIRECTIONALITY_FROM_TEXT), |
| 746 text_direction_(base::i18n::UNKNOWN_DIRECTION), |
704 cursor_enabled_(true), | 747 cursor_enabled_(true), |
705 cursor_visible_(false), | 748 cursor_visible_(false), |
706 insert_mode_(true), | 749 insert_mode_(true), |
707 cursor_color_(kDefaultCursorColor), | 750 cursor_color_(kDefaultCursorColor), |
708 selection_color_(kDefaultSelectionColor), | 751 selection_color_(kDefaultSelectionColor), |
709 selection_background_focused_color_(kDefaultSelectionBackgroundColor), | 752 selection_background_focused_color_(kDefaultSelectionBackgroundColor), |
710 selection_background_unfocused_color_(kDefaultSelectionBackgroundColor), | 753 selection_background_unfocused_color_(kDefaultSelectionBackgroundColor), |
711 focused_(false), | 754 focused_(false), |
712 composition_range_(ui::Range::InvalidRange()), | 755 composition_range_(ui::Range::InvalidRange()), |
713 obscured_(false), | 756 obscured_(false), |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
966 if (cursor_enabled() && cursor_visible() && focused()) { | 1009 if (cursor_enabled() && cursor_visible() && focused()) { |
967 const Rect& bounds = GetUpdatedCursorBounds(); | 1010 const Rect& bounds = GetUpdatedCursorBounds(); |
968 if (bounds.width() != 0) | 1011 if (bounds.width() != 0) |
969 canvas->FillRect(bounds, cursor_color_); | 1012 canvas->FillRect(bounds, cursor_color_); |
970 else | 1013 else |
971 canvas->DrawRect(bounds, cursor_color_); | 1014 canvas->DrawRect(bounds, cursor_color_); |
972 } | 1015 } |
973 } | 1016 } |
974 | 1017 |
975 } // namespace gfx | 1018 } // namespace gfx |
OLD | NEW |