| 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 // For WinDDK ATL compatibility, these ATL headers must come first. | 5 // For WinDDK ATL compatibility, these ATL headers must come first. |
| 6 #include "build/build_config.h" | 6 #include "build/build_config.h" |
| 7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
| 8 #include <atlbase.h> // NOLINT | 8 #include <atlbase.h> // NOLINT |
| 9 #include <atlwin.h> // NOLINT | 9 #include <atlwin.h> // NOLINT |
| 10 #endif | 10 #endif |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 // The minimum distance between the top and bottom of the {icon|text} and the | 43 // The minimum distance between the top and bottom of the {icon|text} and the |
| 44 // top or bottom of the row. | 44 // top or bottom of the row. |
| 45 const int kMinimumIconVerticalPadding = 2; | 45 const int kMinimumIconVerticalPadding = 2; |
| 46 const int kMinimumTextVerticalPadding = 3; | 46 const int kMinimumTextVerticalPadding = 3; |
| 47 | 47 |
| 48 } // namespace | 48 } // namespace |
| 49 | 49 |
| 50 //////////////////////////////////////////////////////////////////////////////// | 50 //////////////////////////////////////////////////////////////////////////////// |
| 51 // OmniboxResultView, public: | 51 // OmniboxResultView, public: |
| 52 | 52 |
| 53 // Precalculated data used to draw the portion of a match classification that | |
| 54 // fits entirely within one run. | |
| 55 struct OmniboxResultView::ClassificationData { | |
| 56 string16 text; | |
| 57 const gfx::Font* font; | |
| 58 SkColor color; | |
| 59 gfx::Size pixel_size; | |
| 60 gfx::RenderText* render_text; // Weak. | |
| 61 }; | |
| 62 | |
| 63 // Precalculated data used to draw a complete visual run within the match. | 53 // Precalculated data used to draw a complete visual run within the match. |
| 64 // This will include all or part of at leasdt one, and possibly several, | 54 // This will include all or part of at least one, and possibly several, |
| 65 // classifications. | 55 // classifications. |
| 66 struct OmniboxResultView::RunData { | 56 struct OmniboxResultView::RunData { |
| 57 RunData() : run_start(0), visual_order(0), is_rtl(false), pixel_width(0) {} |
| 58 |
| 67 size_t run_start; // Offset within the match text where this run begins. | 59 size_t run_start; // Offset within the match text where this run begins. |
| 68 int visual_order; // Where this run occurs in visual order. The earliest | 60 int visual_order; // Where this run occurs in visual order. The earliest |
| 69 // run drawn is run 0. | 61 // run drawn is run 0. |
| 70 bool is_rtl; | 62 bool is_rtl; |
| 71 int pixel_width; | 63 int pixel_width; |
| 72 Classifications classifications; // Classification pieces within this run, | 64 |
| 73 // in logical order. | 65 // Styled text classification pieces within this run, in logical order. |
| 66 Classifications classifications; |
| 74 }; | 67 }; |
| 75 | 68 |
| 76 // This class is a utility class for calculations affected by whether the result | 69 // This class is a utility class for calculations affected by whether the result |
| 77 // view is horizontally mirrored. The drawing functions can be written as if | 70 // view is horizontally mirrored. The drawing functions can be written as if |
| 78 // all drawing occurs left-to-right, and then use this class to get the actual | 71 // all drawing occurs left-to-right, and then use this class to get the actual |
| 79 // coordinates to begin drawing onscreen. | 72 // coordinates to begin drawing onscreen. |
| 80 class OmniboxResultView::MirroringContext { | 73 class OmniboxResultView::MirroringContext { |
| 81 public: | 74 public: |
| 82 MirroringContext() : center_(0), right_(0) {} | 75 MirroringContext() : center_(0), right_(0) {} |
| 83 | 76 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 105 private: | 98 private: |
| 106 int center_; | 99 int center_; |
| 107 int right_; | 100 int right_; |
| 108 | 101 |
| 109 DISALLOW_COPY_AND_ASSIGN(MirroringContext); | 102 DISALLOW_COPY_AND_ASSIGN(MirroringContext); |
| 110 }; | 103 }; |
| 111 | 104 |
| 112 OmniboxResultView::OmniboxResultView( | 105 OmniboxResultView::OmniboxResultView( |
| 113 OmniboxResultViewModel* model, | 106 OmniboxResultViewModel* model, |
| 114 int model_index, | 107 int model_index, |
| 115 const gfx::Font& font, | 108 const gfx::Font& font) |
| 116 const gfx::Font& bold_font) | |
| 117 : edge_item_padding_(LocationBarView::GetItemPadding()), | 109 : edge_item_padding_(LocationBarView::GetItemPadding()), |
| 118 item_padding_(LocationBarView::GetItemPadding()), | 110 item_padding_(LocationBarView::GetItemPadding()), |
| 119 minimum_text_vertical_padding_(kMinimumTextVerticalPadding), | 111 minimum_text_vertical_padding_(kMinimumTextVerticalPadding), |
| 120 model_(model), | 112 model_(model), |
| 121 model_index_(model_index), | 113 model_index_(model_index), |
| 122 normal_font_(font), | 114 font_(font), |
| 123 bold_font_(bold_font), | 115 font_height_(std::max(font.GetHeight(), |
| 116 font.DeriveFont(0, gfx::BOLD).GetHeight())), |
| 124 ellipsis_width_(font.GetStringWidth(string16(kEllipsis))), | 117 ellipsis_width_(font.GetStringWidth(string16(kEllipsis))), |
| 125 mirroring_context_(new MirroringContext()), | 118 mirroring_context_(new MirroringContext()), |
| 126 keyword_icon_(new views::ImageView()), | 119 keyword_icon_(new views::ImageView()), |
| 127 ALLOW_THIS_IN_INITIALIZER_LIST( | 120 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 128 animation_(new ui::SlideAnimation(this))) { | 121 animation_(new ui::SlideAnimation(this))) { |
| 129 CHECK_GE(model_index, 0); | 122 CHECK_GE(model_index, 0); |
| 130 if (default_icon_size_ == 0) { | 123 if (default_icon_size_ == 0) { |
| 131 default_icon_size_ = | 124 default_icon_size_ = |
| 132 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( | 125 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( |
| 133 AutocompleteMatch::TypeToIcon(AutocompleteMatch::URL_WHAT_YOU_TYPED))-> | 126 AutocompleteMatch::TypeToIcon(AutocompleteMatch::URL_WHAT_YOU_TYPED))-> |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 242 ACMatchClassification(0, ACMatchClassification::NONE)); | 235 ACMatchClassification(0, ACMatchClassification::NONE)); |
| 243 x = DrawString(canvas, separator, classifications, true, x, | 236 x = DrawString(canvas, separator, classifications, true, x, |
| 244 text_bounds_.y()); | 237 text_bounds_.y()); |
| 245 | 238 |
| 246 DrawString(canvas, match.description, match.description_class, true, x, | 239 DrawString(canvas, match.description, match.description_class, true, x, |
| 247 text_bounds_.y()); | 240 text_bounds_.y()); |
| 248 } | 241 } |
| 249 } | 242 } |
| 250 | 243 |
| 251 int OmniboxResultView::GetTextHeight() const { | 244 int OmniboxResultView::GetTextHeight() const { |
| 252 return std::max(normal_font_.GetHeight(), bold_font_.GetHeight()); | 245 return font_height_; |
| 253 } | 246 } |
| 254 | 247 |
| 255 // static | 248 // static |
| 256 void OmniboxResultView::CommonInitColors(const ui::NativeTheme* theme, | 249 void OmniboxResultView::CommonInitColors(const ui::NativeTheme* theme, |
| 257 SkColor colors[][NUM_KINDS]) { | 250 SkColor colors[][NUM_KINDS]) { |
| 258 colors[HOVERED][BACKGROUND] = | 251 colors[HOVERED][BACKGROUND] = |
| 259 color_utils::AlphaBlend(colors[SELECTED][BACKGROUND], | 252 color_utils::AlphaBlend(colors[SELECTED][BACKGROUND], |
| 260 colors[NORMAL][BACKGROUND], 64); | 253 colors[NORMAL][BACKGROUND], 64); |
| 261 colors[HOVERED][TEXT] = colors[NORMAL][TEXT]; | 254 colors[HOVERED][TEXT] = colors[NORMAL][TEXT]; |
| 262 #if defined(USE_AURA) | 255 #if defined(USE_AURA) |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 393 const size_t text_start = | 386 const size_t text_start = |
| 394 std::max(classifications[i].offset, current_run->run_start); | 387 std::max(classifications[i].offset, current_run->run_start); |
| 395 if (text_start >= run_end) | 388 if (text_start >= run_end) |
| 396 break; // We're past the last classification in the run. | 389 break; // We're past the last classification in the run. |
| 397 | 390 |
| 398 const size_t text_end = (i < (classifications.size() - 1)) ? | 391 const size_t text_end = (i < (classifications.size() - 1)) ? |
| 399 std::min(classifications[i + 1].offset, run_end) : run_end; | 392 std::min(classifications[i + 1].offset, run_end) : run_end; |
| 400 if (text_end <= current_run->run_start) | 393 if (text_end <= current_run->run_start) |
| 401 continue; // We haven't reached the first classification in the run. | 394 continue; // We haven't reached the first classification in the run. |
| 402 | 395 |
| 403 current_run->classifications.push_back(ClassificationData()); | 396 render_texts.push_back(gfx::RenderText::CreateInstance()); |
| 404 ClassificationData* current_data = | 397 gfx::RenderText* render_text = render_texts.back(); |
| 405 ¤t_run->classifications.back(); | 398 current_run->classifications.push_back(render_text); |
| 406 current_data->text = text.substr(text_start, text_end - text_start); | 399 render_text->SetText(text.substr(text_start, text_end - text_start)); |
| 400 render_text->SetFont(font_); |
| 407 | 401 |
| 408 // Calculate style-related data. | 402 // Calculate style-related data. |
| 409 const int style = classifications[i].style; | 403 if (classifications[i].style & ACMatchClassification::MATCH) |
| 410 const bool use_bold_font = !!(style & ACMatchClassification::MATCH); | 404 render_text->SetStyle(gfx::BOLD, true); |
| 411 current_data->font = &(use_bold_font ? bold_font_ : normal_font_); | |
| 412 const ResultViewState state = GetState(); | 405 const ResultViewState state = GetState(); |
| 413 if (style & ACMatchClassification::URL) | 406 if (classifications[i].style & ACMatchClassification::URL) |
| 414 current_data->color = GetColor(state, URL); | 407 render_text->SetColor(GetColor(state, URL)); |
| 415 else if (style & ACMatchClassification::DIM) | 408 else if (classifications[i].style & ACMatchClassification::DIM) |
| 416 current_data->color = GetColor(state, DIMMED_TEXT); | 409 render_text->SetColor(GetColor(state, DIMMED_TEXT)); |
| 417 else | 410 else |
| 418 current_data->color = GetColor(state, force_dim ? DIMMED_TEXT : TEXT); | 411 render_text->SetColor(GetColor(state, force_dim ? DIMMED_TEXT : TEXT)); |
| 419 | 412 |
| 420 render_texts.push_back(gfx::RenderText::CreateInstance()); | 413 current_run->pixel_width += render_text->GetStringSize().width(); |
| 421 current_data->render_text = render_texts.back(); | |
| 422 current_data->render_text->SetFont(*current_data->font); | |
| 423 current_data->render_text->SetText(current_data->text); | |
| 424 | |
| 425 gfx::StyleRange style_range; | |
| 426 style_range.foreground = current_data->color; | |
| 427 style_range.font_style = current_data->font->GetStyle(); | |
| 428 current_data->render_text->set_default_style(style_range); | |
| 429 current_data->render_text->ApplyDefaultStyle(); | |
| 430 | |
| 431 current_data->pixel_size = current_data->render_text->GetStringSize(); | |
| 432 current_run->pixel_width += current_data->pixel_size.width(); | |
| 433 } | 414 } |
| 434 DCHECK(!current_run->classifications.empty()); | 415 DCHECK(!current_run->classifications.empty()); |
| 435 } | 416 } |
| 436 DCHECK(!runs.empty()); | 417 DCHECK(!runs.empty()); |
| 437 | 418 |
| 438 // Sort into logical order so we can elide logically. | 419 // Sort into logical order so we can elide logically. |
| 439 std::sort(runs.begin(), runs.end(), &SortRunsLogically); | 420 std::sort(runs.begin(), runs.end(), &SortRunsLogically); |
| 440 | 421 |
| 441 // Now determine what to elide, if anything. Several subtle points: | 422 // Now determine what to elide, if anything. Several subtle points: |
| 442 // * Because we have the run data, we can get edge cases correct, like | 423 // * Because we have the run data, we can get edge cases correct, like |
| 443 // whether to place an ellipsis before or after the end of a run when the | 424 // whether to place an ellipsis before or after the end of a run when the |
| 444 // text needs to be elided at the run boundary. | 425 // text needs to be elided at the run boundary. |
| 445 // * The "or one before it" comments below refer to cases where an earlier | 426 // * The "or one before it" comments below refer to cases where an earlier |
| 446 // classification fits completely, but leaves too little space for an | 427 // classification fits completely, but leaves too little space for an |
| 447 // ellipsis that turns out to be needed later. These cases are commented | 428 // ellipsis that turns out to be needed later. These cases are commented |
| 448 // more completely in Elide(). | 429 // more completely in Elide(). |
| 449 int remaining_width = mirroring_context_->remaining_width(x); | 430 int remaining_width = mirroring_context_->remaining_width(x); |
| 450 for (Runs::iterator i(runs.begin()); i != runs.end(); ++i) { | 431 for (Runs::iterator i(runs.begin()); i != runs.end(); ++i) { |
| 451 if (i->pixel_width > remaining_width) { | 432 if (i->pixel_width > remaining_width) { |
| 452 // This run or one before it needs to be elided. | 433 // This run or one before it needs to be elided. |
| 453 for (Classifications::iterator j(i->classifications.begin()); | 434 for (Classifications::iterator j(i->classifications.begin()); |
| 454 j != i->classifications.end(); ++j) { | 435 j != i->classifications.end(); ++j) { |
| 455 if (j->pixel_size.width() > remaining_width) { | 436 const int width = (*j)->GetStringSize().width(); |
| 437 if (width > remaining_width) { |
| 456 // This classification or one before it needs to be elided. Erase all | 438 // This classification or one before it needs to be elided. Erase all |
| 457 // further classifications and runs so Elide() can simply reverse- | 439 // further classifications and runs so Elide() can simply reverse- |
| 458 // iterate over everything to find the specific classification to | 440 // iterate over everything to find the specific classification to |
| 459 // elide. | 441 // elide. |
| 460 i->classifications.erase(++j, i->classifications.end()); | 442 i->classifications.erase(++j, i->classifications.end()); |
| 461 runs.erase(++i, runs.end()); | 443 runs.erase(++i, runs.end()); |
| 462 Elide(&runs, remaining_width); | 444 Elide(&runs, remaining_width); |
| 463 break; | 445 break; |
| 464 } | 446 } |
| 465 remaining_width -= j->pixel_size.width(); | 447 remaining_width -= width; |
| 466 } | 448 } |
| 467 break; | 449 break; |
| 468 } | 450 } |
| 469 remaining_width -= i->pixel_width; | 451 remaining_width -= i->pixel_width; |
| 470 } | 452 } |
| 471 | 453 |
| 472 // Sort back into visual order so we can display the runs correctly. | 454 // Sort back into visual order so we can display the runs correctly. |
| 473 std::sort(runs.begin(), runs.end(), &SortRunsVisually); | 455 std::sort(runs.begin(), runs.end(), &SortRunsVisually); |
| 474 | 456 |
| 475 // Draw the runs. | 457 // Draw the runs. |
| 476 for (Runs::iterator i(runs.begin()); i != runs.end(); ++i) { | 458 for (Runs::iterator i(runs.begin()); i != runs.end(); ++i) { |
| 477 const bool reverse_visible_order = (i->is_rtl != base::i18n::IsRTL()); | 459 const bool reverse_visible_order = (i->is_rtl != base::i18n::IsRTL()); |
| 478 if (reverse_visible_order) | 460 if (reverse_visible_order) |
| 479 std::reverse(i->classifications.begin(), i->classifications.end()); | 461 std::reverse(i->classifications.begin(), i->classifications.end()); |
| 480 for (Classifications::const_iterator j(i->classifications.begin()); | 462 for (Classifications::const_iterator j(i->classifications.begin()); |
| 481 j != i->classifications.end(); ++j) { | 463 j != i->classifications.end(); ++j) { |
| 482 const int left = | 464 const gfx::Size size = (*j)->GetStringSize(); |
| 483 mirroring_context_->mirrored_left_coord(x, x + j->pixel_size.width()); | |
| 484 // Align the text runs to a common baseline. | 465 // Align the text runs to a common baseline. |
| 485 const int top = | 466 const gfx::Rect rect( |
| 486 y + normal_font_.GetBaseline() - j->render_text->GetBaseline(); | 467 mirroring_context_->mirrored_left_coord(x, x + size.width()), |
| 487 gfx::Rect rect(left, top, j->pixel_size.width(), j->pixel_size.height()); | 468 y + font_.GetBaseline() - (*j)->GetBaseline(), |
| 488 j->render_text->SetDisplayRect(rect); | 469 size.width(), size.height()); |
| 489 j->render_text->Draw(canvas); | 470 (*j)->SetDisplayRect(rect); |
| 490 x += j->pixel_size.width(); | 471 (*j)->Draw(canvas); |
| 472 x += size.width(); |
| 491 } | 473 } |
| 492 } | 474 } |
| 493 | 475 |
| 494 return x; | 476 return x; |
| 495 } | 477 } |
| 496 | 478 |
| 497 void OmniboxResultView::Elide(Runs* runs, int remaining_width) const { | 479 void OmniboxResultView::Elide(Runs* runs, int remaining_width) const { |
| 498 // The complexity of this function is due to edge cases like the following: | 480 // The complexity of this function is due to edge cases like the following: |
| 499 // We have 100 px of available space, an initial classification that takes 86 | 481 // We have 100 px of available space, an initial classification that takes 86 |
| 500 // px, and a font that has a 15 px wide ellipsis character. Now if the first | 482 // px, and a font that has a 15 px wide ellipsis character. Now if the first |
| 501 // classification is followed by several very narrow classifications (e.g. 3 | 483 // classification is followed by several very narrow classifications (e.g. 3 |
| 502 // px wide each), we don't know whether we need to elide or not at the time we | 484 // px wide each), we don't know whether we need to elide or not at the time we |
| 503 // see the first classification -- it depends on how many subsequent | 485 // see the first classification -- it depends on how many subsequent |
| 504 // classifications follow, and some of those may be in the next run (or | 486 // classifications follow, and some of those may be in the next run (or |
| 505 // several runs!). This is why instead we let our caller move forward until | 487 // several runs!). This is why instead we let our caller move forward until |
| 506 // we know we definitely need to elide, and then in this function we move | 488 // we know we definitely need to elide, and then in this function we move |
| 507 // backward again until we find a string that we can successfully do the | 489 // backward again until we find a string that we can successfully do the |
| 508 // eliding on. | 490 // eliding on. |
| 509 bool first_classification = true; | 491 bool first_classification = true; |
| 510 for (Runs::reverse_iterator i(runs->rbegin()); i != runs->rend(); ++i) { | 492 for (Runs::reverse_iterator i(runs->rbegin()); i != runs->rend(); ++i) { |
| 511 for (Classifications::reverse_iterator j(i->classifications.rbegin()); | 493 for (Classifications::reverse_iterator j(i->classifications.rbegin()); |
| 512 j != i->classifications.rend(); ++j) { | 494 j != i->classifications.rend(); ++j) { |
| 513 if (!first_classification) { | 495 if (!first_classification) { |
| 496 // We also add this classification's width (sans ellipsis) back to the |
| 497 // available width since we want to consider the available space we'll |
| 498 // have when we draw this classification. |
| 499 remaining_width += (*j)->GetStringSize().width(); |
| 500 |
| 514 // For all but the first classification we consider, we need to append | 501 // For all but the first classification we consider, we need to append |
| 515 // an ellipsis, since there isn't enough room to draw it after this | 502 // an ellipsis, since there isn't enough room to draw it after this |
| 516 // classification. | 503 // classification. |
| 517 j->text += kEllipsis; | 504 (*j)->SetText((*j)->text() + kEllipsis); |
| 518 j->render_text->SetText(j->text); | |
| 519 | |
| 520 // We also add this classification's width (sans ellipsis) back to the | |
| 521 // available width since we want to consider the available space we'll | |
| 522 // have when we draw this classification. | |
| 523 remaining_width += j->pixel_size.width(); | |
| 524 } | 505 } |
| 525 first_classification = false; | 506 first_classification = false; |
| 526 | 507 |
| 527 // Can we fit at least an ellipsis? | 508 // Can we fit at least an ellipsis? |
| 528 string16 elided_text = | 509 string16 elided_text = ui::ElideText((*j)->text(), (*j)->GetFont(), |
| 529 ui::ElideText(j->text, *j->font, remaining_width, ui::ELIDE_AT_END); | 510 remaining_width, ui::ELIDE_AT_END); |
| 530 Classifications::reverse_iterator prior_classification(j); | 511 Classifications::reverse_iterator prior(j + 1); |
| 531 ++prior_classification; | 512 const bool on_first_classification = (prior == i->classifications.rend()); |
| 532 const bool on_first_classification = | |
| 533 (prior_classification == i->classifications.rend()); | |
| 534 if (elided_text.empty() && (remaining_width >= ellipsis_width_) && | 513 if (elided_text.empty() && (remaining_width >= ellipsis_width_) && |
| 535 on_first_classification) { | 514 on_first_classification) { |
| 536 // Edge case: This classification is bold, we can't fit a bold ellipsis | 515 // Edge case: This classification is bold, we can't fit a bold ellipsis |
| 537 // but we can fit a normal one, and this is the first classification in | 516 // but we can fit a normal one, and this is the first classification in |
| 538 // the run. We should display a lone normal ellipsis, because appending | 517 // the run. We should display a lone normal ellipsis, because appending |
| 539 // one to the end of the previous run might put it in the wrong visual | 518 // one to the end of the previous run might put it in the wrong visual |
| 540 // location (if the previous run is reversed from the normal visual | 519 // location (if the previous run is reversed from the normal visual |
| 541 // order). | 520 // order). |
| 542 // NOTE: If this isn't the first classification in the run, we don't | 521 // NOTE: If this isn't the first classification in the run, we don't |
| 543 // need to bother with this; see note below. | 522 // need to bother with this; see note below. |
| 544 elided_text = kEllipsis; | 523 elided_text = kEllipsis; |
| 545 } | 524 } |
| 546 if (!elided_text.empty()) { | 525 if (!elided_text.empty()) { |
| 547 // Success. Elide this classification and stop. | 526 // Success. Elide this classification and stop. |
| 548 j->text = elided_text; | 527 (*j)->SetText(elided_text); |
| 549 | 528 |
| 550 // If we could only fit an ellipsis, then only make it bold if there was | 529 // If we could only fit an ellipsis, then only make it bold if there was |
| 551 // an immediate prior classification in this run that was also bold, or | 530 // an immediate prior classification in this run that was also bold, or |
| 552 // it will look orphaned. | 531 // it will look orphaned. |
| 553 if ((j->font != &normal_font_) && (elided_text.length() == 1) && | 532 if ((((*j)->GetFont().GetStyle() & gfx::BOLD) != 0) && |
| 533 (elided_text.length() == 1) && |
| 554 (on_first_classification || | 534 (on_first_classification || |
| 555 (prior_classification->font == &normal_font_))) { | 535 (((*prior)->GetFont().GetStyle() & gfx::BOLD) == 0))) { |
| 556 j->font = &normal_font_; | 536 (*j)->SetStyle(gfx::BOLD, false); |
| 557 j->render_text->SetFont(*j->font); | |
| 558 } | 537 } |
| 559 | 538 |
| 560 j->render_text->SetText(elided_text); | |
| 561 j->pixel_size = j->render_text->GetStringSize(); | |
| 562 | |
| 563 // Erase any other classifications that come after the elided one. | 539 // Erase any other classifications that come after the elided one. |
| 564 i->classifications.erase(j.base(), i->classifications.end()); | 540 i->classifications.erase(j.base(), i->classifications.end()); |
| 565 runs->erase(i.base(), runs->end()); | 541 runs->erase(i.base(), runs->end()); |
| 566 return; | 542 return; |
| 567 } | 543 } |
| 568 | 544 |
| 569 // We couldn't fit an ellipsis. Move back one classification, | 545 // We couldn't fit an ellipsis. Move back one classification, |
| 570 // append an ellipsis, and try again. | 546 // append an ellipsis, and try again. |
| 571 // NOTE: In the edge case that a bold ellipsis doesn't fit but a | 547 // NOTE: In the edge case that a bold ellipsis doesn't fit but a |
| 572 // normal one would, and we reach here, then there is a previous | 548 // normal one would, and we reach here, then there is a previous |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 641 int x = GetMirroredXForRect(keyword_text_bounds_); | 617 int x = GetMirroredXForRect(keyword_text_bounds_); |
| 642 mirroring_context_->Initialize(x, keyword_text_bounds_.width()); | 618 mirroring_context_->Initialize(x, keyword_text_bounds_.width()); |
| 643 PaintMatch(canvas, *match_.associated_keyword.get(), x); | 619 PaintMatch(canvas, *match_.associated_keyword.get(), x); |
| 644 } | 620 } |
| 645 } | 621 } |
| 646 | 622 |
| 647 void OmniboxResultView::AnimationProgressed(const ui::Animation* animation) { | 623 void OmniboxResultView::AnimationProgressed(const ui::Animation* animation) { |
| 648 Layout(); | 624 Layout(); |
| 649 SchedulePaint(); | 625 SchedulePaint(); |
| 650 } | 626 } |
| OLD | NEW |