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

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: rip-DCHECK_IMPLIES 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 "cc/paint/paint_recorder.h"
18 #include "chrome/app/vector_icons/vector_icons.h" 19 #include "chrome/app/vector_icons/vector_icons.h"
19 #include "chrome/browser/themes/theme_properties.h" 20 #include "chrome/browser/themes/theme_properties.h"
20 #include "chrome/browser/ui/browser.h" 21 #include "chrome/browser/ui/browser.h"
21 #include "chrome/browser/ui/layout_constants.h" 22 #include "chrome/browser/ui/layout_constants.h"
22 #include "chrome/browser/ui/tab_contents/core_tab_helper.h" 23 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
23 #include "chrome/browser/ui/tabs/tab_utils.h" 24 #include "chrome/browser/ui/tabs/tab_utils.h"
24 #include "chrome/browser/ui/view_ids.h" 25 #include "chrome/browser/ui/view_ids.h"
25 #include "chrome/browser/ui/views/frame/browser_view.h" 26 #include "chrome/browser/ui/views/frame/browser_view.h"
26 #include "chrome/browser/ui/views/tabs/alert_indicator_button.h" 27 #include "chrome/browser/ui/views/tabs/alert_indicator_button.h"
27 #include "chrome/browser/ui/views/tabs/browser_tab_strip_controller.h" 28 #include "chrome/browser/ui/views/tabs/browser_tab_strip_controller.h"
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 87
87 // How opaque to make the hover state (out of 1). 88 // How opaque to make the hover state (out of 1).
88 const double kHoverOpacity = 0.33; 89 const double kHoverOpacity = 0.33;
89 90
90 // Opacity of the active tab background painted over inactive selected tabs. 91 // Opacity of the active tab background painted over inactive selected tabs.
91 const double kSelectedTabOpacity = 0.3; 92 const double kSelectedTabOpacity = 0.3;
92 93
93 // Inactive selected tabs have their throb value scaled by this. 94 // Inactive selected tabs have their throb value scaled by this.
94 const double kSelectedTabThrobScale = 0.95 - kSelectedTabOpacity; 95 const double kSelectedTabThrobScale = 0.95 - kSelectedTabOpacity;
95 96
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"; 97 const char kTabCloseButtonName[] = "TabCloseButton";
102 98
103 //////////////////////////////////////////////////////////////////////////////// 99 ////////////////////////////////////////////////////////////////////////////////
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 100 // Drawing and utility functions
186 101
187 // Returns the width of the tab endcap at scale 1. More precisely, this is the 102 // 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; 103 // 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), 104 // 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 105 // the total width of the endcap from tab outer edge to the inside end of the
191 // stroke inner edge is (GetUnscaledEndcapWidth() * scale) + 1. 106 // stroke inner edge is (GetUnscaledEndcapWidth() * scale) + 1.
192 float GetUnscaledEndcapWidth() { 107 float GetUnscaledEndcapWidth() {
193 return GetLayoutInsets(TAB).left() - 0.5f; 108 return GetLayoutInsets(TAB).left() - 0.5f;
194 } 109 }
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 alert_indicator_button_(nullptr), 442 alert_indicator_button_(nullptr),
528 close_button_(nullptr), 443 close_button_(nullptr),
529 title_(new views::Label()), 444 title_(new views::Label()),
530 tab_activated_with_last_tap_down_(false), 445 tab_activated_with_last_tap_down_(false),
531 hover_controller_(this), 446 hover_controller_(this),
532 showing_icon_(false), 447 showing_icon_(false),
533 showing_alert_indicator_(false), 448 showing_alert_indicator_(false),
534 showing_close_button_(false), 449 showing_close_button_(false),
535 button_color_(SK_ColorTRANSPARENT) { 450 button_color_(SK_ColorTRANSPARENT) {
536 DCHECK(controller); 451 DCHECK(controller);
537 InitTabResources();
538 452
539 // So we get don't get enter/exit on children and don't prematurely stop the 453 // So we get don't get enter/exit on children and don't prematurely stop the
540 // hover. 454 // hover.
541 set_notify_enter_exit_on_child(true); 455 set_notify_enter_exit_on_child(true);
542 456
543 set_id(VIEW_ID_TAB); 457 set_id(VIEW_ID_TAB);
544 458
545 SetBorder(views::CreateEmptyBorder(GetLayoutInsets(TAB))); 459 SetBorder(views::CreateEmptyBorder(GetLayoutInsets(TAB)));
546 460
547 title_->SetHorizontalAlignment(gfx::ALIGN_TO_HEAD); 461 title_->SetHorizontalAlignment(gfx::ALIGN_TO_HEAD);
(...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after
1111 if (data().blocked == old.blocked) 1025 if (data().blocked == old.blocked)
1112 return; 1026 return;
1113 1027
1114 if (data().blocked) 1028 if (data().blocked)
1115 StartPulse(); 1029 StartPulse();
1116 else 1030 else
1117 StopPulse(); 1031 StopPulse();
1118 } 1032 }
1119 1033
1120 void Tab::PaintTab(gfx::Canvas* canvas, const gfx::Path& clip) { 1034 void Tab::PaintTab(gfx::Canvas* canvas, const gfx::Path& clip) {
1121 const int kActiveTabFillId = 1035 int active_tab_fill_id = 0;
1122 GetThemeProvider()->HasCustomImage(IDR_THEME_TOOLBAR) ? IDR_THEME_TOOLBAR 1036 int active_tab_y_offset = 0;
1123 : 0; 1037 if (GetThemeProvider()->HasCustomImage(IDR_THEME_TOOLBAR)) {
1124 const int y_offset = -GetLayoutInsets(TAB).top(); 1038 active_tab_fill_id = IDR_THEME_TOOLBAR;
1039 active_tab_y_offset = -GetLayoutInsets(TAB).top();
1040 }
1041
1125 if (IsActive()) { 1042 if (IsActive()) {
1126 PaintTabBackgroundUsingFillId(canvas, canvas, true, kActiveTabFillId, 1043 PaintTabBackground(canvas, true /* active */, active_tab_fill_id,
1127 y_offset); 1044 active_tab_y_offset, nullptr /* clip */);
Peter Kasting 2017/04/08 00:59:37 Nit: Optional, but if you defined this above the c
danakj 2017/04/18 16:02:42 Yeah, I'm not sure it's making this easier to unde
1128 } else { 1045 } else {
1129 PaintInactiveTabBackground(canvas, clip); 1046 PaintInactiveTabBackground(canvas, clip);
1130 1047
1131 const double throb_value = GetThrobValue(); 1048 const double throb_value = GetThrobValue();
1132 if (throb_value > 0) { 1049 if (throb_value > 0) {
1133 canvas->SaveLayerAlpha(gfx::ToRoundedInt(throb_value * 0xff), 1050 canvas->SaveLayerAlpha(gfx::ToRoundedInt(throb_value * 0xff),
1134 GetLocalBounds()); 1051 GetLocalBounds());
1135 PaintTabBackgroundUsingFillId(canvas, canvas, true, kActiveTabFillId, 1052 PaintTabBackground(canvas, true /* active */, active_tab_fill_id,
1136 y_offset); 1053 active_tab_y_offset, nullptr /* clip */);
1137 canvas->Restore(); 1054 canvas->Restore();
1138 } 1055 }
1139 } 1056 }
1140 1057
1141 if (showing_icon_) 1058 if (showing_icon_)
1142 PaintIcon(canvas); 1059 PaintIcon(canvas);
1143 } 1060 }
1144 1061
1145 void Tab::PaintInactiveTabBackground(gfx::Canvas* canvas, 1062 void Tab::PaintInactiveTabBackground(gfx::Canvas* canvas,
1146 const gfx::Path& clip) { 1063 const gfx::Path& clip) {
1064 const ui::ThemeProvider* tp = GetThemeProvider();
Peter Kasting 2017/04/08 00:59:37 Nit: I suggest inlining this into the one use belo
danakj 2017/04/18 16:02:42 clang should complain about an unused var, but don
1065
1147 bool has_custom_image; 1066 bool has_custom_image;
1148 int fill_id = controller_->GetBackgroundResourceId(&has_custom_image); 1067 int fill_id = controller_->GetBackgroundResourceId(&has_custom_image);
1068
1069 // The offset used to read from the image specified by |fill_id|.
1070 int y_offset = 0;
1071
1072 if (!has_custom_image) {
1073 fill_id = 0;
1074 } else if (!tp->HasCustomImage(fill_id)) {
1075 // If there's a custom frame image but no custom image for the tab itself,
1076 // then the tab's background will be the frame's image, so we need to
1077 // provide an offset into the image to read from.
1078 y_offset = background_offset_.y();
1079 }
1080
1081 PaintTabBackground(canvas, false /* active */, fill_id, y_offset,
1082 controller_->MaySetClip() ? &clip : nullptr);
1083 }
1084
1085 void Tab::PaintTabBackground(gfx::Canvas* canvas,
1086 bool active,
1087 int fill_id,
1088 int y_offset,
1089 const gfx::Path* clip) {
1090 // |y_offset| is only set when |fill_id| is being used.
1091 DCHECK(!y_offset || fill_id);
1092
1149 const ui::ThemeProvider* tp = GetThemeProvider(); 1093 const ui::ThemeProvider* tp = GetThemeProvider();
1094 const SkColor active_color = tp->GetColor(ThemeProperties::COLOR_TOOLBAR);
1095 const SkColor inactive_color =
1096 tp->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB);
1097 const SkColor stroke_color = controller_->GetToolbarTopSeparatorColor();
1098 const bool paint_hover_effect = !active && hover_controller_.ShouldDraw();
1150 1099
1151 // We only cache the image when it's the default image and we're not hovered, 1100 // If there is a |fill_id| we don't try to cache. This could be improved
1152 // to avoid caching a background image that isn't the same for all tabs. 1101 // but would require knowing then the image from the ThemeProvider had been
1153 if (has_custom_image) { 1102 // changed, and invalidating when the tab's x-coordinate or background_offset_
1154 // If the theme is providing a custom background image, then its top edge 1103 // changed.
1155 // should be at the top of the tab. Otherwise, we assume that the background 1104 // Similarly, if |paint_hover_effect|, we don't try to cache since hover
1156 // image is a composited foreground + frame image. Note that if the theme 1105 // effects change on every invalidation and we would need to invalidate the
1157 // is only providing a custom frame image, |has_custom_image| will be true, 1106 // cache based on the hover states.
1158 // but we should use the |background_offset_| here. 1107 if (fill_id || paint_hover_effect) {
1159 const int y_offset = 1108 gfx::Path fill_path = GetFillPath(canvas->image_scale(), size());
1160 tp->HasCustomImage(fill_id) ? 0 : background_offset_.y(); 1109 gfx::Path stroke_path =
1161 PaintTabBackgroundUsingFillId(canvas, canvas, false, fill_id, y_offset); 1110 GetBorderPath(canvas->image_scale(), false, false, size());
1162 return; 1111 PaintTabBackgroundFill(canvas, fill_path, active, paint_hover_effect,
1163 } 1112 active_color, inactive_color, fill_id, y_offset);
1164 if (hover_controller_.ShouldDraw()) { 1113 gfx::ScopedCanvas scoped_canvas(clip ? canvas : nullptr);
1165 PaintTabBackgroundUsingFillId(canvas, canvas, false, 0, 0); 1114 if (clip)
1115 canvas->sk_canvas()->clipPath(*clip, SkClipOp::kDifference, true);
1116 PaintTabBackgroundStroke(canvas, fill_path, stroke_path, active,
1117 stroke_color);
1166 return; 1118 return;
1167 } 1119 }
1168 1120
1169 // For efficiency, we don't use separate fill and stroke images unless we 1121 BackgroundCache& cache =
1170 // really need to clip the stroke and not the fill (for stacked tabs). This 1122 active ? background_active_cache_ : background_inactive_cache_;
1171 // saves memory and avoids an extra image draw at the cost of recalculating 1123 if (!cache.CacheKeyIsValid(canvas->image_scale(), size(), active_color,
1172 // the images when MaySetClip() toggles. 1124 inactive_color, stroke_color)) {
1173 const bool use_fill_and_stroke_images = controller_->MaySetClip(); 1125 gfx::Path fill_path = GetFillPath(canvas->image_scale(), size());
1126 gfx::Path stroke_path =
1127 GetBorderPath(canvas->image_scale(), false, false, size());
1128 cc::PaintRecorder recorder;
1174 1129
1175 const ImageCacheEntryMetadata metadata( 1130 {
1176 tp->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB), 1131 gfx::Canvas cache_canvas(
1177 controller_->GetToolbarTopSeparatorColor(), use_fill_and_stroke_images, 1132 recorder.beginRecording(size().width(), size().height()),
1178 canvas->image_scale(), size()); 1133 canvas->image_scale());
1179 auto it = std::find_if( 1134 PaintTabBackgroundFill(&cache_canvas, fill_path, active,
1180 g_image_cache->begin(), g_image_cache->end(), 1135 paint_hover_effect, active_color, inactive_color,
1181 [&metadata](const ImageCacheEntry& e) { return e.metadata == metadata; }); 1136 fill_id, y_offset);
1182 if (it == g_image_cache->end()) { 1137 cache.fill_record = recorder.finishRecordingAsPicture();
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 } 1138 }
1196 if (g_image_cache->size() > kMaxImageCacheSize) 1139 {
1197 g_image_cache->pop_back(); 1140 gfx::Canvas cache_canvas(
1198 it = g_image_cache->begin(); 1141 recorder.beginRecording(size().width(), size().height()),
1142 canvas->image_scale());
1143 PaintTabBackgroundStroke(&cache_canvas, fill_path, stroke_path, active,
1144 stroke_color);
1145 cache.stroke_record = recorder.finishRecordingAsPicture();
1146 }
1147
1148 cache.SetCacheKey(canvas->image_scale(), size(), active_color,
1149 inactive_color, stroke_color);
1199 } 1150 }
1200 1151
1201 gfx::ScopedCanvas scoped_canvas( 1152 canvas->sk_canvas()->PlaybackPaintRecord(cache.fill_record);
1202 use_fill_and_stroke_images ? canvas : nullptr); 1153 gfx::ScopedCanvas scoped_canvas(clip ? canvas : nullptr);
1203 if (use_fill_and_stroke_images) { 1154 if (clip)
1204 canvas->DrawImageInt(it->fill_image, 0, 0); 1155 canvas->sk_canvas()->clipPath(*clip, SkClipOp::kDifference, true);
1205 canvas->sk_canvas()->clipPath(clip, SkClipOp::kDifference, true); 1156 canvas->sk_canvas()->PlaybackPaintRecord(cache.stroke_record);
1206 }
1207 canvas->DrawImageInt(it->stroke_image, 0, 0);
1208 } 1157 }
1209 1158
1210 void Tab::PaintTabBackgroundUsingFillId(gfx::Canvas* fill_canvas, 1159 void Tab::PaintTabBackgroundFill(gfx::Canvas* canvas,
1211 gfx::Canvas* stroke_canvas, 1160 const gfx::Path& fill_path,
1212 bool is_active, 1161 bool active,
1213 int fill_id, 1162 bool paint_hover_effect,
1214 int y_offset) { 1163 SkColor active_color,
1215 gfx::Path fill; 1164 SkColor inactive_color,
1165 int fill_id,
1166 int y_offset) {
1167 gfx::ScopedCanvas scoped_canvas(canvas);
1168 const float scale = canvas->UndoDeviceScaleFactor();
1169
1170 canvas->ClipPath(fill_path, true);
1171 if (fill_id) {
1172 gfx::ScopedCanvas scale_scoper(canvas);
1173 canvas->sk_canvas()->scale(scale, scale);
1174 canvas->TileImageInt(*GetThemeProvider()->GetImageSkiaNamed(fill_id),
1175 GetMirroredX() + background_offset_.x(), y_offset, 0,
1176 0, width(), height());
1177 } else {
1178 cc::PaintFlags flags;
1179 flags.setAntiAlias(true);
1180 flags.setColor(active ? active_color : inactive_color);
1181 canvas->DrawRect(gfx::ScaleToEnclosingRect(GetLocalBounds(), scale), flags);
1182 }
1183
1184 if (paint_hover_effect) {
1185 SkPoint hover_location(gfx::PointToSkPoint(hover_controller_.location()));
1186 hover_location.scale(SkFloatToScalar(scale));
1187 const SkScalar kMinHoverRadius = 16;
1188 const SkScalar radius =
1189 std::max(SkFloatToScalar(width() / 4.f), kMinHoverRadius);
1190 DrawHighlight(canvas, hover_location, radius * scale,
1191 SkColorSetA(active_color, hover_controller_.GetAlpha()));
1192 }
1193 }
1194
1195 void Tab::PaintTabBackgroundStroke(gfx::Canvas* canvas,
1196 const gfx::Path& fill_path,
1197 const gfx::Path& stroke_path,
1198 bool active,
1199 SkColor color) {
1200 gfx::ScopedCanvas scoped_canvas(canvas);
1201 const float scale = canvas->UndoDeviceScaleFactor();
1202
1203 if (!active) {
1204 // Clip out the bottom line; this will be drawn for us by
1205 // TabStrip::PaintChildren().
1206 canvas->ClipRect(gfx::RectF(width() * scale, height() * scale - 1));
1207 }
1216 cc::PaintFlags flags; 1208 cc::PaintFlags flags;
1217 flags.setAntiAlias(true); 1209 flags.setAntiAlias(true);
1218 1210 flags.setColor(color);
1219 // Draw the fill. 1211 SkPath path;
1220 { 1212 Op(stroke_path, fill_path, kDifference_SkPathOp, &path);
1221 gfx::ScopedCanvas scoped_canvas(fill_canvas); 1213 canvas->DrawPath(path, flags);
1222 const float scale = fill_canvas->UndoDeviceScaleFactor();
1223 const ui::ThemeProvider* tp = GetThemeProvider();
1224 const SkColor toolbar_color = tp->GetColor(ThemeProperties::COLOR_TOOLBAR);
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 }
1255 }
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 }
1273 } 1214 }
1274 1215
1275 void Tab::PaintPinnedTabTitleChangedIndicatorAndIcon( 1216 void Tab::PaintPinnedTabTitleChangedIndicatorAndIcon(
1276 gfx::Canvas* canvas, 1217 gfx::Canvas* canvas,
1277 const gfx::Rect& favicon_draw_bounds) { 1218 const gfx::Rect& favicon_draw_bounds) {
1278 // The pinned tab title changed indicator consists of two parts: 1219 // The pinned tab title changed indicator consists of two parts:
1279 // . a clear (totally transparent) part over the bottom right (or left in rtl) 1220 // . 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 1221 // of the favicon. This is done by drawing the favicon to a canvas, then
1281 // drawing the clear part on top of the favicon. 1222 // drawing the clear part on top of the favicon.
1282 // . a circle in the bottom right (or left in rtl) of the favicon. 1223 // . a circle in the bottom right (or left in rtl) of the favicon.
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
1486 gfx::Rect bounds = favicon_bounds_; 1427 gfx::Rect bounds = favicon_bounds_;
1487 if (bounds.IsEmpty()) 1428 if (bounds.IsEmpty())
1488 return; 1429 return;
1489 1430
1490 // Extends the area to the bottom when the crash animation is in progress. 1431 // Extends the area to the bottom when the crash animation is in progress.
1491 if (crash_icon_animation_->is_animating()) 1432 if (crash_icon_animation_->is_animating())
1492 bounds.set_height(height() - bounds.y()); 1433 bounds.set_height(height() - bounds.y());
1493 bounds.set_x(GetMirroredXForRect(bounds)); 1434 bounds.set_x(GetMirroredXForRect(bounds));
1494 SchedulePaintInRect(bounds); 1435 SchedulePaintInRect(bounds);
1495 } 1436 }
1437
1438 Tab::BackgroundCache::BackgroundCache() = default;
1439 Tab::BackgroundCache::~BackgroundCache() = default;
OLDNEW
« chrome/browser/ui/views/tabs/tab.h ('K') | « chrome/browser/ui/views/tabs/tab.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698