OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/gtk/tabs/tab_renderer_gtk.h" | 5 #include "chrome/browser/ui/gtk/tabs/tab_renderer_gtk.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
11 #include "chrome/browser/defaults.h" | 11 #include "chrome/browser/defaults.h" |
12 #include "chrome/browser/extensions/extension_tab_helper.h" | 12 #include "chrome/browser/extensions/extension_tab_helper.h" |
13 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
14 #include "chrome/browser/ui/browser.h" | 14 #include "chrome/browser/ui/browser.h" |
15 #include "chrome/browser/ui/gtk/bookmarks/bookmark_utils_gtk.h" | 15 #include "chrome/browser/ui/gtk/bookmarks/bookmark_utils_gtk.h" |
16 #include "chrome/browser/ui/gtk/custom_button.h" | 16 #include "chrome/browser/ui/gtk/custom_button.h" |
17 #include "chrome/browser/ui/gtk/gtk_theme_service.h" | 17 #include "chrome/browser/ui/gtk/gtk_theme_service.h" |
18 #include "chrome/browser/ui/gtk/gtk_util.h" | 18 #include "chrome/browser/ui/gtk/gtk_util.h" |
19 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" | 19 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" |
20 #include "content/browser/tab_contents/tab_contents.h" | 20 #include "content/browser/tab_contents/tab_contents.h" |
21 #include "content/common/notification_service.h" | 21 #include "content/common/notification_service.h" |
22 #include "grit/app_resources.h" | 22 #include "grit/app_resources.h" |
23 #include "grit/generated_resources.h" | 23 #include "grit/generated_resources.h" |
24 #include "grit/theme_resources.h" | 24 #include "grit/theme_resources.h" |
25 #include "ui/base/animation/slide_animation.h" | 25 #include "ui/base/animation/slide_animation.h" |
26 #include "ui/base/animation/throb_animation.h" | 26 #include "ui/base/animation/throb_animation.h" |
27 #include "ui/base/l10n/l10n_util.h" | 27 #include "ui/base/l10n/l10n_util.h" |
28 #include "ui/base/resource/resource_bundle.h" | 28 #include "ui/base/resource/resource_bundle.h" |
| 29 #include "ui/gfx/canvas_skia.h" |
29 #include "ui/gfx/canvas_skia_paint.h" | 30 #include "ui/gfx/canvas_skia_paint.h" |
30 #include "ui/gfx/favicon_size.h" | 31 #include "ui/gfx/favicon_size.h" |
31 #include "ui/gfx/platform_font_gtk.h" | 32 #include "ui/gfx/platform_font_gtk.h" |
32 #include "ui/gfx/skbitmap_operations.h" | 33 #include "ui/gfx/skbitmap_operations.h" |
33 | 34 |
34 namespace { | 35 namespace { |
35 | 36 |
36 const int kFontPixelSize = 12; | 37 const int kFontPixelSize = 12; |
37 const int kLeftPadding = 16; | 38 const int kLeftPadding = 16; |
38 const int kTopPadding = 6; | 39 const int kTopPadding = 6; |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 void TabRendererGtk::PaintFaviconArea(GdkEventExpose* event) { | 371 void TabRendererGtk::PaintFaviconArea(GdkEventExpose* event) { |
371 DCHECK(ShouldShowIcon()); | 372 DCHECK(ShouldShowIcon()); |
372 | 373 |
373 // The paint area is the favicon bounds, but we're painting into the gdk | 374 // The paint area is the favicon bounds, but we're painting into the gdk |
374 // window belonging to the tabstrip. So the coordinates are relative to the | 375 // window belonging to the tabstrip. So the coordinates are relative to the |
375 // top left of the tab strip. | 376 // top left of the tab strip. |
376 event->area.x = x() + favicon_bounds_.x(); | 377 event->area.x = x() + favicon_bounds_.x(); |
377 event->area.y = y() + favicon_bounds_.y(); | 378 event->area.y = y() + favicon_bounds_.y(); |
378 event->area.width = favicon_bounds_.width(); | 379 event->area.width = favicon_bounds_.width(); |
379 event->area.height = favicon_bounds_.height(); | 380 event->area.height = favicon_bounds_.height(); |
380 gfx::CanvasSkiaPaint canvas(event, false); | 381 gfx::CanvasSkiaPaint canvas_paint(event, false); |
| 382 gfx::CanvasSkia* canvas = canvas_paint.AsCanvas()->AsCanvasSkia(); |
381 | 383 |
382 // The actual paint methods expect 0, 0 to be the tab top left (see | 384 // The actual paint methods expect 0, 0 to be the tab top left (see |
383 // PaintTab). | 385 // PaintTab). |
384 canvas.TranslateInt(x(), y()); | 386 canvas->TranslateInt(x(), y()); |
385 | 387 |
386 // Paint the background behind the favicon. | 388 // Paint the background behind the favicon. |
387 int theme_id; | 389 int theme_id; |
388 int offset_y = 0; | 390 int offset_y = 0; |
389 if (IsSelected()) { | 391 if (IsSelected()) { |
390 theme_id = IDR_THEME_TOOLBAR; | 392 theme_id = IDR_THEME_TOOLBAR; |
391 } else { | 393 } else { |
392 if (!data_.incognito) { | 394 if (!data_.incognito) { |
393 theme_id = IDR_THEME_TAB_BACKGROUND; | 395 theme_id = IDR_THEME_TAB_BACKGROUND; |
394 } else { | 396 } else { |
395 theme_id = IDR_THEME_TAB_BACKGROUND_INCOGNITO; | 397 theme_id = IDR_THEME_TAB_BACKGROUND_INCOGNITO; |
396 } | 398 } |
397 if (!theme_service_->HasCustomImage(theme_id)) | 399 if (!theme_service_->HasCustomImage(theme_id)) |
398 offset_y = background_offset_y_; | 400 offset_y = background_offset_y_; |
399 } | 401 } |
400 SkBitmap* tab_bg = theme_service_->GetBitmapNamed(theme_id); | 402 SkBitmap* tab_bg = theme_service_->GetBitmapNamed(theme_id); |
401 canvas.TileImageInt(*tab_bg, | 403 canvas->TileImageInt(*tab_bg, |
402 x() + favicon_bounds_.x(), offset_y + favicon_bounds_.y(), | 404 x() + favicon_bounds_.x(), offset_y + favicon_bounds_.y(), |
403 favicon_bounds_.x(), favicon_bounds_.y(), | 405 favicon_bounds_.x(), favicon_bounds_.y(), |
404 favicon_bounds_.width(), favicon_bounds_.height()); | 406 favicon_bounds_.width(), favicon_bounds_.height()); |
405 | 407 |
406 if (!IsSelected()) { | 408 if (!IsSelected()) { |
407 double throb_value = GetThrobValue(); | 409 double throb_value = GetThrobValue(); |
408 if (throb_value > 0) { | 410 if (throb_value > 0) { |
409 SkRect bounds; | 411 SkRect bounds; |
410 bounds.set(favicon_bounds_.x(), favicon_bounds_.y(), | 412 bounds.set(favicon_bounds_.x(), favicon_bounds_.y(), |
411 favicon_bounds_.right(), favicon_bounds_.bottom()); | 413 favicon_bounds_.right(), favicon_bounds_.bottom()); |
412 canvas.saveLayerAlpha(&bounds, static_cast<int>(throb_value * 0xff), | 414 canvas->skia_canvas()->saveLayerAlpha(&bounds, |
413 SkCanvas::kARGB_ClipLayer_SaveFlag); | 415 static_cast<int>(throb_value * 0xff), |
414 canvas.drawARGB(0, 255, 255, 255, SkXfermode::kClear_Mode); | 416 SkCanvas::kARGB_ClipLayer_SaveFlag); |
| 417 canvas->skia_canvas()->drawARGB( |
| 418 0, 255, 255, 255, SkXfermode::kClear_Mode); |
415 SkBitmap* active_bg = theme_service_->GetBitmapNamed(IDR_THEME_TOOLBAR); | 419 SkBitmap* active_bg = theme_service_->GetBitmapNamed(IDR_THEME_TOOLBAR); |
416 canvas.TileImageInt(*active_bg, | 420 canvas->TileImageInt(*active_bg, |
417 x() + favicon_bounds_.x(), favicon_bounds_.y(), | 421 x() + favicon_bounds_.x(), favicon_bounds_.y(), |
418 favicon_bounds_.x(), favicon_bounds_.y(), | 422 favicon_bounds_.x(), favicon_bounds_.y(), |
419 favicon_bounds_.width(), favicon_bounds_.height()); | 423 favicon_bounds_.width(), favicon_bounds_.height()); |
420 canvas.restore(); | 424 canvas->Restore(); |
421 } | 425 } |
422 } | 426 } |
423 | 427 |
424 // Now paint the icon. | 428 // Now paint the icon. |
425 PaintIcon(&canvas); | 429 PaintIcon(canvas); |
426 } | 430 } |
427 | 431 |
428 bool TabRendererGtk::ShouldShowIcon() const { | 432 bool TabRendererGtk::ShouldShowIcon() const { |
429 if (mini() && height() >= GetMinimumUnselectedSize().height()) { | 433 if (mini() && height() >= GetMinimumUnselectedSize().height()) { |
430 return true; | 434 return true; |
431 } else if (!data_.show_icon) { | 435 } else if (!data_.show_icon) { |
432 return false; | 436 return false; |
433 } else if (IsSelected()) { | 437 } else if (IsSelected()) { |
434 // The selected tab clips favicon before close button. | 438 // The selected tab clips favicon before close button. |
435 return IconCapacity() >= 2; | 439 return IconCapacity() >= 2; |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
636 PaintTabBackground(canvas); | 640 PaintTabBackground(canvas); |
637 | 641 |
638 if (!mini() || width() > kMiniTabRendererAsNormalTabWidth) | 642 if (!mini() || width() > kMiniTabRendererAsNormalTabWidth) |
639 PaintTitle(canvas); | 643 PaintTitle(canvas); |
640 | 644 |
641 if (show_icon) | 645 if (show_icon) |
642 PaintIcon(canvas); | 646 PaintIcon(canvas); |
643 } | 647 } |
644 | 648 |
645 SkBitmap TabRendererGtk::PaintBitmap() { | 649 SkBitmap TabRendererGtk::PaintBitmap() { |
646 gfx::CanvasSkia canvas(width(), height(), false); | 650 gfx::CanvasSkia canvas; |
| 651 canvas.Init(width(), height(), false); |
647 Paint(&canvas); | 652 Paint(&canvas); |
648 return canvas.ExtractBitmap(); | 653 return canvas.ExtractBitmap(); |
649 } | 654 } |
650 | 655 |
651 cairo_surface_t* TabRendererGtk::PaintToSurface() { | 656 cairo_surface_t* TabRendererGtk::PaintToSurface() { |
652 gfx::CanvasSkia canvas(width(), height(), false); | 657 gfx::CanvasSkia canvas; |
| 658 canvas.Init(width(), height(), false); |
653 Paint(&canvas); | 659 Paint(&canvas); |
654 return cairo_surface_reference(cairo_get_target(canvas.beginPlatformPaint())); | 660 return cairo_surface_reference(cairo_get_target(canvas.BeginPlatformPaint())); |
655 } | 661 } |
656 | 662 |
657 void TabRendererGtk::SchedulePaint() { | 663 void TabRendererGtk::SchedulePaint() { |
658 gtk_widget_queue_draw(tab_.get()); | 664 gtk_widget_queue_draw(tab_.get()); |
659 } | 665 } |
660 | 666 |
661 gfx::Rect TabRendererGtk::GetLocalBounds() { | 667 gfx::Rect TabRendererGtk::GetLocalBounds() { |
662 return gfx::Rect(0, 0, bounds_.width(), bounds_.height()); | 668 return gfx::Rect(0, 0, bounds_.width(), bounds_.height()); |
663 } | 669 } |
664 | 670 |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
784 CachedBitmap bitmap = { | 790 CachedBitmap bitmap = { |
785 bg_offset_x, | 791 bg_offset_x, |
786 bg_offset_y, | 792 bg_offset_y, |
787 new SkBitmap(SkBitmapOperations::CreateMaskedBitmap(image, *mask)) | 793 new SkBitmap(SkBitmapOperations::CreateMaskedBitmap(image, *mask)) |
788 }; | 794 }; |
789 cached_bitmaps_[std::make_pair(mask, background)] = bitmap; | 795 cached_bitmaps_[std::make_pair(mask, background)] = bitmap; |
790 return bitmap.bitmap; | 796 return bitmap.bitmap; |
791 } | 797 } |
792 | 798 |
793 void TabRendererGtk::PaintTab(GdkEventExpose* event) { | 799 void TabRendererGtk::PaintTab(GdkEventExpose* event) { |
794 gfx::CanvasSkiaPaint canvas(event, false); | 800 gfx::CanvasSkiaPaint canvas_paint(event, false); |
795 if (canvas.is_empty()) | 801 if (canvas_paint.IsValid()) |
796 return; | 802 return; |
797 | 803 |
| 804 gfx::Canvas* canvas = canvas_paint.AsCanvas(); |
798 // The tab is rendered into a windowless widget whose offset is at the | 805 // The tab is rendered into a windowless widget whose offset is at the |
799 // coordinate event->area. Translate by these offsets so we can render at | 806 // coordinate event->area. Translate by these offsets so we can render at |
800 // (0,0) to match Windows' rendering metrics. | 807 // (0,0) to match Windows' rendering metrics. |
801 canvas.TranslateInt(event->area.x, event->area.y); | 808 canvas->TranslateInt(event->area.x, event->area.y); |
802 | 809 |
803 // Save the original x offset so we can position background images properly. | 810 // Save the original x offset so we can position background images properly. |
804 background_offset_x_ = event->area.x; | 811 background_offset_x_ = event->area.x; |
805 | 812 |
806 Paint(&canvas); | 813 Paint(canvas); |
807 } | 814 } |
808 | 815 |
809 void TabRendererGtk::PaintTitle(gfx::Canvas* canvas) { | 816 void TabRendererGtk::PaintTitle(gfx::Canvas* canvas) { |
810 // Paint the Title. | 817 // Paint the Title. |
811 string16 title = data_.title; | 818 string16 title = data_.title; |
812 if (title.empty()) { | 819 if (title.empty()) { |
813 title = data_.loading ? | 820 title = data_.loading ? |
814 l10n_util::GetStringUTF16(IDS_TAB_LOADING_TITLE) : | 821 l10n_util::GetStringUTF16(IDS_TAB_LOADING_TITLE) : |
815 TabContentsWrapper::GetDefaultTitle(); | 822 TabContentsWrapper::GetDefaultTitle(); |
816 } else { | 823 } else { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
876 void TabRendererGtk::PaintTabBackground(gfx::Canvas* canvas) { | 883 void TabRendererGtk::PaintTabBackground(gfx::Canvas* canvas) { |
877 if (IsSelected()) { | 884 if (IsSelected()) { |
878 PaintActiveTabBackground(canvas); | 885 PaintActiveTabBackground(canvas); |
879 } else { | 886 } else { |
880 PaintInactiveTabBackground(canvas); | 887 PaintInactiveTabBackground(canvas); |
881 | 888 |
882 double throb_value = GetThrobValue(); | 889 double throb_value = GetThrobValue(); |
883 if (throb_value > 0) { | 890 if (throb_value > 0) { |
884 canvas->SaveLayerAlpha(static_cast<int>(throb_value * 0xff), | 891 canvas->SaveLayerAlpha(static_cast<int>(throb_value * 0xff), |
885 gfx::Rect(width(), height())); | 892 gfx::Rect(width(), height())); |
886 canvas->AsCanvasSkia()->drawARGB(0, 255, 255, 255, | 893 canvas->AsCanvasSkia()->skia_canvas()->drawARGB( |
887 SkXfermode::kClear_Mode); | 894 0, 255, 255, 255, SkXfermode::kClear_Mode); |
888 PaintActiveTabBackground(canvas); | 895 PaintActiveTabBackground(canvas); |
889 canvas->Restore(); | 896 canvas->Restore(); |
890 } | 897 } |
891 } | 898 } |
892 } | 899 } |
893 | 900 |
894 void TabRendererGtk::PaintInactiveTabBackground(gfx::Canvas* canvas) { | 901 void TabRendererGtk::PaintInactiveTabBackground(gfx::Canvas* canvas) { |
895 | 902 |
896 // The tab image needs to be lined up with the background image | 903 // The tab image needs to be lined up with the background image |
897 // so that it feels partially transparent. | 904 // so that it feels partially transparent. |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1083 | 1090 |
1084 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 1091 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
1085 const gfx::Font& base_font = rb.GetFont(ResourceBundle::BaseFont); | 1092 const gfx::Font& base_font = rb.GetFont(ResourceBundle::BaseFont); |
1086 title_font_ = new gfx::Font(base_font.GetFontName(), kFontPixelSize); | 1093 title_font_ = new gfx::Font(base_font.GetFontName(), kFontPixelSize); |
1087 title_font_height_ = title_font_->GetHeight(); | 1094 title_font_height_ = title_font_->GetHeight(); |
1088 | 1095 |
1089 crashed_favicon = rb.GetBitmapNamed(IDR_SAD_FAVICON); | 1096 crashed_favicon = rb.GetBitmapNamed(IDR_SAD_FAVICON); |
1090 | 1097 |
1091 initialized_ = true; | 1098 initialized_ = true; |
1092 } | 1099 } |
OLD | NEW |