summaryrefslogtreecommitdiffstats
path: root/gfx
diff options
context:
space:
mode:
authorben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-17 06:40:57 +0000
committerben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-17 06:40:57 +0000
commit5c7293a73bdaedbe368bc26426a2345f230f2822 (patch)
tree9a5c28a66102e61536730d8335843c14ae5e0a10 /gfx
parentaf63c908603f8a2f58f69167129f819d5d30820c (diff)
downloadchromium_src-5c7293a73bdaedbe368bc26426a2345f230f2822.zip
chromium_src-5c7293a73bdaedbe368bc26426a2345f230f2822.tar.gz
chromium_src-5c7293a73bdaedbe368bc26426a2345f230f2822.tar.bz2
Move some more files to toplevel gfx dir.
TBR=darin BUG=none TEST=none git-svn-id: svn://svn.chromium.org/chrome/trunk/src@41812 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gfx')
-rw-r--r--gfx/blit.cc101
-rw-r--r--gfx/blit.h47
-rw-r--r--gfx/gfx.gyp21
-rw-r--r--gfx/gtk_native_view_id_manager.cc145
-rw-r--r--gfx/gtk_native_view_id_manager.h91
-rw-r--r--gfx/gtk_util.cc90
-rw-r--r--gfx/gtk_util.h67
-rw-r--r--gfx/insets.cc16
-rw-r--r--gfx/insets.h93
-rw-r--r--gfx/insets_unittest.cc68
-rw-r--r--gfx/native_widget_types.h156
-rw-r--r--gfx/native_widget_types_gtk.cc16
-rw-r--r--gfx/path.cc18
-rw-r--r--gfx/path.h54
-rw-r--r--gfx/path_gtk.cc55
-rw-r--r--gfx/path_win.cc45
-rw-r--r--gfx/scrollbar_size.cc23
-rw-r--r--gfx/scrollbar_size.h17
18 files changed, 1123 insertions, 0 deletions
diff --git a/gfx/blit.cc b/gfx/blit.cc
new file mode 100644
index 0000000..f355177
--- /dev/null
+++ b/gfx/blit.cc
@@ -0,0 +1,101 @@
+// Copyright (c) 2009 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 "gfx/blit.h"
+
+#if defined(OS_POSIX) && !defined(OS_MACOSX)
+#include <cairo/cairo.h>
+#endif
+
+#if defined(OS_MACOSX)
+#include "base/scoped_cftyperef.h"
+#endif
+#include "gfx/point.h"
+#include "gfx/rect.h"
+#include "skia/ext/platform_canvas.h"
+#include "skia/ext/platform_device.h"
+
+namespace gfx {
+
+void BlitContextToContext(NativeDrawingContext dst_context,
+ const Rect& dst_rect,
+ NativeDrawingContext src_context,
+ const Point& src_origin) {
+#if defined(OS_WIN)
+ BitBlt(dst_context, dst_rect.x(), dst_rect.y(),
+ dst_rect.width(), dst_rect.height(),
+ src_context, src_origin.x(), src_origin.y(), SRCCOPY);
+#elif defined(OS_MACOSX)
+ // Only translations and/or vertical flips in the source context are
+ // supported; more complex source context transforms will be ignored.
+
+ // If there is a translation on the source context, we need to account for
+ // it ourselves since CGBitmapContextCreateImage will bypass it.
+ Rect src_rect(src_origin, dst_rect.size());
+ CGAffineTransform transform = CGContextGetCTM(src_context);
+ bool flipped = fabs(transform.d + 1) < 0.0001;
+ CGFloat delta_y = flipped ? CGBitmapContextGetHeight(src_context) -
+ transform.ty
+ : transform.ty;
+ src_rect.Offset(transform.tx, delta_y);
+
+ scoped_cftyperef<CGImageRef>
+ src_image(CGBitmapContextCreateImage(src_context));
+ scoped_cftyperef<CGImageRef> src_sub_image(
+ CGImageCreateWithImageInRect(src_image, src_rect.ToCGRect()));
+ CGContextDrawImage(dst_context, dst_rect.ToCGRect(), src_sub_image);
+#else // Linux, BSD, others
+ // Only translations in the source context are supported; more complex
+ // source context transforms will be ignored.
+ cairo_save(dst_context);
+ double surface_x = src_origin.x();
+ double surface_y = src_origin.y();
+ cairo_user_to_device(src_context, &surface_x, &surface_y);
+ cairo_set_source_surface(dst_context, cairo_get_target(src_context),
+ dst_rect.x()-surface_x, dst_rect.y()-surface_y);
+ cairo_rectangle(dst_context, dst_rect.x(), dst_rect.y(),
+ dst_rect.width(), dst_rect.height());
+ cairo_clip(dst_context);
+ cairo_paint(dst_context);
+ cairo_restore(dst_context);
+#endif
+}
+
+static NativeDrawingContext GetContextFromCanvas(
+ skia::PlatformCanvas *canvas) {
+ skia::PlatformDevice& device = canvas->getTopPlatformDevice();
+#if defined(OS_WIN)
+ return device.getBitmapDC();
+#elif defined(OS_MACOSX)
+ return device.GetBitmapContext();
+#else // Linux, BSD, others
+ return device.beginPlatformPaint();
+#endif
+}
+
+void BlitContextToCanvas(skia::PlatformCanvas *dst_canvas,
+ const Rect& dst_rect,
+ NativeDrawingContext src_context,
+ const Point& src_origin) {
+ BlitContextToContext(GetContextFromCanvas(dst_canvas), dst_rect,
+ src_context, src_origin);
+}
+
+void BlitCanvasToContext(NativeDrawingContext dst_context,
+ const Rect& dst_rect,
+ skia::PlatformCanvas *src_canvas,
+ const Point& src_origin) {
+ BlitContextToContext(dst_context, dst_rect,
+ GetContextFromCanvas(src_canvas), src_origin);
+}
+
+void BlitCanvasToCanvas(skia::PlatformCanvas *dst_canvas,
+ const Rect& dst_rect,
+ skia::PlatformCanvas *src_canvas,
+ const Point& src_origin) {
+ BlitContextToContext(GetContextFromCanvas(dst_canvas), dst_rect,
+ GetContextFromCanvas(src_canvas), src_origin);
+}
+
+} // namespace gfx
diff --git a/gfx/blit.h b/gfx/blit.h
new file mode 100644
index 0000000..dd31a9e
--- /dev/null
+++ b/gfx/blit.h
@@ -0,0 +1,47 @@
+// Copyright (c) 2009 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.
+
+#ifndef GFX_BLIT_H_
+#define GFX_BLIT_H_
+
+#include "gfx/native_widget_types.h"
+#include "gfx/point.h"
+#include "gfx/rect.h"
+
+namespace skia {
+class PlatformCanvas;
+} // namespace skia
+
+namespace gfx {
+
+class Point;
+class Rect;
+
+// Blits a rectangle from the source context into the destination context.
+void BlitContextToContext(NativeDrawingContext dst_context,
+ const Rect& dst_rect,
+ NativeDrawingContext src_context,
+ const Point& src_origin);
+
+// Blits a rectangle from the source context into the destination canvas.
+void BlitContextToCanvas(skia::PlatformCanvas *dst_canvas,
+ const Rect& dst_rect,
+ NativeDrawingContext src_context,
+ const Point& src_origin);
+
+// Blits a rectangle from the source canvas into the destination context.
+void BlitCanvasToContext(NativeDrawingContext dst_context,
+ const Rect& dst_rect,
+ skia::PlatformCanvas *src_canvas,
+ const Point& src_origin);
+
+// Blits a rectangle from the source canvas into the destination canvas.
+void BlitCanvasToCanvas(skia::PlatformCanvas *dst_canvas,
+ const Rect& dst_rect,
+ skia::PlatformCanvas *src_canvas,
+ const Point& src_origin);
+
+} // namespace gfx
+
+#endif // GFX_BLIT_H_
diff --git a/gfx/gfx.gyp b/gfx/gfx.gyp
index 0af6121..ab35db6 100644
--- a/gfx/gfx.gyp
+++ b/gfx/gfx.gyp
@@ -17,6 +17,7 @@
'../testing/gtest.gyp:gtest',
],
'sources': [
+ 'insets_unittest.cc',
'rect_unittest.cc',
'run_all_unittests.cc',
'test_suite.h',
@@ -53,12 +54,24 @@
'../third_party/zlib/zlib.gyp:zlib',
],
'sources': [
+ 'blit.cc',
+ 'blit.h',
'gfx_paths.cc',
'gfx_paths.h',
+ 'insets.cc',
+ 'insets.h',
+ 'native_widget_types.h',
+ 'native_widget_types_gtk.cc',
+ 'path.cc',
+ 'path.h',
+ 'path_gtk.cc',
+ 'path_win.cc',
'point.cc',
'point.h',
'rect.cc',
'rect.h',
+ 'scrollbar_size.cc',
+ 'scrollbar_size.h',
'size.cc',
'size.h',
],
@@ -69,6 +82,14 @@
'icon_util.h',
],
}],
+ ['OS=="linux" or OS=="freebsd" or OS=="openbsd"', {
+ 'sources': [
+ 'gtk_native_view_manager.cc',
+ 'gtk_native_view_manager.h',
+ 'gtk_util.cc',
+ 'gtk_util.h',
+ ],
+ }],
],
},
],
diff --git a/gfx/gtk_native_view_id_manager.cc b/gfx/gtk_native_view_id_manager.cc
new file mode 100644
index 0000000..47dc2fb
--- /dev/null
+++ b/gfx/gtk_native_view_id_manager.cc
@@ -0,0 +1,145 @@
+// Copyright (c) 2009 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 "gfx/gtk_native_view_id_manager.h"
+
+#include "base/logging.h"
+#include "base/rand_util.h"
+#include "gfx/rect.h"
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+// -----------------------------------------------------------------------------
+// Bounce functions for GTK to callback into a C++ object...
+
+static void OnRealize(gfx::NativeView widget, void* arg) {
+ GtkNativeViewManager* manager = reinterpret_cast<GtkNativeViewManager*>(arg);
+ manager->OnRealize(widget);
+}
+
+static void OnUnrealize(gfx::NativeView widget, void *arg) {
+ GtkNativeViewManager* manager = reinterpret_cast<GtkNativeViewManager*>(arg);
+ manager->OnUnrealize(widget);
+}
+
+static void OnDestroy(GtkObject* obj, void* arg) {
+ GtkNativeViewManager* manager = reinterpret_cast<GtkNativeViewManager*>(arg);
+ manager->OnDestroy(reinterpret_cast<GtkWidget*>(obj));
+}
+
+// -----------------------------------------------------------------------------
+
+
+// -----------------------------------------------------------------------------
+// Public functions...
+
+GtkNativeViewManager::GtkNativeViewManager() {
+}
+
+gfx::NativeViewId GtkNativeViewManager::GetIdForWidget(gfx::NativeView widget) {
+ // This is just for unit tests:
+ if (!widget)
+ return 0;
+
+ AutoLock locked(lock_);
+
+ std::map<gfx::NativeView, gfx::NativeViewId>::const_iterator i =
+ native_view_to_id_.find(widget);
+
+ if (i != native_view_to_id_.end())
+ return i->second;
+
+ gfx::NativeViewId new_id =
+ static_cast<gfx::NativeViewId>(base::RandUint64());
+ while (id_to_info_.find(new_id) != id_to_info_.end())
+ new_id = static_cast<gfx::NativeViewId>(base::RandUint64());
+
+ NativeViewInfo info;
+ if (GTK_WIDGET_REALIZED(widget)) {
+ GdkWindow *gdk_window = widget->window;
+ CHECK(gdk_window);
+ info.x_window_id = GDK_WINDOW_XID(gdk_window);
+ }
+
+ native_view_to_id_[widget] = new_id;
+ id_to_info_[new_id] = info;
+
+ g_signal_connect(widget, "realize", G_CALLBACK(::OnRealize), this);
+ g_signal_connect(widget, "unrealize", G_CALLBACK(::OnUnrealize), this);
+ g_signal_connect(widget, "destroy", G_CALLBACK(::OnDestroy), this);
+
+ return new_id;
+}
+
+bool GtkNativeViewManager::GetXIDForId(XID* output, gfx::NativeViewId id) {
+ AutoLock locked(lock_);
+
+ std::map<gfx::NativeViewId, NativeViewInfo>::const_iterator i =
+ id_to_info_.find(id);
+
+ if (i == id_to_info_.end())
+ return false;
+
+ *output = i->second.x_window_id;
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+
+
+// -----------------------------------------------------------------------------
+// Private functions...
+
+gfx::NativeViewId GtkNativeViewManager::GetWidgetId(gfx::NativeView widget) {
+ lock_.AssertAcquired();
+
+ std::map<gfx::NativeView, gfx::NativeViewId>::const_iterator i =
+ native_view_to_id_.find(widget);
+
+ CHECK(i != native_view_to_id_.end());
+ return i->second;
+}
+
+void GtkNativeViewManager::OnRealize(gfx::NativeView widget) {
+ AutoLock locked(lock_);
+
+ const gfx::NativeViewId id = GetWidgetId(widget);
+ std::map<gfx::NativeViewId, NativeViewInfo>::iterator i =
+ id_to_info_.find(id);
+
+ CHECK(i != id_to_info_.end());
+ CHECK(widget->window);
+
+ i->second.x_window_id = GDK_WINDOW_XID(widget->window);
+}
+
+void GtkNativeViewManager::OnUnrealize(gfx::NativeView widget) {
+ AutoLock locked(lock_);
+
+ const gfx::NativeViewId id = GetWidgetId(widget);
+ std::map<gfx::NativeViewId, NativeViewInfo>::iterator i =
+ id_to_info_.find(id);
+
+ CHECK(i != id_to_info_.end());
+
+ i->second.x_window_id = 0;
+}
+
+void GtkNativeViewManager::OnDestroy(gfx::NativeView widget) {
+ AutoLock locked(lock_);
+
+ std::map<gfx::NativeView, gfx::NativeViewId>::iterator i =
+ native_view_to_id_.find(widget);
+ CHECK(i != native_view_to_id_.end());
+
+ std::map<gfx::NativeViewId, NativeViewInfo>::iterator j =
+ id_to_info_.find(i->second);
+ CHECK(j != id_to_info_.end());
+
+ native_view_to_id_.erase(i);
+ id_to_info_.erase(j);
+}
+
+// -----------------------------------------------------------------------------
diff --git a/gfx/gtk_native_view_id_manager.h b/gfx/gtk_native_view_id_manager.h
new file mode 100644
index 0000000..048cd2d
--- /dev/null
+++ b/gfx/gtk_native_view_id_manager.h
@@ -0,0 +1,91 @@
+// Copyright (c) 2009 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.
+
+#ifndef GFX_GTK_NATIVE_VIEW_ID_MANAGER_H_
+#define GFX_GTK_NATIVE_VIEW_ID_MANAGER_H_
+
+#include <map>
+
+#include "base/singleton.h"
+#include "gfx/native_widget_types.h"
+
+typedef unsigned long XID;
+
+// NativeViewIds are the opaque values which the renderer holds as a reference
+// to a window. These ids are often used in sync calls from the renderer and
+// one cannot terminate sync calls on the UI thread as that can lead to
+// deadlocks.
+//
+// Because of this, we have the BACKGROUND_X11 thread for these calls and this
+// thread has a separate X connection in order to answer them. But one cannot
+// use GTK on multiple threads, so the BACKGROUND_X11 thread deals only in Xlib
+// calls and, thus, XIDs.
+//
+// So we could make NativeViewIds be the X id of the window. However, at the
+// time when we need to tell the renderer about its NativeViewId, an XID isn't
+// availible and it goes very much against the grain of the code to make it so.
+// Also, we worry that GTK might choose to change the underlying X window id
+// when, say, the widget is hidden or repacked. Finally, if we used XIDs then a
+// compromised renderer could start asking questions about any X windows on the
+// system.
+//
+// Thus, we have this object. It produces random NativeViewIds from GtkWidget
+// pointers and observes the various signals from the widget for when an X
+// window is created, destroyed etc. Thus it provides a thread safe mapping
+// from NativeViewIds to the current XID for that widget.
+//
+// You get a reference to the global instance with:
+// Singleton<GtkNativeViewManager>()
+class GtkNativeViewManager {
+ public:
+ // Must be called from the UI thread:
+ //
+ // Return a NativeViewId for the given widget and attach to the various
+ // signals emitted by that widget. The NativeViewId is pseudo-randomly
+ // allocated so that a compromised renderer trying to guess values will fail
+ // with high probability. The NativeViewId will not be reused for the
+ // lifetime of the GtkWidget.
+ gfx::NativeViewId GetIdForWidget(gfx::NativeView widget);
+
+ // May be called from any thread:
+ //
+ // xid: (output) the resulting X window ID, or 0
+ // id: a value previously returned from GetIdForWidget
+ // returns: true if |id| is a valid id, false otherwise.
+ //
+ // If the widget referenced by |id| does not current have an X window id,
+ // |*xid| is set to 0.
+ bool GetXIDForId(XID* xid, gfx::NativeViewId id);
+
+ // These are actually private functions, but need to be called from statics.
+ void OnRealize(gfx::NativeView widget);
+ void OnUnrealize(gfx::NativeView widget);
+ void OnDestroy(gfx::NativeView widget);
+
+ private:
+ // This object is a singleton:
+ GtkNativeViewManager();
+ friend struct DefaultSingletonTraits<GtkNativeViewManager>;
+
+ struct NativeViewInfo {
+ NativeViewInfo()
+ : x_window_id(0) {
+ }
+
+ XID x_window_id;
+ };
+
+ gfx::NativeViewId GetWidgetId(gfx::NativeView id);
+
+ // protects native_view_to_id_ and id_to_info_
+ Lock lock_;
+ // If asked for an id for the same widget twice, we want to return the same
+ // id. So this records the current mapping.
+ std::map<gfx::NativeView, gfx::NativeViewId> native_view_to_id_;
+ std::map<gfx::NativeViewId, NativeViewInfo> id_to_info_;
+
+ DISALLOW_COPY_AND_ASSIGN(GtkNativeViewManager);
+};
+
+#endif // GFX_GTK_NATIVE_VIEW_ID_MANAGER_H_
diff --git a/gfx/gtk_util.cc b/gfx/gtk_util.cc
new file mode 100644
index 0000000..3485e6a
--- /dev/null
+++ b/gfx/gtk_util.cc
@@ -0,0 +1,90 @@
+// Copyright (c) 2009 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 "gfx/gtk_util.h"
+
+#include <gdk/gdk.h>
+#include <gtk/gtk.h>
+#include <stdlib.h>
+
+#include "base/basictypes.h"
+#include "base/linux_util.h"
+#include "gfx/rect.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/skia/include/core/SkUnPreMultiply.h"
+
+namespace {
+
+void FreePixels(guchar* pixels, gpointer data) {
+ free(data);
+}
+
+} // namespace
+
+namespace gfx {
+
+const GdkColor kGdkWhite = GDK_COLOR_RGB(0xff, 0xff, 0xff);
+const GdkColor kGdkBlack = GDK_COLOR_RGB(0x00, 0x00, 0x00);
+const GdkColor kGdkGreen = GDK_COLOR_RGB(0x00, 0xff, 0x00);
+
+GdkPixbuf* GdkPixbufFromSkBitmap(const SkBitmap* bitmap) {
+ if (bitmap->isNull())
+ return NULL;
+
+ bitmap->lockPixels();
+
+ int width = bitmap->width();
+ int height = bitmap->height();
+ int stride = bitmap->rowBytes();
+
+ // SkBitmaps are premultiplied, we need to unpremultiply them.
+ const int kBytesPerPixel = 4;
+ uint8* divided = static_cast<uint8*>(malloc(height * stride));
+
+ for (int y = 0, i = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ uint32 pixel = bitmap->getAddr32(0, y)[x];
+
+ int alpha = SkColorGetA(pixel);
+ if (alpha != 0 && alpha != 255) {
+ SkColor unmultiplied = SkUnPreMultiply::PMColorToColor(pixel);
+ divided[i + 0] = SkColorGetR(unmultiplied);
+ divided[i + 1] = SkColorGetG(unmultiplied);
+ divided[i + 2] = SkColorGetB(unmultiplied);
+ divided[i + 3] = alpha;
+ } else {
+ divided[i + 0] = SkColorGetR(pixel);
+ divided[i + 1] = SkColorGetG(pixel);
+ divided[i + 2] = SkColorGetB(pixel);
+ divided[i + 3] = alpha;
+ }
+ i += kBytesPerPixel;
+ }
+ }
+
+ // This pixbuf takes ownership of our malloc()ed data and will
+ // free it for us when it is destroyed.
+ GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data(
+ divided,
+ GDK_COLORSPACE_RGB, // The only colorspace gtk supports.
+ true, // There is an alpha channel.
+ 8,
+ width, height, stride, &FreePixels, divided);
+
+ bitmap->unlockPixels();
+ return pixbuf;
+}
+
+void SubtractRectanglesFromRegion(GdkRegion* region,
+ const std::vector<Rect>& cutouts) {
+ for (size_t i = 0; i < cutouts.size(); ++i) {
+ GdkRectangle rect = cutouts[i].ToGdkRectangle();
+ GdkRegion* rect_region = gdk_region_rectangle(&rect);
+ gdk_region_subtract(region, rect_region);
+ // TODO(deanm): It would be nice to be able to reuse the GdkRegion here.
+ gdk_region_destroy(rect_region);
+ }
+}
+
+} // namespace gfx
diff --git a/gfx/gtk_util.h b/gfx/gtk_util.h
new file mode 100644
index 0000000..a958d67
--- /dev/null
+++ b/gfx/gtk_util.h
@@ -0,0 +1,67 @@
+// Copyright (c) 2009 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.
+
+#ifndef GFX_GTK_UTIL_H_
+#define GFX_GTK_UTIL_H_
+
+#include <stdint.h>
+#include <vector>
+
+#include <glib-object.h>
+
+#include "base/scoped_ptr.h"
+
+typedef struct _GdkColor GdkColor;
+typedef struct _GdkPixbuf GdkPixbuf;
+typedef struct _GdkRegion GdkRegion;
+
+class SkBitmap;
+
+const int kSkiaToGDKMultiplier = 257;
+
+// Define a macro for creating GdkColors from RGB values. This is a macro to
+// allow static construction of literals, etc. Use this like:
+// GdkColor white = GDK_COLOR_RGB(0xff, 0xff, 0xff);
+#define GDK_COLOR_RGB(r, g, b) {0, r * kSkiaToGDKMultiplier, \
+ g * kSkiaToGDKMultiplier, b * kSkiaToGDKMultiplier}
+
+namespace gfx {
+
+class Rect;
+
+extern const GdkColor kGdkWhite;
+extern const GdkColor kGdkBlack;
+extern const GdkColor kGdkGreen;
+
+// Convert and copy a SkBitmap to a GdkPixbuf. NOTE: this uses BGRAToRGBA, so
+// it is an expensive operation.
+GdkPixbuf* GdkPixbufFromSkBitmap(const SkBitmap* bitmap);
+
+// Modify the given region by subtracting the given rectangles.
+void SubtractRectanglesFromRegion(GdkRegion* region,
+ const std::vector<Rect>& cutouts);
+
+} // namespace gfx
+
+namespace {
+// A helper class that will g_object_unref |p| when it goes out of scope.
+// This never adds a ref, it only unrefs.
+template <typename Type>
+struct GObjectUnrefer {
+ void operator()(Type* ptr) const {
+ if (ptr)
+ g_object_unref(ptr);
+ }
+};
+} // namespace
+
+// It's not legal C++ to have a templatized typedefs, so we wrap it in a
+// struct. When using this, you need to include ::Type. E.g.,
+// ScopedGObject<GdkPixbufLoader>::Type loader(gdk_pixbuf_loader_new());
+template<class T>
+struct ScopedGObject {
+ typedef scoped_ptr_malloc<T, GObjectUnrefer<T> > Type;
+};
+
+#endif // GFX_GTK_UTIL_H_
diff --git a/gfx/insets.cc b/gfx/insets.cc
new file mode 100644
index 0000000..06cc6aa
--- /dev/null
+++ b/gfx/insets.cc
@@ -0,0 +1,16 @@
+// Copyright (c) 2009 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 "gfx/insets.h"
+
+#include "base/string_util.h"
+
+namespace gfx {
+
+std::string Insets::ToString() const {
+ // Print members in the same order of the constructor parameters.
+ return StringPrintf("%d,%d,%d,%d", top_, left_, bottom_, right_);
+}
+
+} // namespace gfx
diff --git a/gfx/insets.h b/gfx/insets.h
new file mode 100644
index 0000000..bbed270
--- /dev/null
+++ b/gfx/insets.h
@@ -0,0 +1,93 @@
+// Copyright (c) 2006-2008 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.
+
+#ifndef GFX_INSETS_H_
+#define GFX_INSETS_H_
+
+#include "build/build_config.h"
+
+#if defined(OS_POSIX) && !defined(OS_MACOSX)
+#include <gtk/gtkstyle.h>
+#endif
+
+#include <string>
+
+namespace gfx {
+
+//
+// An insets represents the borders of a container (the space the container must
+// leave at each of its edges).
+//
+
+class Insets {
+ public:
+ Insets() : top_(0), left_(0), bottom_(0), right_(0) {}
+ Insets(int top, int left, int bottom, int right)
+ : top_(top),
+ left_(left),
+ bottom_(bottom),
+ right_(right) {}
+#if defined(OS_POSIX) && !defined(OS_MACOSX)
+ explicit Insets(const GtkBorder& border)
+ : top_(border.top),
+ left_(border.left),
+ bottom_(border.bottom),
+ right_(border.right) {}
+#endif
+
+ ~Insets() {}
+
+ int top() const { return top_; }
+ int left() const { return left_; }
+ int bottom() const { return bottom_; }
+ int right() const { return right_; }
+
+ // Returns the total width taken up by the insets, which is the sum of the
+ // left and right insets.
+ int width() const { return left_ + right_; }
+
+ // Returns the total height taken up by the insets, which is the sum of the
+ // top and bottom insets.
+ int height() const { return top_ + bottom_; }
+
+ // Returns true if the insets are empty.
+ bool empty() const { return width() == 0 && height() == 0; }
+
+ void Set(int top, int left, int bottom, int right) {
+ top_ = top;
+ left_ = left;
+ bottom_ = bottom;
+ right_ = right;
+ }
+
+ bool operator==(const Insets& insets) const {
+ return top_ == insets.top_ && left_ == insets.left_ &&
+ bottom_ == insets.bottom_ && right_ == insets.right_;
+ }
+
+ bool operator!=(const Insets& insets) const {
+ return !(*this == insets);
+ }
+
+ Insets& operator+=(const Insets& insets) {
+ top_ += insets.top_;
+ left_ += insets.left_;
+ bottom_ += insets.bottom_;
+ right_ += insets.right_;
+ return *this;
+ }
+
+ // Returns a string representation of the insets.
+ std::string ToString() const;
+
+ private:
+ int top_;
+ int left_;
+ int bottom_;
+ int right_;
+};
+
+} // namespace gfx
+
+#endif // GFX_INSETS_H_
diff --git a/gfx/insets_unittest.cc b/gfx/insets_unittest.cc
new file mode 100644
index 0000000..f08fc38
--- /dev/null
+++ b/gfx/insets_unittest.cc
@@ -0,0 +1,68 @@
+// Copyright (c) 2009 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 "gfx/insets.h"
+
+#include <iostream>
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+TEST(InsetsTest, InsetsDefault) {
+ gfx::Insets insets;
+ EXPECT_EQ(0, insets.top());
+ EXPECT_EQ(0, insets.left());
+ EXPECT_EQ(0, insets.bottom());
+ EXPECT_EQ(0, insets.right());
+ EXPECT_EQ(0, insets.width());
+ EXPECT_EQ(0, insets.height());
+ EXPECT_TRUE(insets.empty());
+}
+
+TEST(InsetsTest, Insets) {
+ gfx::Insets insets(1, 2, 3, 4);
+ EXPECT_EQ(1, insets.top());
+ EXPECT_EQ(2, insets.left());
+ EXPECT_EQ(3, insets.bottom());
+ EXPECT_EQ(4, insets.right());
+ EXPECT_EQ(6, insets.width()); // Left + right.
+ EXPECT_EQ(4, insets.height()); // Top + bottom.
+ EXPECT_FALSE(insets.empty());
+}
+
+TEST(InsetsTest, Set) {
+ gfx::Insets insets;
+ insets.Set(1, 2, 3, 4);
+ EXPECT_EQ(1, insets.top());
+ EXPECT_EQ(2, insets.left());
+ EXPECT_EQ(3, insets.bottom());
+ EXPECT_EQ(4, insets.right());
+}
+
+TEST(InsetsTest, Add) {
+ gfx::Insets insets;
+ insets.Set(1, 2, 3, 4);
+ insets += gfx::Insets(5, 6, 7, 8);
+ EXPECT_EQ(6, insets.top());
+ EXPECT_EQ(8, insets.left());
+ EXPECT_EQ(10, insets.bottom());
+ EXPECT_EQ(12, insets.right());
+}
+
+TEST(InsetsTest, Equality) {
+ gfx::Insets insets1;
+ insets1.Set(1, 2, 3, 4);
+ gfx::Insets insets2;
+ // Test operator== and operator!=.
+ EXPECT_FALSE(insets1 == insets2);
+ EXPECT_TRUE(insets1 != insets2);
+
+ insets2.Set(1, 2, 3, 4);
+ EXPECT_TRUE(insets1 == insets2);
+ EXPECT_FALSE(insets1 != insets2);
+}
+
+TEST(InsetsTest, ToString) {
+ gfx::Insets insets(1, 2, 3, 4);
+ EXPECT_EQ("1,2,3,4", insets.ToString());
+}
diff --git a/gfx/native_widget_types.h b/gfx/native_widget_types.h
new file mode 100644
index 0000000..b3eb0e0
--- /dev/null
+++ b/gfx/native_widget_types.h
@@ -0,0 +1,156 @@
+// Copyright (c) 2009 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.
+
+#ifndef GFX_NATIVE_WIDGET_TYPES_H_
+#define GFX_NATIVE_WIDGET_TYPES_H_
+
+#include "base/basictypes.h"
+#include "build/build_config.h"
+
+// This file provides cross platform typedefs for native widget types.
+// NativeWindow: this is a handle to a native, top-level window
+// NativeView: this is a handle to a native UI element. It may be the
+// same type as a NativeWindow on some platforms.
+// NativeViewId: Often, in our cross process model, we need to pass around a
+// reference to a "window". This reference will, say, be echoed back from a
+// renderer to the browser when it wishes to query it's size. On Windows, a
+// HWND can be used for this. On other platforms, we may wish to pass
+// around X window ids, or maybe abstract identifiers.
+//
+// As a rule of thumb - if you're in the renderer, you should be dealing
+// with NativeViewIds. This should remind you that you shouldn't be doing
+// direct operations on platform widgets from the renderer process.
+//
+// If you're in the browser, you're probably dealing with NativeViews,
+// unless you're in the IPC layer, which will be translating between
+// NativeViewIds from the renderer and NativeViews.
+//
+// NativeEditView: a handle to a native edit-box. The Mac folks wanted this
+// specific typedef.
+//
+// The name 'View' here meshes with OS X where the UI elements are called
+// 'views' and with our Chrome UI code where the elements are also called
+// 'views'.
+
+#if defined(OS_WIN)
+#include <windows.h>
+#elif defined(OS_MACOSX)
+struct CGContext;
+#ifdef __OBJC__
+@class NSView;
+@class NSWindow;
+@class NSTextField;
+#else
+class NSView;
+class NSWindow;
+class NSTextField;
+#endif // __OBJC__
+#elif defined(USE_X11)
+typedef struct _GdkCursor GdkCursor;
+typedef struct _GdkRegion GdkRegion;
+typedef struct _GtkWidget GtkWidget;
+typedef struct _GtkWindow GtkWindow;
+typedef struct _cairo cairo_t;
+#endif
+
+namespace gfx {
+
+#if defined(OS_WIN)
+typedef HWND NativeView;
+typedef HWND NativeWindow;
+typedef HWND NativeEditView;
+typedef HDC NativeDrawingContext;
+typedef HCURSOR NativeCursor;
+typedef HMENU NativeMenu;
+typedef HRGN NativeRegion;
+#elif defined(OS_MACOSX)
+typedef NSView* NativeView;
+typedef NSWindow* NativeWindow;
+typedef NSTextField* NativeEditView;
+typedef CGContext* NativeDrawingContext;
+typedef void* NativeCursor;
+typedef void* NativeMenu;
+#elif defined(USE_X11)
+typedef GtkWidget* NativeView;
+typedef GtkWindow* NativeWindow;
+typedef GtkWidget* NativeEditView;
+typedef cairo_t* NativeDrawingContext;
+typedef GdkCursor* NativeCursor;
+typedef GtkWidget* NativeMenu;
+typedef GdkRegion* NativeRegion;
+#endif
+
+// Note: for test_shell we're packing a pointer into the NativeViewId. So, if
+// you make it a type which is smaller than a pointer, you have to fix
+// test_shell.
+//
+// See comment at the top of the file for usage.
+typedef intptr_t NativeViewId;
+
+// Convert a NativeViewId to a NativeView.
+// On Windows, these are both HWNDS so it's just a cast.
+// On Mac, for now, we pass the NSView pointer into the renderer
+// On Linux we use an opaque id
+#if defined(OS_WIN)
+static inline NativeView NativeViewFromId(NativeViewId id) {
+ return reinterpret_cast<NativeView>(id);
+}
+#elif defined(OS_MACOSX)
+
+// A recent CL removed the need for Mac to actually convert
+// NativeViewId to NativeView. Until other platforms make changes,
+// the platform-independent code cannot be removed. The following is
+// to discourage new platform-independent uses.
+
+#define NativeViewFromId(x) NATIVE_VIEW_FROM_ID_NOT_AVAILABLE_ON_MAC
+
+#elif defined(USE_X11)
+// A NativeView on Linux is a GtkWidget*. However, we can't go directly from an
+// X window ID to a GtkWidget. Thus, functions which handle NativeViewIds from
+// the renderer have to use Xlib. This is fine since these functions are
+// generally performed on the BACKGROUND_X thread which can't use GTK anyway.
+
+#define NativeViewFromId(x) NATIVE_VIEW_FROM_ID_NOT_AVAILIBLE_ON_X11
+
+#endif // defined(USE_X11)
+
+// Convert a NativeView to a NativeViewId. See the comments above
+// NativeViewFromId.
+#if defined(OS_WIN) || defined(OS_MACOSX)
+static inline NativeViewId IdFromNativeView(NativeView view) {
+ return reinterpret_cast<NativeViewId>(view);
+}
+#elif defined(USE_X11)
+// Not inlined because it involves pulling too many headers.
+NativeViewId IdFromNativeView(NativeView view);
+#endif // defined(USE_X11)
+
+
+// PluginWindowHandle is an abstraction wrapping "the types of windows
+// used by NPAPI plugins". On Windows it's an HWND, on X it's an X
+// window id.
+#if defined(OS_WIN)
+ typedef HWND PluginWindowHandle;
+ const PluginWindowHandle kNullPluginWindow = NULL;
+#elif defined(USE_X11)
+ typedef unsigned long PluginWindowHandle;
+ const PluginWindowHandle kNullPluginWindow = 0;
+#else
+ // On OS X we don't have windowed plugins.
+ // We use a NULL/0 PluginWindowHandle in shared code to indicate there
+ // is no window present, so mirror that behavior here.
+ //
+ // The GPU plugin is currently an exception to this rule. As of this
+ // writing it uses some NPAPI infrastructure, and minimally we need
+ // to identify the plugin instance via this window handle. When the
+ // GPU plugin becomes a full-on GPU process, this typedef can be
+ // returned to a bool. For now we use a type large enough to hold a
+ // pointer on 64-bit architectures in case we need this capability.
+ typedef uint64 PluginWindowHandle;
+ const PluginWindowHandle kNullPluginWindow = 0;
+#endif
+
+} // namespace gfx
+
+#endif // GFX_NATIVE_WIDGET_TYPES_H_
diff --git a/gfx/native_widget_types_gtk.cc b/gfx/native_widget_types_gtk.cc
new file mode 100644
index 0000000..0813686
--- /dev/null
+++ b/gfx/native_widget_types_gtk.cc
@@ -0,0 +1,16 @@
+// Copyright (c) 2009 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 "gfx/native_widget_types.h"
+
+#include "base/logging.h"
+#include "gfx/gtk_native_view_id_manager.h"
+
+namespace gfx {
+
+NativeViewId IdFromNativeView(NativeView view) {
+ return Singleton<GtkNativeViewManager>()->GetIdForWidget(view);
+}
+
+} // namespace gfx
diff --git a/gfx/path.cc b/gfx/path.cc
new file mode 100644
index 0000000..10d1ddd
--- /dev/null
+++ b/gfx/path.cc
@@ -0,0 +1,18 @@
+// Copyright (c) 2009 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 "gfx/path.h"
+
+#include "base/logging.h"
+
+namespace gfx {
+
+Path::Path(const Point* points, size_t count) {
+ DCHECK(count > 1);
+ moveTo(SkIntToScalar(points[0].x), SkIntToScalar(points[0].y));
+ for (size_t i = 1; i < count; ++i)
+ lineTo(SkIntToScalar(points[i].x), SkIntToScalar(points[i].y));
+}
+
+} // namespace gfx
diff --git a/gfx/path.h b/gfx/path.h
new file mode 100644
index 0000000..97cda884
--- /dev/null
+++ b/gfx/path.h
@@ -0,0 +1,54 @@
+// Copyright (c) 2009 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.
+
+#ifndef GFX_PATH_H_
+#define GFX_PATH_H_
+
+#include "base/basictypes.h"
+#include "gfx/native_widget_types.h"
+
+#include "third_party/skia/include/core/SkPath.h"
+
+namespace gfx {
+
+class Path : public SkPath {
+ public:
+ // Used by Path(Point,size_t) constructor.
+ struct Point {
+ int x;
+ int y;
+ };
+
+ Path() : SkPath() { moveTo(0, 0); }
+
+ // Creates a path populated with the specified points.
+ Path(const Point* points, size_t count);
+
+#if defined(OS_WIN) || defined(USE_X11)
+ // Creates a NativeRegion from the path. The caller is responsible for freeing
+ // resources used by this region. This only supports polygon paths.
+ NativeRegion CreateNativeRegion() const;
+
+ // Returns the intersection of the two regions. The caller owns the returned
+ // object.
+ static gfx::NativeRegion IntersectRegions(gfx::NativeRegion r1,
+ gfx::NativeRegion r2);
+
+ // Returns the union of the two regions. The caller owns the returned object.
+ static gfx::NativeRegion CombineRegions(gfx::NativeRegion r1,
+ gfx::NativeRegion r2);
+
+ // Returns the difference of the two regions. The caller owns the returned
+ // object.
+ static gfx::NativeRegion SubtractRegion(gfx::NativeRegion r1,
+ gfx::NativeRegion r2);
+#endif
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Path);
+};
+
+}
+
+#endif // GFX_PATH_H_
diff --git a/gfx/path_gtk.cc b/gfx/path_gtk.cc
new file mode 100644
index 0000000..2149aad
--- /dev/null
+++ b/gfx/path_gtk.cc
@@ -0,0 +1,55 @@
+// Copyright (c) 2006-2008 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 "gfx/path.h"
+
+#include <gdk/gdk.h>
+
+#include "base/scoped_ptr.h"
+#include "base/command_line.h"
+
+namespace gfx {
+
+GdkRegion* Path::CreateNativeRegion() const {
+ int point_count = getPoints(NULL, 0);
+ if (point_count <= 1) {
+ // NOTE: ideally this would return gdk_empty_region, but that returns a
+ // region with nothing in it.
+ return NULL;
+ }
+
+ scoped_array<SkPoint> points(new SkPoint[point_count]);
+ getPoints(points.get(), point_count);
+
+ scoped_array<GdkPoint> gdk_points(new GdkPoint[point_count]);
+ for (int i = 0; i < point_count; ++i) {
+ gdk_points[i].x = SkScalarRound(points[i].fX);
+ gdk_points[i].y = SkScalarRound(points[i].fY);
+ }
+
+ return gdk_region_polygon(gdk_points.get(), point_count, GDK_EVEN_ODD_RULE);
+}
+
+// static
+NativeRegion Path::IntersectRegions(NativeRegion r1, NativeRegion r2) {
+ GdkRegion* copy = gdk_region_copy(r1);
+ gdk_region_intersect(copy, r2);
+ return copy;
+}
+
+// static
+NativeRegion Path::CombineRegions(NativeRegion r1, NativeRegion r2) {
+ GdkRegion* copy = gdk_region_copy(r1);
+ gdk_region_union(copy, r2);
+ return copy;
+}
+
+// static
+NativeRegion Path::SubtractRegion(NativeRegion r1, NativeRegion r2) {
+ GdkRegion* copy = gdk_region_copy(r1);
+ gdk_region_subtract(copy, r2);
+ return copy;
+}
+
+} // namespace gfx
diff --git a/gfx/path_win.cc b/gfx/path_win.cc
new file mode 100644
index 0000000..b5f206c
--- /dev/null
+++ b/gfx/path_win.cc
@@ -0,0 +1,45 @@
+// Copyright (c) 2006-2008 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 "gfx/path.h"
+
+#include "base/scoped_ptr.h"
+
+namespace gfx {
+
+HRGN Path::CreateNativeRegion() const {
+ int point_count = getPoints(NULL, 0);
+ scoped_array<SkPoint> points(new SkPoint[point_count]);
+ getPoints(points.get(), point_count);
+ scoped_array<POINT> windows_points(new POINT[point_count]);
+ for (int i = 0; i < point_count; ++i) {
+ windows_points[i].x = SkScalarRound(points[i].fX);
+ windows_points[i].y = SkScalarRound(points[i].fY);
+ }
+
+ return ::CreatePolygonRgn(windows_points.get(), point_count, ALTERNATE);
+}
+
+// static
+NativeRegion Path::IntersectRegions(NativeRegion r1, NativeRegion r2) {
+ HRGN dest = CreateRectRgn(0, 0, 1, 1);
+ CombineRgn(dest, r1, r2, RGN_AND);
+ return dest;
+}
+
+// static
+NativeRegion Path::CombineRegions(NativeRegion r1, NativeRegion r2) {
+ HRGN dest = CreateRectRgn(0, 0, 1, 1);
+ CombineRgn(dest, r1, r2, RGN_OR);
+ return dest;
+}
+
+// static
+NativeRegion Path::SubtractRegion(NativeRegion r1, NativeRegion r2) {
+ HRGN dest = CreateRectRgn(0, 0, 1, 1);
+ CombineRgn(dest, r1, r2, RGN_DIFF);
+ return dest;
+}
+
+} // namespace gfx
diff --git a/gfx/scrollbar_size.cc b/gfx/scrollbar_size.cc
new file mode 100644
index 0000000..426b0ac
--- /dev/null
+++ b/gfx/scrollbar_size.cc
@@ -0,0 +1,23 @@
+// Copyright (c) 2009 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 "gfx/scrollbar_size.h"
+
+#include "base/compiler_specific.h"
+
+#if defined(OS_WIN)
+#include <windows.h>
+#endif
+
+namespace gfx {
+
+int scrollbar_size() {
+#if defined(OS_WIN)
+ return GetSystemMetrics(SM_CXVSCROLL);
+#else
+ return 15;
+#endif
+}
+
+} // namespace gfx
diff --git a/gfx/scrollbar_size.h b/gfx/scrollbar_size.h
new file mode 100644
index 0000000..364d929
--- /dev/null
+++ b/gfx/scrollbar_size.h
@@ -0,0 +1,17 @@
+// Copyright (c) 2009 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.
+
+#ifndef GFX_SCROLLBAR_SIZE_H_
+#define GFX_SCROLLBAR_SIZE_H_
+
+namespace gfx {
+
+// This should return the thickness, in pixels, of a scrollbar in web content.
+// This needs to match the values in WebCore's
+// ScrollbarThemeChromiumXXX.cpp::scrollbarThickness().
+int scrollbar_size();
+
+} // namespace gfx
+
+#endif // GFX_SCROLLBAR_SIZE_H_