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

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

Issue 2118853002: Fix pixelation of tab borders when device scale changes (abandoned) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Merge Created 4 years, 4 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
« no previous file with comments | « chrome/browser/ui/views/tabs/tab.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 "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
(...skipping 26 matching lines...) Expand all
37 #include "ui/base/material_design/material_design_controller.h" 37 #include "ui/base/material_design/material_design_controller.h"
38 #include "ui/base/models/list_selection_model.h" 38 #include "ui/base/models/list_selection_model.h"
39 #include "ui/base/resource/resource_bundle.h" 39 #include "ui/base/resource/resource_bundle.h"
40 #include "ui/base/theme_provider.h" 40 #include "ui/base/theme_provider.h"
41 #include "ui/gfx/animation/animation_container.h" 41 #include "ui/gfx/animation/animation_container.h"
42 #include "ui/gfx/animation/throb_animation.h" 42 #include "ui/gfx/animation/throb_animation.h"
43 #include "ui/gfx/canvas.h" 43 #include "ui/gfx/canvas.h"
44 #include "ui/gfx/color_analysis.h" 44 #include "ui/gfx/color_analysis.h"
45 #include "ui/gfx/favicon_size.h" 45 #include "ui/gfx/favicon_size.h"
46 #include "ui/gfx/geometry/rect_conversions.h" 46 #include "ui/gfx/geometry/rect_conversions.h"
47 #include "ui/gfx/image/canvas_image_source.h"
47 #include "ui/gfx/image/image_skia_operations.h" 48 #include "ui/gfx/image/image_skia_operations.h"
48 #include "ui/gfx/paint_vector_icon.h" 49 #include "ui/gfx/paint_vector_icon.h"
49 #include "ui/gfx/path.h" 50 #include "ui/gfx/path.h"
50 #include "ui/gfx/scoped_canvas.h" 51 #include "ui/gfx/scoped_canvas.h"
51 #include "ui/gfx/skia_util.h" 52 #include "ui/gfx/skia_util.h"
52 #include "ui/gfx/vector_icons_public.h" 53 #include "ui/gfx/vector_icons_public.h"
53 #include "ui/resources/grit/ui_resources.h" 54 #include "ui/resources/grit/ui_resources.h"
54 #include "ui/views/border.h" 55 #include "ui/views/border.h"
55 #include "ui/views/controls/button/image_button.h" 56 #include "ui/views/controls/button/image_button.h"
56 #include "ui/views/controls/label.h" 57 #include "ui/views/controls/label.h"
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 // Number of steps in the immersive mode loading animation. 115 // Number of steps in the immersive mode loading animation.
115 const int kImmersiveLoadingStepCount = 32; 116 const int kImmersiveLoadingStepCount = 32;
116 117
117 const char kTabCloseButtonName[] = "TabCloseButton"; 118 const char kTabCloseButtonName[] = "TabCloseButton";
118 119
119 // Desaturate favicon HSL shift values. 120 // Desaturate favicon HSL shift values.
120 const double kDesaturateHue = -1.0; 121 const double kDesaturateHue = -1.0;
121 const double kDesaturateSaturation = 0.0; 122 const double kDesaturateSaturation = 0.0;
122 const double kDesaturateLightness = 0.6; 123 const double kDesaturateLightness = 0.6;
123 124
124 // Parameters for PaintTabBackgroundUsingParams(). 125 // Parameters for PaintTabFill/StrokeUsingParams().
125 struct PaintBackgroundParams { 126 struct PaintBackgroundParams {
126 PaintBackgroundParams(bool is_active, 127 PaintBackgroundParams(bool is_active,
127 gfx::ImageSkia* fill_image_ptr, 128 gfx::ImageSkia* fill_image,
128 bool has_custom_image, 129 bool has_custom_image,
129 gfx::Rect rect, 130 const gfx::Rect& rect,
130 SkColor stroke_color, 131 SkColor stroke_color,
131 SkColor toolbar_color, 132 SkColor toolbar_color,
132 SkColor background_tab_color) 133 SkColor background_tab_color,
134 bool draw_hover,
135 const gfx::Point& hover_location,
136 SkAlpha hover_alpha)
133 : is_active(is_active), 137 : is_active(is_active),
134 fill_image(fill_image_ptr ? *fill_image_ptr : gfx::ImageSkia()), 138 fill_image(fill_image ? *fill_image : gfx::ImageSkia()),
135 has_custom_image(has_custom_image),
136 rect(rect), 139 rect(rect),
137 stroke_color(stroke_color), 140 stroke_color(stroke_color),
138 toolbar_color(toolbar_color), 141 toolbar_color(toolbar_color),
139 background_tab_color(background_tab_color) {} 142 background_tab_color(background_tab_color),
143 draw_hover(draw_hover),
144 hover_location(PointToSkPoint(hover_location)),
145 hover_alpha(hover_alpha) {}
140 146
141 const bool is_active; 147 const bool is_active;
142 const gfx::ImageSkia fill_image; 148 const gfx::ImageSkia fill_image;
143 const bool has_custom_image;
144 const gfx::Rect rect; 149 const gfx::Rect rect;
145 const SkColor stroke_color; 150 const SkColor stroke_color;
146 const SkColor toolbar_color; 151 const SkColor toolbar_color;
147 const SkColor background_tab_color; 152 const SkColor background_tab_color;
153 const bool draw_hover;
154 const SkPoint hover_location;
155 const SkAlpha hover_alpha;
148 }; 156 };
149 157
158 void PaintTabFillUsingParams(gfx::Canvas* canvas,
159 const PaintBackgroundParams& params);
160
161 void PaintTabStrokeUsingParams(gfx::Canvas* canvas,
162 const PaintBackgroundParams& params);
163
164 ////////////////////////////////////////////////////////////////////////////////
165 // TabImageSource
166 //
167 // This subclass of CanvasImageSource allows the inactive tab image to be cached
168 // once for each requested scale factor.
169 class TabImageSource : public gfx::CanvasImageSource {
170 public:
171 enum UseCanvas { FILL, STROKE, BOTH };
172
173 TabImageSource(UseCanvas use_canvas, Tab* tab, int fill_id, int y_offset);
174 ~TabImageSource() override {}
175
176 // gfx::CanvasImageSource override.
177 void Draw(gfx::Canvas* canvas) override;
178 bool HasRepresentationAtAllScales() const override { return true; }
179
180 private:
181 const UseCanvas use_canvas_;
182 const PaintBackgroundParams params_;
183
184 DISALLOW_COPY_AND_ASSIGN(TabImageSource);
185 };
186
187 TabImageSource::TabImageSource(UseCanvas use_canvas,
188 Tab* tab,
189 int fill_id,
190 int y_offset)
191 : gfx::CanvasImageSource(tab->size(), true),
192 use_canvas_(use_canvas),
193 params_(false,
194 tab->GetThemeProvider()->GetImageSkiaNamed(fill_id),
195 false,
196 gfx::Rect(gfx::Point(0, y_offset), tab->size()),
197 tab->controller()->GetToolbarTopSeparatorColor(),
198 tab->GetThemeProvider()->GetColor(ThemeProperties::COLOR_TOOLBAR),
199 tab->GetThemeProvider()->GetColor(
200 ThemeProperties::COLOR_BACKGROUND_TAB),
201 false,
202 gfx::Point(),
203 255) {}
204
205 void TabImageSource::Draw(gfx::Canvas* canvas) {
206 if (use_canvas_ != STROKE)
207 PaintTabFillUsingParams(canvas, params_);
208 if (use_canvas_ != FILL)
209 PaintTabStrokeUsingParams(canvas, params_);
210 }
211
150 //////////////////////////////////////////////////////////////////////////////// 212 ////////////////////////////////////////////////////////////////////////////////
151 // ImageCacheEntryMetadata 213 // ImageCacheEntryMetadata
152 // 214 //
153 // All metadata necessary to uniquely identify a cached image. 215 // All metadata necessary to uniquely identify a cached image.
154 struct ImageCacheEntryMetadata { 216 struct ImageCacheEntryMetadata {
155 ImageCacheEntryMetadata(int resource_id, 217 ImageCacheEntryMetadata(int resource_id,
156 SkColor fill_color, 218 SkColor fill_color,
157 SkColor stroke_color, 219 SkColor stroke_color,
158 bool use_fill_and_stroke_images, 220 bool use_fill_and_stroke_images,
159 ui::ScaleFactor scale_factor,
160 const gfx::Size& size); 221 const gfx::Size& size);
161 222
162 ~ImageCacheEntryMetadata(); 223 ~ImageCacheEntryMetadata();
163 224
164 bool operator==(const ImageCacheEntryMetadata& rhs) const; 225 bool operator==(const ImageCacheEntryMetadata& rhs) const;
165 226
166 int resource_id; // Only needed by pre-MD 227 int resource_id; // Only needed by pre-MD
167 SkColor fill_color; // Both colors only needed by MD 228 SkColor fill_color; // Both colors only needed by MD
168 SkColor stroke_color; 229 SkColor stroke_color;
169 bool use_fill_and_stroke_images; 230 bool use_fill_and_stroke_images;
170 ui::ScaleFactor scale_factor;
171 gfx::Size size; 231 gfx::Size size;
172 }; 232 };
173 233
174 ImageCacheEntryMetadata::ImageCacheEntryMetadata( 234 ImageCacheEntryMetadata::ImageCacheEntryMetadata(
175 int resource_id, 235 int resource_id,
176 SkColor fill_color, 236 SkColor fill_color,
177 SkColor stroke_color, 237 SkColor stroke_color,
178 bool use_fill_and_stroke_images, 238 bool use_fill_and_stroke_images,
179 ui::ScaleFactor scale_factor,
180 const gfx::Size& size) 239 const gfx::Size& size)
181 : resource_id(resource_id), 240 : resource_id(resource_id),
182 fill_color(fill_color), 241 fill_color(fill_color),
183 stroke_color(stroke_color), 242 stroke_color(stroke_color),
184 use_fill_and_stroke_images(use_fill_and_stroke_images), 243 use_fill_and_stroke_images(use_fill_and_stroke_images),
185 scale_factor(scale_factor),
186 size(size) { 244 size(size) {
187 DCHECK_NE(ui::SCALE_FACTOR_NONE, scale_factor);
188
189 // Some fields are only relevant for pre-MD vs. MD. Erase the irrelevant ones 245 // Some fields are only relevant for pre-MD vs. MD. Erase the irrelevant ones
190 // so they don't cause incorrect cache misses. 246 // so they don't cause incorrect cache misses.
191 // TODO(pkasting): Remove |resource_id| field when non-MD code is deleted. 247 // TODO(pkasting): Remove |resource_id| field when non-MD code is deleted.
192 if (ui::MaterialDesignController::IsModeMaterial()) 248 if (ui::MaterialDesignController::IsModeMaterial())
193 resource_id = 0; 249 resource_id = 0;
194 else 250 else
195 fill_color = stroke_color = SK_ColorTRANSPARENT; 251 fill_color = stroke_color = SK_ColorTRANSPARENT;
196 } 252 }
197 253
198 ImageCacheEntryMetadata::~ImageCacheEntryMetadata() {} 254 ImageCacheEntryMetadata::~ImageCacheEntryMetadata() {}
199 255
200 bool ImageCacheEntryMetadata::operator==( 256 bool ImageCacheEntryMetadata::operator==(
201 const ImageCacheEntryMetadata& rhs) const { 257 const ImageCacheEntryMetadata& rhs) const {
202 return resource_id == rhs.resource_id && fill_color == rhs.fill_color && 258 return resource_id == rhs.resource_id && fill_color == rhs.fill_color &&
203 stroke_color == rhs.stroke_color && 259 stroke_color == rhs.stroke_color &&
204 use_fill_and_stroke_images == rhs.use_fill_and_stroke_images && 260 use_fill_and_stroke_images == rhs.use_fill_and_stroke_images &&
205 scale_factor == rhs.scale_factor && size == rhs.size; 261 size == rhs.size;
206 } 262 }
207 263
208 //////////////////////////////////////////////////////////////////////////////// 264 ////////////////////////////////////////////////////////////////////////////////
209 // ImageCacheEntry and cache management 265 // ImageCacheEntry and cache management
210 // 266 //
211 // A cached image and the metadata used to generate it. 267 // A cached image and the metadata used to generate it.
212 struct ImageCacheEntry { 268 struct ImageCacheEntry {
213 ImageCacheEntry(const ImageCacheEntryMetadata& metadata, 269 ImageCacheEntry(const ImageCacheEntryMetadata& metadata,
214 const gfx::ImageSkia& fill_image, 270 Tab* tab,
215 const gfx::ImageSkia& stroke_image); 271 int fill_id,
272 int y_offset);
216 ~ImageCacheEntry(); 273 ~ImageCacheEntry();
217 274
218 ImageCacheEntryMetadata metadata; 275 ImageCacheEntryMetadata metadata;
219 gfx::ImageSkia fill_image; 276 gfx::ImageSkia fill_image;
220 gfx::ImageSkia stroke_image; 277 gfx::ImageSkia stroke_image;
221 }; 278 };
222 279
223 ImageCacheEntry::ImageCacheEntry(const ImageCacheEntryMetadata& metadata, 280 ImageCacheEntry::ImageCacheEntry(const ImageCacheEntryMetadata& metadata,
224 const gfx::ImageSkia& fill_image, 281 Tab* tab,
225 const gfx::ImageSkia& stroke_image) 282 int fill_id,
226 : metadata(metadata), fill_image(fill_image), stroke_image(stroke_image) {} 283 int y_offset)
284 : metadata(metadata) {
285 if (metadata.use_fill_and_stroke_images) {
286 fill_image = gfx::ImageSkia(
287 new TabImageSource(TabImageSource::FILL, tab, fill_id, y_offset),
288 tab->size());
289 }
290 TabImageSource::UseCanvas use = metadata.use_fill_and_stroke_images
291 ? TabImageSource::STROKE
292 : TabImageSource::BOTH;
293 stroke_image = gfx::ImageSkia(new TabImageSource(use, tab, fill_id, y_offset),
294 tab->size());
295 }
227 296
228 ImageCacheEntry::~ImageCacheEntry() {} 297 ImageCacheEntry::~ImageCacheEntry() {}
229 298
230 typedef std::list<ImageCacheEntry> ImageCache; 299 typedef std::list<ImageCacheEntry> ImageCache;
231 300
232 // As the majority of the tabs are inactive, and painting tabs is slowish, 301 // As the majority of the tabs are inactive, and painting tabs is slowish,
233 // we cache a handful of the inactive tab backgrounds here. 302 // we cache a handful of the inactive tab backgrounds here.
234 static ImageCache* g_image_cache = nullptr; 303 static ImageCache* g_image_cache = nullptr;
235 304
236 struct TabImages { 305 struct TabImages {
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 theme_r.height() - toolbar_overlap, false); 548 theme_r.height() - toolbar_overlap, false);
480 549
481 // Draw center. Instead of masking out the top portion we simply skip over it 550 // Draw center. Instead of masking out the top portion we simply skip over it
482 // by incrementing by the top padding, since it's a simple rectangle. 551 // by incrementing by the top padding, since it's a simple rectangle.
483 rect.Inset(g_mask_images.l_width, tab_insets.top(), g_mask_images.r_width, 552 rect.Inset(g_mask_images.l_width, tab_insets.top(), g_mask_images.r_width,
484 toolbar_overlap); 553 toolbar_overlap);
485 canvas->TileImageInt(fill_image, rect.x(), rect.y(), g_mask_images.l_width, 554 canvas->TileImageInt(fill_image, rect.x(), rect.y(), g_mask_images.l_width,
486 tab_insets.top(), rect.width(), rect.height()); 555 tab_insets.top(), rect.width(), rect.height());
487 } 556 }
488 557
489 void PaintTabBackgroundUsingParams(gfx::Canvas* fill_canvas, 558 // In non-MD mode, there is never a need to draw fill and stroke onto separate
490 gfx::Canvas* stroke_canvas, 559 // canvases, so in that case, this function does both.
491 views::GlowHoverController* hc, 560 void PaintTabFillUsingParams(gfx::Canvas* canvas,
492 const PaintBackgroundParams& params) { 561 const PaintBackgroundParams& params) {
493 const gfx::Rect& rect = params.rect; 562 const gfx::Rect& rect = params.rect;
494 const SkScalar kMinHoverRadius = 16; 563 const SkScalar kMinHoverRadius = 16;
495 const SkScalar radius = 564 const SkScalar radius =
496 std::max(SkFloatToScalar(rect.width() / 4.f), kMinHoverRadius); 565 std::max(SkFloatToScalar(rect.width() / 4.f), kMinHoverRadius);
497 const bool draw_hover = !params.is_active && hc;
498 SkPoint hover_location(
499 gfx::PointToSkPoint(draw_hover ? hc->location() : gfx::Point()));
500 const SkColor hover_color = 566 const SkColor hover_color =
501 SkColorSetA(params.toolbar_color, draw_hover ? hc->GetAlpha() : 255); 567 SkColorSetA(params.toolbar_color, params.hover_alpha);
502 568
503 if (ui::MaterialDesignController::IsModeMaterial()) { 569 if (ui::MaterialDesignController::IsModeMaterial()) {
504 gfx::Path fill; 570 gfx::ScopedCanvas scoped_canvas(canvas);
505 SkPaint paint; 571 const float scale = canvas->UndoDeviceScaleFactor();
506 paint.setAntiAlias(true); 572 gfx::Path fill = GetFillPath(scale, rect.size());
507 573
508 // Draw the fill.
509 { 574 {
510 gfx::ScopedCanvas scoped_canvas(fill_canvas); 575 gfx::ScopedCanvas clip_scoper(canvas);
511 const float scale = fill_canvas->UndoDeviceScaleFactor(); 576 canvas->ClipPath(fill, true);
512 577 if (!params.fill_image.isNull()) {
513 fill = GetFillPath(scale, rect.size()); 578 gfx::ScopedCanvas scale_scoper(canvas);
514 { 579 canvas->sk_canvas()->scale(scale, scale);
515 gfx::ScopedCanvas clip_scoper(fill_canvas); 580 canvas->TileImageInt(params.fill_image, rect.x(), rect.y(), 0, 0,
516 fill_canvas->ClipPath(fill, true); 581 rect.width(), rect.height());
517 if (!params.fill_image.isNull()) { 582 } else {
518 gfx::ScopedCanvas scale_scoper(fill_canvas); 583 SkPaint paint;
519 fill_canvas->sk_canvas()->scale(scale, scale); 584 paint.setAntiAlias(true);
520 fill_canvas->TileImageInt(params.fill_image, rect.x(), rect.y(), 0, 0, 585 paint.setColor(params.is_active ? params.toolbar_color
521 rect.width(), rect.height()); 586 : params.background_tab_color);
522 } else { 587 canvas->DrawRect(
523 paint.setColor(params.is_active ? params.toolbar_color 588 gfx::ScaleToEnclosingRect(gfx::Rect(rect.size()), scale), paint);
524 : params.background_tab_color); 589 }
525 fill_canvas->DrawRect( 590 if (params.draw_hover) {
526 gfx::ScaleToEnclosingRect(gfx::Rect(rect.size()), scale), 591 DrawHighlight(canvas, params.hover_location * scale, radius * scale,
527 paint); 592 hover_color);
528 }
529 if (draw_hover) {
530 hover_location.scale(SkFloatToScalar(scale));
531 DrawHighlight(fill_canvas, hover_location, radius * scale,
532 hover_color);
533 }
534 } 593 }
535 } 594 }
536
537 // Draw the stroke.
538 {
539 gfx::ScopedCanvas scoped_canvas(stroke_canvas);
540 const float scale = stroke_canvas->UndoDeviceScaleFactor();
541
542 gfx::Path stroke = GetBorderPath(scale, false, false, rect.size());
543 Op(stroke, fill, kDifference_SkPathOp, &stroke);
544 if (!params.is_active) {
545 // Clip out the bottom line; this will be drawn for us by
546 // TabStrip::PaintChildren().
547 stroke_canvas->ClipRect(gfx::RectF(rect.width() * scale,
548 rect.height() * scale - 1));
549 }
550 paint.setColor(params.stroke_color);
551 stroke_canvas->DrawPath(stroke, paint);
552 }
553 } else { 595 } else {
554 gfx::Canvas* canvas = stroke_canvas; 596 if (params.draw_hover) {
555 if (draw_hover) {
556 // Draw everything to a temporary canvas so we can extract an image for 597 // Draw everything to a temporary canvas so we can extract an image for
557 // use in masking the hover glow. 598 // use in masking the hover glow.
558 gfx::Canvas background_canvas(rect.size(), canvas->image_scale(), false); 599 gfx::Canvas background_canvas(rect.size(), canvas->image_scale(), false);
559 PaintTabFill(&background_canvas, params.fill_image, rect, 600 PaintTabFill(&background_canvas, params.fill_image, rect,
560 params.is_active); 601 params.is_active);
561 gfx::ImageSkia background_image(background_canvas.ExtractImageRep()); 602 gfx::ImageSkia background_image(background_canvas.ExtractImageRep());
562 canvas->DrawImageInt(background_image, 0, 0); 603 canvas->DrawImageInt(background_image, 0, 0);
563 604
564 gfx::Canvas hover_canvas(rect.size(), canvas->image_scale(), false); 605 gfx::Canvas hover_canvas(rect.size(), canvas->image_scale(), false);
565 DrawHighlight(&hover_canvas, hover_location, radius, hover_color); 606 DrawHighlight(&hover_canvas, params.hover_location, radius, hover_color);
566 gfx::ImageSkia result = gfx::ImageSkiaOperations::CreateMaskedImage( 607 gfx::ImageSkia result = gfx::ImageSkiaOperations::CreateMaskedImage(
567 gfx::ImageSkia(hover_canvas.ExtractImageRep()), background_image); 608 gfx::ImageSkia(hover_canvas.ExtractImageRep()), background_image);
568 canvas->DrawImageInt(result, 0, 0); 609 canvas->DrawImageInt(result, 0, 0);
569 } else { 610 } else {
570 PaintTabFill(canvas, params.fill_image, rect, params.is_active); 611 PaintTabFill(canvas, params.fill_image, rect, params.is_active);
571 } 612 }
572 613
573 // Now draw the stroke, highlights, and shadows around the tab edge. 614 // Now draw the stroke, highlights, and shadows around the tab edge.
574 TabImages* stroke_images = 615 TabImages* stroke_images =
575 params.is_active ? &g_active_images : &g_inactive_images; 616 params.is_active ? &g_active_images : &g_inactive_images;
576 canvas->DrawImageInt(*stroke_images->image_l, 0, 0); 617 canvas->DrawImageInt(*stroke_images->image_l, 0, 0);
577 canvas->TileImageInt( 618 canvas->TileImageInt(
578 *stroke_images->image_c, stroke_images->l_width, 0, 619 *stroke_images->image_c, stroke_images->l_width, 0,
579 rect.width() - stroke_images->l_width - stroke_images->r_width, 620 rect.width() - stroke_images->l_width - stroke_images->r_width,
580 rect.height()); 621 rect.height());
581 canvas->DrawImageInt(*stroke_images->image_r, 622 canvas->DrawImageInt(*stroke_images->image_r,
582 rect.width() - stroke_images->r_width, 0); 623 rect.width() - stroke_images->r_width, 0);
583 } 624 }
584 } 625 }
585 626
627 void PaintTabStrokeUsingParams(gfx::Canvas* canvas,
628 const PaintBackgroundParams& params) {
629 DCHECK(ui::MaterialDesignController::IsModeMaterial());
630 gfx::ScopedCanvas scoped_canvas(canvas);
631 const float scale = canvas->UndoDeviceScaleFactor();
632
633 SkPaint paint;
634 paint.setAntiAlias(true);
635 gfx::Path stroke = GetBorderPath(scale, false, false, params.rect.size());
636 gfx::Path fill = GetFillPath(scale, params.rect.size());
637 Op(stroke, fill, kDifference_SkPathOp, &stroke);
638 if (!params.is_active) {
639 // Clip out the bottom line; this will be drawn for us by
640 // TabStrip::PaintChildren().
641 canvas->ClipRect(gfx::RectF(params.rect.width() * scale,
642 params.rect.height() * scale - 1));
643 }
644 paint.setColor(params.stroke_color);
645 canvas->DrawPath(stroke, paint);
646 }
647
586 // Desaturates the favicon. Should only be used for when a tab encounters a 648 // Desaturates the favicon. Should only be used for when a tab encounters a
587 // network error state. 649 // network error state.
588 void PaintDesaturatedFavIcon(gfx::Canvas* canvas, 650 void PaintDesaturatedFavIcon(gfx::Canvas* canvas,
589 gfx::ImageSkia& favicon, 651 gfx::ImageSkia& favicon,
590 const gfx::Rect& bounds) { 652 const gfx::Rect& bounds) {
591 color_utils::HSL shift = {kDesaturateHue, 653 color_utils::HSL shift = {kDesaturateHue,
592 kDesaturateSaturation, 654 kDesaturateSaturation,
593 kDesaturateLightness}; 655 kDesaturateLightness};
594 gfx::ImageSkia desaturated_favicon = 656 gfx::ImageSkia desaturated_favicon =
595 gfx::ImageSkiaOperations::CreateHSLShiftedImage(favicon, shift); 657 gfx::ImageSkiaOperations::CreateHSLShiftedImage(favicon, shift);
(...skipping 849 matching lines...) Expand 10 before | Expand all | Expand 10 after
1445 else 1507 else
1446 StopPulse(); 1508 StopPulse();
1447 } 1509 }
1448 1510
1449 void Tab::PaintTab(gfx::Canvas* canvas, const gfx::Path& clip) { 1511 void Tab::PaintTab(gfx::Canvas* canvas, const gfx::Path& clip) {
1450 const int kActiveTabFillId = IDR_THEME_TOOLBAR; 1512 const int kActiveTabFillId = IDR_THEME_TOOLBAR;
1451 const bool has_custom_image = 1513 const bool has_custom_image =
1452 GetThemeProvider()->HasCustomImage(kActiveTabFillId); 1514 GetThemeProvider()->HasCustomImage(kActiveTabFillId);
1453 const int y_offset = -GetYInsetForActiveTabBackground(); 1515 const int y_offset = -GetYInsetForActiveTabBackground();
1454 if (IsActive()) { 1516 if (IsActive()) {
1455 PaintTabBackgroundUsingFillId(canvas, canvas, true, kActiveTabFillId, 1517 PaintTabBackgroundUsingFillId(canvas, true, kActiveTabFillId,
1456 has_custom_image, y_offset); 1518 has_custom_image, y_offset);
1457 } else { 1519 } else {
1458 PaintInactiveTabBackground(canvas, clip); 1520 PaintInactiveTabBackground(canvas, clip);
1459 1521
1460 const double throb_value = GetThrobValue(); 1522 const double throb_value = GetThrobValue();
1461 if (throb_value > 0) { 1523 if (throb_value > 0) {
1462 canvas->SaveLayerAlpha(gfx::ToRoundedInt(throb_value * 0xff), 1524 canvas->SaveLayerAlpha(gfx::ToRoundedInt(throb_value * 0xff),
1463 GetLocalBounds()); 1525 GetLocalBounds());
1464 PaintTabBackgroundUsingFillId(canvas, canvas, true, kActiveTabFillId, 1526 PaintTabBackgroundUsingFillId(canvas, true, kActiveTabFillId,
1465 has_custom_image, y_offset); 1527 has_custom_image, y_offset);
1466 canvas->Restore(); 1528 canvas->Restore();
1467 } 1529 }
1468 } 1530 }
1469 1531
1470 if (showing_icon_) 1532 if (showing_icon_)
1471 PaintIcon(canvas); 1533 PaintIcon(canvas);
1472 } 1534 }
1473 1535
1474 void Tab::PaintImmersiveTab(gfx::Canvas* canvas) { 1536 void Tab::PaintImmersiveTab(gfx::Canvas* canvas) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1525 // image is a composited foreground + frame image. Note that if the theme is 1587 // image is a composited foreground + frame image. Note that if the theme is
1526 // only providing a custom frame image, |has_custom_image| will be true, but 1588 // only providing a custom frame image, |has_custom_image| will be true, but
1527 // we should use the |background_offset_| here. 1589 // we should use the |background_offset_| here.
1528 const ui::ThemeProvider* tp = GetThemeProvider(); 1590 const ui::ThemeProvider* tp = GetThemeProvider();
1529 const int y_offset = tp->HasCustomImage(fill_id) ? 1591 const int y_offset = tp->HasCustomImage(fill_id) ?
1530 -GetLayoutConstant(TAB_TOP_EXCLUSION_HEIGHT) : background_offset_.y(); 1592 -GetLayoutConstant(TAB_TOP_EXCLUSION_HEIGHT) : background_offset_.y();
1531 1593
1532 // We only cache the image when it's the default image and we're not hovered, 1594 // We only cache the image when it's the default image and we're not hovered,
1533 // to avoid caching a background image that isn't the same for all tabs. 1595 // to avoid caching a background image that isn't the same for all tabs.
1534 if (has_custom_image || hover_controller_.ShouldDraw()) { 1596 if (has_custom_image || hover_controller_.ShouldDraw()) {
1535 PaintTabBackgroundUsingFillId(canvas, canvas, false, fill_id, 1597 PaintTabBackgroundUsingFillId(canvas, false, fill_id, has_custom_image,
1536 has_custom_image, y_offset); 1598 y_offset);
1537 return; 1599 return;
1538 } 1600 }
1539 1601
1540 // For efficiency, we don't use separate fill and stroke images unless we 1602 // For efficiency, we don't use separate fill and stroke images unless we
1541 // really need to clip the stroke and not the fill (for stacked tabs). This 1603 // really need to clip the stroke and not the fill (for stacked tabs). This
1542 // saves memory and avoids an extra image draw at the cost of recalculating 1604 // saves memory and avoids an extra image draw at the cost of recalculating
1543 // the images when MaySetClip() toggles. 1605 // the images when MaySetClip() toggles.
1544 const bool use_fill_and_stroke_images = 1606 const bool use_fill_and_stroke_images =
1545 controller_->MaySetClip() && 1607 controller_->MaySetClip() &&
1546 ui::MaterialDesignController::IsModeMaterial(); 1608 ui::MaterialDesignController::IsModeMaterial();
1547 1609
1548 const ImageCacheEntryMetadata metadata( 1610 const ImageCacheEntryMetadata metadata(
1549 fill_id, tp->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB), 1611 fill_id, tp->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB),
1550 controller_->GetToolbarTopSeparatorColor(), use_fill_and_stroke_images, 1612 controller_->GetToolbarTopSeparatorColor(), use_fill_and_stroke_images,
1551 ui::GetSupportedScaleFactor(canvas->image_scale()), size()); 1613 size());
1552 auto it = std::find_if( 1614 auto it = std::find_if(
1553 g_image_cache->begin(), g_image_cache->end(), 1615 g_image_cache->begin(), g_image_cache->end(),
1554 [&metadata](const ImageCacheEntry& e) { return e.metadata == metadata; }); 1616 [&metadata](const ImageCacheEntry& e) { return e.metadata == metadata; });
1555 if (it == g_image_cache->end()) { 1617 if (it == g_image_cache->end()) {
1556 gfx::Canvas tmp_canvas(size(), canvas->image_scale(), false); 1618 g_image_cache->emplace_front(metadata, this, fill_id, y_offset);
1557 if (use_fill_and_stroke_images) {
1558 gfx::Canvas tmp_fill_canvas(size(), canvas->image_scale(), false);
1559 PaintTabBackgroundUsingFillId(&tmp_fill_canvas, &tmp_canvas, false,
1560 fill_id, false, y_offset);
1561 g_image_cache->emplace_front(
1562 metadata, gfx::ImageSkia(tmp_fill_canvas.ExtractImageRep()),
1563 gfx::ImageSkia(tmp_canvas.ExtractImageRep()));
1564 } else {
1565 PaintTabBackgroundUsingFillId(&tmp_canvas, &tmp_canvas, false, fill_id,
1566 false, y_offset);
1567 g_image_cache->emplace_front(
1568 metadata, gfx::ImageSkia(),
1569 gfx::ImageSkia(tmp_canvas.ExtractImageRep()));
1570 }
1571 if (g_image_cache->size() > kMaxImageCacheSize) 1619 if (g_image_cache->size() > kMaxImageCacheSize)
1572 g_image_cache->pop_back(); 1620 g_image_cache->pop_back();
1573 it = g_image_cache->begin(); 1621 it = g_image_cache->begin();
1574 } 1622 }
1575 1623
1576 gfx::ScopedCanvas scoped_canvas( 1624 gfx::ScopedCanvas scoped_canvas(
1577 use_fill_and_stroke_images ? canvas : nullptr); 1625 use_fill_and_stroke_images ? canvas : nullptr);
1578 if (use_fill_and_stroke_images) { 1626 if (use_fill_and_stroke_images) {
1579 canvas->DrawImageInt(it->fill_image, 0, 0); 1627 canvas->DrawImageInt(it->fill_image, 0, 0);
1580 canvas->sk_canvas()->clipPath(clip, SkRegion::kDifference_Op, true); 1628 canvas->sk_canvas()->clipPath(clip, SkRegion::kDifference_Op, true);
1581 } 1629 }
1582 canvas->DrawImageInt(it->stroke_image, 0, 0); 1630 canvas->DrawImageInt(it->stroke_image, 0, 0);
1583 } 1631 }
1584 1632
1585 void Tab::PaintTabBackgroundUsingFillId(gfx::Canvas* fill_canvas, 1633 void Tab::PaintTabBackgroundUsingFillId(gfx::Canvas* canvas,
1586 gfx::Canvas* stroke_canvas,
1587 bool is_active, 1634 bool is_active,
1588 int fill_id, 1635 int fill_id,
1589 bool has_custom_image, 1636 bool has_custom_image,
1590 int y_offset) { 1637 int y_offset) {
1591 views::GlowHoverController* hc =
1592 hover_controller_.ShouldDraw() ? &hover_controller_ : nullptr;
1593 gfx::ImageSkia* fill_image = 1638 gfx::ImageSkia* fill_image =
1594 has_custom_image || !ui::MaterialDesignController::IsModeMaterial() 1639 has_custom_image || !ui::MaterialDesignController::IsModeMaterial()
1595 ? GetThemeProvider()->GetImageSkiaNamed(fill_id) 1640 ? GetThemeProvider()->GetImageSkiaNamed(fill_id)
1596 : nullptr; 1641 : nullptr;
1597 // The tab image needs to be lined up with the background image 1642 // The tab image needs to be lined up with the background image
1598 // so that it feels partially transparent. These offsets represent the tab 1643 // so that it feels partially transparent. These offsets represent the tab
1599 // position within the frame background image. 1644 // position within the frame background image.
1600 gfx::Rect rect(GetLocalBounds()); 1645 gfx::Rect rect(GetLocalBounds());
1601 rect.Offset(GetMirroredX() + background_offset_.x(), y_offset); 1646 rect.Offset(GetMirroredX() + background_offset_.x(), y_offset);
1602 PaintBackgroundParams params( 1647 PaintBackgroundParams params(
1603 is_active, fill_image, has_custom_image, rect, 1648 is_active, fill_image, has_custom_image, rect,
1604 controller_->GetToolbarTopSeparatorColor(), 1649 controller_->GetToolbarTopSeparatorColor(),
1605 GetThemeProvider()->GetColor(ThemeProperties::COLOR_TOOLBAR), 1650 GetThemeProvider()->GetColor(ThemeProperties::COLOR_TOOLBAR),
1606 GetThemeProvider()->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB)); 1651 GetThemeProvider()->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB),
1652 !is_active && hover_controller_.ShouldDraw(),
1653 hover_controller_.location(), hover_controller_.GetAlpha());
1607 1654
1608 PaintTabBackgroundUsingParams(fill_canvas, stroke_canvas, hc, params); 1655 PaintTabFillUsingParams(canvas, params);
1656 PaintTabStrokeUsingParams(canvas, params);
1609 } 1657 }
1610 1658
1611 void Tab::PaintPinnedTabTitleChangedIndicatorAndIcon( 1659 void Tab::PaintPinnedTabTitleChangedIndicatorAndIcon(
1612 gfx::Canvas* canvas, 1660 gfx::Canvas* canvas,
1613 const gfx::Rect& favicon_draw_bounds) { 1661 const gfx::Rect& favicon_draw_bounds) {
1614 // The pinned tab title changed indicator consists of two parts: 1662 // The pinned tab title changed indicator consists of two parts:
1615 // . a clear (totally transparent) part over the bottom right (or left in rtl) 1663 // . a clear (totally transparent) part over the bottom right (or left in rtl)
1616 // of the favicon. This is done by drawing the favicon to a canvas, then 1664 // of the favicon. This is done by drawing the favicon to a canvas, then
1617 // drawing the clear part on top of the favicon. 1665 // drawing the clear part on top of the favicon.
1618 // . a circle in the bottom right (or left in rtl) of the favicon. 1666 // . a circle in the bottom right (or left in rtl) of the favicon.
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
1859 gfx::Rect Tab::GetImmersiveBarRect() const { 1907 gfx::Rect Tab::GetImmersiveBarRect() const {
1860 // The main bar is as wide as the normal tab's horizontal top line. 1908 // The main bar is as wide as the normal tab's horizontal top line.
1861 // This top line of the tab extends a few pixels left and right of the 1909 // This top line of the tab extends a few pixels left and right of the
1862 // center image due to pixels in the rounded corner images. 1910 // center image due to pixels in the rounded corner images.
1863 const int kBarPadding = 1; 1911 const int kBarPadding = 1;
1864 int main_bar_left = g_active_images.l_width - kBarPadding; 1912 int main_bar_left = g_active_images.l_width - kBarPadding;
1865 int main_bar_right = width() - g_active_images.r_width + kBarPadding; 1913 int main_bar_right = width() - g_active_images.r_width + kBarPadding;
1866 return gfx::Rect( 1914 return gfx::Rect(
1867 main_bar_left, 0, main_bar_right - main_bar_left, kImmersiveBarHeight); 1915 main_bar_left, 0, main_bar_right - main_bar_left, kImmersiveBarHeight);
1868 } 1916 }
OLDNEW
« no previous file with comments | « 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