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

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: Use CanvasImageSource to draw at different scales Created 4 years, 5 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
(...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 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 } 412 }
412 } 413 }
413 414
414 //////////////////////////////////////////////////////////////////////////////// 415 ////////////////////////////////////////////////////////////////////////////////
415 // Tab::ImageCacheEntryMetadata 416 // Tab::ImageCacheEntryMetadata
416 417
417 struct Tab::ImageCacheEntryMetadata { 418 struct Tab::ImageCacheEntryMetadata {
418 ImageCacheEntryMetadata(int resource_id, 419 ImageCacheEntryMetadata(int resource_id,
419 SkColor fill_color, 420 SkColor fill_color,
420 SkColor stroke_color, 421 SkColor stroke_color,
421 ui::ScaleFactor scale_factor,
422 const gfx::Size& size); 422 const gfx::Size& size);
423 423
424 ~ImageCacheEntryMetadata(); 424 ~ImageCacheEntryMetadata();
425 425
426 // Making this a non-member would require a friend declaration in Tab. Bleh. 426 // Making this a non-member would require a friend declaration in Tab. Bleh.
427 bool operator==(const ImageCacheEntryMetadata& rhs) const; 427 bool operator==(const ImageCacheEntryMetadata& rhs) const;
428 428
429 int resource_id; // Only needed by pre-MD 429 int resource_id; // Only needed by pre-MD
430 SkColor fill_color; // Both colors only needed by MD 430 SkColor fill_color; // Both colors only needed by MD
431 SkColor stroke_color; 431 SkColor stroke_color;
Greg Levin 2016/07/12 23:23:45 I've removed cache as a differentiator of cache en
432 ui::ScaleFactor scale_factor;
433 gfx::Size size; 432 gfx::Size size;
434 }; 433 };
435 434
436 Tab::ImageCacheEntryMetadata::ImageCacheEntryMetadata( 435 Tab::ImageCacheEntryMetadata::ImageCacheEntryMetadata(
437 int resource_id, 436 int resource_id,
438 SkColor fill_color, 437 SkColor fill_color,
439 SkColor stroke_color, 438 SkColor stroke_color,
440 ui::ScaleFactor scale_factor,
441 const gfx::Size& size) 439 const gfx::Size& size)
442 : resource_id(resource_id), 440 : resource_id(resource_id),
443 fill_color(fill_color), 441 fill_color(fill_color),
444 stroke_color(stroke_color), 442 stroke_color(stroke_color),
445 scale_factor(scale_factor),
446 size(size) { 443 size(size) {
447 DCHECK_NE(ui::SCALE_FACTOR_NONE, scale_factor);
448
449 // Some fields are only relevant for pre-MD vs. MD. Erase the irrelevant ones 444 // Some fields are only relevant for pre-MD vs. MD. Erase the irrelevant ones
450 // so they don't cause incorrect cache misses. 445 // so they don't cause incorrect cache misses.
451 // TODO(pkasting): Remove |resource_id| field when non-MD code is deleted. 446 // TODO(pkasting): Remove |resource_id| field when non-MD code is deleted.
452 if (ui::MaterialDesignController::IsModeMaterial()) 447 if (ui::MaterialDesignController::IsModeMaterial())
453 resource_id = 0; 448 resource_id = 0;
454 else 449 else
455 fill_color = stroke_color = SK_ColorTRANSPARENT; 450 fill_color = stroke_color = SK_ColorTRANSPARENT;
456 } 451 }
457 452
458 Tab::ImageCacheEntryMetadata::~ImageCacheEntryMetadata() {} 453 Tab::ImageCacheEntryMetadata::~ImageCacheEntryMetadata() {}
459 454
460 bool Tab::ImageCacheEntryMetadata::operator==( 455 bool Tab::ImageCacheEntryMetadata::operator==(
461 const ImageCacheEntryMetadata& rhs) const { 456 const ImageCacheEntryMetadata& rhs) const {
462 return resource_id == rhs.resource_id && fill_color == rhs.fill_color && 457 return resource_id == rhs.resource_id && fill_color == rhs.fill_color &&
463 stroke_color == rhs.stroke_color && scale_factor == rhs.scale_factor && 458 stroke_color == rhs.stroke_color && size == rhs.size;
464 size == rhs.size;
465 } 459 }
466 460
467 //////////////////////////////////////////////////////////////////////////////// 461 ////////////////////////////////////////////////////////////////////////////////
462 // Tab::TabImageSource
463 //
464 // This subclass of CanvasImageSource allows the inactive tab image to be cached
465 // once and rendered correctly for all scale factors.
466 class Tab::TabImageSource : public gfx::CanvasImageSource {
467 public:
468 TabImageSource(Tab* tab, int fill_id, int y_offset);
469 ~TabImageSource() override {}
470
471 // gfx::CanvasImageSource override.
472 void Draw(gfx::Canvas* canvas) override;
473
474 private:
475 PaintBackgroundParams params_;
476
477 DISALLOW_COPY_AND_ASSIGN(TabImageSource);
478 };
479
480 Tab::TabImageSource::TabImageSource(Tab* tab, int fill_id, int y_offset)
481 : gfx::CanvasImageSource(tab->size(), true) {
482 params_.tp = tab->GetThemeProvider();
483 params_.hc = nullptr;
484 params_.is_active = false;
485 params_.fill_id = fill_id;
486 params_.has_custom_image = false;
487 params_.x_offset = 0;
488 params_.y_offset = y_offset;
489 params_.size = tab->size();
490 params_.stroke_color = tab->controller()->GetToolbarTopSeparatorColor();
491 }
492
493 void Tab::TabImageSource::Draw(gfx::Canvas* canvas) {
494 PaintTabBackgroundUsingFillId(canvas, params_);
495 }
496
497 ////////////////////////////////////////////////////////////////////////////////
468 // Tab::ImageCacheEntry 498 // Tab::ImageCacheEntry
469 499
470 struct Tab::ImageCacheEntry { 500 struct Tab::ImageCacheEntry {
471 ImageCacheEntry(const ImageCacheEntryMetadata& metadata, 501 ImageCacheEntry(const ImageCacheEntryMetadata& metadata,
472 const gfx::ImageSkia& image); 502 Tab* tab,
503 int fill_id,
504 int y_offset);
473 ~ImageCacheEntry(); 505 ~ImageCacheEntry();
474 506
475 ImageCacheEntryMetadata metadata; 507 ImageCacheEntryMetadata metadata;
476 gfx::ImageSkia image; 508 gfx::ImageSkia image;
477 }; 509 };
478 510
479 Tab::ImageCacheEntry::ImageCacheEntry(const ImageCacheEntryMetadata& metadata, 511 Tab::ImageCacheEntry::ImageCacheEntry(const ImageCacheEntryMetadata& metadata,
480 const gfx::ImageSkia& image) 512 Tab* tab,
481 : metadata(metadata), image(image) {} 513 int fill_id,
514 int y_offset)
515 : metadata(metadata),
516 image(new TabImageSource(tab, fill_id, y_offset), tab->size()) {}
482 517
483 Tab::ImageCacheEntry::~ImageCacheEntry() {} 518 Tab::ImageCacheEntry::~ImageCacheEntry() {}
484 519
485 //////////////////////////////////////////////////////////////////////////////// 520 ////////////////////////////////////////////////////////////////////////////////
486 // Tab, statics: 521 // Tab, statics:
487 522
488 // static 523 // static
489 const char Tab::kViewClassName[] = "Tab"; 524 const char Tab::kViewClassName[] = "Tab";
490 Tab::TabImages Tab::active_images_ = {0}; 525 Tab::TabImages Tab::active_images_ = {0};
491 Tab::TabImages Tab::inactive_images_ = {0}; 526 Tab::TabImages Tab::inactive_images_ = {0};
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
803 // When the window is maximized we don't want to shave off the edges or top 838 // When the window is maximized we don't want to shave off the edges or top
804 // shadow of the tab, such that the user can click anywhere along the top 839 // shadow of the tab, such that the user can click anywhere along the top
805 // edge of the screen to select a tab. Ditto for immersive fullscreen. 840 // edge of the screen to select a tab. Ditto for immersive fullscreen.
806 const views::Widget* widget = GetWidget(); 841 const views::Widget* widget = GetWidget();
807 const bool extend_to_top = 842 const bool extend_to_top =
808 widget && (widget->IsMaximized() || widget->IsFullscreen()); 843 widget && (widget->IsMaximized() || widget->IsFullscreen());
809 844
810 if (ui::MaterialDesignController::IsModeMaterial()) { 845 if (ui::MaterialDesignController::IsModeMaterial()) {
811 SkPath border; 846 SkPath border;
812 const float scale = GetWidget()->GetCompositor()->device_scale_factor(); 847 const float scale = GetWidget()->GetCompositor()->device_scale_factor();
813 GetBorderPath(scale, extend_to_top, &border); 848 GetBorderPath(scale, size(), extend_to_top, &border);
814 mask->addPath(border, SkMatrix::MakeScale(1 / scale)); 849 mask->addPath(border, SkMatrix::MakeScale(1 / scale));
815 } else { 850 } else {
816 // Hit mask constants. 851 // Hit mask constants.
817 const SkScalar kTabCapWidth = 15; 852 const SkScalar kTabCapWidth = 15;
818 const SkScalar kTabTopCurveWidth = 4; 853 const SkScalar kTabTopCurveWidth = 4;
819 const SkScalar kTabBottomCurveWidth = 3; 854 const SkScalar kTabBottomCurveWidth = 3;
820 #if defined(OS_MACOSX) 855 #if defined(OS_MACOSX)
821 // Mac's Cocoa UI doesn't have shadows. 856 // Mac's Cocoa UI doesn't have shadows.
822 const SkScalar kTabInset = 0; 857 const SkScalar kTabInset = 0;
823 #elif defined(TOOLKIT_VIEWS) 858 #elif defined(TOOLKIT_VIEWS)
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after
1282 // We only cache the image when it's the default image and we're not hovered, 1317 // We only cache the image when it's the default image and we're not hovered,
1283 // to avoid caching a background image that isn't the same for all tabs. 1318 // to avoid caching a background image that isn't the same for all tabs.
1284 if (has_custom_image || hover_controller_.ShouldDraw()) { 1319 if (has_custom_image || hover_controller_.ShouldDraw()) {
1285 PaintTabBackgroundUsingFillId(canvas, false, fill_id, has_custom_image, 1320 PaintTabBackgroundUsingFillId(canvas, false, fill_id, has_custom_image,
1286 y_offset); 1321 y_offset);
1287 return; 1322 return;
1288 } 1323 }
1289 1324
1290 const ImageCacheEntryMetadata metadata( 1325 const ImageCacheEntryMetadata metadata(
1291 fill_id, tp->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB), 1326 fill_id, tp->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB),
1292 controller_->GetToolbarTopSeparatorColor(), 1327 controller_->GetToolbarTopSeparatorColor(), size());
1293 ui::GetSupportedScaleFactor(canvas->image_scale()), size());
1294 auto it = std::find_if( 1328 auto it = std::find_if(
1295 image_cache_->begin(), image_cache_->end(), 1329 image_cache_->begin(), image_cache_->end(),
1296 [&metadata](const ImageCacheEntry& e) { return e.metadata == metadata; }); 1330 [&metadata](const ImageCacheEntry& e) { return e.metadata == metadata; });
1297 if (it == image_cache_->end()) { 1331 if (it == image_cache_->end()) {
1298 gfx::Canvas tmp_canvas(size(), canvas->image_scale(), false); 1332 image_cache_->emplace_front(metadata, this, fill_id, y_offset);
Greg Levin 2016/07/12 23:23:45 Previously, the image would be rendered here, then
1299 PaintTabBackgroundUsingFillId(&tmp_canvas, false, fill_id, false, y_offset);
1300 image_cache_->emplace_front(metadata,
1301 gfx::ImageSkia(tmp_canvas.ExtractImageRep()));
1302 if (image_cache_->size() > kMaxImageCacheSize) 1333 if (image_cache_->size() > kMaxImageCacheSize)
1303 image_cache_->pop_back(); 1334 image_cache_->pop_back();
1304 it = image_cache_->begin(); 1335 it = image_cache_->begin();
1305 } 1336 }
1306 canvas->DrawImageInt(it->image, 0, 0); 1337 canvas->DrawImageInt(it->image, 0, 0);
1307 } 1338 }
1308 1339
1309 void Tab::PaintTabBackgroundUsingFillId(gfx::Canvas* canvas, 1340 void Tab::PaintTabBackgroundUsingFillId(gfx::Canvas* canvas,
1310 bool is_active, 1341 bool is_active,
1311 int fill_id, 1342 int fill_id,
1312 bool has_custom_image, 1343 bool has_custom_image,
1313 int y_offset) { 1344 int y_offset) {
1314 const ui::ThemeProvider* tp = GetThemeProvider(); 1345 PaintBackgroundParams params;
1315 const SkColor toolbar_color = tp->GetColor(ThemeProperties::COLOR_TOOLBAR); 1346 params.tp = GetThemeProvider();
1316 gfx::ImageSkia* fill_image = tp->GetImageSkiaNamed(fill_id); 1347 params.hc = &hover_controller_;
1348 params.is_active = is_active;
1349 params.fill_id = fill_id;
1350 params.has_custom_image = has_custom_image;
1317 // The tab image needs to be lined up with the background image 1351 // The tab image needs to be lined up with the background image
1318 // so that it feels partially transparent. These offsets represent the tab 1352 // so that it feels partially transparent. These offsets represent the tab
1319 // position within the frame background image. 1353 // position within the frame background image.
1320 const int x_offset = GetMirroredX() + background_offset_.x(); 1354 params.x_offset = GetMirroredX() + background_offset_.x();
1355 params.y_offset = y_offset;
1356 params.size = size();
1357 params.stroke_color = controller_->GetToolbarTopSeparatorColor();
1358
1359 PaintTabBackgroundUsingFillId(canvas, params);
1360 }
1361
1362 // static
1363 // For use by Tab and TabImageSource
1364 void Tab::PaintTabBackgroundUsingFillId(gfx::Canvas* canvas,
1365 const PaintBackgroundParams& params) {
1366 const SkColor toolbar_color =
1367 params.tp->GetColor(ThemeProperties::COLOR_TOOLBAR);
1368 gfx::ImageSkia* fill_image = params.tp->GetImageSkiaNamed(params.fill_id);
oshima 2016/07/13 20:55:28 instead of passing tp/fill_id etc, can you just pa
Greg Levin 2016/07/15 22:24:48 I'm still constructing TabImageSource with tab and
1321 1369
1322 const SkScalar kMinHoverRadius = 16; 1370 const SkScalar kMinHoverRadius = 16;
1323 const SkScalar radius = 1371 const SkScalar radius =
1324 std::max(SkFloatToScalar(width() / 4.f), kMinHoverRadius); 1372 std::max(SkFloatToScalar(params.size.width() / 4.f), kMinHoverRadius);
1325 const bool draw_hover = !is_active && hover_controller_.ShouldDraw(); 1373 const bool draw_hover =
1326 SkPoint hover_location(PointToSkPoint(hover_controller_.location())); 1374 !params.is_active && params.hc && params.hc->ShouldDraw();
oshima 2016/07/13 20:55:28 you can also just pas nullptr if !ShouldDraw()
Greg Levin 2016/07/15 22:24:48 Done.
1375 SkPoint hover_location(
1376 PointToSkPoint(draw_hover ? params.hc->location() : gfx::Point()));
1327 const SkColor hover_color = 1377 const SkColor hover_color =
1328 SkColorSetA(toolbar_color, hover_controller_.GetAlpha()); 1378 SkColorSetA(toolbar_color, draw_hover ? params.hc->GetAlpha() : 255);
1329 1379
1330 if (ui::MaterialDesignController::IsModeMaterial()) { 1380 if (ui::MaterialDesignController::IsModeMaterial()) {
1331 gfx::ScopedCanvas scoped_canvas(canvas); 1381 gfx::ScopedCanvas scoped_canvas(canvas);
1332 const float scale = canvas->UndoDeviceScaleFactor(); 1382 const float scale = canvas->UndoDeviceScaleFactor();
1333 1383
1334 // Draw the fill. 1384 // Draw the fill.
1335 SkPath fill; 1385 SkPath fill;
1336 GetFillPath(scale, &fill); 1386 GetFillPath(scale, params.size, &fill);
1337 SkPaint paint; 1387 SkPaint paint;
1338 paint.setAntiAlias(true); 1388 paint.setAntiAlias(true);
1339 { 1389 {
1340 gfx::ScopedCanvas clip_scoper(canvas); 1390 gfx::ScopedCanvas clip_scoper(canvas);
1341 canvas->ClipPath(fill, true); 1391 canvas->ClipPath(fill, true);
1342 if (has_custom_image) { 1392 if (params.has_custom_image) {
1343 gfx::ScopedCanvas scale_scoper(canvas); 1393 gfx::ScopedCanvas scale_scoper(canvas);
1344 canvas->sk_canvas()->scale(scale, scale); 1394 canvas->sk_canvas()->scale(scale, scale);
1345 canvas->TileImageInt(*fill_image, x_offset, y_offset, 0, 0, width(), 1395 canvas->TileImageInt(*fill_image, params.x_offset, params.y_offset, 0,
1346 height()); 1396 0, params.size.width(), params.size.height());
1347 } else { 1397 } else {
1348 paint.setColor( 1398 paint.setColor(
1349 is_active ? toolbar_color 1399 params.is_active
1350 : tp->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB)); 1400 ? toolbar_color
1351 canvas->DrawRect(gfx::ScaleToEnclosingRect(GetLocalBounds(), scale), 1401 : params.tp->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB));
1352 paint); 1402 canvas->DrawRect(
1403 gfx::ScaleToEnclosingRect(gfx::Rect(params.size), scale), paint);
1353 } 1404 }
1354 if (draw_hover) { 1405 if (draw_hover) {
1355 hover_location.scale(SkFloatToScalar(scale)); 1406 hover_location.scale(SkFloatToScalar(scale));
1356 DrawHighlight(canvas, hover_location, radius * scale, hover_color); 1407 DrawHighlight(canvas, hover_location, radius * scale, hover_color);
1357 } 1408 }
1358 } 1409 }
1359 1410
1360 // Draw the stroke. 1411 // Draw the stroke.
1361 SkPath stroke; 1412 SkPath stroke;
1362 GetBorderPath(scale, false, &stroke); 1413 GetBorderPath(scale, params.size, false, &stroke);
1363 Op(stroke, fill, kDifference_SkPathOp, &stroke); 1414 Op(stroke, fill, kDifference_SkPathOp, &stroke);
1364 if (!is_active) { 1415 if (!params.is_active) {
1365 // Clip out the bottom line; this will be drawn for us by 1416 // Clip out the bottom line; this will be drawn for us by
1366 // TabStrip::PaintChildren(). 1417 // TabStrip::PaintChildren().
1367 canvas->sk_canvas()->clipRect( 1418 canvas->sk_canvas()->clipRect(SkRect::MakeWH(
1368 SkRect::MakeWH(width() * scale, height() * scale - 1)); 1419 params.size.width() * scale, params.size.height() * scale - 1));
1369 } 1420 }
1370 paint.setColor(controller_->GetToolbarTopSeparatorColor()); 1421 paint.setColor(params.stroke_color);
1371 canvas->DrawPath(stroke, paint); 1422 canvas->DrawPath(stroke, paint);
1372 } else { 1423 } else {
1373 if (draw_hover) { 1424 if (draw_hover) {
1374 // Draw everything to a temporary canvas so we can extract an image for 1425 // Draw everything to a temporary canvas so we can extract an image for
1375 // use in masking the hover glow. 1426 // use in masking the hover glow.
1376 gfx::Canvas background_canvas(size(), canvas->image_scale(), false); 1427 gfx::Canvas background_canvas(params.size, canvas->image_scale(), false);
1377 PaintTabFill(&background_canvas, fill_image, x_offset, y_offset, 1428 PaintTabFill(&background_canvas, fill_image, params.x_offset,
1378 is_active); 1429 params.y_offset, params.size, params.is_active);
1379 gfx::ImageSkia background_image(background_canvas.ExtractImageRep()); 1430 gfx::ImageSkia background_image(background_canvas.ExtractImageRep());
1380 canvas->DrawImageInt(background_image, 0, 0); 1431 canvas->DrawImageInt(background_image, 0, 0);
1381 1432
1382 gfx::Canvas hover_canvas(size(), canvas->image_scale(), false); 1433 gfx::Canvas hover_canvas(params.size, canvas->image_scale(), false);
1383 DrawHighlight(&hover_canvas, hover_location, radius, hover_color); 1434 DrawHighlight(&hover_canvas, hover_location, radius, hover_color);
1384 gfx::ImageSkia result = gfx::ImageSkiaOperations::CreateMaskedImage( 1435 gfx::ImageSkia result = gfx::ImageSkiaOperations::CreateMaskedImage(
1385 gfx::ImageSkia(hover_canvas.ExtractImageRep()), background_image); 1436 gfx::ImageSkia(hover_canvas.ExtractImageRep()), background_image);
1386 canvas->DrawImageInt(result, 0, 0); 1437 canvas->DrawImageInt(result, 0, 0);
1387 } else { 1438 } else {
1388 PaintTabFill(canvas, fill_image, x_offset, y_offset, is_active); 1439 PaintTabFill(canvas, fill_image, params.x_offset, params.y_offset,
Greg Levin 2016/07/12 23:23:45 I'm a little concerned about this use of x_offset.
1440 params.size, params.is_active);
1389 } 1441 }
1390 1442
1391 // Now draw the stroke, highlights, and shadows around the tab edge. 1443 // Now draw the stroke, highlights, and shadows around the tab edge.
1392 TabImages* stroke_images = is_active ? &active_images_ : &inactive_images_; 1444 TabImages* stroke_images =
1445 params.is_active ? &active_images_ : &inactive_images_;
1393 canvas->DrawImageInt(*stroke_images->image_l, 0, 0); 1446 canvas->DrawImageInt(*stroke_images->image_l, 0, 0);
1394 canvas->TileImageInt( 1447 canvas->TileImageInt(
1395 *stroke_images->image_c, stroke_images->l_width, 0, 1448 *stroke_images->image_c, stroke_images->l_width, 0,
1396 width() - stroke_images->l_width - stroke_images->r_width, height()); 1449 params.size.width() - stroke_images->l_width - stroke_images->r_width,
1450 params.size.height());
1397 canvas->DrawImageInt(*stroke_images->image_r, 1451 canvas->DrawImageInt(*stroke_images->image_r,
1398 width() - stroke_images->r_width, 0); 1452 params.size.width() - stroke_images->r_width, 0);
1399 } 1453 }
1400 } 1454 }
1401 1455
1456 // static
1402 void Tab::PaintTabFill(gfx::Canvas* canvas, 1457 void Tab::PaintTabFill(gfx::Canvas* canvas,
1403 gfx::ImageSkia* fill_image, 1458 gfx::ImageSkia* fill_image,
1404 int x_offset, 1459 int x_offset,
1405 int y_offset, 1460 int y_offset,
1461 const gfx::Size& size,
1406 bool is_active) { 1462 bool is_active) {
1407 const gfx::Insets tab_insets(GetLayoutInsets(TAB)); 1463 const gfx::Insets tab_insets(GetLayoutInsets(TAB));
1408 // If this isn't the foreground tab, don't draw over the toolbar, but do 1464 // If this isn't the foreground tab, don't draw over the toolbar, but do
1409 // include the 1 px divider stroke at the bottom. 1465 // include the 1 px divider stroke at the bottom.
1410 const int toolbar_overlap = is_active ? 0 : (tab_insets.bottom() - 1); 1466 const int toolbar_overlap = is_active ? 0 : (tab_insets.bottom() - 1);
1411 1467
1412 // Draw left edge. 1468 // Draw left edge.
1413 gfx::ImageSkia tab_l = gfx::ImageSkiaOperations::CreateTiledImage( 1469 gfx::ImageSkia tab_l = gfx::ImageSkiaOperations::CreateTiledImage(
1414 *fill_image, x_offset, y_offset, mask_images_.l_width, height()); 1470 *fill_image, x_offset, y_offset, mask_images_.l_width, size.height());
1415 gfx::ImageSkia theme_l = 1471 gfx::ImageSkia theme_l =
1416 gfx::ImageSkiaOperations::CreateMaskedImage(tab_l, *mask_images_.image_l); 1472 gfx::ImageSkiaOperations::CreateMaskedImage(tab_l, *mask_images_.image_l);
1417 canvas->DrawImageInt( 1473 canvas->DrawImageInt(
1418 theme_l, 0, 0, theme_l.width(), theme_l.height() - toolbar_overlap, 0, 0, 1474 theme_l, 0, 0, theme_l.width(), theme_l.height() - toolbar_overlap, 0, 0,
1419 theme_l.width(), theme_l.height() - toolbar_overlap, false); 1475 theme_l.width(), theme_l.height() - toolbar_overlap, false);
1420 1476
1421 // Draw right edge. 1477 // Draw right edge.
1422 gfx::ImageSkia tab_r = gfx::ImageSkiaOperations::CreateTiledImage( 1478 gfx::ImageSkia tab_r = gfx::ImageSkiaOperations::CreateTiledImage(
1423 *fill_image, x_offset + width() - mask_images_.r_width, y_offset, 1479 *fill_image, x_offset + size.width() - mask_images_.r_width, y_offset,
1424 mask_images_.r_width, height()); 1480 mask_images_.r_width, size.height());
1425 gfx::ImageSkia theme_r = 1481 gfx::ImageSkia theme_r =
1426 gfx::ImageSkiaOperations::CreateMaskedImage(tab_r, *mask_images_.image_r); 1482 gfx::ImageSkiaOperations::CreateMaskedImage(tab_r, *mask_images_.image_r);
1427 canvas->DrawImageInt(theme_r, 0, 0, theme_r.width(), 1483 canvas->DrawImageInt(theme_r, 0, 0, theme_r.width(),
1428 theme_r.height() - toolbar_overlap, 1484 theme_r.height() - toolbar_overlap,
1429 width() - theme_r.width(), 0, theme_r.width(), 1485 size.width() - theme_r.width(), 0, theme_r.width(),
1430 theme_r.height() - toolbar_overlap, false); 1486 theme_r.height() - toolbar_overlap, false);
1431 1487
1432 // Draw center. Instead of masking out the top portion we simply skip over it 1488 // Draw center. Instead of masking out the top portion we simply skip over it
1433 // by incrementing by the top padding, since it's a simple rectangle. 1489 // by incrementing by the top padding, since it's a simple rectangle.
1434 canvas->TileImageInt(*fill_image, x_offset + mask_images_.l_width, 1490 canvas->TileImageInt(
1435 y_offset + tab_insets.top(), mask_images_.l_width, 1491 *fill_image, x_offset + mask_images_.l_width, y_offset + tab_insets.top(),
1436 tab_insets.top(), 1492 mask_images_.l_width, tab_insets.top(),
1437 width() - mask_images_.l_width - mask_images_.r_width, 1493 size.width() - mask_images_.l_width - mask_images_.r_width,
1438 height() - tab_insets.top() - toolbar_overlap); 1494 size.height() - tab_insets.top() - toolbar_overlap);
1439 } 1495 }
1440 1496
1441 void Tab::PaintPinnedTabTitleChangedIndicatorAndIcon( 1497 void Tab::PaintPinnedTabTitleChangedIndicatorAndIcon(
1442 gfx::Canvas* canvas, 1498 gfx::Canvas* canvas,
1443 const gfx::Rect& favicon_draw_bounds) { 1499 const gfx::Rect& favicon_draw_bounds) {
1444 // The pinned tab title changed indicator consists of two parts: 1500 // The pinned tab title changed indicator consists of two parts:
1445 // . a clear (totally transparent) part over the bottom right (or left in rtl) 1501 // . a clear (totally transparent) part over the bottom right (or left in rtl)
1446 // of the favicon. This is done by drawing the favicon to a canvas, then 1502 // of the favicon. This is done by drawing the favicon to a canvas, then
1447 // drawing the clear part on top of the favicon. 1503 // drawing the clear part on top of the favicon.
1448 // . a circle in the bottom right (or left in rtl) of the favicon. 1504 // . a circle in the bottom right (or left in rtl) of the favicon.
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
1667 if (bounds.IsEmpty()) 1723 if (bounds.IsEmpty())
1668 return; 1724 return;
1669 1725
1670 // Extends the area to the bottom when the crash animation is in progress. 1726 // Extends the area to the bottom when the crash animation is in progress.
1671 if (crash_icon_animation_->is_animating()) 1727 if (crash_icon_animation_->is_animating())
1672 bounds.set_height(height() - bounds.y()); 1728 bounds.set_height(height() - bounds.y());
1673 bounds.set_x(GetMirroredXForRect(bounds)); 1729 bounds.set_x(GetMirroredXForRect(bounds));
1674 SchedulePaintInRect(bounds); 1730 SchedulePaintInRect(bounds);
1675 } 1731 }
1676 1732
1677 void Tab::GetFillPath(float scale, SkPath* fill) const { 1733 // static
1678 const float right = width() * scale; 1734 void Tab::GetFillPath(float scale, const gfx::Size& size, SkPath* fill) {
1735 const float right = size.width() * scale;
1679 // The bottom of the tab needs to be pixel-aligned or else when we call 1736 // The bottom of the tab needs to be pixel-aligned or else when we call
1680 // ClipPath with anti-aliasing enabled it can cause artifacts. 1737 // ClipPath with anti-aliasing enabled it can cause artifacts.
1681 const float bottom = std::ceil(height() * scale); 1738 const float bottom = std::ceil(size.height() * scale);
1682 const float unscaled_endcap_width = GetUnscaledEndcapWidth(); 1739 const float unscaled_endcap_width = GetUnscaledEndcapWidth();
1683 1740
1684 fill->moveTo(right - 1, bottom); 1741 fill->moveTo(right - 1, bottom);
1685 fill->rCubicTo(-0.75 * scale, 0, -1.625 * scale, -0.5 * scale, -2 * scale, 1742 fill->rCubicTo(-0.75 * scale, 0, -1.625 * scale, -0.5 * scale, -2 * scale,
1686 -1.5 * scale); 1743 -1.5 * scale);
1687 fill->lineTo(right - 1 - (unscaled_endcap_width - 2) * scale, 2.5 * scale); 1744 fill->lineTo(right - 1 - (unscaled_endcap_width - 2) * scale, 2.5 * scale);
1688 // Prevent overdraw in the center near minimum width (only happens if 1745 // Prevent overdraw in the center near minimum width (only happens if
1689 // scale < 2). We could instead avoid this by increasing the tab inset 1746 // scale < 2). We could instead avoid this by increasing the tab inset
1690 // values, but that would shift all the content inward as well, unless we 1747 // values, but that would shift all the content inward as well, unless we
1691 // then overlapped the content on the endcaps, by which point we'd have a 1748 // then overlapped the content on the endcaps, by which point we'd have a
1692 // huge mess. 1749 // huge mess.
1693 const float scaled_endcap_width = 1 + unscaled_endcap_width * scale; 1750 const float scaled_endcap_width = 1 + unscaled_endcap_width * scale;
1694 const float overlap = scaled_endcap_width * 2 - right; 1751 const float overlap = scaled_endcap_width * 2 - right;
1695 const float offset = (overlap > 0) ? (overlap / 2) : 0; 1752 const float offset = (overlap > 0) ? (overlap / 2) : 0;
1696 fill->rCubicTo(-0.375 * scale, -1 * scale, -1.25 * scale + offset, 1753 fill->rCubicTo(-0.375 * scale, -1 * scale, -1.25 * scale + offset,
1697 -1.5 * scale, -2 * scale + offset, -1.5 * scale); 1754 -1.5 * scale, -2 * scale + offset, -1.5 * scale);
1698 if (overlap < 0) 1755 if (overlap < 0)
1699 fill->lineTo(scaled_endcap_width, scale); 1756 fill->lineTo(scaled_endcap_width, scale);
1700 fill->rCubicTo(-0.75 * scale, 0, -1.625 * scale - offset, 0.5 * scale, 1757 fill->rCubicTo(-0.75 * scale, 0, -1.625 * scale - offset, 0.5 * scale,
1701 -2 * scale - offset, 1.5 * scale); 1758 -2 * scale - offset, 1.5 * scale);
1702 fill->lineTo(1 + 2 * scale, bottom - 1.5 * scale); 1759 fill->lineTo(1 + 2 * scale, bottom - 1.5 * scale);
1703 fill->rCubicTo(-0.375 * scale, scale, -1.25 * scale, 1.5 * scale, -2 * scale, 1760 fill->rCubicTo(-0.375 * scale, scale, -1.25 * scale, 1.5 * scale, -2 * scale,
1704 1.5 * scale); 1761 1.5 * scale);
1705 fill->close(); 1762 fill->close();
1706 } 1763 }
1707 1764
1708 void Tab::GetBorderPath(float scale, bool extend_to_top, SkPath* path) const { 1765 // static
1766 void Tab::GetBorderPath(float scale,
1767 const gfx::Size& size,
1768 bool extend_to_top,
1769 SkPath* path) {
1709 const float top = scale - 1; 1770 const float top = scale - 1;
1710 const float right = width() * scale; 1771 const float right = size.width() * scale;
1711 const float bottom = height() * scale; 1772 const float bottom = size.height() * scale;
1712 const float unscaled_endcap_width = GetUnscaledEndcapWidth(); 1773 const float unscaled_endcap_width = GetUnscaledEndcapWidth();
1713 1774
1714 path->moveTo(0, bottom); 1775 path->moveTo(0, bottom);
1715 path->rLineTo(0, -1); 1776 path->rLineTo(0, -1);
1716 path->rCubicTo(0.75 * scale, 0, 1.625 * scale, -0.5 * scale, 2 * scale, 1777 path->rCubicTo(0.75 * scale, 0, 1.625 * scale, -0.5 * scale, 2 * scale,
1717 -1.5 * scale); 1778 -1.5 * scale);
1718 path->lineTo((unscaled_endcap_width - 2) * scale, top + 1.5 * scale); 1779 path->lineTo((unscaled_endcap_width - 2) * scale, top + 1.5 * scale);
1719 if (extend_to_top) { 1780 if (extend_to_top) {
1720 // Create the vertical extension by extending the side diagonals until they 1781 // Create the vertical extension by extending the side diagonals until they
1721 // reach the top of the bounds. 1782 // reach the top of the bounds.
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1782 inactive_images_.image_c = rb.GetImageSkiaNamed(IDR_TAB_INACTIVE_CENTER); 1843 inactive_images_.image_c = rb.GetImageSkiaNamed(IDR_TAB_INACTIVE_CENTER);
1783 inactive_images_.image_r = rb.GetImageSkiaNamed(IDR_TAB_INACTIVE_RIGHT); 1844 inactive_images_.image_r = rb.GetImageSkiaNamed(IDR_TAB_INACTIVE_RIGHT);
1784 inactive_images_.l_width = inactive_images_.image_l->width(); 1845 inactive_images_.l_width = inactive_images_.image_l->width();
1785 inactive_images_.r_width = inactive_images_.image_r->width(); 1846 inactive_images_.r_width = inactive_images_.image_r->width();
1786 1847
1787 mask_images_.image_l = rb.GetImageSkiaNamed(IDR_TAB_ALPHA_LEFT); 1848 mask_images_.image_l = rb.GetImageSkiaNamed(IDR_TAB_ALPHA_LEFT);
1788 mask_images_.image_r = rb.GetImageSkiaNamed(IDR_TAB_ALPHA_RIGHT); 1849 mask_images_.image_r = rb.GetImageSkiaNamed(IDR_TAB_ALPHA_RIGHT);
1789 mask_images_.l_width = mask_images_.image_l->width(); 1850 mask_images_.l_width = mask_images_.image_l->width();
1790 mask_images_.r_width = mask_images_.image_r->width(); 1851 mask_images_.r_width = mask_images_.image_r->width();
1791 } 1852 }
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