| 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 |