Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(145)

Side by Side Diff: ui/views/controls/label.cc

Issue 843503003: Cache DrawStringParams in views::Label (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: comments addressed Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« ui/views/controls/label.h ('K') | « ui/views/controls/label.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/views/controls/label.h" 5 #include "ui/views/controls/label.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <limits> 9 #include <limits>
10 #include <vector> 10 #include <vector>
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 Label::Label(const base::string16& text, const gfx::FontList& font_list) { 49 Label::Label(const base::string16& text, const gfx::FontList& font_list) {
50 Init(text, font_list); 50 Init(text, font_list);
51 } 51 }
52 52
53 Label::~Label() { 53 Label::~Label() {
54 } 54 }
55 55
56 void Label::SetFontList(const gfx::FontList& font_list) { 56 void Label::SetFontList(const gfx::FontList& font_list) {
57 is_first_paint_text_ = true; 57 is_first_paint_text_ = true;
58 font_list_ = font_list; 58 font_list_ = font_list;
59 ResetCachedSize(); 59 ResetLayoutCache();
60 PreferredSizeChanged(); 60 PreferredSizeChanged();
61 SchedulePaint(); 61 SchedulePaint();
62 } 62 }
63 63
64 void Label::SetText(const base::string16& text) { 64 void Label::SetText(const base::string16& text) {
65 if (text != text_) 65 if (text != text_)
66 SetTextInternal(text); 66 SetTextInternal(text);
67 } 67 }
68 68
69 void Label::SetTextInternal(const base::string16& text) { 69 void Label::SetTextInternal(const base::string16& text) {
70 is_first_paint_text_ = true; 70 is_first_paint_text_ = true;
71 text_ = text; 71 text_ = text;
72 72
73 if (obscured_) { 73 if (obscured_) {
74 size_t obscured_text_length = 74 size_t obscured_text_length =
75 static_cast<size_t>(gfx::UTF16IndexToOffset(text_, 0, text_.length())); 75 static_cast<size_t>(gfx::UTF16IndexToOffset(text_, 0, text_.length()));
76 layout_text_.assign(obscured_text_length, kPasswordReplacementChar); 76 layout_text_.assign(obscured_text_length, kPasswordReplacementChar);
77 } else { 77 } else {
78 layout_text_ = text_; 78 layout_text_ = text_;
79 } 79 }
80 80
81 ResetCachedSize(); 81 ResetLayoutCache();
82 PreferredSizeChanged(); 82 PreferredSizeChanged();
83 SchedulePaint(); 83 SchedulePaint();
84 } 84 }
85 85
86 void Label::SetAutoColorReadabilityEnabled(bool enabled) { 86 void Label::SetAutoColorReadabilityEnabled(bool enabled) {
87 is_first_paint_text_ = true; 87 is_first_paint_text_ = true;
88 auto_color_readability_ = enabled; 88 auto_color_readability_ = enabled;
89 RecalculateColors(); 89 RecalculateColors();
90 } 90 }
91 91
(...skipping 14 matching lines...) Expand all
106 void Label::SetBackgroundColor(SkColor color) { 106 void Label::SetBackgroundColor(SkColor color) {
107 is_first_paint_text_ = true; 107 is_first_paint_text_ = true;
108 background_color_ = color; 108 background_color_ = color;
109 background_color_set_ = true; 109 background_color_set_ = true;
110 RecalculateColors(); 110 RecalculateColors();
111 } 111 }
112 112
113 void Label::SetShadows(const gfx::ShadowValues& shadows) { 113 void Label::SetShadows(const gfx::ShadowValues& shadows) {
114 is_first_paint_text_ = true; 114 is_first_paint_text_ = true;
115 shadows_ = shadows; 115 shadows_ = shadows;
116 text_size_valid_ = false; 116 ResetLayoutCache();
117 } 117 }
118 118
119 void Label::SetSubpixelRenderingEnabled(bool subpixel_rendering_enabled) { 119 void Label::SetSubpixelRenderingEnabled(bool subpixel_rendering_enabled) {
120 is_first_paint_text_ = true; 120 is_first_paint_text_ = true;
121 subpixel_rendering_enabled_ = subpixel_rendering_enabled; 121 subpixel_rendering_enabled_ = subpixel_rendering_enabled;
122 } 122 }
123 123
124 void Label::SetHorizontalAlignment(gfx::HorizontalAlignment alignment) { 124 void Label::SetHorizontalAlignment(gfx::HorizontalAlignment alignment) {
125 is_first_paint_text_ = true; 125 is_first_paint_text_ = true;
126 // If the UI layout is right-to-left, flip the alignment direction. 126 // If the UI layout is right-to-left, flip the alignment direction.
(...skipping 14 matching lines...) Expand all
141 141
142 const base::i18n::TextDirection dir = 142 const base::i18n::TextDirection dir =
143 base::i18n::GetFirstStrongCharacterDirection(layout_text_); 143 base::i18n::GetFirstStrongCharacterDirection(layout_text_);
144 return dir == base::i18n::RIGHT_TO_LEFT ? gfx::ALIGN_RIGHT : gfx::ALIGN_LEFT; 144 return dir == base::i18n::RIGHT_TO_LEFT ? gfx::ALIGN_RIGHT : gfx::ALIGN_LEFT;
145 } 145 }
146 146
147 void Label::SetLineHeight(int height) { 147 void Label::SetLineHeight(int height) {
148 is_first_paint_text_ = true; 148 is_first_paint_text_ = true;
149 if (height != line_height_) { 149 if (height != line_height_) {
150 line_height_ = height; 150 line_height_ = height;
151 ResetCachedSize(); 151 ResetLayoutCache();
152 PreferredSizeChanged(); 152 PreferredSizeChanged();
153 SchedulePaint(); 153 SchedulePaint();
154 } 154 }
155 } 155 }
156 156
157 void Label::SetMultiLine(bool multi_line) { 157 void Label::SetMultiLine(bool multi_line) {
158 is_first_paint_text_ = true; 158 is_first_paint_text_ = true;
159 DCHECK(!multi_line || (elide_behavior_ == gfx::ELIDE_TAIL || 159 DCHECK(!multi_line || (elide_behavior_ == gfx::ELIDE_TAIL ||
160 elide_behavior_ == gfx::NO_ELIDE)); 160 elide_behavior_ == gfx::NO_ELIDE));
161 if (multi_line != multi_line_) { 161 if (multi_line != multi_line_) {
162 multi_line_ = multi_line; 162 multi_line_ = multi_line;
163 ResetCachedSize(); 163 ResetLayoutCache();
164 PreferredSizeChanged(); 164 PreferredSizeChanged();
165 SchedulePaint(); 165 SchedulePaint();
166 } 166 }
167 } 167 }
168 168
169 void Label::SetObscured(bool obscured) { 169 void Label::SetObscured(bool obscured) {
170 is_first_paint_text_ = true; 170 is_first_paint_text_ = true;
171 if (obscured != obscured_) { 171 if (obscured != obscured_) {
172 obscured_ = obscured; 172 obscured_ = obscured;
173 SetTextInternal(text_); 173 SetTextInternal(text_);
174 } 174 }
175 } 175 }
176 176
177 void Label::SetAllowCharacterBreak(bool allow_character_break) { 177 void Label::SetAllowCharacterBreak(bool allow_character_break) {
178 is_first_paint_text_ = true; 178 is_first_paint_text_ = true;
179 if (allow_character_break != allow_character_break_) { 179 if (allow_character_break != allow_character_break_) {
180 allow_character_break_ = allow_character_break; 180 allow_character_break_ = allow_character_break;
181 ResetCachedSize(); 181 ResetLayoutCache();
182 PreferredSizeChanged(); 182 PreferredSizeChanged();
183 SchedulePaint(); 183 SchedulePaint();
184 } 184 }
185 } 185 }
186 186
187 void Label::SetElideBehavior(gfx::ElideBehavior elide_behavior) { 187 void Label::SetElideBehavior(gfx::ElideBehavior elide_behavior) {
188 is_first_paint_text_ = true; 188 is_first_paint_text_ = true;
189 DCHECK(!multi_line_ || (elide_behavior_ == gfx::ELIDE_TAIL || 189 DCHECK(!multi_line_ || (elide_behavior_ == gfx::ELIDE_TAIL ||
190 elide_behavior_ == gfx::NO_ELIDE)); 190 elide_behavior_ == gfx::NO_ELIDE));
191 if (elide_behavior != elide_behavior_) { 191 if (elide_behavior != elide_behavior_) {
192 elide_behavior_ = elide_behavior; 192 elide_behavior_ = elide_behavior;
193 ResetCachedSize(); 193 ResetLayoutCache();
194 PreferredSizeChanged(); 194 PreferredSizeChanged();
195 SchedulePaint(); 195 SchedulePaint();
196 } 196 }
197 } 197 }
198 198
199 void Label::SetTooltipText(const base::string16& tooltip_text) { 199 void Label::SetTooltipText(const base::string16& tooltip_text) {
200 DCHECK(handles_tooltips_); 200 DCHECK(handles_tooltips_);
201 tooltip_text_ = tooltip_text; 201 tooltip_text_ = tooltip_text;
202 } 202 }
203 203
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 const gfx::Insets shadow_margin = -gfx::ShadowValue::GetMargin(shadows_); 389 const gfx::Insets shadow_margin = -gfx::ShadowValue::GetMargin(shadows_);
390 text_size_.Enlarge(shadow_margin.width(), shadow_margin.height()); 390 text_size_.Enlarge(shadow_margin.width(), shadow_margin.height());
391 text_size_valid_ = true; 391 text_size_valid_ = true;
392 } 392 }
393 393
394 return text_size_; 394 return text_size_;
395 } 395 }
396 396
397 void Label::OnBoundsChanged(const gfx::Rect& previous_bounds) { 397 void Label::OnBoundsChanged(const gfx::Rect& previous_bounds) {
398 text_size_valid_ &= !multi_line_; 398 text_size_valid_ &= !multi_line_;
399 cached_draw_params_.reset();
399 } 400 }
400 401
401 void Label::OnPaint(gfx::Canvas* canvas) { 402 void Label::OnPaint(gfx::Canvas* canvas) {
402 OnPaintBackground(canvas); 403 OnPaintBackground(canvas);
403 // We skip painting the focus border because it is being handled seperately by 404 // We skip painting the focus border because it is being handled seperately by
404 // some subclasses of Label. We do not want View's focus border painting to 405 // some subclasses of Label. We do not want View's focus border painting to
405 // interfere with that. 406 // interfere with that.
406 OnPaintBorder(canvas); 407 OnPaintBorder(canvas);
407 408
408 base::string16 paint_text; 409 const DrawStringParams* params = CalculateDrawStringParams();
409 gfx::Rect text_bounds;
410 int flags = 0;
411 CalculateDrawStringParams(&paint_text, &text_bounds, &flags);
412 if (is_first_paint_text_) { 410 if (is_first_paint_text_) {
413 // TODO(vadimt): Remove ScopedTracker below once crbug.com/431326 is fixed. 411 // TODO(vadimt): Remove ScopedTracker below once crbug.com/431326 is fixed.
414 tracked_objects::ScopedTracker tracking_profile( 412 tracked_objects::ScopedTracker tracking_profile(
415 FROM_HERE_WITH_EXPLICIT_FUNCTION("431326 Label::PaintText first")); 413 FROM_HERE_WITH_EXPLICIT_FUNCTION("431326 Label::PaintText first"));
416 414
417 is_first_paint_text_ = false; 415 is_first_paint_text_ = false;
418 PaintText(canvas, paint_text, text_bounds, flags); 416 PaintText(canvas, params->text, params->bounds, params->flags);
419 } else { 417 } else {
420 // TODO(vadimt): Remove ScopedTracker below once crbug.com/431326 is fixed. 418 // TODO(vadimt): Remove ScopedTracker below once crbug.com/431326 is fixed.
421 tracked_objects::ScopedTracker tracking_profile( 419 tracked_objects::ScopedTracker tracking_profile(
422 FROM_HERE_WITH_EXPLICIT_FUNCTION("431326 Label::PaintText not first")); 420 FROM_HERE_WITH_EXPLICIT_FUNCTION("431326 Label::PaintText not first"));
423 421
424 PaintText(canvas, paint_text, text_bounds, flags); 422 PaintText(canvas, params->text, params->bounds, params->flags);
425 } 423 }
426 } 424 }
427 425
428 void Label::OnNativeThemeChanged(const ui::NativeTheme* theme) { 426 void Label::OnNativeThemeChanged(const ui::NativeTheme* theme) {
429 UpdateColorsFromTheme(theme); 427 UpdateColorsFromTheme(theme);
430 } 428 }
431 429
432 void Label::Init(const base::string16& text, const gfx::FontList& font_list) { 430 void Label::Init(const base::string16& text, const gfx::FontList& font_list) {
433 font_list_ = font_list; 431 font_list_ = font_list;
434 enabled_color_set_ = disabled_color_set_ = background_color_set_ = false; 432 enabled_color_set_ = disabled_color_set_ = background_color_set_ = false;
435 subpixel_rendering_enabled_ = true; 433 subpixel_rendering_enabled_ = true;
436 auto_color_readability_ = true; 434 auto_color_readability_ = true;
437 UpdateColorsFromTheme(ui::NativeTheme::instance()); 435 UpdateColorsFromTheme(ui::NativeTheme::instance());
438 horizontal_alignment_ = gfx::ALIGN_CENTER; 436 horizontal_alignment_ = gfx::ALIGN_CENTER;
439 line_height_ = 0; 437 line_height_ = 0;
440 multi_line_ = false; 438 multi_line_ = false;
441 obscured_ = false; 439 obscured_ = false;
442 allow_character_break_ = false; 440 allow_character_break_ = false;
443 elide_behavior_ = gfx::ELIDE_TAIL; 441 elide_behavior_ = gfx::ELIDE_TAIL;
444 handles_tooltips_ = true; 442 handles_tooltips_ = true;
445 collapse_when_hidden_ = false; 443 collapse_when_hidden_ = false;
446 cached_heights_.resize(kCachedSizeLimit); 444 cached_heights_.resize(kCachedSizeLimit);
447 ResetCachedSize(); 445 ResetLayoutCache();
448 is_first_paint_text_ = true; 446 is_first_paint_text_ = true;
449 447
450 SetText(text); 448 SetText(text);
451 } 449 }
452 450
453 void Label::RecalculateColors() { 451 void Label::RecalculateColors() {
454 actual_enabled_color_ = auto_color_readability_ ? 452 actual_enabled_color_ = auto_color_readability_ ?
455 color_utils::GetReadableColor(requested_enabled_color_, 453 color_utils::GetReadableColor(requested_enabled_color_,
456 background_color_) : 454 background_color_) :
457 requested_enabled_color_; 455 requested_enabled_color_;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 532
535 return flags; 533 return flags;
536 } 534 }
537 535
538 gfx::Rect Label::GetAvailableRect() const { 536 gfx::Rect Label::GetAvailableRect() const {
539 gfx::Rect bounds(size()); 537 gfx::Rect bounds(size());
540 bounds.Inset(GetInsets()); 538 bounds.Inset(GetInsets());
541 return bounds; 539 return bounds;
542 } 540 }
543 541
544 void Label::CalculateDrawStringParams(base::string16* paint_text, 542 const Label::DrawStringParams* Label::CalculateDrawStringParams() const {
545 gfx::Rect* text_bounds, 543 if (!cached_draw_params_) {
546 int* flags) const { 544 DrawStringParams* params = new DrawStringParams();
547 DCHECK(paint_text && text_bounds && flags);
548 545
549 const bool forbid_ellipsis = elide_behavior_ == gfx::NO_ELIDE || 546 const bool forbid_ellipsis = elide_behavior_ == gfx::NO_ELIDE ||
550 elide_behavior_ == gfx::FADE_TAIL; 547 elide_behavior_ == gfx::FADE_TAIL;
551 if (multi_line_ || forbid_ellipsis) { 548 if (multi_line_ || forbid_ellipsis) {
552 *paint_text = layout_text_; 549 params->text = layout_text_;
553 } else { 550 } else {
554 *paint_text = gfx::ElideText(layout_text_, font_list_, 551 params->text = gfx::ElideText(layout_text_, font_list_,
555 GetAvailableRect().width(), elide_behavior_); 552 GetAvailableRect().width(), elide_behavior_);
553 }
554
555 params->bounds = GetTextBounds();
556 params->flags = ComputeDrawStringFlags();
557 // TODO(msw): Elide multi-line text with ElideRectangleText instead.
558 if (!multi_line_ || forbid_ellipsis)
559 params->flags |= gfx::Canvas::NO_ELLIPSIS;
560
561 cached_draw_params_.reset(params);
556 } 562 }
557 563
558 *text_bounds = GetTextBounds(); 564 return cached_draw_params_.get();
559 *flags = ComputeDrawStringFlags();
560 // TODO(msw): Elide multi-line text with ElideRectangleText instead.
561 if (!multi_line_ || forbid_ellipsis)
562 *flags |= gfx::Canvas::NO_ELLIPSIS;
563 } 565 }
564 566
565 void Label::UpdateColorsFromTheme(const ui::NativeTheme* theme) { 567 void Label::UpdateColorsFromTheme(const ui::NativeTheme* theme) {
566 if (!enabled_color_set_) { 568 if (!enabled_color_set_) {
567 requested_enabled_color_ = theme->GetSystemColor( 569 requested_enabled_color_ = theme->GetSystemColor(
568 ui::NativeTheme::kColorId_LabelEnabledColor); 570 ui::NativeTheme::kColorId_LabelEnabledColor);
569 } 571 }
570 if (!disabled_color_set_) { 572 if (!disabled_color_set_) {
571 requested_disabled_color_ = theme->GetSystemColor( 573 requested_disabled_color_ = theme->GetSystemColor(
572 ui::NativeTheme::kColorId_LabelDisabledColor); 574 ui::NativeTheme::kColorId_LabelDisabledColor);
573 } 575 }
574 if (!background_color_set_) { 576 if (!background_color_set_) {
575 background_color_ = theme->GetSystemColor( 577 background_color_ = theme->GetSystemColor(
576 ui::NativeTheme::kColorId_LabelBackgroundColor); 578 ui::NativeTheme::kColorId_LabelBackgroundColor);
577 } 579 }
578 RecalculateColors(); 580 RecalculateColors();
579 } 581 }
580 582
581 void Label::ResetCachedSize() { 583 void Label::ResetLayoutCache() {
584 cached_draw_params_.reset();
582 text_size_valid_ = false; 585 text_size_valid_ = false;
583 cached_heights_cursor_ = 0; 586 cached_heights_cursor_ = 0;
584 for (int i = 0; i < kCachedSizeLimit; ++i) 587 for (int i = 0; i < kCachedSizeLimit; ++i)
585 cached_heights_[i] = gfx::Size(); 588 cached_heights_[i] = gfx::Size();
586 } 589 }
587 590
588 bool Label::ShouldShowDefaultTooltip() const { 591 bool Label::ShouldShowDefaultTooltip() const {
589 const gfx::Size text_size = GetTextSize(); 592 const gfx::Size text_size = GetTextSize();
590 const gfx::Size size = GetContentsBounds().size(); 593 const gfx::Size size = GetContentsBounds().size();
591 return !obscured() && (text_size.width() > size.width() || 594 return !obscured() && (text_size.width() > size.width() ||
592 (multi_line_ && text_size.height() > size.height())); 595 (multi_line_ && text_size.height() > size.height()));
593 } 596 }
594 597
595 } // namespace views 598 } // namespace views
OLDNEW
« ui/views/controls/label.h ('K') | « ui/views/controls/label.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698