diff options
author | skanuj@chromium.org <skanuj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-24 02:17:49 +0000 |
---|---|---|
committer | skanuj@chromium.org <skanuj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-24 02:17:49 +0000 |
commit | 61f9908f6732c769e0dfa5f9c53c740bf98a17ce (patch) | |
tree | 779cab30feaac574fc1790e0de9751c97063eec5 /ui/gfx | |
parent | 0624275c81af9616d4c93d2d09bb655fa5c8e676 (diff) | |
download | chromium_src-61f9908f6732c769e0dfa5f9c53c740bf98a17ce.zip chromium_src-61f9908f6732c769e0dfa5f9c53c740bf98a17ce.tar.gz chromium_src-61f9908f6732c769e0dfa5f9c53c740bf98a17ce.tar.bz2 |
Infinite Suggest - views implementation
(See comment 36 on crbug.com/327833 for screenshots)
RenderText:
Allow layout_text_ to be empty if there is no room to render a single character.
----------------
OmniboxResultView:
Revises the OmniboxResultView to rely on RenderText for eliding and rendering.
The match contents and description can not be rendered together as one string.
See crbug.com/331153 for a possible error case. The relevant TODO is removed.
-----------------------------------------------------------
Infinite Suggestion:
These suggestions show a leading ellipsis to suggest tail completion. Ideally
they should appear at an offset equivalent to that of omitted text. This is
accomplished by computing the required width as if the full text is present and
the actual width required to show the suggestion with leading ellipsis.
If the window is not wide enough to show the suggestion at the offset of the
omitted text, the suggestions are shifted towards the start edge such that the
longest infinite suggestion is visible. The suggestions are never shifted beyond
the start edge.
The suggestions are shown aligned to the start edge when directionality of suggestion differs from directionality of UI.
When the directionality of suggestion differs from directionality of UI, we try
to show the suggestions such that the leading ellipsis is still vertically
aligned for all suggestions.
BUG=327833, 336543, 328699
TBR=msw@chromium.org
Review URL: https://codereview.chromium.org/171153004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@252873 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/gfx')
-rw-r--r-- | ui/gfx/render_text.cc | 18 | ||||
-rw-r--r-- | ui/gfx/render_text.h | 12 | ||||
-rw-r--r-- | ui/gfx/render_text_pango.cc | 1 | ||||
-rw-r--r-- | ui/gfx/render_text_unittest.cc | 7 |
4 files changed, 21 insertions, 17 deletions
diff --git a/ui/gfx/render_text.cc b/ui/gfx/render_text.cc index 2a65660..0e5bfd2 100644 --- a/ui/gfx/render_text.cc +++ b/ui/gfx/render_text.cc @@ -878,7 +878,7 @@ void RenderText::SetSelectionModel(const SelectionModel& model) { } const base::string16& RenderText::GetLayoutText() const { - return layout_text_.empty() ? text_ : layout_text_; + return layout_text_; } const BreakList<size_t>& RenderText::GetLineBreaks() { @@ -1112,9 +1112,11 @@ void RenderText::UpdateLayoutText() { if (layout_text_.length() > cp_start) layout_text_.replace(cp_start, 1, text_.substr(start, end - start)); } + } else { + layout_text_ = text_; } - const base::string16& text = GetLayoutText(); + const base::string16& text = layout_text_; if (truncate_length_ > 0 && truncate_length_ < text.length()) { // Truncate the text at a valid character break and append an ellipsis. icu::StringCharacterIterator iter(text.c_str()); @@ -1123,13 +1125,12 @@ void RenderText::UpdateLayoutText() { } if (elide_behavior_ != NO_ELIDE && display_rect_.width() > 0 && - !GetLayoutText().empty() && GetContentWidth() > display_rect_.width()) { - base::string16 elided_text = ElideText(GetLayoutText()); - + !layout_text_.empty() && GetContentWidth() > display_rect_.width()) { // This doesn't trim styles so ellipsis may get rendered as a different // style than the preceding text. See crbug.com/327850. - layout_text_.assign(elided_text); + layout_text_.assign(ElideText(layout_text_)); } + ResetLayout(); } @@ -1177,6 +1178,7 @@ base::string16 RenderText::ElideText(const base::string16& text) { // Use binary search to compute the elided text. size_t lo = 0; size_t hi = text.length() - 1; + const base::i18n::TextDirection text_direction = GetTextDirection(); for (size_t guess = (lo + hi) / 2; lo <= hi; guess = (lo + hi) / 2) { // Restore styles and colors. They will be truncated to size by SetText. render_text->styles_ = styles_; @@ -1192,12 +1194,10 @@ base::string16 RenderText::ElideText(const base::string16& text) { // whole text. Since we want ellipsis to indicate continuation of the // preceding text, we force the directionality of ellipsis to be same as // the preceding text using LTR or RTL markers. - base::i18n::TextDirection leading_text_direction = - base::i18n::GetFirstStrongCharacterDirection(new_text); base::i18n::TextDirection trailing_text_direction = base::i18n::GetLastStrongCharacterDirection(new_text); new_text.append(ellipsis); - if (trailing_text_direction != leading_text_direction) { + if (trailing_text_direction != text_direction) { if (trailing_text_direction == base::i18n::LEFT_TO_RIGHT) new_text += base::i18n::kLeftToRightMark; else diff --git a/ui/gfx/render_text.h b/ui/gfx/render_text.h index af5ce30..7af9743 100644 --- a/ui/gfx/render_text.h +++ b/ui/gfx/render_text.h @@ -398,6 +398,12 @@ class GFX_EXPORT RenderText { // chosen. virtual std::vector<FontSpan> GetFontSpansForTesting() = 0; + // Gets the horizontal bounds (relative to the left of the text, not the view) + // of the glyph starting at |index|. If the glyph is RTL then the returned + // Range will have is_reversed() true. (This does not return a Rect because a + // Rect can't have a negative width.) + virtual Range GetGlyphBounds(size_t index) = 0; + protected: RenderText(); @@ -462,12 +468,6 @@ class GFX_EXPORT RenderText { // Sets the selection model, the argument is assumed to be valid. virtual void SetSelectionModel(const SelectionModel& model); - // Get the horizontal bounds (relative to the left of the text, not the view) - // of the glyph starting at |index|. If the glyph is RTL then the returned - // Range will have is_reversed() true. (This does not return a Rect because a - // Rect can't have a negative width.) - virtual Range GetGlyphBounds(size_t index) = 0; - // Get the visual bounds containing the logical substring within the |range|. // If |range| is empty, the result is empty. These bounds could be visually // discontinuous if the substring is split by a LTR/RTL level change. diff --git a/ui/gfx/render_text_pango.cc b/ui/gfx/render_text_pango.cc index f7a61b17..4bfdaa7 100644 --- a/ui/gfx/render_text_pango.cc +++ b/ui/gfx/render_text_pango.cc @@ -211,6 +211,7 @@ SelectionModel RenderTextPango::AdjacentWordSelectionModel( } Range RenderTextPango::GetGlyphBounds(size_t index) { + EnsureLayout(); PangoRectangle pos; pango_layout_index_to_pos(layout_, TextIndexToLayoutIndex(index), &pos); // TODO(derat): Support fractional ranges for subpixel positioning? diff --git a/ui/gfx/render_text_unittest.cc b/ui/gfx/render_text_unittest.cc index 7565921..977cea4 100644 --- a/ui/gfx/render_text_unittest.cc +++ b/ui/gfx/render_text_unittest.cc @@ -419,6 +419,8 @@ TEST_F(RenderTextTest, ElidedText) { } cases[] = { // Strings shorter than the elision width should be laid out in full. { L"", L"" , false }, + { L"M", L"" , false }, + { L" . ", L" . " , false }, { kWeak, kWeak , false }, { kLtr, kLtr , false }, { kLtrRtl, kLtrRtl , false }, @@ -443,7 +445,7 @@ TEST_F(RenderTextTest, ElidedText) { { L"0\x05e9\x05bc\x05c1\x05b8", L"0\x05e9\x05bc\x05c1\x05b8", false }, { L"0\x05e9\x05bc\x05c1\x05b8", L"0\x05e9\x05bc\x2026" , true }, { L"01\x05e9\x05bc\x05c1\x05b8", L"01\x05e9\x2026" , true }, - { L"012\x05e9\x05bc\x05c1\x05b8", L"012\x2026" , true }, + { L"012\x05e9\x05bc\x05c1\x05b8", L"012\x2026\x200E" , true }, { L"012\xF0\x9D\x84\x9E", L"012\xF0\x2026" , true }, }; @@ -468,7 +470,8 @@ TEST_F(RenderTextTest, ElidedText) { render_text->SetText(input); render_text->SetDisplayRect(gfx::Rect(0, 0, expected_width, 100)); - EXPECT_EQ(input, render_text->text()); + EXPECT_EQ(input, render_text->text()) + << "->For case " << i << ": " << cases[i].text << "\n"; EXPECT_EQ(WideToUTF16(cases[i].layout_text), render_text->GetLayoutText()) << "->For case " << i << ": " << cases[i].text << "\n"; expected_render_text->SetText(base::string16()); |