OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |