| 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" |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 399 if (directionality_mode_ == DIRECTIONALITY_FROM_TEXT) | 399 if (directionality_mode_ == DIRECTIONALITY_FROM_TEXT) |
| 400 text_direction_ = base::i18n::UNKNOWN_DIRECTION; | 400 text_direction_ = base::i18n::UNKNOWN_DIRECTION; |
| 401 | 401 |
| 402 UpdateObscuredText(); | 402 UpdateObscuredText(); |
| 403 ResetLayout(); | 403 ResetLayout(); |
| 404 } | 404 } |
| 405 | 405 |
| 406 void RenderText::SetHorizontalAlignment(HorizontalAlignment alignment) { | 406 void RenderText::SetHorizontalAlignment(HorizontalAlignment alignment) { |
| 407 if (horizontal_alignment_ != alignment) { | 407 if (horizontal_alignment_ != alignment) { |
| 408 horizontal_alignment_ = alignment; | 408 horizontal_alignment_ = alignment; |
| 409 display_offset_ = Point(); | 409 display_offset_ = Vector2d(); |
| 410 cached_bounds_and_offset_valid_ = false; | 410 cached_bounds_and_offset_valid_ = false; |
| 411 } | 411 } |
| 412 } | 412 } |
| 413 | 413 |
| 414 void RenderText::SetFontList(const FontList& font_list) { | 414 void RenderText::SetFontList(const FontList& font_list) { |
| 415 font_list_ = font_list; | 415 font_list_ = font_list; |
| 416 cached_bounds_and_offset_valid_ = false; | 416 cached_bounds_and_offset_valid_ = false; |
| 417 ResetLayout(); | 417 ResetLayout(); |
| 418 } | 418 } |
| 419 | 419 |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 758 focused_(false), | 758 focused_(false), |
| 759 composition_range_(ui::Range::InvalidRange()), | 759 composition_range_(ui::Range::InvalidRange()), |
| 760 obscured_(false), | 760 obscured_(false), |
| 761 fade_head_(false), | 761 fade_head_(false), |
| 762 fade_tail_(false), | 762 fade_tail_(false), |
| 763 background_is_transparent_(false), | 763 background_is_transparent_(false), |
| 764 clip_to_display_rect_(true), | 764 clip_to_display_rect_(true), |
| 765 cached_bounds_and_offset_valid_(false) { | 765 cached_bounds_and_offset_valid_(false) { |
| 766 } | 766 } |
| 767 | 767 |
| 768 const Point& RenderText::GetUpdatedDisplayOffset() { | 768 const Vector2d& RenderText::GetUpdatedDisplayOffset() { |
| 769 UpdateCachedBoundsAndOffset(); | 769 UpdateCachedBoundsAndOffset(); |
| 770 return display_offset_; | 770 return display_offset_; |
| 771 } | 771 } |
| 772 | 772 |
| 773 SelectionModel RenderText::GetAdjacentSelectionModel( | 773 SelectionModel RenderText::GetAdjacentSelectionModel( |
| 774 const SelectionModel& current, | 774 const SelectionModel& current, |
| 775 BreakType break_type, | 775 BreakType break_type, |
| 776 VisualCursorDirection direction) { | 776 VisualCursorDirection direction) { |
| 777 EnsureLayout(); | 777 EnsureLayout(); |
| 778 | 778 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 832 StyleRange replacement_mode_style(default_style_); | 832 StyleRange replacement_mode_style(default_style_); |
| 833 replacement_mode_style.foreground = selection_color_; | 833 replacement_mode_style.foreground = selection_color_; |
| 834 size_t cursor = cursor_position(); | 834 size_t cursor = cursor_position(); |
| 835 replacement_mode_style.range.set_start(cursor); | 835 replacement_mode_style.range.set_start(cursor); |
| 836 replacement_mode_style.range.set_end( | 836 replacement_mode_style.range.set_end( |
| 837 IndexOfAdjacentGrapheme(cursor, CURSOR_FORWARD)); | 837 IndexOfAdjacentGrapheme(cursor, CURSOR_FORWARD)); |
| 838 ApplyStyleRangeImpl(style_ranges, replacement_mode_style); | 838 ApplyStyleRangeImpl(style_ranges, replacement_mode_style); |
| 839 } | 839 } |
| 840 } | 840 } |
| 841 | 841 |
| 842 Point RenderText::GetTextOrigin() { | 842 Vector2d RenderText::GetTextOffset() { |
| 843 Point origin = display_rect().origin(); | 843 Vector2d offset = display_rect().OffsetFromOrigin(); |
| 844 origin = origin.Add(GetUpdatedDisplayOffset()); | 844 offset.Add(GetUpdatedDisplayOffset()); |
| 845 origin = origin.Add(GetAlignmentOffset()); | 845 offset.Add(GetAlignmentOffset()); |
| 846 return origin; | 846 return offset; |
| 847 } | 847 } |
| 848 | 848 |
| 849 Point RenderText::ToTextPoint(const Point& point) { | 849 Point RenderText::ToTextPoint(const Point& point) { |
| 850 return point.Subtract(GetTextOrigin()); | 850 return point.Subtract(GetTextOffset()); |
| 851 } | 851 } |
| 852 | 852 |
| 853 Point RenderText::ToViewPoint(const Point& point) { | 853 Point RenderText::ToViewPoint(const Point& point) { |
| 854 return point.Add(GetTextOrigin()); | 854 return point.Add(GetTextOffset()); |
| 855 } | 855 } |
| 856 | 856 |
| 857 int RenderText::GetContentWidth() { | 857 int RenderText::GetContentWidth() { |
| 858 return GetStringSize().width() + (cursor_enabled_ ? 1 : 0); | 858 return GetStringSize().width() + (cursor_enabled_ ? 1 : 0); |
| 859 } | 859 } |
| 860 | 860 |
| 861 Point RenderText::GetAlignmentOffset() { | 861 Vector2d RenderText::GetAlignmentOffset() { |
| 862 if (horizontal_alignment() != ALIGN_LEFT) { | 862 if (horizontal_alignment() == ALIGN_LEFT) |
| 863 int x_offset = display_rect().width() - GetContentWidth(); | 863 return Vector2d(); |
| 864 if (horizontal_alignment() == ALIGN_CENTER) | 864 |
| 865 x_offset /= 2; | 865 int x_offset = display_rect().width() - GetContentWidth(); |
| 866 return Point(x_offset, 0); | 866 if (horizontal_alignment() == ALIGN_CENTER) |
| 867 } | 867 x_offset /= 2; |
| 868 return Point(); | 868 return Vector2d(x_offset, 0); |
| 869 } | 869 } |
| 870 | 870 |
| 871 Point RenderText::GetOriginForDrawing() { | 871 Point RenderText::GetOriginForDrawing() { |
| 872 Point origin(GetTextOrigin()); | |
| 873 const int height = GetStringSize().height(); | |
| 874 // Center the text vertically in the display area. | 872 // Center the text vertically in the display area. |
| 875 origin.Offset(0, (display_rect().height() - height) / 2); | 873 return gfx::PointAtOffsetFromOrigin(GetTextOffset()) + |
| 876 return origin; | 874 Vector2d(0, (display_rect().height() - GetStringSize().height()) / 2); |
| 877 } | 875 } |
| 878 | 876 |
| 879 void RenderText::ApplyFadeEffects(internal::SkiaTextRenderer* renderer) { | 877 void RenderText::ApplyFadeEffects(internal::SkiaTextRenderer* renderer) { |
| 880 if (!fade_head() && !fade_tail()) | 878 if (!fade_head() && !fade_tail()) |
| 881 return; | 879 return; |
| 882 | 880 |
| 883 const int text_width = GetStringSize().width(); | 881 const int text_width = GetStringSize().width(); |
| 884 const int display_width = display_rect().width(); | 882 const int display_width = display_rect().width(); |
| 885 | 883 |
| 886 // If the text fits as-is, no need to fade. | 884 // If the text fits as-is, no need to fade. |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 967 // First, set the valid flag true to calculate the current cursor bounds using | 965 // First, set the valid flag true to calculate the current cursor bounds using |
| 968 // the stale |display_offset_|. Applying |delta_offset| at the end of this | 966 // the stale |display_offset_|. Applying |delta_offset| at the end of this |
| 969 // function will set |cursor_bounds_| and |display_offset_| to correct values. | 967 // function will set |cursor_bounds_| and |display_offset_| to correct values. |
| 970 cached_bounds_and_offset_valid_ = true; | 968 cached_bounds_and_offset_valid_ = true; |
| 971 cursor_bounds_ = GetCursorBounds(selection_model_, insert_mode_); | 969 cursor_bounds_ = GetCursorBounds(selection_model_, insert_mode_); |
| 972 | 970 |
| 973 // Update |display_offset_| to ensure the current cursor is visible. | 971 // Update |display_offset_| to ensure the current cursor is visible. |
| 974 const int display_width = display_rect_.width(); | 972 const int display_width = display_rect_.width(); |
| 975 const int content_width = GetContentWidth(); | 973 const int content_width = GetContentWidth(); |
| 976 | 974 |
| 977 int delta_offset = 0; | 975 int delta_x = 0; |
| 978 if (content_width <= display_width || !cursor_enabled()) { | 976 if (content_width <= display_width || !cursor_enabled()) { |
| 979 // Don't pan if the text fits in the display width or when the cursor is | 977 // Don't pan if the text fits in the display width or when the cursor is |
| 980 // disabled. | 978 // disabled. |
| 981 delta_offset = -display_offset_.x(); | 979 delta_x = -display_offset_.x(); |
| 982 } else if (cursor_bounds_.right() >= display_rect_.right()) { | 980 } else if (cursor_bounds_.right() >= display_rect_.right()) { |
| 983 // TODO(xji): when the character overflow is a RTL character, currently, if | 981 // TODO(xji): when the character overflow is a RTL character, currently, if |
| 984 // we pan cursor at the rightmost position, the entered RTL character is not | 982 // we pan cursor at the rightmost position, the entered RTL character is not |
| 985 // displayed. Should pan cursor to show the last logical characters. | 983 // displayed. Should pan cursor to show the last logical characters. |
| 986 // | 984 // |
| 987 // Pan to show the cursor when it overflows to the right, | 985 // Pan to show the cursor when it overflows to the right, |
| 988 delta_offset = display_rect_.right() - cursor_bounds_.right() - 1; | 986 delta_x = display_rect_.right() - cursor_bounds_.right() - 1; |
| 989 } else if (cursor_bounds_.x() < display_rect_.x()) { | 987 } else if (cursor_bounds_.x() < display_rect_.x()) { |
| 990 // TODO(xji): have similar problem as above when overflow character is a | 988 // TODO(xji): have similar problem as above when overflow character is a |
| 991 // LTR character. | 989 // LTR character. |
| 992 // | 990 // |
| 993 // Pan to show the cursor when it overflows to the left. | 991 // Pan to show the cursor when it overflows to the left. |
| 994 delta_offset = display_rect_.x() - cursor_bounds_.x(); | 992 delta_x = display_rect_.x() - cursor_bounds_.x(); |
| 995 } else if (display_offset_.x() != 0) { | 993 } else if (display_offset_.x() != 0) { |
| 996 // Reduce the pan offset to show additional overflow text when the display | 994 // Reduce the pan offset to show additional overflow text when the display |
| 997 // width increases. | 995 // width increases. |
| 998 const int negate_rtl = horizontal_alignment_ == ALIGN_RIGHT ? -1 : 1; | 996 const int negate_rtl = horizontal_alignment_ == ALIGN_RIGHT ? -1 : 1; |
| 999 const int offset = negate_rtl * display_offset_.x(); | 997 const int offset = negate_rtl * display_offset_.x(); |
| 1000 if (display_width > (content_width + offset)) | 998 if (display_width > (content_width + offset)) { |
| 1001 delta_offset = negate_rtl * (display_width - (content_width + offset)); | 999 delta_x = negate_rtl * (display_width - (content_width + offset)); |
| 1000 } |
| 1002 } | 1001 } |
| 1003 | 1002 |
| 1004 display_offset_.Offset(delta_offset, 0); | 1003 gfx::Vector2d delta_offset(delta_x, 0); |
| 1005 cursor_bounds_.Offset(delta_offset, 0); | 1004 display_offset_ += delta_offset; |
| 1005 cursor_bounds_.Offset(delta_offset); |
| 1006 } | 1006 } |
| 1007 | 1007 |
| 1008 void RenderText::DrawSelection(Canvas* canvas) { | 1008 void RenderText::DrawSelection(Canvas* canvas) { |
| 1009 const SkColor color = focused() ? selection_background_focused_color_ : | 1009 const SkColor color = focused() ? selection_background_focused_color_ : |
| 1010 selection_background_unfocused_color_; | 1010 selection_background_unfocused_color_; |
| 1011 const std::vector<Rect> sel = GetSubstringBounds(selection()); | 1011 const std::vector<Rect> sel = GetSubstringBounds(selection()); |
| 1012 for (std::vector<Rect>::const_iterator i = sel.begin(); i < sel.end(); ++i) | 1012 for (std::vector<Rect>::const_iterator i = sel.begin(); i < sel.end(); ++i) |
| 1013 canvas->FillRect(*i, color); | 1013 canvas->FillRect(*i, color); |
| 1014 } | 1014 } |
| 1015 | 1015 |
| 1016 void RenderText::DrawCursor(Canvas* canvas) { | 1016 void RenderText::DrawCursor(Canvas* canvas) { |
| 1017 // Paint cursor. Replace cursor is drawn as rectangle for now. | 1017 // Paint cursor. Replace cursor is drawn as rectangle for now. |
| 1018 // TODO(msw): Draw a better cursor with a better indication of association. | 1018 // TODO(msw): Draw a better cursor with a better indication of association. |
| 1019 if (cursor_enabled() && cursor_visible() && focused()) { | 1019 if (cursor_enabled() && cursor_visible() && focused()) { |
| 1020 const Rect& bounds = GetUpdatedCursorBounds(); | 1020 const Rect& bounds = GetUpdatedCursorBounds(); |
| 1021 if (bounds.width() != 0) | 1021 if (bounds.width() != 0) |
| 1022 canvas->FillRect(bounds, cursor_color_); | 1022 canvas->FillRect(bounds, cursor_color_); |
| 1023 else | 1023 else |
| 1024 canvas->DrawRect(bounds, cursor_color_); | 1024 canvas->DrawRect(bounds, cursor_color_); |
| 1025 } | 1025 } |
| 1026 } | 1026 } |
| 1027 | 1027 |
| 1028 } // namespace gfx | 1028 } // namespace gfx |
| OLD | NEW |