Chromium Code Reviews| 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 |