diff options
author | erg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-02 20:54:19 +0000 |
---|---|---|
committer | erg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-02 20:54:19 +0000 |
commit | 61e3009b9f5b3134fa3697befba4bc69c6be1e35 (patch) | |
tree | 81e35d5ca6efe019c1c888b7d7edbcdd0cf4fc7d | |
parent | 716b7785e16a2049525e406b17d75776cc1911ee (diff) | |
download | chromium_src-61e3009b9f5b3134fa3697befba4bc69c6be1e35.zip chromium_src-61e3009b9f5b3134fa3697befba4bc69c6be1e35.tar.gz chromium_src-61e3009b9f5b3134fa3697befba4bc69c6be1e35.tar.bz2 |
GTK: Move CairoCachedSurface from being owned by GtkThemeService to gfx::Image.
CairoCachedSurfaces are representations of a GdkPixbuf that live on the display
server instead of in process. GtkThemeService currently returns a
CairoCachedSurface for a (IDR#, Display). Instead, make gfx::Image keep
CairoCachedSurfaces as a representation and make CairoCachedSurface work on any
display, keeping the mapping to display server resources as an implementation
detail.
This has the benefit of:
- You don't need to go through GtkThemeService to access all resources,
simplifying the code in some places and allowing sharing of static images
across profiles.
- This will let us (in the future) remove several image conversions in the GTK
port.
This is part 1. Part 2 will remove the custom CairoCachedSurface calls from
GtkThemeService.
BUG=106060
TEST=none
R=rsesek@chromium.org
TBR=ben@chromium.org
Review URL: http://codereview.chromium.org/8769017
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@112778 0039d316-1c4b-4281-b951-d872f2087c98
22 files changed, 324 insertions, 218 deletions
diff --git a/chrome/browser/ui/gtk/about_chrome_dialog.cc b/chrome/browser/ui/gtk/about_chrome_dialog.cc index 5f1d855..68e4ea7 100644 --- a/chrome/browser/ui/gtk/about_chrome_dialog.cc +++ b/chrome/browser/ui/gtk/about_chrome_dialog.cc @@ -13,9 +13,7 @@ #include "chrome/browser/google/google_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser_list.h" -#include "chrome/browser/ui/gtk/cairo_cached_surface.h" #include "chrome/browser/ui/gtk/gtk_chrome_link_button.h" -#include "chrome/browser/ui/gtk/gtk_theme_service.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_version_info.h" #include "chrome/common/url_constants.h" @@ -26,6 +24,7 @@ #include "ui/base/gtk/gtk_hig_constants.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/image/cairo_cached_surface.h" #include "ui/gfx/image/image.h" #include "webkit/glue/webkit_glue.h" @@ -84,12 +83,12 @@ gboolean OnEventBoxExpose(GtkWidget* event_box, cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(event_box->window)); gdk_cairo_rectangle(cr, &expose->area); cairo_clip(cr); - GtkThemeService* theme_provider = - GtkThemeService::GetFrom(BrowserList::GetLastActive()->profile()); - CairoCachedSurface* background = theme_provider->GetSurfaceNamed( - IDR_ABOUT_BACKGROUND_COLOR, event_box); - background->SetSource(cr, 0, 0); + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + gfx::CairoCachedSurface* background = + rb.GetNativeImageNamed(IDR_ABOUT_BACKGROUND).ToCairo(); + background->SetSource(cr, event_box, 0, 0); + cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); gdk_cairo_rectangle(cr, &expose->area); cairo_fill(cr); diff --git a/chrome/browser/ui/gtk/bookmarks/bookmark_bar_gtk.cc b/chrome/browser/ui/gtk/bookmarks/bookmark_bar_gtk.cc index 2a86dba..537ee5b 100644 --- a/chrome/browser/ui/gtk/bookmarks/bookmark_bar_gtk.cc +++ b/chrome/browser/ui/gtk/bookmarks/bookmark_bar_gtk.cc @@ -21,7 +21,6 @@ #include "chrome/browser/ui/gtk/bookmarks/bookmark_menu_controller_gtk.h" #include "chrome/browser/ui/gtk/bookmarks/bookmark_utils_gtk.h" #include "chrome/browser/ui/gtk/browser_window_gtk.h" -#include "chrome/browser/ui/gtk/cairo_cached_surface.h" #include "chrome/browser/ui/gtk/custom_button.h" #include "chrome/browser/ui/gtk/gtk_chrome_button.h" #include "chrome/browser/ui/gtk/gtk_theme_service.h" @@ -47,6 +46,7 @@ #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/canvas_skia_paint.h" #include "ui/gfx/gtk_util.h" +#include "ui/gfx/image/cairo_cached_surface.h" #include "ui/gfx/image/image.h" namespace { diff --git a/chrome/browser/ui/gtk/browser_actions_toolbar_gtk.cc b/chrome/browser/ui/gtk/browser_actions_toolbar_gtk.cc index 97af9e4..ba41578 100644 --- a/chrome/browser/ui/gtk/browser_actions_toolbar_gtk.cc +++ b/chrome/browser/ui/gtk/browser_actions_toolbar_gtk.cc @@ -17,7 +17,6 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sessions/restore_tab_helper.h" #include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/gtk/cairo_cached_surface.h" #include "chrome/browser/ui/gtk/extensions/extension_popup_gtk.h" #include "chrome/browser/ui/gtk/gtk_chrome_button.h" #include "chrome/browser/ui/gtk/gtk_chrome_shrinkable_hbox.h" diff --git a/chrome/browser/ui/gtk/browser_toolbar_gtk.cc b/chrome/browser/ui/gtk/browser_toolbar_gtk.cc index 75171ba..aea48e4 100644 --- a/chrome/browser/ui/gtk/browser_toolbar_gtk.cc +++ b/chrome/browser/ui/gtk/browser_toolbar_gtk.cc @@ -27,7 +27,6 @@ #include "chrome/browser/ui/gtk/bookmarks/bookmark_sub_menu_model_gtk.h" #include "chrome/browser/ui/gtk/browser_actions_toolbar_gtk.h" #include "chrome/browser/ui/gtk/browser_window_gtk.h" -#include "chrome/browser/ui/gtk/cairo_cached_surface.h" #include "chrome/browser/ui/gtk/custom_button.h" #include "chrome/browser/ui/gtk/gtk_chrome_button.h" #include "chrome/browser/ui/gtk/gtk_theme_service.h" @@ -55,6 +54,7 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/canvas_skia_paint.h" #include "ui/gfx/gtk_util.h" +#include "ui/gfx/image/cairo_cached_surface.h" #include "ui/gfx/skbitmap_operations.h" namespace { @@ -504,9 +504,9 @@ gboolean BrowserToolbarGtk::OnAlignmentExpose(GtkWidget* widget, area = area.Subtract(right).Subtract(left); } - CairoCachedSurface* background = theme_service_->GetSurfaceNamed( + gfx::CairoCachedSurface* background = theme_service_->GetSurfaceNamed( IDR_THEME_TOOLBAR, widget); - background->SetSource(cr, tabstrip_origin.x(), tabstrip_origin.y()); + background->SetSource(cr, widget, tabstrip_origin.x(), tabstrip_origin.y()); cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); cairo_rectangle(cr, area.x(), area.y(), area.width(), area.height()); cairo_fill(cr); @@ -531,15 +531,15 @@ gboolean BrowserToolbarGtk::OnAlignmentExpose(GtkWidget* widget, cairo_set_operator(copy_cr, CAIRO_OPERATOR_SOURCE); if (draw_left_corner) { - CairoCachedSurface* left_corner = theme_service_->GetSurfaceNamed( + gfx::CairoCachedSurface* left_corner = theme_service_->GetSurfaceNamed( IDR_CONTENT_TOP_LEFT_CORNER_MASK, widget); - left_corner->SetSource(copy_cr, left.x(), left.y()); + left_corner->SetSource(copy_cr, widget, left.x(), left.y()); cairo_paint(copy_cr); } if (draw_right_corner) { - CairoCachedSurface* right_corner = theme_service_->GetSurfaceNamed( + gfx::CairoCachedSurface* right_corner = theme_service_->GetSurfaceNamed( IDR_CONTENT_TOP_RIGHT_CORNER_MASK, widget); - right_corner->SetSource(copy_cr, right.x(), right.y()); + right_corner->SetSource(copy_cr, widget, right.x(), right.y()); // We fill a path rather than just painting because we don't want to // overwrite the left corner. cairo_rectangle(copy_cr, right.x(), right.y(), @@ -549,7 +549,8 @@ gboolean BrowserToolbarGtk::OnAlignmentExpose(GtkWidget* widget, // Draw the background. CAIRO_OPERATOR_IN uses the existing pixel data as // an alpha mask. - background->SetSource(copy_cr, tabstrip_origin.x(), tabstrip_origin.y()); + background->SetSource(copy_cr, widget, + tabstrip_origin.x(), tabstrip_origin.y()); cairo_set_operator(copy_cr, CAIRO_OPERATOR_IN); cairo_pattern_set_extend(cairo_get_source(copy_cr), CAIRO_EXTEND_REPEAT); cairo_paint(copy_cr); diff --git a/chrome/browser/ui/gtk/browser_window_gtk.cc b/chrome/browser/ui/gtk/browser_window_gtk.cc index 4e46d41..2ecbc30 100644 --- a/chrome/browser/ui/gtk/browser_window_gtk.cc +++ b/chrome/browser/ui/gtk/browser_window_gtk.cc @@ -46,7 +46,6 @@ #include "chrome/browser/ui/gtk/bookmarks/bookmark_bar_gtk.h" #include "chrome/browser/ui/gtk/browser_titlebar.h" #include "chrome/browser/ui/gtk/browser_toolbar_gtk.h" -#include "chrome/browser/ui/gtk/cairo_cached_surface.h" #include "chrome/browser/ui/gtk/collected_cookies_gtk.h" #include "chrome/browser/ui/gtk/create_application_shortcuts_dialog_gtk.h" #include "chrome/browser/ui/gtk/download/download_in_progress_dialog_gtk.h" @@ -96,6 +95,7 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/x/active_window_watcher_x.h" #include "ui/gfx/gtk_util.h" +#include "ui/gfx/image/cairo_cached_surface.h" #include "ui/gfx/rect.h" #include "ui/gfx/skia_utils_gtk.h" @@ -452,11 +452,11 @@ void BrowserWindowGtk::DrawContentShadow(cairo_t* cr) { &top_y); int center_width = window_vbox_->allocation.width; - CairoCachedSurface* top_center = theme_provider->GetSurfaceNamed( + gfx::CairoCachedSurface* top_center = theme_provider->GetSurfaceNamed( IDR_CONTENT_TOP_CENTER, GTK_WIDGET(window_)); - CairoCachedSurface* top_right = theme_provider->GetSurfaceNamed( + gfx::CairoCachedSurface* top_right = theme_provider->GetSurfaceNamed( IDR_CONTENT_TOP_RIGHT_CORNER, GTK_WIDGET(window_)); - CairoCachedSurface* top_left = theme_provider->GetSurfaceNamed( + gfx::CairoCachedSurface* top_left = theme_provider->GetSurfaceNamed( IDR_CONTENT_TOP_LEFT_CORNER, GTK_WIDGET(window_)); int center_left_x = left_x; @@ -467,7 +467,8 @@ void BrowserWindowGtk::DrawContentShadow(cairo_t* cr) { center_width += 2 * kContentShadowThickness; } - top_center->SetSource(cr, center_left_x, top_y - kContentShadowThickness); + top_center->SetSource(cr, GTK_WIDGET(window_), + center_left_x, top_y - kContentShadowThickness); cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); cairo_rectangle(cr, center_left_x, top_y - kContentShadowThickness, center_width, top_center->Height()); @@ -483,8 +484,8 @@ void BrowserWindowGtk::DrawContentShadow(cairo_t* cr) { // corners extend to the base of the toolbar (one pixel above the dividing // line). int right_x = center_left_x + center_width; - top_left->SetSource( - cr, left_x - kContentShadowThickness, top_y - kContentShadowThickness); + top_left->SetSource(cr, GTK_WIDGET(window_), + left_x - kContentShadowThickness, top_y - kContentShadowThickness); // The toolbar is shorter in location bar only mode so clip the image to the // height of the toolbar + the amount of shadow above the toolbar. cairo_rectangle(cr, @@ -495,7 +496,8 @@ void BrowserWindowGtk::DrawContentShadow(cairo_t* cr) { cairo_fill(cr); // Likewise, we crop off the left column of pixels for the top right corner. - top_right->SetSource(cr, right_x, top_y - kContentShadowThickness); + top_right->SetSource(cr, GTK_WIDGET(window_), + right_x, top_y - kContentShadowThickness); cairo_rectangle(cr, right_x, top_y - kContentShadowThickness, @@ -517,9 +519,10 @@ void BrowserWindowGtk::DrawContentShadow(cairo_t* cr) { // drawn by the bottom corners. int side_height = bottom_y - side_y - 1; if (side_height > 0) { - CairoCachedSurface* left = theme_provider->GetSurfaceNamed( + gfx::CairoCachedSurface* left = theme_provider->GetSurfaceNamed( IDR_CONTENT_LEFT_SIDE, GTK_WIDGET(window_)); - left->SetSource(cr, left_x - kContentShadowThickness, side_y); + left->SetSource(cr, GTK_WIDGET(window_), + left_x - kContentShadowThickness, side_y); cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); cairo_rectangle(cr, left_x - kContentShadowThickness, @@ -528,11 +531,11 @@ void BrowserWindowGtk::DrawContentShadow(cairo_t* cr) { side_height); cairo_fill(cr); - CairoCachedSurface* right = theme_provider->GetSurfaceNamed( + gfx::CairoCachedSurface* right = theme_provider->GetSurfaceNamed( IDR_CONTENT_RIGHT_SIDE, GTK_WIDGET(window_)); int right_side_x = right_x + top_right->Width() - kContentShadowThickness - 1; - right->SetSource(cr, right_side_x, side_y); + right->SetSource(cr, GTK_WIDGET(window_), right_side_x, side_y); cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); cairo_rectangle(cr, right_side_x, @@ -544,21 +547,22 @@ void BrowserWindowGtk::DrawContentShadow(cairo_t* cr) { // Draw the bottom corners. The bottom corners also draw the bottom row of // pixels of the side shadows. - CairoCachedSurface* bottom_left = theme_provider->GetSurfaceNamed( + gfx::CairoCachedSurface* bottom_left = theme_provider->GetSurfaceNamed( IDR_CONTENT_BOTTOM_LEFT_CORNER, GTK_WIDGET(window_)); - bottom_left->SetSource(cr, left_x - kContentShadowThickness, bottom_y - 1); + bottom_left->SetSource(cr, GTK_WIDGET(window_), + left_x - kContentShadowThickness, bottom_y - 1); cairo_paint(cr); - CairoCachedSurface* bottom_right = theme_provider->GetSurfaceNamed( + gfx::CairoCachedSurface* bottom_right = theme_provider->GetSurfaceNamed( IDR_CONTENT_BOTTOM_RIGHT_CORNER, GTK_WIDGET(window_)); - bottom_right->SetSource(cr, right_x - 1, bottom_y - 1); + bottom_right->SetSource(cr, GTK_WIDGET(window_), right_x - 1, bottom_y - 1); cairo_paint(cr); // Finally, draw the bottom row. Since we don't overlap the contents, we clip // the top row of pixels. - CairoCachedSurface* bottom = theme_provider->GetSurfaceNamed( + gfx::CairoCachedSurface* bottom = theme_provider->GetSurfaceNamed( IDR_CONTENT_BOTTOM_CENTER, GTK_WIDGET(window_)); - bottom->SetSource(cr, left_x + 1, bottom_y - 1); + bottom->SetSource(cr, GTK_WIDGET(window_), left_x + 1, bottom_y - 1); cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); cairo_rectangle(cr, left_x + 1, @@ -579,9 +583,9 @@ void BrowserWindowGtk::DrawPopupFrame(cairo_t* cr, // theme that we can draw text on. (We tried using the tab background, but // that has inverse saturation from what the user usually expects). int image_name = GetThemeFrameResource(); - CairoCachedSurface* surface = theme_provider->GetUnthemedSurfaceNamed( + gfx::CairoCachedSurface* surface = theme_provider->GetUnthemedSurfaceNamed( image_name, widget); - surface->SetSource(cr, 0, GetVerticalOffset()); + surface->SetSource(cr, widget, 0, GetVerticalOffset()); cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REFLECT); cairo_rectangle(cr, event->area.x, event->area.y, event->area.width, event->area.height); @@ -596,10 +600,10 @@ void BrowserWindowGtk::DrawCustomFrame(cairo_t* cr, int image_name = GetThemeFrameResource(); - CairoCachedSurface* surface = theme_provider->GetSurfaceNamed( + gfx::CairoCachedSurface* surface = theme_provider->GetSurfaceNamed( image_name, widget); if (event->area.y < surface->Height()) { - surface->SetSource(cr, 0, GetVerticalOffset()); + surface->SetSource(cr, widget, 0, GetVerticalOffset()); // The frame background isn't tiled vertically. cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); @@ -610,10 +614,10 @@ void BrowserWindowGtk::DrawCustomFrame(cairo_t* cr, if (theme_provider->HasCustomImage(IDR_THEME_FRAME_OVERLAY) && !browser()->profile()->IsOffTheRecord()) { - CairoCachedSurface* theme_overlay = theme_provider->GetSurfaceNamed( + gfx::CairoCachedSurface* theme_overlay = theme_provider->GetSurfaceNamed( IsActive() ? IDR_THEME_FRAME_OVERLAY : IDR_THEME_FRAME_OVERLAY_INACTIVE, widget); - theme_overlay->SetSource(cr, 0, GetVerticalOffset()); + theme_overlay->SetSource(cr, widget, 0, GetVerticalOffset()); cairo_paint(cr); } } diff --git a/chrome/browser/ui/gtk/cairo_cached_surface.cc b/chrome/browser/ui/gtk/cairo_cached_surface.cc deleted file mode 100644 index 98dd6d1..0000000 --- a/chrome/browser/ui/gtk/cairo_cached_surface.cc +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/gtk/cairo_cached_surface.h" - -#include <gtk/gtk.h> - -#include "base/basictypes.h" -#include "base/logging.h" - -CairoCachedSurface::CairoCachedSurface() : pixbuf_(NULL), surface_(NULL) { -} - -CairoCachedSurface::~CairoCachedSurface() { - Reset(); -} - -void CairoCachedSurface::Reset() { - if (surface_) { - cairo_surface_destroy(surface_); - surface_ = NULL; - } - - if (pixbuf_) { - g_object_unref(pixbuf_); - pixbuf_ = NULL; - } -} - -int CairoCachedSurface::Width() const { - return pixbuf_ ? gdk_pixbuf_get_width(pixbuf_) : -1; -} - -int CairoCachedSurface::Height() const { - return pixbuf_ ? gdk_pixbuf_get_height(pixbuf_) : -1; -} - -void CairoCachedSurface::UsePixbuf(GdkPixbuf* pixbuf) { - if (surface_) { - cairo_surface_destroy(surface_); - surface_ = NULL; - } - - if (pixbuf) - g_object_ref(pixbuf); - - if (pixbuf_) - g_object_unref(pixbuf_); - - pixbuf_ = pixbuf; -} - -void CairoCachedSurface::SetSource(cairo_t* cr, int x, int y) { - DCHECK(pixbuf_); - DCHECK(cr); - - EnsureSurfaceValid(cr); - cairo_set_source_surface(cr, surface_, x, y); -} - -void CairoCachedSurface::MaskSource(cairo_t* cr, int x, int y) { - DCHECK(pixbuf_); - DCHECK(cr); - - EnsureSurfaceValid(cr); - cairo_mask_surface(cr, surface_, x, y); -} - -void CairoCachedSurface::EnsureSurfaceValid(cairo_t* cr) { - if (!surface_) { - // First time here since last UsePixbuf call. Generate the surface. - cairo_surface_t* target = cairo_get_target(cr); - surface_ = cairo_surface_create_similar( - target, - CAIRO_CONTENT_COLOR_ALPHA, - gdk_pixbuf_get_width(pixbuf_), - gdk_pixbuf_get_height(pixbuf_)); - - DCHECK(surface_); -#if !defined(NDEBUG) - int surface_type = cairo_surface_get_type(surface_); - DCHECK(surface_type == CAIRO_SURFACE_TYPE_XLIB || - surface_type == CAIRO_SURFACE_TYPE_XCB || - surface_type == CAIRO_SURFACE_TYPE_IMAGE); -#endif - - cairo_t* copy_cr = cairo_create(surface_); - gdk_cairo_set_source_pixbuf(copy_cr, pixbuf_, 0, 0); - cairo_paint(copy_cr); - cairo_destroy(copy_cr); - } -} diff --git a/chrome/browser/ui/gtk/custom_button.cc b/chrome/browser/ui/gtk/custom_button.cc index c0f8111..2b25796 100644 --- a/chrome/browser/ui/gtk/custom_button.cc +++ b/chrome/browser/ui/gtk/custom_button.cc @@ -6,7 +6,6 @@ #include "base/basictypes.h" #include "base/logging.h" -#include "chrome/browser/ui/gtk/cairo_cached_surface.h" #include "chrome/browser/ui/gtk/gtk_chrome_button.h" #include "chrome/browser/ui/gtk/gtk_theme_service.h" #include "chrome/browser/ui/gtk/gtk_util.h" @@ -16,6 +15,7 @@ #include "third_party/skia/include/core/SkBitmap.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/gtk_util.h" +#include "ui/gfx/image/cairo_cached_surface.h" #include "ui/gfx/skbitmap_operations.h" CustomDrawButtonBase::CustomDrawButtonBase(GtkThemeService* theme_provider, @@ -32,8 +32,8 @@ CustomDrawButtonBase::CustomDrawButtonBase(GtkThemeService* theme_provider, theme_service_(theme_provider), flipped_(false) { for (int i = 0; i < (GTK_STATE_INSENSITIVE + 1); ++i) - surfaces_[i].reset(new CairoCachedSurface); - background_image_.reset(new CairoCachedSurface); + surfaces_[i].reset(new gfx::CairoCachedSurface); + background_image_.reset(new gfx::CairoCachedSurface); if (theme_provider) { // Load images by pretending that we got a BROWSER_THEME_CHANGED @@ -81,8 +81,8 @@ gboolean CustomDrawButtonBase::OnExpose(GtkWidget* widget, paint_state = GTK_STATE_NORMAL; bool animating_hover = hover_state > 0.0 && paint_state == GTK_STATE_NORMAL; - CairoCachedSurface* pixbuf = PixbufForState(paint_state); - CairoCachedSurface* hover_pixbuf = PixbufForState(GTK_STATE_PRELIGHT); + gfx::CairoCachedSurface* pixbuf = PixbufForState(paint_state); + gfx::CairoCachedSurface* hover_pixbuf = PixbufForState(GTK_STATE_PRELIGHT); if (!pixbuf || !pixbuf->valid()) return FALSE; @@ -107,15 +107,15 @@ gboolean CustomDrawButtonBase::OnExpose(GtkWidget* widget, int y = allocation.height - pixbuf->Height(); if (background_image_->valid()) { - background_image_->SetSource(cairo_context, x, y); + background_image_->SetSource(cairo_context, widget, x, y); cairo_paint(cairo_context); } - pixbuf->SetSource(cairo_context, x, y); + pixbuf->SetSource(cairo_context, widget, x, y); cairo_paint(cairo_context); if (animating_hover) { - hover_pixbuf->SetSource(cairo_context, x, y); + hover_pixbuf->SetSource(cairo_context, widget, x, y); cairo_paint_with_alpha(cairo_context, hover_state); } @@ -161,8 +161,8 @@ void CustomDrawButtonBase::Observe(int type, theme_service_->GetRTLEnabledPixbufNamed(disabled_id_) : NULL); } -CairoCachedSurface* CustomDrawButtonBase::PixbufForState(int state) { - CairoCachedSurface* pixbuf = surfaces_[state].get(); +gfx::CairoCachedSurface* CustomDrawButtonBase::PixbufForState(int state) { + gfx::CairoCachedSurface* pixbuf = surfaces_[state].get(); // Fall back to the default image if we don't have one for this state. if (!pixbuf || !pixbuf->valid()) diff --git a/chrome/browser/ui/gtk/custom_button.h b/chrome/browser/ui/gtk/custom_button.h index 15d837e..6d3bff8 100644 --- a/chrome/browser/ui/gtk/custom_button.h +++ b/chrome/browser/ui/gtk/custom_button.h @@ -19,10 +19,13 @@ #include "ui/base/gtk/owned_widget_gtk.h" #include "ui/gfx/rect.h" -class CairoCachedSurface; class GtkThemeService; class SkBitmap; +namespace gfx { +class CairoCachedSurface; +} + // These classes implement two kinds of custom-drawn buttons. They're // used on the toolbar and the bookmarks bar. @@ -64,14 +67,14 @@ class CustomDrawButtonBase : public content::NotificationObserver { private: // Get the CairoCachedSurface from |surfaces_| for |state|. - CairoCachedSurface* PixbufForState(int state); + gfx::CairoCachedSurface* PixbufForState(int state); // We store one surface for each possible state of the button; // INSENSITIVE is the last available state; - scoped_ptr<CairoCachedSurface> surfaces_[GTK_STATE_INSENSITIVE + 1]; + scoped_ptr<gfx::CairoCachedSurface> surfaces_[GTK_STATE_INSENSITIVE + 1]; // The background image. - scoped_ptr<CairoCachedSurface> background_image_; + scoped_ptr<gfx::CairoCachedSurface> background_image_; // If non-negative, the state to paint the button. int paint_override_; diff --git a/chrome/browser/ui/gtk/find_bar_gtk.cc b/chrome/browser/ui/gtk/find_bar_gtk.cc index 28fa758..eeda89a 100644 --- a/chrome/browser/ui/gtk/find_bar_gtk.cc +++ b/chrome/browser/ui/gtk/find_bar_gtk.cc @@ -21,7 +21,6 @@ #include "chrome/browser/ui/find_bar/find_notification_details.h" #include "chrome/browser/ui/find_bar/find_tab_helper.h" #include "chrome/browser/ui/gtk/browser_window_gtk.h" -#include "chrome/browser/ui/gtk/cairo_cached_surface.h" #include "chrome/browser/ui/gtk/custom_button.h" #include "chrome/browser/ui/gtk/gtk_theme_service.h" #include "chrome/browser/ui/gtk/gtk_util.h" @@ -43,6 +42,7 @@ #include "ui/base/gtk/gtk_hig_constants.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/image/cairo_cached_surface.h" namespace { @@ -888,19 +888,20 @@ gboolean FindBarGtk::OnExpose(GtkWidget* widget, GdkEventExpose* e, GtkAllocation border_allocation = bar->border_bin_->allocation; // Blit the left part of the background image once on the left. - CairoCachedSurface* background_left = + gfx::CairoCachedSurface* background_left = bar->theme_service_->GetRTLEnabledSurfaceNamed( IDR_FIND_BOX_BACKGROUND_LEFT, widget); - background_left->SetSource(cr, border_allocation.x, border_allocation.y); + background_left->SetSource(cr, widget, + border_allocation.x, border_allocation.y); cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); cairo_rectangle(cr, border_allocation.x, border_allocation.y, background_left->Width(), background_left->Height()); cairo_fill(cr); // Blit the center part of the background image in all the space between. - CairoCachedSurface* background = bar->theme_service_->GetSurfaceNamed( + gfx::CairoCachedSurface* background = bar->theme_service_->GetSurfaceNamed( IDR_FIND_BOX_BACKGROUND, widget); - background->SetSource(cr, + background->SetSource(cr, widget, border_allocation.x + background_left->Width(), border_allocation.y); cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); diff --git a/chrome/browser/ui/gtk/gtk_theme_service.cc b/chrome/browser/ui/gtk/gtk_theme_service.cc index 567e48f..11a06c4 100644 --- a/chrome/browser/ui/gtk/gtk_theme_service.cc +++ b/chrome/browser/ui/gtk/gtk_theme_service.cc @@ -18,7 +18,6 @@ #include "chrome/browser/themes/theme_service_factory.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/gtk/cairo_cached_surface.h" #include "chrome/browser/ui/gtk/chrome_gtk_frame.h" #include "chrome/browser/ui/gtk/gtk_chrome_button.h" #include "chrome/browser/ui/gtk/gtk_chrome_link_button.h" @@ -43,6 +42,7 @@ #include "ui/gfx/canvas_skia.h" #include "ui/gfx/color_utils.h" #include "ui/gfx/gtk_util.h" +#include "ui/gfx/image/cairo_cached_surface.h" #include "ui/gfx/image/image.h" #include "ui/gfx/skbitmap_operations.h" #include "ui/gfx/skia_util.h" @@ -563,7 +563,7 @@ void GtkThemeService::GetScrollbarColors(GdkColor* thumb_active_color, *track_color = *theme_trough_color; } -CairoCachedSurface* GtkThemeService::GetSurfaceNamed( +gfx::CairoCachedSurface* GtkThemeService::GetSurfaceNamed( int id, GtkWidget* widget_on_display) { return GetSurfaceNamedImpl( @@ -573,7 +573,7 @@ CairoCachedSurface* GtkThemeService::GetSurfaceNamed( widget_on_display); } -CairoCachedSurface* GtkThemeService::GetRTLEnabledSurfaceNamed( +gfx::CairoCachedSurface* GtkThemeService::GetRTLEnabledSurfaceNamed( int id, GtkWidget* widget_on_display) { // We flip the sign of |id| when passing it to GetSurfaceNamedImpl() for the @@ -588,7 +588,7 @@ CairoCachedSurface* GtkThemeService::GetRTLEnabledSurfaceNamed( widget_on_display); } -CairoCachedSurface* GtkThemeService::GetUnthemedSurfaceNamed( +gfx::CairoCachedSurface* GtkThemeService::GetUnthemedSurfaceNamed( int id, GtkWidget* widget_on_display) { return GetSurfaceNamedImpl(id, @@ -597,7 +597,7 @@ CairoCachedSurface* GtkThemeService::GetUnthemedSurfaceNamed( widget_on_display); } -CairoCachedSurface* GtkThemeService::GetCairoIcon( +gfx::CairoCachedSurface* GtkThemeService::GetCairoIcon( int id, GtkWidget* widget_on_display) { return GetSurfaceNamedImpl(id, @@ -1131,7 +1131,7 @@ void GtkThemeService::GetSelectedEntryForegroundHSL( color_utils::SkColorToHSL(GdkToSkColor(&color), tint); } -CairoCachedSurface* GtkThemeService::GetSurfaceNamedImpl( +gfx::CairoCachedSurface* GtkThemeService::GetSurfaceNamedImpl( int id, PerDisplaySurfaceMap* display_surface_map, PixbufProvidingMethod provider, @@ -1144,7 +1144,7 @@ CairoCachedSurface* GtkThemeService::GetSurfaceNamedImpl( if (found != surface_map.end()) return found->second; - CairoCachedSurface* surface = new CairoCachedSurface; + gfx::CairoCachedSurface* surface = new gfx::CairoCachedSurface; surface->UsePixbuf((this->*provider)(id)); surface_map[id] = surface; diff --git a/chrome/browser/ui/gtk/gtk_theme_service.h b/chrome/browser/ui/gtk/gtk_theme_service.h index 421670e..96538e8 100644 --- a/chrome/browser/ui/gtk/gtk_theme_service.h +++ b/chrome/browser/ui/gtk/gtk_theme_service.h @@ -19,9 +19,12 @@ #include "ui/base/gtk/owned_widget_gtk.h" #include "ui/gfx/color_utils.h" -class CairoCachedSurface; class Profile; +namespace gfx { +class CairoCachedSurface; +} + namespace ui { class GtkSignalRegistrar; } @@ -116,23 +119,24 @@ class GtkThemeService : public ThemeService { // Returns a CairoCachedSurface for a particular Display. CairoCachedSurfaces // (hopefully) live on the X server, instead of the client so we don't have // to send the image to the server on each expose. - CairoCachedSurface* GetSurfaceNamed(int id, GtkWidget* widget_on_display); + gfx::CairoCachedSurface* GetSurfaceNamed( + int id, GtkWidget* widget_on_display); // Same as above, but auto-mirrors the underlying pixbuf in RTL mode. - CairoCachedSurface* GetRTLEnabledSurfaceNamed(int id, - GtkWidget* widget_on_display); + gfx::CairoCachedSurface* GetRTLEnabledSurfaceNamed( + int id, GtkWidget* widget_on_display); // Same as above, but gets the resource from the ResourceBundle instead of the // ThemeService. // NOTE: Never call this with resource IDs that are ever passed to the above // two functions! Depending on which call comes first, all callers will // either get the themed or the unthemed version. - CairoCachedSurface* GetUnthemedSurfaceNamed(int id, - GtkWidget* widget_on_display); + gfx::CairoCachedSurface* GetUnthemedSurfaceNamed( + int id, GtkWidget* widget_on_display); // A way to get a cached cairo surface for the equivalent of GetFolderIcon() // or GetDefaultFavicon(). Uses the ids defined in CairoDefaultIcon. - CairoCachedSurface* GetCairoIcon(int id, GtkWidget* widget_on_display); + gfx::CairoCachedSurface* GetCairoIcon(int id, GtkWidget* widget_on_display); // Returns colors that we pass to webkit to match the system theme. const SkColor& get_focus_ring_color() const { return focus_ring_color_; } @@ -167,7 +171,7 @@ class GtkThemeService : public ThemeService { typedef std::map<int, SkColor> ColorMap; typedef std::map<int, color_utils::HSL> TintMap; typedef std::map<int, SkBitmap*> ImageCache; - typedef std::map<int, CairoCachedSurface*> CairoCachedSurfaceMap; + typedef std::map<int, gfx::CairoCachedSurface*> CairoCachedSurfaceMap; typedef std::map<GdkDisplay*, CairoCachedSurfaceMap> PerDisplaySurfaceMap; typedef GdkPixbuf*(GtkThemeService::*PixbufProvidingMethod)(int id) const; @@ -251,7 +255,7 @@ class GtkThemeService : public ThemeService { void GetSelectedEntryForegroundHSL(color_utils::HSL* tint) const; // Implements GetXXXSurfaceNamed(), given the appropriate pixbuf to use. - CairoCachedSurface* GetSurfaceNamedImpl( + gfx::CairoCachedSurface* GetSurfaceNamedImpl( int id, PerDisplaySurfaceMap* surface_map, PixbufProvidingMethod provider, diff --git a/chrome/browser/ui/gtk/gtk_util.cc b/chrome/browser/ui/gtk/gtk_util.cc index 7c1c9e36..33855f9 100644 --- a/chrome/browser/ui/gtk/gtk_util.cc +++ b/chrome/browser/ui/gtk/gtk_util.cc @@ -24,7 +24,6 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/gtk/cairo_cached_surface.h" #include "chrome/browser/ui/gtk/gtk_theme_service.h" #include "content/browser/disposition_utils.h" #include "content/browser/renderer_host/render_view_host.h" @@ -43,6 +42,7 @@ #include "ui/base/text/text_elider.h" #include "ui/base/x/x11_util.h" #include "ui/gfx/gtk_util.h" +#include "ui/gfx/image/cairo_cached_surface.h" #include "ui/gfx/image/image.h" #if defined(OS_CHROMEOS) @@ -801,9 +801,9 @@ void DrawThemedToolbarBackground(GtkWidget* widget, // The toolbar is supposed to blend in with the active tab, so we have to pass // coordinates for the IDR_THEME_TOOLBAR bitmap relative to the top of the // tab strip. - CairoCachedSurface* background = theme_service->GetSurfaceNamed( + gfx::CairoCachedSurface* background = theme_service->GetSurfaceNamed( IDR_THEME_TOOLBAR, widget); - background->SetSource(cr, tabstrip_origin.x(), tabstrip_origin.y()); + background->SetSource(cr, widget, tabstrip_origin.x(), tabstrip_origin.y()); // We tile the toolbar background in both directions. cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); cairo_rectangle(cr, diff --git a/chrome/browser/ui/gtk/location_bar_view_gtk.cc b/chrome/browser/ui/gtk/location_bar_view_gtk.cc index 79b5396..7bdb062 100644 --- a/chrome/browser/ui/gtk/location_bar_view_gtk.cc +++ b/chrome/browser/ui/gtk/location_bar_view_gtk.cc @@ -36,7 +36,6 @@ #include "chrome/browser/ui/content_settings/content_setting_image_model.h" #include "chrome/browser/ui/gtk/bookmarks/bookmark_bubble_gtk.h" #include "chrome/browser/ui/gtk/bookmarks/bookmark_utils_gtk.h" -#include "chrome/browser/ui/gtk/cairo_cached_surface.h" #include "chrome/browser/ui/gtk/content_setting_bubble_gtk.h" #include "chrome/browser/ui/gtk/extensions/extension_popup_gtk.h" #include "chrome/browser/ui/gtk/first_run_bubble.h" diff --git a/chrome/browser/ui/gtk/tabs/tab_renderer_gtk.cc b/chrome/browser/ui/gtk/tabs/tab_renderer_gtk.cc index a1a446f..d3438da 100644 --- a/chrome/browser/ui/gtk/tabs/tab_renderer_gtk.cc +++ b/chrome/browser/ui/gtk/tabs/tab_renderer_gtk.cc @@ -14,7 +14,6 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/gtk/bookmarks/bookmark_utils_gtk.h" -#include "chrome/browser/ui/gtk/cairo_cached_surface.h" #include "chrome/browser/ui/gtk/custom_button.h" #include "chrome/browser/ui/gtk/gtk_theme_service.h" #include "chrome/browser/ui/gtk/gtk_util.h" @@ -33,6 +32,7 @@ #include "ui/gfx/canvas_skia_paint.h" #include "ui/gfx/favicon_size.h" #include "ui/gfx/gtk_util.h" +#include "ui/gfx/image/cairo_cached_surface.h" #include "ui/gfx/pango_util.h" #include "ui/gfx/platform_font_pango.h" #include "ui/gfx/skbitmap_operations.h" @@ -483,9 +483,9 @@ void TabRendererGtk::PaintFaviconArea(GtkWidget* widget, cairo_t* cr) { } // Paint the background behind the favicon. - CairoCachedSurface* tab_bg = + gfx::CairoCachedSurface* tab_bg = theme_service_->GetSurfaceNamed(theme_id, widget); - tab_bg->SetSource(cr, -x(), -offset_y); + tab_bg->SetSource(cr, widget, -x(), -offset_y); cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); cairo_rectangle(cr, favicon_bounds_.x(), favicon_bounds_.y(), @@ -496,9 +496,9 @@ void TabRendererGtk::PaintFaviconArea(GtkWidget* widget, cairo_t* cr) { double throb_value = GetThrobValue(); if (throb_value > 0) { cairo_push_group(cr); - CairoCachedSurface* active_bg = theme_service_->GetSurfaceNamed( + gfx::CairoCachedSurface* active_bg = theme_service_->GetSurfaceNamed( IDR_THEME_TOOLBAR, widget); - active_bg->SetSource(cr, -x(), 0); + active_bg->SetSource(cr, widget, -x(), 0); cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); cairo_rectangle(cr, @@ -859,7 +859,7 @@ void TabRendererGtk::PaintIcon(GtkWidget* widget, cairo_t* cr) { return; } - CairoCachedSurface* to_display = NULL; + gfx::CairoCachedSurface* to_display = NULL; if (should_display_crashed_favicon_) { to_display = theme_service_->GetSurfaceNamed(IDR_SAD_FAVICON, widget); } else if (!data_.favicon.isNull()) { @@ -873,6 +873,7 @@ void TabRendererGtk::PaintIcon(GtkWidget* widget, cairo_t* cr) { if (to_display) { to_display->SetSource(cr, + widget, favicon_bounds_.x(), favicon_bounds_.y() + favicon_hiding_offset_); cairo_paint(cr); @@ -898,16 +899,16 @@ void TabRendererGtk::PaintTabBackground(GtkWidget* widget, cairo_t* cr) { void TabRendererGtk::DrawTabBackground( cairo_t* cr, GtkWidget* widget, - CairoCachedSurface* tab_bg, + gfx::CairoCachedSurface* tab_bg, int offset_x, int offset_y) { - tab_bg->SetSource(cr, -offset_x, -offset_y); + tab_bg->SetSource(cr, widget, -offset_x, -offset_y); cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); // Draw left edge - CairoCachedSurface* tab_l_mask = + gfx::CairoCachedSurface* tab_l_mask = theme_service_->GetSurfaceNamed(IDR_TAB_ALPHA_LEFT, widget); - tab_l_mask->MaskSource(cr, 0, 0); + tab_l_mask->MaskSource(cr, widget, 0, 0); // Draw center cairo_rectangle(cr, @@ -917,9 +918,9 @@ void TabRendererGtk::DrawTabBackground( cairo_fill(cr); // Draw right edge - CairoCachedSurface* tab_r_mask = + gfx::CairoCachedSurface* tab_r_mask = theme_service_->GetSurfaceNamed(IDR_TAB_ALPHA_RIGHT, widget); - tab_r_mask->MaskSource(cr, width() - tab_active_l_width_, 0); + tab_r_mask->MaskSource(cr, widget, width() - tab_active_l_width_, 0); } void TabRendererGtk::DrawTabShadow( @@ -929,15 +930,15 @@ void TabRendererGtk::DrawTabShadow( int center_idr, int right_idr) { // Draw left drop shadow - CairoCachedSurface* active_image_l = + gfx::CairoCachedSurface* active_image_l = theme_service_->GetSurfaceNamed(left_idr, widget); - active_image_l->SetSource(cr, 0, 0); + active_image_l->SetSource(cr, widget, 0, 0); cairo_paint(cr); // Draw the center shadow - CairoCachedSurface* active_image_c = + gfx::CairoCachedSurface* active_image_c = theme_service_->GetSurfaceNamed(center_idr, widget); - active_image_c->SetSource(cr, 0, 0); + active_image_c->SetSource(cr, widget, 0, 0); cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); cairo_rectangle(cr, tab_active_l_width_, 0, width() - (2 * tab_active_l_width_), @@ -945,9 +946,9 @@ void TabRendererGtk::DrawTabShadow( cairo_fill(cr); // Draw right drop shadow - CairoCachedSurface* active_image_r = + gfx::CairoCachedSurface* active_image_r = theme_service_->GetSurfaceNamed(right_idr, widget); - active_image_r->SetSource(cr, width() - active_image_r->Width(), 0); + active_image_r->SetSource(cr, widget, width() - active_image_r->Width(), 0); cairo_paint(cr); } @@ -956,7 +957,7 @@ void TabRendererGtk::PaintInactiveTabBackground(GtkWidget* widget, int theme_id = data_.incognito ? IDR_THEME_TAB_BACKGROUND_INCOGNITO : IDR_THEME_TAB_BACKGROUND; - CairoCachedSurface* tab_bg = + gfx::CairoCachedSurface* tab_bg = theme_service_->GetSurfaceNamed(theme_id, widget); // If the theme is providing a custom background image, then its top edge @@ -972,8 +973,8 @@ void TabRendererGtk::PaintInactiveTabBackground(GtkWidget* widget, } void TabRendererGtk::PaintActiveTabBackground(GtkWidget* widget, - cairo_t* cr) { - CairoCachedSurface* tab_bg = + cairo_t* cr) { + gfx::CairoCachedSurface* tab_bg = theme_service_->GetSurfaceNamed(IDR_THEME_TOOLBAR, widget); DrawTabBackground(cr, widget, tab_bg, background_offset_x_, 0); @@ -982,17 +983,18 @@ void TabRendererGtk::PaintActiveTabBackground(GtkWidget* widget, } void TabRendererGtk::PaintLoadingAnimation(GtkWidget* widget, - cairo_t* cr) { + cairo_t* cr) { int id = loading_animation_.animation_state() == ANIMATION_WAITING ? IDR_THROBBER_WAITING : IDR_THROBBER; - CairoCachedSurface* throbber = theme_service_->GetSurfaceNamed(id, widget); + gfx::CairoCachedSurface* throbber = + theme_service_->GetSurfaceNamed(id, widget); const int image_size = throbber->Height(); const int image_offset = loading_animation_.animation_frame() * image_size; DCHECK(image_size == favicon_bounds_.height()); DCHECK(image_size == favicon_bounds_.width()); - throbber->SetSource(cr, favicon_bounds_.x() - image_offset, + throbber->SetSource(cr, widget, favicon_bounds_.x() - image_offset, favicon_bounds_.y()); cairo_rectangle(cr, favicon_bounds_.x(), favicon_bounds_.y(), image_size, image_size); diff --git a/chrome/browser/ui/gtk/tabs/tab_renderer_gtk.h b/chrome/browser/ui/gtk/tabs/tab_renderer_gtk.h index a40f4c1..40769fb 100644 --- a/chrome/browser/ui/gtk/tabs/tab_renderer_gtk.h +++ b/chrome/browser/ui/gtk/tabs/tab_renderer_gtk.h @@ -13,7 +13,6 @@ #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" #include "base/string16.h" -#include "chrome/browser/ui/gtk/cairo_cached_surface.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -22,13 +21,14 @@ #include "ui/base/gtk/owned_widget_gtk.h" #include "ui/gfx/canvas.h" #include "ui/gfx/font.h" +#include "ui/gfx/image/cairo_cached_surface.h" #include "ui/gfx/rect.h" namespace gfx { +class CairoCachedSurface; class Size; } // namespace gfx -class CairoCachedSurface; class CustomDrawButton; class TabContents; class GtkThemeService; @@ -242,7 +242,7 @@ class TabRendererGtk : public ui::AnimationDelegate, ~TabData(); SkBitmap favicon; - CairoCachedSurface cairo_favicon; + gfx::CairoCachedSurface cairo_favicon; bool is_default_favicon; string16 title; bool loading; @@ -300,7 +300,7 @@ class TabRendererGtk : public ui::AnimationDelegate, // sides for the rounded tab shape. void DrawTabBackground(cairo_t* cr, GtkWidget* widget, - CairoCachedSurface* tab_bg, + gfx::CairoCachedSurface* tab_bg, int offset_x, int offset_y); diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 8871930..4d1d451 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -2976,8 +2976,6 @@ 'browser/ui/gtk/bubble/bubble_accelerators_gtk.h', 'browser/ui/gtk/bubble/bubble_gtk.cc', 'browser/ui/gtk/bubble/bubble_gtk.h', - 'browser/ui/gtk/cairo_cached_surface.cc', - 'browser/ui/gtk/cairo_cached_surface.h', 'browser/ui/gtk/certificate_viewer.cc', 'browser/ui/gtk/chrome_gtk_frame.cc', 'browser/ui/gtk/chrome_gtk_frame.h', diff --git a/ui/gfx/image/cairo_cached_surface.cc b/ui/gfx/image/cairo_cached_surface.cc new file mode 100644 index 0000000..2de4a32 --- /dev/null +++ b/ui/gfx/image/cairo_cached_surface.cc @@ -0,0 +1,109 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/gfx/image/cairo_cached_surface.h" + +#include <gtk/gtk.h> + +#include "base/basictypes.h" +#include "base/logging.h" + +namespace gfx { + +CairoCachedSurface::CairoCachedSurface() : pixbuf_(NULL) { +} + +CairoCachedSurface::~CairoCachedSurface() { + Reset(); +} + +void CairoCachedSurface::Reset() { + for (SurfaceVector::iterator it = surface_map_.begin(); + it != surface_map_.end(); ++it) { + cairo_surface_destroy(it->second); + } + surface_map_.clear(); + + if (pixbuf_) { + g_object_unref(pixbuf_); + pixbuf_ = NULL; + } +} + +int CairoCachedSurface::Width() const { + return pixbuf_ ? gdk_pixbuf_get_width(pixbuf_) : -1; +} + +int CairoCachedSurface::Height() const { + return pixbuf_ ? gdk_pixbuf_get_height(pixbuf_) : -1; +} + +void CairoCachedSurface::UsePixbuf(GdkPixbuf* pixbuf) { + if (pixbuf) + g_object_ref(pixbuf); + + Reset(); + + pixbuf_ = pixbuf; +} + +void CairoCachedSurface::SetSource(cairo_t* cr, GtkWidget* widget, + int x, int y) const { + SetSource(cr, gtk_widget_get_display(widget), x, y); +} + +void CairoCachedSurface::SetSource(cairo_t* cr, GdkDisplay* display, + int x, int y) const { + DCHECK(pixbuf_); + DCHECK(cr); + DCHECK(display); + + cairo_surface_t* surface = GetSurfaceFor(cr, display); + cairo_set_source_surface(cr, surface, x, y); +} + +void CairoCachedSurface::MaskSource(cairo_t* cr, GtkWidget* widget, + int x, int y) const { + MaskSource(cr, gtk_widget_get_display(widget), x, y); +} + +void CairoCachedSurface::MaskSource(cairo_t* cr, GdkDisplay* display, + int x, int y) const { + DCHECK(pixbuf_); + DCHECK(cr); + DCHECK(display); + + cairo_surface_t* surface = GetSurfaceFor(cr, display); + cairo_mask_surface(cr, surface, x, y); +} + +cairo_surface_t* CairoCachedSurface::GetSurfaceFor(cairo_t* cr, + GdkDisplay* display) const { + for (SurfaceVector::const_iterator it = surface_map_.begin(); + it != surface_map_.end(); ++it) { + if (display == it->first) { + return it->second; + } + } + + // First time here since last UsePixbuf call. Generate the surface. + cairo_surface_t* target = cairo_get_target(cr); + cairo_surface_t* out = cairo_surface_create_similar( + target, + CAIRO_CONTENT_COLOR_ALPHA, + gdk_pixbuf_get_width(pixbuf_), + gdk_pixbuf_get_height(pixbuf_)); + + DCHECK(out); + + cairo_t* copy_cr = cairo_create(out); + gdk_cairo_set_source_pixbuf(copy_cr, pixbuf_, 0, 0); + cairo_paint(copy_cr); + cairo_destroy(copy_cr); + + surface_map_.push_back(std::make_pair(display, out)); + return out; +} + +} // namespace gfx diff --git a/chrome/browser/ui/gtk/cairo_cached_surface.h b/ui/gfx/image/cairo_cached_surface.h index eb481e8..2be63f3 100644 --- a/chrome/browser/ui/gtk/cairo_cached_surface.h +++ b/ui/gfx/image/cairo_cached_surface.h @@ -2,17 +2,25 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_GTK_CAIRO_CACHED_SURFACE_H_ -#define CHROME_BROWSER_UI_GTK_CAIRO_CACHED_SURFACE_H_ +#ifndef UI_GFX_IMAGE_CAIRO_CACHED_SURFACE_H_ +#define UI_GFX_IMAGE_CAIRO_CACHED_SURFACE_H_ #pragma once +#include <vector> + +#include "ui/base/ui_export.h" + +typedef struct _GdkDisplay GdkDisplay; typedef struct _GdkPixbuf GdkPixbuf; +typedef struct _GtkWidget GtkWidget; typedef struct _cairo cairo_t; typedef struct _cairo_surface cairo_surface_t; +namespace gfx { + // A helper class that takes a GdkPixbuf* and renders it to the screen. Unlike // gdk_cairo_set_source_pixbuf(), CairoCachedSurface assumes that the pixbuf is -// immutable after UsePixbuf() is called and can be sent to the X server +// immutable after UsePixbuf() is called and can be sent to the display server // once. From then on, that cached version is used so we don't upload the same // image each and every time we expose. // @@ -20,7 +28,7 @@ typedef struct _cairo_surface cairo_surface_t; // them with a certain XDisplay. Some users of surfaces (CustomDrawButtonBase, // for example) own their surfaces instead since they interact with the // ResourceBundle instead of the GtkThemeService. -class CairoCachedSurface { +class UI_EXPORT CairoCachedSurface { public: CairoCachedSurface(); ~CairoCachedSurface(); @@ -45,26 +53,33 @@ class CairoCachedSurface { // Sets our pixbuf as the active surface starting at (x, y), uploading it in // case we don't have an X backed surface cached. - void SetSource(cairo_t* cr, int x, int y); + void SetSource(cairo_t* cr, GtkWidget* widget, int x, int y) const; + void SetSource(cairo_t* cr, GdkDisplay* display, int x, int y) const; // Performs a mask operation, using this surface as the alpha channel. - void MaskSource(cairo_t* cr, int x, int y); + void MaskSource(cairo_t* cr, GtkWidget* widget, int x, int y) const; + void MaskSource(cairo_t* cr, GdkDisplay* display, int x, int y) const; // Raw access to the pixbuf. May be NULL. Used for a few gdk operations // regarding window shaping. GdkPixbuf* pixbuf() { return pixbuf_; } private: - // Makes sure |surface_| is a valid thing that lives on the X server, - // uploading it if necessary. - void EnsureSurfaceValid(cairo_t* cr); + typedef std::vector<std::pair<GdkDisplay*, cairo_surface_t*> > SurfaceVector; + + // Returns a surface . Caches results so only one copy of the image data + // lives on the display server. + cairo_surface_t* GetSurfaceFor(cairo_t* cr, GdkDisplay* display) const; // The source pixbuf. GdkPixbuf* pixbuf_; - // Our cached surface. This should be a xlib surface so the data lives on the - // server instead of on the client. - cairo_surface_t* surface_; + // Our list of cached surfaces. 99% of the time, this will only contain a + // single entry. At most two. We need to get this right for multiple displays + // to work correct, since each GdkDisplay is a different display server. + mutable SurfaceVector surface_map_; }; -#endif // CHROME_BROWSER_UI_GTK_CAIRO_CACHED_SURFACE_H_ +} // namespace gfx + +#endif // UI_GFX_IMAGE_CAIRO_CACHED_SURFACE_H_ diff --git a/ui/gfx/image/image.cc b/ui/gfx/image/image.cc index 2ba2eba..f14b9ec 100644 --- a/ui/gfx/image/image.cc +++ b/ui/gfx/image/image.cc @@ -15,6 +15,7 @@ #include <glib-object.h> #include "ui/gfx/canvas_skia.h" #include "ui/gfx/gtk_util.h" +#include "ui/gfx/image/cairo_cached_surface.h" #elif defined(OS_MACOSX) #include "base/mac/mac_util.h" #include "skia/ext/skia_utils_mac.h" @@ -42,6 +43,7 @@ const SkBitmap* GdkPixbufToSkBitmap(GdkPixbuf* pixbuf) { class ImageRepSkia; class ImageRepGdk; +class ImageRepCairoCached; class ImageRepCocoa; // An ImageRep is the object that holds the backing memory for an Image. Each @@ -67,6 +69,11 @@ class ImageRep { CHECK_EQ(type_, Image::kImageRepGdk); return reinterpret_cast<ImageRepGdk*>(this); } + + ImageRepCairoCached* AsImageRepCairo() { + CHECK_EQ(type_, Image::kImageRepCairoCache); + return reinterpret_cast<ImageRepCairoCached*>(this); + } #endif #if defined(OS_MACOSX) @@ -133,7 +140,29 @@ class ImageRepGdk : public ImageRep { DISALLOW_COPY_AND_ASSIGN(ImageRepGdk); }; -#endif + +// Represents data that lives on the display server instead of in the client. +class ImageRepCairoCached : public ImageRep { + public: + explicit ImageRepCairoCached(GdkPixbuf* pixbuf) + : ImageRep(Image::kImageRepCairoCache), + cairo_cache_(new CairoCachedSurface) { + CHECK(pixbuf); + cairo_cache_->UsePixbuf(pixbuf); + } + + virtual ~ImageRepCairoCached() { + delete cairo_cache_; + } + + CairoCachedSurface* surface() const { return cairo_cache_; } + + private: + CairoCachedSurface* cairo_cache_; + + DISALLOW_COPY_AND_ASSIGN(ImageRepCairoCached); +}; +#endif // defined(TOOLKIT_USES_GTK) #if defined(OS_MACOSX) class ImageRepCocoa : public ImageRep { @@ -156,7 +185,7 @@ class ImageRepCocoa : public ImageRep { DISALLOW_COPY_AND_ASSIGN(ImageRepCocoa); }; -#endif +#endif // defined(OS_MACOSX) // The Storage class acts similarly to the pixels in a SkBitmap: the Image // class holds a refptr instance of Storage, which in turn holds all the @@ -244,6 +273,11 @@ GdkPixbuf* Image::ToGdkPixbuf() const { internal::ImageRep* rep = GetRepresentation(Image::kImageRepGdk); return rep->AsImageRepGdk()->pixbuf(); } + +CairoCachedSurface* const Image::ToCairo() const { + internal::ImageRep* rep = GetRepresentation(Image::kImageRepCairoCache); + return rep->AsImageRepCairo()->surface(); +} #endif #if defined(OS_MACOSX) @@ -337,6 +371,9 @@ internal::ImageRep* Image::GetRepresentation( rep = new internal::ImageRepSkia( internal::GdkPixbufToSkBitmap(pixbuf_rep->pixbuf())); } + // We don't do conversions from CairoCachedSurfaces to Skia because the + // data lives on the display server and we'll always have a GdkPixbuf if we + // have a CairoCachedSurface. #elif defined(OS_MACOSX) if (storage_->default_representation_type() == Image::kImageRepCocoa) { internal::ImageRepCocoa* nsimage_rep = default_rep->AsImageRepCocoa(); @@ -349,6 +386,19 @@ internal::ImageRep* Image::GetRepresentation( AddRepresentation(rep); return rep; } +#if defined(TOOLKIT_USES_GTK) + else if (rep_type == Image::kImageRepCairoCache) { + // Handle any-to-Cairo conversion. This may recursively create an + // intermediate pixbuf before we send the data to the display server. + internal::ImageRep* rep = GetRepresentation(Image::kImageRepGdk); + internal::ImageRepCairoCached* native_rep = + new internal::ImageRepCairoCached(rep->AsImageRepGdk()->pixbuf()); + + CHECK(native_rep); + AddRepresentation(native_rep); + return native_rep; + } +#endif // Handle Skia-to-native conversions. if (default_rep->type() == Image::kImageRepSkia) { diff --git a/ui/gfx/image/image.h b/ui/gfx/image/image.h index c9aff41..dd4b8ec 100644 --- a/ui/gfx/image/image.h +++ b/ui/gfx/image/image.h @@ -35,6 +35,10 @@ class ImageMacTest; namespace gfx { +#if defined(TOOLKIT_USES_GTK) +class CairoCachedSurface; +#endif + namespace internal { class ImageRep; class ImageStorage; @@ -45,6 +49,7 @@ class UI_EXPORT Image { enum RepresentationType { kImageRepGdk, kImageRepCocoa, + kImageRepCairoCache, kImageRepSkia, }; @@ -84,6 +89,7 @@ class UI_EXPORT Image { const SkBitmap* ToSkBitmap() const; #if defined(TOOLKIT_USES_GTK) GdkPixbuf* ToGdkPixbuf() const; + CairoCachedSurface* const ToCairo() const; #elif defined(OS_MACOSX) NSImage* ToNSImage() const; #endif diff --git a/ui/gfx/image/image_unittest.cc b/ui/gfx/image/image_unittest.cc index 2df0715..2c82700 100644 --- a/ui/gfx/image/image_unittest.cc +++ b/ui/gfx/image/image_unittest.cc @@ -141,6 +141,13 @@ TEST_F(ImageTest, SkiaToGdkCopy) { EXPECT_TRUE(pixbuf); g_object_unref(pixbuf); } + +TEST_F(ImageTest, SkiaToCairoCreatesGdk) { + gfx::Image image(gt::CreateBitmap(25, 25)); + EXPECT_FALSE(image.HasRepresentation(gfx::Image::kImageRepGdk)); + EXPECT_TRUE(image.ToCairo()); + EXPECT_TRUE(image.HasRepresentation(gfx::Image::kImageRepGdk)); +} #endif #if defined(OS_MACOSX) @@ -419,6 +419,8 @@ 'gfx/gtk_preserve_window.h', 'gfx/gtk_util.cc', 'gfx/gtk_util.h', + 'gfx/image/cairo_cached_surface.cc', + 'gfx/image/cairo_cached_surface.h', ], }, { # toolkit_uses_gtk != 1 'sources!': [ |