| Index: chrome/browser/ui/views/omnibox/omnibox_result_view.cc
|
| diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
|
| index 7d199b2e0dbccb195cd26487303becfb5a658a30..d79a220fb1fb4ca087af2663bebb8e77326f6e43 100644
|
| --- a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
|
| +++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
|
| @@ -50,27 +50,20 @@ const int kMinimumTextVerticalPadding = 3;
|
| ////////////////////////////////////////////////////////////////////////////////
|
| // OmniboxResultView, public:
|
|
|
| -// Precalculated data used to draw the portion of a match classification that
|
| -// fits entirely within one run.
|
| -struct OmniboxResultView::ClassificationData {
|
| - string16 text;
|
| - const gfx::Font* font;
|
| - SkColor color;
|
| - gfx::Size pixel_size;
|
| - gfx::RenderText* render_text; // Weak.
|
| -};
|
| -
|
| // Precalculated data used to draw a complete visual run within the match.
|
| -// This will include all or part of at leasdt one, and possibly several,
|
| +// This will include all or part of at least one, and possibly several,
|
| // classifications.
|
| struct OmniboxResultView::RunData {
|
| + RunData() : run_start(0), visual_order(0), is_rtl(false), pixel_width(0) {}
|
| +
|
| size_t run_start; // Offset within the match text where this run begins.
|
| int visual_order; // Where this run occurs in visual order. The earliest
|
| // run drawn is run 0.
|
| bool is_rtl;
|
| int pixel_width;
|
| - Classifications classifications; // Classification pieces within this run,
|
| - // in logical order.
|
| +
|
| + // Styled text classification pieces within this run, in logical order.
|
| + Classifications classifications;
|
| };
|
|
|
| // This class is a utility class for calculations affected by whether the result
|
| @@ -112,15 +105,15 @@ class OmniboxResultView::MirroringContext {
|
| OmniboxResultView::OmniboxResultView(
|
| OmniboxResultViewModel* model,
|
| int model_index,
|
| - const gfx::Font& font,
|
| - const gfx::Font& bold_font)
|
| + const gfx::Font& font)
|
| : edge_item_padding_(LocationBarView::GetItemPadding()),
|
| item_padding_(LocationBarView::GetItemPadding()),
|
| minimum_text_vertical_padding_(kMinimumTextVerticalPadding),
|
| model_(model),
|
| model_index_(model_index),
|
| - normal_font_(font),
|
| - bold_font_(bold_font),
|
| + font_(font),
|
| + font_height_(std::max(font.GetHeight(),
|
| + font.DeriveFont(0, gfx::BOLD).GetHeight())),
|
| ellipsis_width_(font.GetStringWidth(string16(kEllipsis))),
|
| mirroring_context_(new MirroringContext()),
|
| keyword_icon_(new views::ImageView()),
|
| @@ -249,7 +242,7 @@ void OmniboxResultView::PaintMatch(gfx::Canvas* canvas,
|
| }
|
|
|
| int OmniboxResultView::GetTextHeight() const {
|
| - return std::max(normal_font_.GetHeight(), bold_font_.GetHeight());
|
| + return font_height_;
|
| }
|
|
|
| // static
|
| @@ -400,36 +393,24 @@ int OmniboxResultView::DrawString(
|
| if (text_end <= current_run->run_start)
|
| continue; // We haven't reached the first classification in the run.
|
|
|
| - current_run->classifications.push_back(ClassificationData());
|
| - ClassificationData* current_data =
|
| - ¤t_run->classifications.back();
|
| - current_data->text = text.substr(text_start, text_end - text_start);
|
| + render_texts.push_back(gfx::RenderText::CreateInstance());
|
| + gfx::RenderText* render_text = render_texts.back();
|
| + current_run->classifications.push_back(render_text);
|
| + render_text->SetText(text.substr(text_start, text_end - text_start));
|
| + render_text->SetFont(font_);
|
|
|
| // Calculate style-related data.
|
| - const int style = classifications[i].style;
|
| - const bool use_bold_font = !!(style & ACMatchClassification::MATCH);
|
| - current_data->font = &(use_bold_font ? bold_font_ : normal_font_);
|
| + if (classifications[i].style & ACMatchClassification::MATCH)
|
| + render_text->SetStyle(gfx::BOLD, true);
|
| const ResultViewState state = GetState();
|
| - if (style & ACMatchClassification::URL)
|
| - current_data->color = GetColor(state, URL);
|
| - else if (style & ACMatchClassification::DIM)
|
| - current_data->color = GetColor(state, DIMMED_TEXT);
|
| + if (classifications[i].style & ACMatchClassification::URL)
|
| + render_text->SetColor(GetColor(state, URL));
|
| + else if (classifications[i].style & ACMatchClassification::DIM)
|
| + render_text->SetColor(GetColor(state, DIMMED_TEXT));
|
| else
|
| - current_data->color = GetColor(state, force_dim ? DIMMED_TEXT : TEXT);
|
| + render_text->SetColor(GetColor(state, force_dim ? DIMMED_TEXT : TEXT));
|
|
|
| - render_texts.push_back(gfx::RenderText::CreateInstance());
|
| - current_data->render_text = render_texts.back();
|
| - current_data->render_text->SetFont(*current_data->font);
|
| - current_data->render_text->SetText(current_data->text);
|
| -
|
| - gfx::StyleRange style_range;
|
| - style_range.foreground = current_data->color;
|
| - style_range.font_style = current_data->font->GetStyle();
|
| - current_data->render_text->set_default_style(style_range);
|
| - current_data->render_text->ApplyDefaultStyle();
|
| -
|
| - current_data->pixel_size = current_data->render_text->GetStringSize();
|
| - current_run->pixel_width += current_data->pixel_size.width();
|
| + current_run->pixel_width += render_text->GetStringSize().width();
|
| }
|
| DCHECK(!current_run->classifications.empty());
|
| }
|
| @@ -452,7 +433,8 @@ int OmniboxResultView::DrawString(
|
| // This run or one before it needs to be elided.
|
| for (Classifications::iterator j(i->classifications.begin());
|
| j != i->classifications.end(); ++j) {
|
| - if (j->pixel_size.width() > remaining_width) {
|
| + const int width = (*j)->GetStringSize().width();
|
| + if (width > remaining_width) {
|
| // This classification or one before it needs to be elided. Erase all
|
| // further classifications and runs so Elide() can simply reverse-
|
| // iterate over everything to find the specific classification to
|
| @@ -462,7 +444,7 @@ int OmniboxResultView::DrawString(
|
| Elide(&runs, remaining_width);
|
| break;
|
| }
|
| - remaining_width -= j->pixel_size.width();
|
| + remaining_width -= width;
|
| }
|
| break;
|
| }
|
| @@ -479,15 +461,15 @@ int OmniboxResultView::DrawString(
|
| std::reverse(i->classifications.begin(), i->classifications.end());
|
| for (Classifications::const_iterator j(i->classifications.begin());
|
| j != i->classifications.end(); ++j) {
|
| - const int left =
|
| - mirroring_context_->mirrored_left_coord(x, x + j->pixel_size.width());
|
| + const gfx::Size size = (*j)->GetStringSize();
|
| // Align the text runs to a common baseline.
|
| - const int top =
|
| - y + normal_font_.GetBaseline() - j->render_text->GetBaseline();
|
| - gfx::Rect rect(left, top, j->pixel_size.width(), j->pixel_size.height());
|
| - j->render_text->SetDisplayRect(rect);
|
| - j->render_text->Draw(canvas);
|
| - x += j->pixel_size.width();
|
| + const gfx::Rect rect(
|
| + mirroring_context_->mirrored_left_coord(x, x + size.width()),
|
| + y + font_.GetBaseline() - (*j)->GetBaseline(),
|
| + size.width(), size.height());
|
| + (*j)->SetDisplayRect(rect);
|
| + (*j)->Draw(canvas);
|
| + x += size.width();
|
| }
|
| }
|
|
|
| @@ -511,26 +493,23 @@ void OmniboxResultView::Elide(Runs* runs, int remaining_width) const {
|
| for (Classifications::reverse_iterator j(i->classifications.rbegin());
|
| j != i->classifications.rend(); ++j) {
|
| if (!first_classification) {
|
| - // For all but the first classification we consider, we need to append
|
| - // an ellipsis, since there isn't enough room to draw it after this
|
| - // classification.
|
| - j->text += kEllipsis;
|
| - j->render_text->SetText(j->text);
|
| -
|
| // We also add this classification's width (sans ellipsis) back to the
|
| // available width since we want to consider the available space we'll
|
| // have when we draw this classification.
|
| - remaining_width += j->pixel_size.width();
|
| + remaining_width += (*j)->GetStringSize().width();
|
| +
|
| + // For all but the first classification we consider, we need to append
|
| + // an ellipsis, since there isn't enough room to draw it after this
|
| + // classification.
|
| + (*j)->SetText((*j)->text() + kEllipsis);
|
| }
|
| first_classification = false;
|
|
|
| // Can we fit at least an ellipsis?
|
| - string16 elided_text =
|
| - ui::ElideText(j->text, *j->font, remaining_width, ui::ELIDE_AT_END);
|
| - Classifications::reverse_iterator prior_classification(j);
|
| - ++prior_classification;
|
| - const bool on_first_classification =
|
| - (prior_classification == i->classifications.rend());
|
| + string16 elided_text = ui::ElideText((*j)->text(), (*j)->GetFont(),
|
| + remaining_width, ui::ELIDE_AT_END);
|
| + Classifications::reverse_iterator prior(j + 1);
|
| + const bool on_first_classification = (prior == i->classifications.rend());
|
| if (elided_text.empty() && (remaining_width >= ellipsis_width_) &&
|
| on_first_classification) {
|
| // Edge case: This classification is bold, we can't fit a bold ellipsis
|
| @@ -545,21 +524,18 @@ void OmniboxResultView::Elide(Runs* runs, int remaining_width) const {
|
| }
|
| if (!elided_text.empty()) {
|
| // Success. Elide this classification and stop.
|
| - j->text = elided_text;
|
| + (*j)->SetText(elided_text);
|
|
|
| // If we could only fit an ellipsis, then only make it bold if there was
|
| // an immediate prior classification in this run that was also bold, or
|
| // it will look orphaned.
|
| - if ((j->font != &normal_font_) && (elided_text.length() == 1) &&
|
| + if ((((*j)->GetFont().GetStyle() & gfx::BOLD) != 0) &&
|
| + (elided_text.length() == 1) &&
|
| (on_first_classification ||
|
| - (prior_classification->font == &normal_font_))) {
|
| - j->font = &normal_font_;
|
| - j->render_text->SetFont(*j->font);
|
| + (((*prior)->GetFont().GetStyle() & gfx::BOLD) == 0))) {
|
| + (*j)->SetStyle(gfx::BOLD, false);
|
| }
|
|
|
| - j->render_text->SetText(elided_text);
|
| - j->pixel_size = j->render_text->GetStringSize();
|
| -
|
| // Erase any other classifications that come after the elided one.
|
| i->classifications.erase(j.base(), i->classifications.end());
|
| runs->erase(i.base(), runs->end());
|
|
|