diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-17 06:40:57 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-17 06:40:57 +0000 |
commit | 5c7293a73bdaedbe368bc26426a2345f230f2822 (patch) | |
tree | 9a5c28a66102e61536730d8335843c14ae5e0a10 /gfx | |
parent | af63c908603f8a2f58f69167129f819d5d30820c (diff) | |
download | chromium_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.cc | 101 | ||||
-rw-r--r-- | gfx/blit.h | 47 | ||||
-rw-r--r-- | gfx/gfx.gyp | 21 | ||||
-rw-r--r-- | gfx/gtk_native_view_id_manager.cc | 145 | ||||
-rw-r--r-- | gfx/gtk_native_view_id_manager.h | 91 | ||||
-rw-r--r-- | gfx/gtk_util.cc | 90 | ||||
-rw-r--r-- | gfx/gtk_util.h | 67 | ||||
-rw-r--r-- | gfx/insets.cc | 16 | ||||
-rw-r--r-- | gfx/insets.h | 93 | ||||
-rw-r--r-- | gfx/insets_unittest.cc | 68 | ||||
-rw-r--r-- | gfx/native_widget_types.h | 156 | ||||
-rw-r--r-- | gfx/native_widget_types_gtk.cc | 16 | ||||
-rw-r--r-- | gfx/path.cc | 18 | ||||
-rw-r--r-- | gfx/path.h | 54 | ||||
-rw-r--r-- | gfx/path_gtk.cc | 55 | ||||
-rw-r--r-- | gfx/path_win.cc | 45 | ||||
-rw-r--r-- | gfx/scrollbar_size.cc | 23 | ||||
-rw-r--r-- | gfx/scrollbar_size.h | 17 |
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_ |