172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/nine_box.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/basictypes.h"
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/i18n/rtl.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h"
1072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/resource/resource_bundle.h"
1172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/gtk_util.h"
1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/point.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Draw pixbuf |src| into |dst| at position (x, y).
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid DrawPixbuf(cairo_t* cr, GdkPixbuf* src, int x, int y, double alpha) {
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gdk_cairo_set_source_pixbuf(cr, src, x, y);
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cairo_paint_with_alpha(cr, alpha);
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tile pixbuf |src| across |cr| at |x|, |y| for |width| and |height|.
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TileImage(cairo_t* cr, GdkPixbuf* src,
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch               int x, int y, int width, int height, double alpha) {
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (alpha == 1.0) {
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gdk_cairo_set_source_pixbuf(cr, src, x, y);
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT);
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cairo_rectangle(cr, x, y, width, height);
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cairo_fill(cr);
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Since there is no easy way to apply a mask to a fill operation, we create
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // a secondary surface and tile into that, then paint it with |alpha|.
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cairo_surface_t* surface = cairo_image_surface_create(
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        CAIRO_FORMAT_ARGB32, width, height);
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cairo_t* tiled = cairo_create(surface);
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gdk_cairo_set_source_pixbuf(tiled, src, 0, 0);
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cairo_pattern_set_extend(cairo_get_source(tiled), CAIRO_EXTEND_REPEAT);
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cairo_rectangle(tiled, 0, 0, width, height);
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cairo_fill(tiled);
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cairo_set_source_surface(cr, surface, x, y);
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cairo_paint_with_alpha(cr, alpha);
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cairo_destroy(tiled);
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cairo_surface_destroy(surface);
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNineBox::NineBox(int top_left, int top, int top_right, int left, int center,
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 int right, int bottom_left, int bottom, int bottom_right)
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : unref_pixbufs_on_destroy_(false) {
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  images_[0] = top_left ? rb.GetPixbufNamed(top_left) : NULL;
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  images_[1] = top ? rb.GetPixbufNamed(top) : NULL;
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  images_[2] = top_right ? rb.GetPixbufNamed(top_right) : NULL;
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  images_[3] = left ? rb.GetPixbufNamed(left) : NULL;
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  images_[4] = center ? rb.GetPixbufNamed(center) : NULL;
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  images_[5] = right ? rb.GetPixbufNamed(right) : NULL;
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  images_[6] = bottom_left ? rb.GetPixbufNamed(bottom_left) : NULL;
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  images_[7] = bottom ? rb.GetPixbufNamed(bottom) : NULL;
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  images_[8] = bottom_right ? rb.GetPixbufNamed(bottom_right) : NULL;
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNineBox::NineBox(int image, int top_margin, int bottom_margin, int left_margin,
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 int right_margin)
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : unref_pixbufs_on_destroy_(true) {
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GdkPixbuf* pixbuf = rb.GetPixbufNamed(image);
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int width = gdk_pixbuf_get_width(pixbuf);
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int height = gdk_pixbuf_get_height(pixbuf);
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int inset_width = left_margin + right_margin;
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int inset_height = top_margin + bottom_margin;
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  images_[0] = gdk_pixbuf_new_subpixbuf(pixbuf, 0, 0, left_margin, top_margin);
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  images_[1] = gdk_pixbuf_new_subpixbuf(pixbuf, left_margin, 0,
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        width - inset_width, top_margin);
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  images_[2] = gdk_pixbuf_new_subpixbuf(pixbuf, width - right_margin, 0,
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        right_margin, top_margin);
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  images_[3] = gdk_pixbuf_new_subpixbuf(pixbuf, 0, top_margin,
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        left_margin, height - inset_height);
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  images_[4] = gdk_pixbuf_new_subpixbuf(pixbuf, left_margin, top_margin,
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        width - inset_width,
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        height - inset_height);
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  images_[5] = gdk_pixbuf_new_subpixbuf(pixbuf, width - right_margin,
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        top_margin, right_margin,
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        height - inset_height);
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  images_[6] = gdk_pixbuf_new_subpixbuf(pixbuf, 0, height - bottom_margin,
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        left_margin, bottom_margin);
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  images_[7] = gdk_pixbuf_new_subpixbuf(pixbuf, left_margin,
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        height - bottom_margin,
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        width - inset_width, bottom_margin);
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  images_[8] = gdk_pixbuf_new_subpixbuf(pixbuf, width - right_margin,
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        height - bottom_margin,
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        right_margin, bottom_margin);
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNineBox::~NineBox() {
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (unref_pixbufs_on_destroy_) {
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (int i = 0; i < 9; i++) {
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      g_object_unref(images_[i]);
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NineBox::RenderToWidget(GtkWidget* dst) const {
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RenderToWidgetWithOpacity(dst, 1.0);
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NineBox::RenderToWidgetWithOpacity(GtkWidget* dst, double opacity) const {
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int dst_width = dst->allocation.width;
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int dst_height = dst->allocation.height;
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The upper-left and lower-right corners of the center square in the
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // rendering of the ninebox.
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int x1 = gdk_pixbuf_get_width(images_[0]);
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int y1 = gdk_pixbuf_get_height(images_[0]);
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int x2 = images_[2] ? dst_width - gdk_pixbuf_get_width(images_[2]) : x1;
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int y2 = images_[6] ? dst_height - gdk_pixbuf_get_height(images_[6]) : y1;
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Paint nothing if there's not enough room.
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (x2 < x1 || y2 < y1)
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(dst->window));
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // For widgets that have their own window, the allocation (x,y) coordinates
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // are GdkWindow relative. For other widgets, the coordinates are relative
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // to their container.
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (GTK_WIDGET_NO_WINDOW(dst)) {
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Transform our cairo from window to widget coordinates.
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cairo_translate(cr, dst->allocation.x, dst->allocation.y);
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (base::i18n::IsRTL()) {
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cairo_translate(cr, dst_width, 0.0f);
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cairo_scale(cr, -1.0f, 1.0f);
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Top row, center image is horizontally tiled.
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (images_[0])
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DrawPixbuf(cr, images_[0], 0, 0, opacity);
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (images_[1])
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TileImage(cr, images_[1], x1, 0, x2 - x1, y1, opacity);
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (images_[2])
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DrawPixbuf(cr, images_[2], x2, 0, opacity);
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Center row, all images are vertically tiled, center is horizontally tiled.
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (images_[3])
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TileImage(cr, images_[3], 0, y1, x1, y2 - y1, opacity);
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (images_[4])
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TileImage(cr, images_[4], x1, y1, x2 - x1, y2 - y1, opacity);
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (images_[5])
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TileImage(cr, images_[5], x2, y1, dst_width - x2, y2 - y1, opacity);
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Bottom row, center image is horizontally tiled.
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (images_[6])
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DrawPixbuf(cr, images_[6], 0, y2, opacity);
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (images_[7])
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TileImage(cr, images_[7], x1, y2, x2 - x1, dst_height - y2, opacity);
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (images_[8])
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DrawPixbuf(cr, images_[8], x2, y2, opacity);
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cairo_destroy(cr);
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NineBox::RenderTopCenterStrip(cairo_t* cr, int x, int y,
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   int width) const {
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const int height = gdk_pixbuf_get_height(images_[1]);
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TileImage(cr, images_[1], x, y, width, height, 1.0);
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NineBox::ChangeWhiteToTransparent() {
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int image_idx = 0; image_idx < 9; ++image_idx) {
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GdkPixbuf* pixbuf = images_[image_idx];
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!pixbuf)
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      continue;
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!gdk_pixbuf_get_has_alpha(pixbuf))
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      continue;
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    guchar* pixels = gdk_pixbuf_get_pixels(pixbuf);
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int rowstride = gdk_pixbuf_get_rowstride(pixbuf);
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int width = gdk_pixbuf_get_width(pixbuf);
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int height = gdk_pixbuf_get_height(pixbuf);
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (width * 4 > rowstride) {
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NOTREACHED();
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      continue;
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (int i = 0; i < height; ++i) {
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      for (int j = 0; j < width; ++j) {
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         guchar* pixel = &pixels[i * rowstride + j * 4];
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         if (pixel[0] == 0xff && pixel[1] == 0xff && pixel[2] == 0xff) {
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch           pixel[3] = 0;
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         }
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NineBox::ContourWidget(GtkWidget* widget) const {
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int width = widget->allocation.width;
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int height = widget->allocation.height;
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int x1 = gdk_pixbuf_get_width(images_[0]);
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int x2 = width - gdk_pixbuf_get_width(images_[2]);
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Paint the left and right sides.
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GdkBitmap* mask = gdk_pixmap_new(NULL, width, height, 1);
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gdk_pixbuf_render_threshold_alpha(images_[0], mask,
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    0, 0,
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    0, 0, -1, -1,
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    1);
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gdk_pixbuf_render_threshold_alpha(images_[2], mask,
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    0, 0,
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    x2, 0, -1, -1,
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    1);
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Assume no transparency in the middle rectangle.
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cairo_t* cr = gdk_cairo_create(mask);
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cairo_rectangle(cr, x1, 0, x2 - x1, height);
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cairo_fill(cr);
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cairo_destroy(cr);
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Mask the widget's window's shape.
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!base::i18n::IsRTL()) {
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gtk_widget_shape_combine_mask(widget, mask, 0, 0);
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GdkBitmap* flipped_mask = gdk_pixmap_new(NULL, width, height, 1);
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cairo_t* flipped_cr = gdk_cairo_create(flipped_mask);
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Clear the target bitmap.
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cairo_set_operator(flipped_cr, CAIRO_OPERATOR_CLEAR);
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cairo_paint(flipped_cr);
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Apply flipping transformation.
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cairo_translate(flipped_cr, width, 0.0f);
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cairo_scale(flipped_cr, -1.0f, 1.0f);
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Paint the source bitmap onto the target.
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cairo_set_operator(flipped_cr, CAIRO_OPERATOR_SOURCE);
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gdk_cairo_set_source_pixmap(flipped_cr, mask, 0, 0);
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cairo_paint(flipped_cr);
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cairo_destroy(flipped_cr);
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Mask the widget.
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gtk_widget_shape_combine_mask(widget, flipped_mask, 0, 0);
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    g_object_unref(flipped_mask);
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  g_object_unref(mask);
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
253