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

Side by Side Diff: chrome/browser/ui/views/tabs/tab.cc

Issue 2803583003: ui: Remove use of bitmaps when painting tab backgrounds. (Closed)
Patch Set: tabbackground: pointers Created 3 years, 8 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
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 "chrome/browser/ui/views/tabs/tab.h" 5 #include "chrome/browser/ui/views/tabs/tab.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <limits> 8 #include <limits>
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/debug/alias.h" 12 #include "base/debug/alias.h"
13 #include "base/macros.h" 13 #include "base/macros.h"
14 #include "base/metrics/user_metrics.h" 14 #include "base/metrics/user_metrics.h"
15 #include "base/strings/utf_string_conversions.h" 15 #include "base/strings/utf_string_conversions.h"
16 #include "build/build_config.h" 16 #include "build/build_config.h"
17 #include "cc/paint/paint_shader.h" 17 #include "cc/paint/paint_flags.h"
18 #include "chrome/app/vector_icons/vector_icons.h" 18 #include "chrome/app/vector_icons/vector_icons.h"
19 #include "chrome/browser/themes/theme_properties.h" 19 #include "chrome/browser/themes/theme_properties.h"
20 #include "chrome/browser/ui/browser.h" 20 #include "chrome/browser/ui/browser.h"
21 #include "chrome/browser/ui/layout_constants.h" 21 #include "chrome/browser/ui/layout_constants.h"
22 #include "chrome/browser/ui/tab_contents/core_tab_helper.h" 22 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
23 #include "chrome/browser/ui/tabs/tab_utils.h" 23 #include "chrome/browser/ui/tabs/tab_utils.h"
24 #include "chrome/browser/ui/view_ids.h" 24 #include "chrome/browser/ui/view_ids.h"
25 #include "chrome/browser/ui/views/frame/browser_view.h" 25 #include "chrome/browser/ui/views/frame/browser_view.h"
26 #include "chrome/browser/ui/views/tabs/alert_indicator_button.h" 26 #include "chrome/browser/ui/views/tabs/alert_indicator_button.h"
27 #include "chrome/browser/ui/views/tabs/browser_tab_strip_controller.h" 27 #include "chrome/browser/ui/views/tabs/browser_tab_strip_controller.h"
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 86
87 // How opaque to make the hover state (out of 1). 87 // How opaque to make the hover state (out of 1).
88 const double kHoverOpacity = 0.33; 88 const double kHoverOpacity = 0.33;
89 89
90 // Opacity of the active tab background painted over inactive selected tabs. 90 // Opacity of the active tab background painted over inactive selected tabs.
91 const double kSelectedTabOpacity = 0.3; 91 const double kSelectedTabOpacity = 0.3;
92 92
93 // Inactive selected tabs have their throb value scaled by this. 93 // Inactive selected tabs have their throb value scaled by this.
94 const double kSelectedTabThrobScale = 0.95 - kSelectedTabOpacity; 94 const double kSelectedTabThrobScale = 0.95 - kSelectedTabOpacity;
95 95
96 // Max number of images to cache. This has to be at least two since rounding
97 // errors may lead to tabs in the same tabstrip having different sizes.
98 // 8 = normal/incognito, active/inactive, 2 sizes within tabstrip.
99 const size_t kMaxImageCacheSize = 8;
100
101 const char kTabCloseButtonName[] = "TabCloseButton"; 96 const char kTabCloseButtonName[] = "TabCloseButton";
102 97
103 //////////////////////////////////////////////////////////////////////////////// 98 ////////////////////////////////////////////////////////////////////////////////
104 // ImageCacheEntryMetadata
105 //
106 // All metadata necessary to uniquely identify a cached image.
107 struct ImageCacheEntryMetadata {
108 ImageCacheEntryMetadata(SkColor fill_color,
109 SkColor stroke_color,
110 bool use_fill_and_stroke_images,
111 float scale_factor,
112 const gfx::Size& size);
113
114 ~ImageCacheEntryMetadata();
115
116 bool operator==(const ImageCacheEntryMetadata& rhs) const;
117
118 SkColor fill_color;
119 SkColor stroke_color;
120 bool use_fill_and_stroke_images;
121 float scale_factor;
122 gfx::Size size;
123 };
124
125 ImageCacheEntryMetadata::ImageCacheEntryMetadata(
126 SkColor fill_color,
127 SkColor stroke_color,
128 bool use_fill_and_stroke_images,
129 float scale_factor,
130 const gfx::Size& size)
131 : fill_color(fill_color),
132 stroke_color(stroke_color),
133 use_fill_and_stroke_images(use_fill_and_stroke_images),
134 scale_factor(scale_factor),
135 size(size) {}
136
137 ImageCacheEntryMetadata::~ImageCacheEntryMetadata() {}
138
139 bool ImageCacheEntryMetadata::operator==(
140 const ImageCacheEntryMetadata& rhs) const {
141 return fill_color == rhs.fill_color && stroke_color == rhs.stroke_color &&
142 use_fill_and_stroke_images == rhs.use_fill_and_stroke_images &&
143 scale_factor == rhs.scale_factor && size == rhs.size;
144 }
145
146 ////////////////////////////////////////////////////////////////////////////////
147 // ImageCacheEntry and cache management
148 //
149 // A cached image and the metadata used to generate it.
150 struct ImageCacheEntry {
151 ImageCacheEntry(const ImageCacheEntryMetadata& metadata,
152 const gfx::ImageSkia& fill_image,
153 const gfx::ImageSkia& stroke_image);
154 ~ImageCacheEntry();
155
156 ImageCacheEntryMetadata metadata;
157 gfx::ImageSkia fill_image;
158 gfx::ImageSkia stroke_image;
159 };
160
161 ImageCacheEntry::ImageCacheEntry(const ImageCacheEntryMetadata& metadata,
162 const gfx::ImageSkia& fill_image,
163 const gfx::ImageSkia& stroke_image)
164 : metadata(metadata), fill_image(fill_image), stroke_image(stroke_image) {}
165
166 ImageCacheEntry::~ImageCacheEntry() {}
167
168 typedef std::list<ImageCacheEntry> ImageCache;
169
170 // As the majority of the tabs are inactive, and painting tabs is slowish,
171 // we cache a handful of the inactive tab backgrounds here.
172 static ImageCache* g_image_cache = nullptr;
173
174 // Performs a one-time initialization of static resources such as tab images.
175 void InitTabResources() {
176 static bool initialized = false;
177 if (initialized)
178 return;
179
180 initialized = true;
181 g_image_cache = new ImageCache();
182 }
183
184 ////////////////////////////////////////////////////////////////////////////////
185 // Drawing and utility functions 99 // Drawing and utility functions
186 100
187 // Returns the width of the tab endcap at scale 1. More precisely, this is the 101 // Returns the width of the tab endcap at scale 1. More precisely, this is the
188 // width of the curve making up either the outer or inner edge of the stroke; 102 // width of the curve making up either the outer or inner edge of the stroke;
189 // since these two curves are horizontally offset by 1 px (regardless of scale), 103 // since these two curves are horizontally offset by 1 px (regardless of scale),
190 // the total width of the endcap from tab outer edge to the inside end of the 104 // the total width of the endcap from tab outer edge to the inside end of the
191 // stroke inner edge is (GetUnscaledEndcapWidth() * scale) + 1. 105 // stroke inner edge is (GetUnscaledEndcapWidth() * scale) + 1.
192 float GetUnscaledEndcapWidth() { 106 float GetUnscaledEndcapWidth() {
193 return GetLayoutInsets(TAB).left() - 0.5f; 107 return GetLayoutInsets(TAB).left() - 0.5f;
194 } 108 }
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 alert_indicator_button_(nullptr), 441 alert_indicator_button_(nullptr),
528 close_button_(nullptr), 442 close_button_(nullptr),
529 title_(new views::Label()), 443 title_(new views::Label()),
530 tab_activated_with_last_tap_down_(false), 444 tab_activated_with_last_tap_down_(false),
531 hover_controller_(this), 445 hover_controller_(this),
532 showing_icon_(false), 446 showing_icon_(false),
533 showing_alert_indicator_(false), 447 showing_alert_indicator_(false),
534 showing_close_button_(false), 448 showing_close_button_(false),
535 button_color_(SK_ColorTRANSPARENT) { 449 button_color_(SK_ColorTRANSPARENT) {
536 DCHECK(controller); 450 DCHECK(controller);
537 InitTabResources();
538 451
539 // So we get don't get enter/exit on children and don't prematurely stop the 452 // So we get don't get enter/exit on children and don't prematurely stop the
540 // hover. 453 // hover.
541 set_notify_enter_exit_on_child(true); 454 set_notify_enter_exit_on_child(true);
542 455
543 set_id(VIEW_ID_TAB); 456 set_id(VIEW_ID_TAB);
544 457
545 SetBorder(views::CreateEmptyBorder(GetLayoutInsets(TAB))); 458 SetBorder(views::CreateEmptyBorder(GetLayoutInsets(TAB)));
546 459
547 title_->SetHorizontalAlignment(gfx::ALIGN_TO_HEAD); 460 title_->SetHorizontalAlignment(gfx::ALIGN_TO_HEAD);
(...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after
1111 if (data().blocked == old.blocked) 1024 if (data().blocked == old.blocked)
1112 return; 1025 return;
1113 1026
1114 if (data().blocked) 1027 if (data().blocked)
1115 StartPulse(); 1028 StartPulse();
1116 else 1029 else
1117 StopPulse(); 1030 StopPulse();
1118 } 1031 }
1119 1032
1120 void Tab::PaintTab(gfx::Canvas* canvas, const gfx::Path& clip) { 1033 void Tab::PaintTab(gfx::Canvas* canvas, const gfx::Path& clip) {
1121 const int kActiveTabFillId = 1034 const int kActiveTabFillId =
danakj 2017/04/07 19:10:49 btw while we're pointing at naming, these should n
1122 GetThemeProvider()->HasCustomImage(IDR_THEME_TOOLBAR) ? IDR_THEME_TOOLBAR 1035 GetThemeProvider()->HasCustomImage(IDR_THEME_TOOLBAR) ? IDR_THEME_TOOLBAR
1123 : 0; 1036 : 0;
1124 const int y_offset = -GetLayoutInsets(TAB).top(); 1037 const int y_offset = -GetLayoutInsets(TAB).top();
1125 if (IsActive()) { 1038 if (IsActive()) {
1126 PaintTabBackgroundUsingFillId(canvas, canvas, true, kActiveTabFillId, 1039 bool active = true;
1127 y_offset); 1040 gfx::Path* no_clip = nullptr;
Peter Kasting 2017/04/06 00:52:11 Nit: Please don't pull this kind of thing out. It
danakj 2017/04/06 17:05:28 If I didn't give it a name this way I'd want to wr
Peter Kasting 2017/04/06 18:49:44 don't love it enough to do it myself, but I don't
danakj 2017/04/07 19:10:49 Sure, I think that's nicer than inline comments. I
1041 PaintTabBackground(canvas, active, kActiveTabFillId, y_offset, no_clip);
1128 } else { 1042 } else {
1129 PaintInactiveTabBackground(canvas, clip); 1043 PaintInactiveTabBackground(canvas, clip);
1130 1044
1131 const double throb_value = GetThrobValue(); 1045 const double throb_value = GetThrobValue();
1132 if (throb_value > 0) { 1046 if (throb_value > 0) {
1133 canvas->SaveLayerAlpha(gfx::ToRoundedInt(throb_value * 0xff), 1047 canvas->SaveLayerAlpha(gfx::ToRoundedInt(throb_value * 0xff),
1134 GetLocalBounds()); 1048 GetLocalBounds());
1135 PaintTabBackgroundUsingFillId(canvas, canvas, true, kActiveTabFillId, 1049 bool active = true;
1136 y_offset); 1050 gfx::Path* no_clip = nullptr;
1051 PaintTabBackground(canvas, active, kActiveTabFillId, y_offset, no_clip);
1137 canvas->Restore(); 1052 canvas->Restore();
1138 } 1053 }
1139 } 1054 }
1140 1055
1141 if (showing_icon_) 1056 if (showing_icon_)
1142 PaintIcon(canvas); 1057 PaintIcon(canvas);
1143 } 1058 }
1144 1059
1145 void Tab::PaintInactiveTabBackground(gfx::Canvas* canvas, 1060 void Tab::PaintInactiveTabBackground(gfx::Canvas* canvas,
1146 const gfx::Path& clip) { 1061 const gfx::Path& clip) {
1147 bool has_custom_image; 1062 bool has_custom_image;
1148 int fill_id = controller_->GetBackgroundResourceId(&has_custom_image); 1063 int background_resource_id =
1149 const ui::ThemeProvider* tp = GetThemeProvider(); 1064 controller_->GetBackgroundResourceId(&has_custom_image);
1150 1065
1151 // We only cache the image when it's the default image and we're not hovered, 1066 int fill_id = 0;
1152 // to avoid caching a background image that isn't the same for all tabs. 1067 int y_offset = 0;
1068 bool may_clip = controller_->MaySetClip();
1069
1153 if (has_custom_image) { 1070 if (has_custom_image) {
1071 const ui::ThemeProvider* tp = GetThemeProvider();
1072
1154 // If the theme is providing a custom background image, then its top edge 1073 // If the theme is providing a custom background image, then its top edge
1155 // should be at the top of the tab. Otherwise, we assume that the background 1074 // should be at the top of the tab. Otherwise, we assume that the background
1156 // image is a composited foreground + frame image. Note that if the theme 1075 // image is a composited foreground + frame image. Note that if the theme
1157 // is only providing a custom frame image, |has_custom_image| will be true, 1076 // is only providing a custom frame image, |has_custom_image| will be true,
1158 // but we should use the |background_offset_| here. 1077 // but we should use the |background_offset_| here.
1159 const int y_offset = 1078 fill_id = background_resource_id;
1160 tp->HasCustomImage(fill_id) ? 0 : background_offset_.y(); 1079 y_offset =
1161 PaintTabBackgroundUsingFillId(canvas, canvas, false, fill_id, y_offset); 1080 tp->HasCustomImage(background_resource_id) ? 0 : background_offset_.y();
1162 return; 1081 may_clip = false;
1163 }
1164 if (hover_controller_.ShouldDraw()) {
1165 PaintTabBackgroundUsingFillId(canvas, canvas, false, 0, 0);
1166 return;
1167 } 1082 }
1168 1083
1169 // For efficiency, we don't use separate fill and stroke images unless we 1084 bool active = false;
1170 // really need to clip the stroke and not the fill (for stacked tabs). This 1085 PaintTabBackground(canvas, active, fill_id, y_offset,
1171 // saves memory and avoids an extra image draw at the cost of recalculating 1086 may_clip ? &clip : nullptr);
Peter Kasting 2017/04/06 00:52:11 Nit: All the temps have made this function hard fo
danakj 2017/04/06 17:05:28 I really liked not splitting this into multiple ca
Peter Kasting 2017/04/06 18:49:44 After suggesting rewriting yesterday, I asked myse
danakj 2017/04/07 19:10:49 Done. Also observing that we always now clip inact
Peter Kasting 2017/04/07 23:34:02 Correct; the active tab should always be frontmost
1172 // the images when MaySetClip() toggles.
1173 const bool use_fill_and_stroke_images = controller_->MaySetClip();
1174
1175 const ImageCacheEntryMetadata metadata(
1176 tp->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB),
1177 controller_->GetToolbarTopSeparatorColor(), use_fill_and_stroke_images,
1178 canvas->image_scale(), size());
1179 auto it = std::find_if(
1180 g_image_cache->begin(), g_image_cache->end(),
1181 [&metadata](const ImageCacheEntry& e) { return e.metadata == metadata; });
1182 if (it == g_image_cache->end()) {
1183 gfx::Canvas tmp_canvas(size(), canvas->image_scale(), false);
1184 if (use_fill_and_stroke_images) {
1185 gfx::Canvas tmp_fill_canvas(size(), canvas->image_scale(), false);
1186 PaintTabBackgroundUsingFillId(&tmp_fill_canvas, &tmp_canvas, false, 0, 0);
1187 g_image_cache->emplace_front(
1188 metadata, gfx::ImageSkia(tmp_fill_canvas.ExtractImageRep()),
1189 gfx::ImageSkia(tmp_canvas.ExtractImageRep()));
1190 } else {
1191 PaintTabBackgroundUsingFillId(&tmp_canvas, &tmp_canvas, false, 0, 0);
1192 g_image_cache->emplace_front(
1193 metadata, gfx::ImageSkia(),
1194 gfx::ImageSkia(tmp_canvas.ExtractImageRep()));
1195 }
1196 if (g_image_cache->size() > kMaxImageCacheSize)
1197 g_image_cache->pop_back();
1198 it = g_image_cache->begin();
1199 }
1200
1201 gfx::ScopedCanvas scoped_canvas(
1202 use_fill_and_stroke_images ? canvas : nullptr);
1203 if (use_fill_and_stroke_images) {
1204 canvas->DrawImageInt(it->fill_image, 0, 0);
1205 canvas->sk_canvas()->clipPath(clip, SkClipOp::kDifference, true);
1206 }
1207 canvas->DrawImageInt(it->stroke_image, 0, 0);
1208 } 1087 }
1209 1088
1210 void Tab::PaintTabBackgroundUsingFillId(gfx::Canvas* fill_canvas, 1089 void Tab::PaintTabBackground(gfx::Canvas* canvas,
1211 gfx::Canvas* stroke_canvas, 1090 bool active,
1212 bool is_active, 1091 int fill_id,
1213 int fill_id, 1092 int y_offset,
1214 int y_offset) { 1093 const gfx::Path* clip) {
1215 gfx::Path fill; 1094 gfx::Path fill_path = GetFillPath(canvas->image_scale(), size());
1216 cc::PaintFlags flags;
1217 flags.setAntiAlias(true);
1218 1095
1219 // Draw the fill. 1096 PaintTabBackgroundFill(canvas, fill_path, active, fill_id, y_offset);
1220 { 1097 {
1221 gfx::ScopedCanvas scoped_canvas(fill_canvas); 1098 base::Optional<gfx::ScopedCanvas> scoped_canvas;
Peter Kasting 2017/04/06 00:52:11 Nit: It seems like it would be marginally simpler
danakj 2017/04/06 17:05:28 Ya that's fair, if you can move, then we can init
1222 const float scale = fill_canvas->UndoDeviceScaleFactor(); 1099 if (clip) {
1223 const ui::ThemeProvider* tp = GetThemeProvider(); 1100 scoped_canvas.emplace(canvas);
1224 const SkColor toolbar_color = tp->GetColor(ThemeProperties::COLOR_TOOLBAR); 1101 canvas->sk_canvas()->clipPath(*clip, SkClipOp::kDifference, true);
1225
1226 fill = GetFillPath(scale, size());
1227 {
1228 gfx::ScopedCanvas clip_scoper(fill_canvas);
1229 fill_canvas->ClipPath(fill, true);
1230 if (fill_id) {
1231 gfx::ScopedCanvas scale_scoper(fill_canvas);
1232 fill_canvas->sk_canvas()->scale(scale, scale);
1233 fill_canvas->TileImageInt(*tp->GetImageSkiaNamed(fill_id),
1234 GetMirroredX() + background_offset_.x(),
1235 y_offset, 0, 0, width(), height());
1236 } else {
1237 flags.setColor(
1238 is_active ? toolbar_color
1239 : tp->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB));
1240 fill_canvas->DrawRect(
1241 gfx::ScaleToEnclosingRect(GetLocalBounds(), scale), flags);
1242 }
1243
1244 if (!is_active && hover_controller_.ShouldDraw()) {
1245 SkPoint hover_location(
1246 gfx::PointToSkPoint(hover_controller_.location()));
1247 hover_location.scale(SkFloatToScalar(scale));
1248 const SkScalar kMinHoverRadius = 16;
1249 const SkScalar radius =
1250 std::max(SkFloatToScalar(width() / 4.f), kMinHoverRadius);
1251 DrawHighlight(fill_canvas, hover_location, radius * scale,
1252 SkColorSetA(toolbar_color, hover_controller_.GetAlpha()));
1253 }
1254 } 1102 }
1255 } 1103 PaintTabBackgroundStroke(canvas, fill_path, active);
1256
1257 // Draw the stroke.
1258 {
1259 gfx::ScopedCanvas scoped_canvas(stroke_canvas);
1260 const float scale = stroke_canvas->UndoDeviceScaleFactor();
1261
1262 gfx::Path stroke = GetBorderPath(scale, false, false, size());
1263 Op(stroke, fill, kDifference_SkPathOp, &stroke);
1264 if (!is_active) {
1265 // Clip out the bottom line; this will be drawn for us by
1266 // TabStrip::PaintChildren().
1267 stroke_canvas->ClipRect(
1268 gfx::RectF(width() * scale, height() * scale - 1));
1269 }
1270 flags.setColor(controller_->GetToolbarTopSeparatorColor());
1271 stroke_canvas->DrawPath(stroke, flags);
1272 } 1104 }
1273 } 1105 }
1274 1106
1107 void Tab::PaintTabBackgroundFill(gfx::Canvas* canvas,
1108 const gfx::Path& fill_path,
1109 bool active,
1110 int fill_id,
1111 int y_offset) {
1112 const ui::ThemeProvider* tp = GetThemeProvider();
1113 SkColor active_color = tp->GetColor(ThemeProperties::COLOR_TOOLBAR);
1114 SkColor inactive_color = tp->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB);
1115
1116 gfx::ScopedCanvas scoped_canvas(canvas);
1117 const float scale = canvas->UndoDeviceScaleFactor();
1118
1119 canvas->ClipPath(fill_path, true);
1120 if (fill_id) {
1121 gfx::ScopedCanvas scale_scoper(canvas);
1122 canvas->sk_canvas()->scale(scale, scale);
1123 canvas->TileImageInt(*tp->GetImageSkiaNamed(fill_id),
1124 GetMirroredX() + background_offset_.x(), y_offset, 0,
1125 0, width(), height());
1126 } else {
1127 cc::PaintFlags flags;
1128 flags.setAntiAlias(true);
1129 flags.setColor(active ? active_color : inactive_color);
1130 canvas->DrawRect(gfx::ScaleToEnclosingRect(GetLocalBounds(), scale), flags);
1131 }
1132
1133 if (!active && hover_controller_.ShouldDraw()) {
1134 SkPoint hover_location(gfx::PointToSkPoint(hover_controller_.location()));
1135 hover_location.scale(SkFloatToScalar(scale));
1136 const SkScalar kMinHoverRadius = 16;
1137 const SkScalar radius =
1138 std::max(SkFloatToScalar(width() / 4.f), kMinHoverRadius);
1139 DrawHighlight(canvas, hover_location, radius * scale,
1140 SkColorSetA(active_color, hover_controller_.GetAlpha()));
1141 }
1142 }
1143
1144 void Tab::PaintTabBackgroundStroke(gfx::Canvas* canvas,
1145 const gfx::Path& fill_path,
1146 bool active) {
1147 SkColor color = controller_->GetToolbarTopSeparatorColor();
1148
1149 gfx::ScopedCanvas scoped_canvas(canvas);
1150 const float scale = canvas->UndoDeviceScaleFactor();
1151
1152 gfx::Path stroke = GetBorderPath(scale, false, false, size());
1153 Op(stroke, fill_path, kDifference_SkPathOp, &stroke);
1154 if (!active) {
1155 // Clip out the bottom line; this will be drawn for us by
1156 // TabStrip::PaintChildren().
1157 canvas->ClipRect(gfx::RectF(width() * scale, height() * scale - 1));
1158 }
1159 cc::PaintFlags flags;
1160 flags.setAntiAlias(true);
1161 flags.setColor(color);
1162 canvas->DrawPath(stroke, flags);
1163 }
1164
1275 void Tab::PaintPinnedTabTitleChangedIndicatorAndIcon( 1165 void Tab::PaintPinnedTabTitleChangedIndicatorAndIcon(
1276 gfx::Canvas* canvas, 1166 gfx::Canvas* canvas,
1277 const gfx::Rect& favicon_draw_bounds) { 1167 const gfx::Rect& favicon_draw_bounds) {
1278 // The pinned tab title changed indicator consists of two parts: 1168 // The pinned tab title changed indicator consists of two parts:
1279 // . a clear (totally transparent) part over the bottom right (or left in rtl) 1169 // . a clear (totally transparent) part over the bottom right (or left in rtl)
1280 // of the favicon. This is done by drawing the favicon to a canvas, then 1170 // of the favicon. This is done by drawing the favicon to a canvas, then
1281 // drawing the clear part on top of the favicon. 1171 // drawing the clear part on top of the favicon.
1282 // . a circle in the bottom right (or left in rtl) of the favicon. 1172 // . a circle in the bottom right (or left in rtl) of the favicon.
1283 if (!favicon_.isNull()) { 1173 if (!favicon_.isNull()) {
1284 const float kIndicatorCropRadius = 4.5; 1174 const float kIndicatorCropRadius = 4.5;
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
1486 gfx::Rect bounds = favicon_bounds_; 1376 gfx::Rect bounds = favicon_bounds_;
1487 if (bounds.IsEmpty()) 1377 if (bounds.IsEmpty())
1488 return; 1378 return;
1489 1379
1490 // Extends the area to the bottom when the crash animation is in progress. 1380 // Extends the area to the bottom when the crash animation is in progress.
1491 if (crash_icon_animation_->is_animating()) 1381 if (crash_icon_animation_->is_animating())
1492 bounds.set_height(height() - bounds.y()); 1382 bounds.set_height(height() - bounds.y());
1493 bounds.set_x(GetMirroredXForRect(bounds)); 1383 bounds.set_x(GetMirroredXForRect(bounds));
1494 SchedulePaintInRect(bounds); 1384 SchedulePaintInRect(bounds);
1495 } 1385 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698