15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For WinDDK ATL compatibility, these ATL headers must come first.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <atlbase.h>  // NOLINT
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <atlwin.h>  // NOLINT
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/omnibox/omnibox_result_view.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>  // NOLINT
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/bidi_line_iterator.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_vector.h"
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/strings/string_number_conversions.h"
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/strings/string_util.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/omnibox/omnibox_popup_model.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h"
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/grit/generated_resources.h"
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "grit/components_scaled_resources.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/theme_provider.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/color_utils.h"
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/gfx/image/image.h"
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/gfx/range/range.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/render_text.h"
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/text_utils.h"
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/native_theme/native_theme.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochusing ui::NativeTheme;
37c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The minimum distance between the top and bottom of the {icon|text} and the
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// top or bottom of the row.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMinimumIconVerticalPadding = 2;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMinimumTextVerticalPadding = 3;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// A mapping from OmniboxResultView's ResultViewState/ColorKind types to
46c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// NativeTheme colors.
47c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochstruct TranslationTable {
48c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ui::NativeTheme::ColorId id;
49c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  OmniboxResultView::ResultViewState state;
50c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  OmniboxResultView::ColorKind kind;
51c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} static const kTranslationTable[] = {
52c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  { NativeTheme::kColorId_ResultsTableNormalBackground,
53c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    OmniboxResultView::NORMAL, OmniboxResultView::BACKGROUND },
54c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  { NativeTheme::kColorId_ResultsTableHoveredBackground,
55c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    OmniboxResultView::HOVERED, OmniboxResultView::BACKGROUND },
56c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  { NativeTheme::kColorId_ResultsTableSelectedBackground,
57c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    OmniboxResultView::SELECTED, OmniboxResultView::BACKGROUND },
58c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  { NativeTheme::kColorId_ResultsTableNormalText,
59c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    OmniboxResultView::NORMAL, OmniboxResultView::TEXT },
60c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  { NativeTheme::kColorId_ResultsTableHoveredText,
61c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    OmniboxResultView::HOVERED, OmniboxResultView::TEXT },
62c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  { NativeTheme::kColorId_ResultsTableSelectedText,
63c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    OmniboxResultView::SELECTED, OmniboxResultView::TEXT },
64c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  { NativeTheme::kColorId_ResultsTableNormalDimmedText,
65c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    OmniboxResultView::NORMAL, OmniboxResultView::DIMMED_TEXT },
66c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  { NativeTheme::kColorId_ResultsTableHoveredDimmedText,
67c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    OmniboxResultView::HOVERED, OmniboxResultView::DIMMED_TEXT },
68c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  { NativeTheme::kColorId_ResultsTableSelectedDimmedText,
69c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    OmniboxResultView::SELECTED, OmniboxResultView::DIMMED_TEXT },
70c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  { NativeTheme::kColorId_ResultsTableNormalUrl,
71c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    OmniboxResultView::NORMAL, OmniboxResultView::URL },
72c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  { NativeTheme::kColorId_ResultsTableHoveredUrl,
73c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    OmniboxResultView::HOVERED, OmniboxResultView::URL },
74c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  { NativeTheme::kColorId_ResultsTableSelectedUrl,
75c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    OmniboxResultView::SELECTED, OmniboxResultView::URL },
76c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  { NativeTheme::kColorId_ResultsTableNormalDivider,
77c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    OmniboxResultView::NORMAL, OmniboxResultView::DIVIDER },
78c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  { NativeTheme::kColorId_ResultsTableHoveredDivider,
79c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    OmniboxResultView::HOVERED, OmniboxResultView::DIVIDER },
80c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  { NativeTheme::kColorId_ResultsTableSelectedDivider,
81c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    OmniboxResultView::SELECTED, OmniboxResultView::DIVIDER },
82c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch};
83c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OmniboxResultView, public:
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class is a utility class for calculations affected by whether the result
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// view is horizontally mirrored.  The drawing functions can be written as if
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// all drawing occurs left-to-right, and then use this class to get the actual
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// coordinates to begin drawing onscreen.
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OmniboxResultView::MirroringContext {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MirroringContext() : center_(0), right_(0) {}
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Tells the mirroring context to use the provided range as the physical
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // bounds of the drawing region.  When coordinate mirroring is needed, the
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // mirror point will be the center of this range.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Initialize(int x, int width) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    center_ = x + width / 2;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    right_ = x + width;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Given a logical range within the drawing region, returns the coordinate of
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the possibly-mirrored "left" side.  (This functions exactly like
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // View::MirroredLeftPointForRect().)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int mirrored_left_coord(int left, int right) const {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return base::i18n::IsRTL() ? (center_ + (center_ - right)) : left;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Given a logical coordinate within the drawing region, returns the remaining
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // width available.
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int remaining_width(int x) const {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return right_ - x;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int center_;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int right_;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MirroringContext);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)OmniboxResultView::OmniboxResultView(OmniboxPopupContentsView* model,
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                     int model_index,
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                     LocationBarView* location_bar_view,
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                     const gfx::FontList& font_list)
1295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    : edge_item_padding_(LocationBarView::kItemPadding),
1305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      item_padding_(LocationBarView::kItemPadding),
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      minimum_text_vertical_padding_(kMinimumTextVerticalPadding),
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      model_(model),
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      model_index_(model_index),
134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      location_bar_view_(location_bar_view),
135a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      font_list_(font_list),
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      font_height_(
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          std::max(font_list.GetHeight(),
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   font_list.DeriveWithStyle(gfx::Font::BOLD).GetHeight())),
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mirroring_context_(new MirroringContext()),
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      keyword_icon_(new views::ImageView()),
141d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      animation_(new gfx::SlideAnimation(this)) {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_GE(model_index, 0);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (default_icon_size_ == 0) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default_icon_size_ =
145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        location_bar_view_->GetThemeProvider()->GetImageSkiaNamed(
14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            AutocompleteMatch::TypeToIcon(
14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                AutocompleteMatchType::URL_WHAT_YOU_TYPED))->width();
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  keyword_icon_->set_owned_by_client();
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  keyword_icon_->EnableCanvasFlippingForRTLUI(true);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  keyword_icon_->SetImage(GetKeywordIcon());
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  keyword_icon_->SizeToPreferredSize();
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OmniboxResultView::~OmniboxResultView() {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkColor OmniboxResultView::GetColor(
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ResultViewState state,
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ColorKind kind) const {
161c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  for (size_t i = 0; i < arraysize(kTranslationTable); ++i) {
162c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    if (kTranslationTable[i].state == state &&
163c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        kTranslationTable[i].kind == kind) {
164c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      return GetNativeTheme()->GetSystemColor(kTranslationTable[i].id);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
167c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
168c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  NOTREACHED();
169c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return SK_ColorRED;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OmniboxResultView::SetMatch(const AutocompleteMatch& match) {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  match_ = match;
17423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  ResetRenderTexts();
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  animation_->Reset();
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AutocompleteMatch* associated_keyword_match = match_.associated_keyword.get();
178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (associated_keyword_match) {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keyword_icon_->SetImage(GetKeywordIcon());
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!keyword_icon_->parent())
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AddChildView(keyword_icon_.get());
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (keyword_icon_->parent()) {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RemoveChildView(keyword_icon_.get());
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Layout();
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OmniboxResultView::ShowKeyword(bool show_keyword) {
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (show_keyword)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    animation_->Show();
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    animation_->Hide();
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OmniboxResultView::Invalidate() {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  keyword_icon_->SetImage(GetKeywordIcon());
19823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // While the text in the RenderTexts may not have changed, the styling
19923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // (color/bold) may need to change. So we reset them to cause them to be
20023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // recomputed in OnPaint().
20123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  ResetRenderTexts();
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SchedulePaint();
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size OmniboxResultView::GetPreferredSize() const {
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::Size(0, std::max(
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default_icon_size_ + (kMinimumIconVerticalPadding * 2),
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetTextHeight() + (minimum_text_vertical_padding_ * 2)));
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OmniboxResultView, protected:
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OmniboxResultView::ResultViewState OmniboxResultView::GetState() const {
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (model_->IsSelectedIndex(model_index_))
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SELECTED;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return model_->IsHoveredIndex(model_index_) ? HOVERED : NORMAL;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int OmniboxResultView::GetTextHeight() const {
221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return font_height_;
222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
22423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void OmniboxResultView::PaintMatch(
22523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const AutocompleteMatch& match,
22623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    gfx::RenderText* contents,
22723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    gfx::RenderText* description,
22823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    gfx::Canvas* canvas,
22923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    int x) const {
230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int y = text_bounds_.y();
231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
23223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (!separator_rendertext_) {
23323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const base::string16& separator =
23423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        l10n_util::GetStringUTF16(IDS_AUTOCOMPLETE_MATCH_DESCRIPTION_SEPARATOR);
23523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    separator_rendertext_.reset(CreateRenderText(separator).release());
23623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    separator_rendertext_->SetColor(GetColor(GetState(), DIMMED_TEXT));
23723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    separator_width_ = separator_rendertext_->GetContentWidth();
23823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
24023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  int contents_max_width, description_max_width;
24123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  OmniboxPopupModel::ComputeMatchMaxWidths(
24223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      contents->GetContentWidth(),
24323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      separator_width_,
24423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      description ? description->GetContentWidth() : 0,
245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      mirroring_context_->remaining_width(x),
246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      !AutocompleteMatch::IsSearchType(match.type),
247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      &contents_max_width,
248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      &description_max_width);
249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
25023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  x = DrawRenderText(match, contents, true, canvas, x, y, contents_max_width);
251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (description_max_width != 0) {
25323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    x = DrawRenderText(match, separator_rendertext_.get(), false, canvas, x, y,
25423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                       separator_width_);
25523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    DrawRenderText(match, description, false, canvas, x, y,
25623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                   description_max_width);
257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)int OmniboxResultView::DrawRenderText(
26123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const AutocompleteMatch& match,
262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    gfx::RenderText* render_text,
263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    bool contents,
26423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    gfx::Canvas* canvas,
265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int x,
266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int y,
267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int max_width) const {
268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(!render_text->text().empty());
269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
270effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  const int remaining_width = mirroring_context_->remaining_width(x);
271effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  int right_x = x + max_width;
272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Infinite suggestions should appear with the leading ellipses vertically
274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // stacked.
275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (contents &&
276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      (match.type == AutocompleteMatchType::SEARCH_SUGGEST_INFINITE)) {
277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // When the directionality of suggestion doesn't match the UI, we try to
278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // vertically stack the ellipsis by restricting the end edge (right_x).
279a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const bool is_ui_rtl = base::i18n::IsRTL();
280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const bool is_match_contents_rtl =
281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        (render_text->GetTextDirection() == base::i18n::RIGHT_TO_LEFT);
28223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const int offset =
28323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        GetDisplayOffset(match, is_ui_rtl, is_match_contents_rtl);
284a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    scoped_ptr<gfx::RenderText> prefix_render_text(
286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        CreateRenderText(base::UTF8ToUTF16(
287effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch            match.GetAdditionalInfo(kACMatchPropertyContentsPrefix))));
288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const int prefix_width = prefix_render_text->GetContentWidth();
289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int prefix_x = x;
290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const int max_match_contents_width = model_->max_match_contents_width();
292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (is_ui_rtl != is_match_contents_rtl) {
294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // RTL infinite suggestions appear near the left edge in LTR UI, while LTR
295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // infinite suggestions appear near the right edge in RTL UI. This is
296a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // against the natural horizontal alignment of the text. We reduce the
297a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // width of the box for suggestion display, so that the suggestions appear
298a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // in correct confines.  This reduced width allows us to modify the text
299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // alignment (see below).
300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      right_x = x + std::min(remaining_width - prefix_width,
301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             std::max(offset, max_match_contents_width));
302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      prefix_x = right_x;
303a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // We explicitly set the horizontal alignment so that when LTR suggestions
304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // show in RTL UI (or vice versa), their ellipses appear stacked in a
305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // single column.
306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      render_text->SetHorizontalAlignment(
307a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          is_match_contents_rtl ? gfx::ALIGN_RIGHT : gfx::ALIGN_LEFT);
308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    } else {
309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // If the dropdown is wide enough, place the ellipsis at the position
310a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // where the omitted text would have ended. Otherwise reduce the offset of
311a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // the ellipsis such that the widest suggestion reaches the end of the
312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // dropdown.
313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const int start_offset = std::max(prefix_width,
314effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          std::min(remaining_width - max_match_contents_width, offset));
31523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      right_x = x + std::min(remaining_width, start_offset + max_width);
316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      x += start_offset;
317a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      prefix_x = x - prefix_width;
318a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    prefix_render_text->SetDirectionalityMode(is_match_contents_rtl ?
320a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        gfx::DIRECTIONALITY_FORCE_RTL : gfx::DIRECTIONALITY_FORCE_LTR);
321a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    prefix_render_text->SetHorizontalAlignment(
322a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          is_match_contents_rtl ? gfx::ALIGN_RIGHT : gfx::ALIGN_LEFT);
323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    prefix_render_text->SetDisplayRect(gfx::Rect(
324a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          mirroring_context_->mirrored_left_coord(
325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)              prefix_x, prefix_x + prefix_width), y,
326a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          prefix_width, height()));
327a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    prefix_render_text->Draw(canvas);
328a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
329a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
330a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Set the display rect to trigger eliding.
331a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  render_text->SetDisplayRect(gfx::Rect(
332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      mirroring_context_->mirrored_left_coord(x, right_x), y,
333a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      right_x - x, height()));
334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  render_text->Draw(canvas);
335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return right_x;
336a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
337a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
338a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)scoped_ptr<gfx::RenderText> OmniboxResultView::CreateRenderText(
339a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const base::string16& text) const {
340a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<gfx::RenderText> render_text(gfx::RenderText::CreateInstance());
341116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  render_text->SetDisplayRect(gfx::Rect(gfx::Size(INT_MAX, 0)));
34223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  render_text->SetCursorEnabled(false);
34346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  render_text->SetElideBehavior(gfx::ELIDE_TAIL);
344a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  render_text->SetFontList(font_list_);
345a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  render_text->SetText(text);
346a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return render_text.Pass();
347a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
348a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
34923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)scoped_ptr<gfx::RenderText> OmniboxResultView::CreateClassifiedRenderText(
35023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const base::string16& text,
351a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const ACMatchClassifications& classifications,
352a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    bool force_dim) const {
35323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_ptr<gfx::RenderText> render_text(CreateRenderText(text));
354a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const size_t text_length = render_text->text().length();
355a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (size_t i = 0; i < classifications.size(); ++i) {
356a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const size_t text_start = classifications[i].offset;
357a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (text_start >= text_length)
358a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      break;
359a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
360a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const size_t text_end = (i < (classifications.size() - 1)) ?
361a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        std::min(classifications[i + 1].offset, text_length) :
362a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        text_length;
363a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const gfx::Range current_range(text_start, text_end);
364a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
365a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Calculate style-related data.
366a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (classifications[i].style & ACMatchClassification::MATCH)
367a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      render_text->ApplyStyle(gfx::BOLD, true, current_range);
368a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
369a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ColorKind color_kind = TEXT;
370a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (classifications[i].style & ACMatchClassification::URL) {
371a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      color_kind = URL;
372a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // Consider logical string for domain "ABC.comי/hello" where ABC are
373a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // Hebrew (RTL) characters. This string should ideally show as
374a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // "CBA.com/hello". If we do not force LTR on URL, it will appear as
375a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // "com/hello.CBA".
376a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // With IDN and RTL TLDs, it might be okay to allow RTL rendering of URLs,
377a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // but it still has some pitfalls like :
378a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // ABC.COM/abc-pqr/xyz/FGH will appear as HGF/abc-pqr/xyz/MOC.CBA which
379a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // really confuses the path hierarchy of the URL.
380a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // Also, if the URL supports https, the appearance will change into LTR
381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // directionality.
382a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // In conclusion, LTR rendering of URL is probably the safest bet.
383a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      render_text->SetDirectionalityMode(gfx::DIRECTIONALITY_FORCE_LTR);
384a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    } else if (force_dim ||
385a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        (classifications[i].style & ACMatchClassification::DIM)) {
386a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      color_kind = DIMMED_TEXT;
387a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
388a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    render_text->ApplyColor(GetColor(GetState(), color_kind), current_range);
389a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
39023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return render_text.Pass();
391a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
392a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
393a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)int OmniboxResultView::GetMatchContentsWidth() const {
39423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  InitContentsRenderTextIfNecessary();
39523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return contents_rendertext_ ? contents_rendertext_->GetContentWidth() : 0;
396a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
397a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
398a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// TODO(skanuj): This is probably identical across all OmniboxResultView rows in
399a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// the omnibox dropdown. Consider sharing the result.
400a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)int OmniboxResultView::GetDisplayOffset(
40123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const AutocompleteMatch& match,
402a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    bool is_ui_rtl,
403a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    bool is_match_contents_rtl) const {
404a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (match.type != AutocompleteMatchType::SEARCH_SUGGEST_INFINITE)
405a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return 0;
406a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
407a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const base::string16& input_text =
408effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      base::UTF8ToUTF16(match.GetAdditionalInfo(kACMatchPropertyInputText));
409a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int contents_start_index = 0;
410effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  base::StringToInt(match.GetAdditionalInfo(kACMatchPropertyContentsStartIndex),
411a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    &contents_start_index);
412a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
413a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<gfx::RenderText> input_render_text(CreateRenderText(input_text));
414a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const gfx::Range& glyph_bounds =
415a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      input_render_text->GetGlyphBounds(contents_start_index);
416a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const int start_padding = is_match_contents_rtl ?
417a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      std::max(glyph_bounds.start(), glyph_bounds.end()) :
418a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      std::min(glyph_bounds.start(), glyph_bounds.end());
419a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
420a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return is_ui_rtl ?
421a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      (input_render_text->GetContentWidth() - start_padding) : start_padding;
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
425a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)int OmniboxResultView::default_icon_size_ = 0;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::ImageSkia OmniboxResultView::GetIcon() const {
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const gfx::Image image = model_->GetIconIfExtensionMatch(model_index_);
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!image.IsEmpty())
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return image.AsImageSkia();
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int icon = model_->IsStarredMatch(match_) ?
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IDR_OMNIBOX_STAR : AutocompleteMatch::TypeToIcon(match_.type);
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (GetState() == SELECTED) {
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (icon) {
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case IDR_OMNIBOX_EXTENSION_APP:
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        icon = IDR_OMNIBOX_EXTENSION_APP_SELECTED;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case IDR_OMNIBOX_HTTP:
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        icon = IDR_OMNIBOX_HTTP_SELECTED;
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case IDR_OMNIBOX_SEARCH:
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        icon = IDR_OMNIBOX_SEARCH_SELECTED;
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case IDR_OMNIBOX_STAR:
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        icon = IDR_OMNIBOX_STAR_SELECTED;
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NOTREACHED();
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
453868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return *(location_bar_view_->GetThemeProvider()->GetImageSkiaNamed(icon));
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const gfx::ImageSkia* OmniboxResultView::GetKeywordIcon() const {
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: If we ever begin returning icons of varying size, then callers need
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to ensure that |keyword_icon_| is resized each time its image is reset.
459868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return location_bar_view_->GetThemeProvider()->GetImageSkiaNamed(
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (GetState() == SELECTED) ? IDR_OMNIBOX_TTS_SELECTED : IDR_OMNIBOX_TTS);
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)bool OmniboxResultView::ShowOnlyKeywordMatch() const {
46423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return match_.associated_keyword &&
46523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      (keyword_icon_->x() <= icon_bounds_.right());
46623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
46723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
46823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void OmniboxResultView::ResetRenderTexts() const {
46923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  contents_rendertext_.reset();
47023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  description_rendertext_.reset();
47123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  separator_rendertext_.reset();
47223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  keyword_contents_rendertext_.reset();
47323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  keyword_description_rendertext_.reset();
47423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
47523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
47623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void OmniboxResultView::InitContentsRenderTextIfNecessary() const {
47723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (!contents_rendertext_) {
47823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    contents_rendertext_.reset(
47923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        CreateClassifiedRenderText(
48023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)            match_.contents, match_.contents_class, false).release());
48123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
48223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
48323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OmniboxResultView::Layout() {
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const gfx::ImageSkia icon = GetIcon();
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  icon_bounds_.SetRect(edge_item_padding_ +
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ((icon.width() == default_icon_size_) ?
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          0 : LocationBarView::kIconInternalPadding),
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (height() - icon.height()) / 2, icon.width(), icon.height());
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int text_x = edge_item_padding_ + default_icon_size_ + item_padding_;
4930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  int text_width = width() - text_x - edge_item_padding_;
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (match_.associated_keyword.get()) {
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int kw_collapsed_size =
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        keyword_icon_->width() + edge_item_padding_;
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int max_kw_x = width() - kw_collapsed_size;
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int kw_x =
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        animation_->CurrentValueBetween(max_kw_x, edge_item_padding_);
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int kw_text_x = kw_x + keyword_icon_->width() + item_padding_;
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    text_width = kw_x - text_x - item_padding_;
5040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    keyword_text_bounds_.SetRect(
5050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        kw_text_x, 0,
5060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        std::max(width() - kw_text_x - edge_item_padding_, 0), height());
5070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    keyword_icon_->SetPosition(
5080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        gfx::Point(kw_x, (height() - keyword_icon_->height()) / 2));
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  text_bounds_.SetRect(text_x, 0, std::max(text_width, 0), height());
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OmniboxResultView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  animation_->SetSlideDuration(width() / 4);
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OmniboxResultView::OnPaint(gfx::Canvas* canvas) {
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ResultViewState state = GetState();
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (state != NORMAL)
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->DrawColor(GetColor(state, BACKGROUND));
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // NOTE: While animating the keyword match, both matches may be visible.
52423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
52523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (!ShowOnlyKeywordMatch()) {
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->DrawImageInt(GetIcon(), GetMirroredXForRect(icon_bounds_),
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         icon_bounds_.y());
52823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    int x = GetMirroredXForRect(text_bounds_);
52923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    mirroring_context_->Initialize(x, text_bounds_.width());
53023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    InitContentsRenderTextIfNecessary();
53123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    if (!description_rendertext_ && !match_.description.empty()) {
53223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      description_rendertext_.reset(
53323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)          CreateClassifiedRenderText(
53423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)              match_.description, match_.description_class, true).release());
53523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    }
53623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    PaintMatch(match_, contents_rendertext_.get(),
53723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)               description_rendertext_.get(), canvas, x);
53823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
53923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
54023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  AutocompleteMatch* keyword_match = match_.associated_keyword.get();
54123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (keyword_match) {
54223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    int x = GetMirroredXForRect(keyword_text_bounds_);
54323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    mirroring_context_->Initialize(x, keyword_text_bounds_.width());
54423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    if (!keyword_contents_rendertext_) {
54523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      keyword_contents_rendertext_.reset(
54623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)          CreateClassifiedRenderText(keyword_match->contents,
54723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                     keyword_match->contents_class,
54823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                     false).release());
54923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    }
55023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    if (!keyword_description_rendertext_ &&
55123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        !keyword_match->description.empty()) {
55223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      keyword_description_rendertext_.reset(
55323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)          CreateClassifiedRenderText(keyword_match->description,
55423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                     keyword_match->description_class,
55523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                     true).release());
55623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    }
55723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    PaintMatch(*keyword_match, keyword_contents_rendertext_.get(),
55823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)               keyword_description_rendertext_.get(), canvas, x);
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
562d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void OmniboxResultView::AnimationProgressed(const gfx::Animation* animation) {
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Layout();
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SchedulePaint();
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
566