summaryrefslogtreecommitdiffstats
path: root/chrome/browser/gtk/nine_box.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/gtk/nine_box.cc')
-rw-r--r--chrome/browser/gtk/nine_box.cc62
1 files changed, 42 insertions, 20 deletions
diff --git a/chrome/browser/gtk/nine_box.cc b/chrome/browser/gtk/nine_box.cc
index ddad809..572c1b5 100644
--- a/chrome/browser/gtk/nine_box.cc
+++ b/chrome/browser/gtk/nine_box.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 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.
@@ -15,18 +15,36 @@
namespace {
// Draw pixbuf |src| into |dst| at position (x, y).
-void DrawPixbuf(cairo_t* cr, GdkPixbuf* src, int x, int y) {
+void DrawPixbuf(cairo_t* cr, GdkPixbuf* src, int x, int y, double alpha) {
gdk_cairo_set_source_pixbuf(cr, src, x, y);
- cairo_paint(cr);
+ cairo_paint_with_alpha(cr, alpha);
}
// Tile pixbuf |src| across |cr| at |x|, |y| for |width| and |height|.
void TileImage(cairo_t* cr, GdkPixbuf* src,
- int x, int y, int width, int height) {
- gdk_cairo_set_source_pixbuf(cr, src, x, y);
- cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT);
- cairo_rectangle(cr, x, y, width, height);
- cairo_fill(cr);
+ int x, int y, int width, int height, double alpha) {
+ if (alpha == 1.0) {
+ gdk_cairo_set_source_pixbuf(cr, src, x, y);
+ cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT);
+ cairo_rectangle(cr, x, y, width, height);
+ cairo_fill(cr);
+ } else {
+ // Since there is no easy way to apply a mask to a fill operation, we create
+ // a secondary surface and tile into that, then paint it with |alpha|.
+ cairo_surface_t* surface = cairo_image_surface_create(
+ CAIRO_FORMAT_ARGB32, width, height);
+ cairo_t* tiled = cairo_create(surface);
+ gdk_cairo_set_source_pixbuf(tiled, src, 0, 0);
+ cairo_pattern_set_extend(cairo_get_source(tiled), CAIRO_EXTEND_REPEAT);
+ cairo_rectangle(tiled, 0, 0, width, height);
+ cairo_fill(tiled);
+
+ cairo_set_source_surface(cr, surface, x, y);
+ cairo_paint_with_alpha(cr, alpha);
+
+ cairo_destroy(tiled);
+ cairo_surface_destroy(surface);
+ }
}
} // namespace
@@ -88,6 +106,10 @@ NineBox::~NineBox() {
}
void NineBox::RenderToWidget(GtkWidget* dst) const {
+ RenderToWidgetWithOpacity(dst, 1.0);
+}
+
+void NineBox::RenderToWidgetWithOpacity(GtkWidget* dst, double opacity) const {
int dst_width = dst->allocation.width;
int dst_height = dst->allocation.height;
@@ -117,35 +139,35 @@ void NineBox::RenderToWidget(GtkWidget* dst) const {
// Top row, center image is horizontally tiled.
if (images_[0])
- DrawPixbuf(cr, images_[0], 0, 0);
+ DrawPixbuf(cr, images_[0], 0, 0, opacity);
if (images_[1])
- RenderTopCenterStrip(cr, x1, 0, x2 - x1);
+ TileImage(cr, images_[1], x1, 0, x2 - x1, y1, opacity);
if (images_[2])
- DrawPixbuf(cr, images_[2], x2, 0);
+ DrawPixbuf(cr, images_[2], x2, 0, opacity);
// Center row, all images are vertically tiled, center is horizontally tiled.
if (images_[3])
- TileImage(cr, images_[3], 0, y1, x1, y2 - y1);
+ TileImage(cr, images_[3], 0, y1, x1, y2 - y1, opacity);
if (images_[4])
- TileImage(cr, images_[4], x1, y1, x2 - x1, y2 - y1);
+ TileImage(cr, images_[4], x1, y1, x2 - x1, y2 - y1, opacity);
if (images_[5])
- TileImage(cr, images_[5], x2, y1, dst_width - x2, y2 - y1);
+ TileImage(cr, images_[5], x2, y1, dst_width - x2, y2 - y1, opacity);
// Bottom row, center image is horizontally tiled.
if (images_[6])
- DrawPixbuf(cr, images_[6], 0, y2);
+ DrawPixbuf(cr, images_[6], 0, y2, opacity);
if (images_[7])
- TileImage(cr, images_[7], x1, y2, x2 - x1, dst_height - y2);
+ TileImage(cr, images_[7], x1, y2, x2 - x1, dst_height - y2, opacity);
if (images_[8])
- DrawPixbuf(cr, images_[8], x2, y2);
+ DrawPixbuf(cr, images_[8], x2, y2, opacity);
cairo_destroy(cr);
}
-void NineBox::RenderTopCenterStrip(cairo_t* cr,
- int x, int y, int width) const {
+void NineBox::RenderTopCenterStrip(cairo_t* cr, int x, int y,
+ int width) const {
const int height = gdk_pixbuf_get_height(images_[1]);
- TileImage(cr, images_[1], x, y, width, height);
+ TileImage(cr, images_[1], x, y, width, height, 1.0);
}
void NineBox::ChangeWhiteToTransparent() {