summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorbrettw@google.com <brettw@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-19 18:52:38 +0000
committerbrettw@google.com <brettw@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-19 18:52:38 +0000
commit6165b4070b7e3a2fd33efd0eb66043c86f61d8b2 (patch)
treed2f7f195c13274ca524d264dc34639e276805325 /base
parent941ac7fca4afc89cb28ffa760f5a4a4ca077912c (diff)
downloadchromium_src-6165b4070b7e3a2fd33efd0eb66043c86f61d8b2.zip
chromium_src-6165b4070b7e3a2fd33efd0eb66043c86f61d8b2.tar.gz
chromium_src-6165b4070b7e3a2fd33efd0eb66043c86f61d8b2.tar.bz2
Move PlatformCanvas and PlatformDevice from base/gfx to webkit/port. I left header files in the original locations that include the ones in the new location so I don't have to change all the includes in Chrome at once. These will be removed later.
I kept the names, indenting, and the namespaces the same for now. I will also be cleaning this up in separate passes. Review URL: http://codereview.chromium.org/11244 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@5690 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r--base/base_unittests.scons2
-rw-r--r--base/build/base_gfx.vcproj28
-rw-r--r--base/build/base_unittests.vcproj8
-rw-r--r--base/gfx/base_gfx.scons10
-rw-r--r--base/gfx/bitmap_platform_device.h26
-rw-r--r--base/gfx/bitmap_platform_device_linux.cc94
-rw-r--r--base/gfx/bitmap_platform_device_linux.h85
-rwxr-xr-xbase/gfx/bitmap_platform_device_mac.cc289
-rwxr-xr-xbase/gfx/bitmap_platform_device_mac.h88
-rw-r--r--base/gfx/bitmap_platform_device_win.cc446
-rw-r--r--base/gfx/bitmap_platform_device_win.h104
-rw-r--r--base/gfx/platform_canvas.h31
-rw-r--r--base/gfx/platform_canvas_linux.cc55
-rw-r--r--base/gfx/platform_canvas_linux.h45
-rwxr-xr-xbase/gfx/platform_canvas_mac.cc80
-rwxr-xr-xbase/gfx/platform_canvas_mac.h80
-rw-r--r--base/gfx/platform_canvas_unittest.cc296
-rw-r--r--base/gfx/platform_canvas_win.cc122
-rw-r--r--base/gfx/platform_canvas_win.h189
-rw-r--r--base/gfx/platform_device.h26
-rw-r--r--base/gfx/platform_device_linux.cc18
-rw-r--r--base/gfx/platform_device_linux.h19
-rwxr-xr-xbase/gfx/platform_device_mac.cc161
-rwxr-xr-xbase/gfx/platform_device_mac.h79
-rw-r--r--base/gfx/platform_device_win.cc229
-rw-r--r--base/gfx/platform_device_win.h89
-rw-r--r--base/gfx/vector_canvas.cc90
-rw-r--r--base/gfx/vector_canvas_unittest.cc1008
-rw-r--r--base/gfx/vector_device.cc612
-rw-r--r--base/gfx/vector_device.h118
30 files changed, 39 insertions, 4488 deletions
diff --git a/base/base_unittests.scons b/base/base_unittests.scons
index 61f9140..b8aafbc 100644
--- a/base/base_unittests.scons
+++ b/base/base_unittests.scons
@@ -124,7 +124,6 @@ input_files = [
'gfx/native_theme_unittest.cc',
'gfx/png_codec_unittest.cc',
'gfx/rect_unittest.cc',
- 'gfx/vector_canvas_unittest.cc',
]
if env['PLATFORM'] in ('posix', 'darwin'):
@@ -139,7 +138,6 @@ if env['PLATFORM'] in ('posix', 'darwin'):
'watchdog_unittest.cc',
'gfx/native_theme_unittest.cc',
- 'gfx/vector_canvas_unittest.cc',
]
for remove in to_be_ported_files:
input_files.remove(remove)
diff --git a/base/build/base_gfx.vcproj b/base/build/base_gfx.vcproj
index 22dc8b4..8b2bc64 100644
--- a/base/build/base_gfx.vcproj
+++ b/base/build/base_gfx.vcproj
@@ -122,10 +122,6 @@
</References>
<Files>
<File
- RelativePath="..\gfx\bitmap_platform_device_win.cc"
- >
- </File>
- <File
RelativePath="..\gfx\bitmap_platform_device_win.h"
>
</File>
@@ -162,18 +158,10 @@
>
</File>
<File
- RelativePath="..\gfx\platform_canvas_win.cc"
- >
- </File>
- <File
RelativePath="..\gfx\platform_canvas_win.h"
>
</File>
<File
- RelativePath="..\gfx\platform_device_win.cc"
- >
- </File>
- <File
RelativePath="..\gfx\platform_device_win.h"
>
</File>
@@ -225,22 +213,6 @@
RelativePath="..\gfx\skia_utils.h"
>
</File>
- <File
- RelativePath="..\gfx\vector_canvas.cc"
- >
- </File>
- <File
- RelativePath="..\gfx\vector_canvas.h"
- >
- </File>
- <File
- RelativePath="..\gfx\vector_device.cc"
- >
- </File>
- <File
- RelativePath="..\gfx\vector_device.h"
- >
- </File>
</Files>
<Globals>
</Globals>
diff --git a/base/build/base_unittests.vcproj b/base/build/base_unittests.vcproj
index df3444b..3c75166 100644
--- a/base/build/base_unittests.vcproj
+++ b/base/build/base_unittests.vcproj
@@ -404,17 +404,9 @@
>
</File>
<File
- RelativePath="..\gfx\platform_canvas_unittest.cc"
- >
- </File>
- <File
RelativePath="..\gfx\png_codec_unittest.cc"
>
</File>
- <File
- RelativePath="..\gfx\vector_canvas_unittest.cc"
- >
- </File>
</Filter>
</Files>
<Globals>
diff --git a/base/gfx/base_gfx.scons b/base/gfx/base_gfx.scons
index 748f13b..0af67c6 100644
--- a/base/gfx/base_gfx.scons
+++ b/base/gfx/base_gfx.scons
@@ -42,8 +42,6 @@ input_files = [
'rect.cc',
'size.cc',
'skia_utils.cc',
- 'vector_canvas.cc',
- 'vector_device.cc',
]
if env['PLATFORM'] in ('posix', 'darwin'):
@@ -53,23 +51,15 @@ if env['PLATFORM'] in ('posix', 'darwin'):
'gdi_util.cc',
'native_theme.cc',
'skia_utils.cc',
- 'vector_canvas.cc',
- 'vector_device.cc',
]
for remove in to_be_ported_files:
input_files.remove(remove)
if env['PLATFORM'] == 'win32':
input_files.extend([
- 'bitmap_platform_device_win.cc',
- 'platform_canvas_win.cc',
- 'platform_device_win.cc',
])
elif env['PLATFORM'] == 'posix':
input_files.extend([
- 'bitmap_platform_device_linux.cc',
- 'platform_canvas_linux.cc',
- 'platform_device_linux.cc',
])
env.ChromeStaticLibrary('base_gfx', input_files)
diff --git a/base/gfx/bitmap_platform_device.h b/base/gfx/bitmap_platform_device.h
index 1efa65c..7c25eb2 100644
--- a/base/gfx/bitmap_platform_device.h
+++ b/base/gfx/bitmap_platform_device.h
@@ -2,26 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Declare a platform-neutral name for this platform's bitmap device class
-// that can be used by upper-level classes that just need to pass a reference
-// around.
-
-#if defined(OS_WIN)
-#include "base/gfx/bitmap_platform_device_win.h"
-#elif defined(OS_MACOSX)
-#include "base/gfx/bitmap_platform_device_mac.h"
-#elif defined(OS_LINUX)
-#include "base/gfx/bitmap_platform_device_linux.h"
-#endif
-
-namespace gfx {
-
-#if defined(OS_WIN)
-typedef BitmapPlatformDeviceWin BitmapPlatformDevice;
-#elif defined(OS_MACOSX)
-typedef BitmapPlatformDeviceMac BitmapPlatformDevice;
-#elif defined(OS_LINUX)
-typedef BitmapPlatformDeviceLinux BitmapPlatformDevice;
-#endif
-
-}
+// TODO(brettw) this file should be removed and the includes changed to this
+// new location.
+#include "webkit/port/platform/graphics/skia/public/BitmapPlatformDevice.h"
diff --git a/base/gfx/bitmap_platform_device_linux.cc b/base/gfx/bitmap_platform_device_linux.cc
deleted file mode 100644
index 18f8ab1..0000000
--- a/base/gfx/bitmap_platform_device_linux.cc
+++ /dev/null
@@ -1,94 +0,0 @@
-// 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 "base/gfx/bitmap_platform_device_linux.h"
-
-#include <cairo/cairo.h>
-
-#include "base/logging.h"
-
-namespace gfx {
-
-// -----------------------------------------------------------------------------
-// These objects are reference counted and own a Cairo surface. The surface is
-// the backing store for a Skia bitmap and we reference count it so that we can
-// copy BitmapPlatformDeviceLinux objects without having to copy all the image
-// data.
-// -----------------------------------------------------------------------------
-class BitmapPlatformDeviceLinux::BitmapPlatformDeviceLinuxData
- : public base::RefCounted<BitmapPlatformDeviceLinuxData> {
- public:
- explicit BitmapPlatformDeviceLinuxData(cairo_surface_t* surface)
- : surface_(surface) { }
-
- cairo_surface_t* surface() const { return surface_; }
-
- protected:
- cairo_surface_t *const surface_;
-
- friend class base::RefCounted<BitmapPlatformDeviceLinuxData>;
- ~BitmapPlatformDeviceLinuxData() {
- cairo_surface_destroy(surface_);
- }
-
- DISALLOW_EVIL_CONSTRUCTORS(BitmapPlatformDeviceLinuxData);
-};
-
-// We use this static factory function instead of the regular constructor so
-// that we can create the pixel data before calling the constructor. This is
-// required so that we can call the base class' constructor with the pixel
-// data.
-BitmapPlatformDeviceLinux* BitmapPlatformDeviceLinux::Create(
- int width, int height, bool is_opaque) {
- cairo_surface_t* surface =
- cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
- width, height);
-
- SkBitmap bitmap;
- bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height,
- cairo_image_surface_get_stride(surface));
- bitmap.setPixels(cairo_image_surface_get_data(surface));
- bitmap.setIsOpaque(is_opaque);
-
-#ifndef NDEBUG
- if (is_opaque) {
- bitmap.eraseARGB(255, 0, 255, 128); // bright bluish green
- }
-#endif
-
- // The device object will take ownership of the graphics context.
- return new BitmapPlatformDeviceLinux
- (bitmap, new BitmapPlatformDeviceLinuxData(surface));
-}
-
-// The device will own the bitmap, which corresponds to also owning the pixel
-// data. Therefore, we do not transfer ownership to the SkDevice's bitmap.
-BitmapPlatformDeviceLinux::BitmapPlatformDeviceLinux(
- const SkBitmap& bitmap,
- BitmapPlatformDeviceLinuxData* data)
- : PlatformDeviceLinux(bitmap),
- data_(data) {
-}
-
-BitmapPlatformDeviceLinux::BitmapPlatformDeviceLinux(
- const BitmapPlatformDeviceLinux& other)
- : PlatformDeviceLinux(const_cast<BitmapPlatformDeviceLinux&>(
- other).accessBitmap(true)),
- data_(other.data_) {
-}
-
-BitmapPlatformDeviceLinux::~BitmapPlatformDeviceLinux() {
-}
-
-cairo_surface_t* BitmapPlatformDeviceLinux::surface() const {
- return data_->surface();
-}
-
-BitmapPlatformDeviceLinux& BitmapPlatformDeviceLinux::operator=(
- const BitmapPlatformDeviceLinux& other) {
- data_ = other.data_;
- return *this;
-}
-
-} // namespace gfx
diff --git a/base/gfx/bitmap_platform_device_linux.h b/base/gfx/bitmap_platform_device_linux.h
index 629fd1d..3db11cb 100644
--- a/base/gfx/bitmap_platform_device_linux.h
+++ b/base/gfx/bitmap_platform_device_linux.h
@@ -5,87 +5,8 @@
#ifndef BASE_GFX_BITMAP_PLATFORM_DEVICE_LINUX_H_
#define BASE_GFX_BITMAP_PLATFORM_DEVICE_LINUX_H_
-#include "base/gfx/platform_device_linux.h"
-#include "base/ref_counted.h"
-
-typedef struct _cairo_surface cairo_surface_t;
-
-// -----------------------------------------------------------------------------
-// Image byte ordering on Linux:
-//
-// Pixels are packed into 32-bit words these days. Even for 24-bit images,
-// often 8-bits will be left unused for alignment reasons. Thus, when you see
-// ARGB as the byte order you have to wonder if that's in memory order or
-// little-endian order. Here I'll write A.R.G.B to specifiy the memory order.
-//
-// GdkPixbuf's provide a nice backing store and defaults to R.G.B.A order.
-// They'll do the needed byte swapping to match the X server when drawn.
-//
-// Skia can be controled in skia/include/corecg/SkUserConfig.h (see bits about
-// SK_R32_SHIFT). For Linux we define it to be ARGB in registers. For little
-// endian machines that means B.G.R.A in memory.
-//
-// The image loaders are controlled in
-// webkit/port/platform/image-decoders/ImageDecoder.h (see setRGBA). These are
-// also configured for ARGB in registers.
-//
-// Cairo's only 32-bit mode is ARGB in registers.
-//
-// X servers commonly have a 32-bit visual with xRGB in registers (since they
-// typically don't do alpha blending of drawables at the user level. Composite
-// extensions aside.)
-//
-// We don't use GdkPixbuf because its byte order differs from the rest. Most
-// importantly, it differs from Cairo which, being a system library, is
-// something that we can't easily change.
-// -----------------------------------------------------------------------------
-
-namespace gfx {
-
-// -----------------------------------------------------------------------------
-// This is the Linux bitmap backing for Skia. We create a Cairo image surface
-// to store the backing buffer. This buffer is BGRA in memory (on little-endian
-// machines).
-//
-// For now we are also using Cairo to paint to the Drawables so we provide an
-// accessor for getting the surface.
-//
-// This is all quite ok for test_shell. In the future we will want to use
-// shared memory between the renderer and the main process at least. In this
-// case we'll probably create the buffer from a precreated region of memory.
-// -----------------------------------------------------------------------------
-class BitmapPlatformDeviceLinux : public PlatformDeviceLinux {
- // A reference counted cairo surface
- class BitmapPlatformDeviceLinuxData;
-
- public:
- /// Static constructor. I don't understand this, it's just a copy of the mac
- static BitmapPlatformDeviceLinux* Create(int width, int height,
- bool is_opaque);
-
- // Create a BitmapPlatformDeviceLinux from an already constructed bitmap;
- // you should probably be using Create(). This may become private later if
- // we ever have to share state between some native drawing UI and Skia, like
- // the Windows and Mac versions of this class do.
- //
- // This object takes ownership of @data.
- BitmapPlatformDeviceLinux(const SkBitmap& other,
- BitmapPlatformDeviceLinuxData* data);
- virtual ~BitmapPlatformDeviceLinux();
- BitmapPlatformDeviceLinux& operator=(const BitmapPlatformDeviceLinux& other);
-
- // A stub copy constructor. Needs to be properly implemented.
- BitmapPlatformDeviceLinux(const BitmapPlatformDeviceLinux& other);
-
- // Bitmaps aren't vector graphics.
- virtual bool IsVectorial() { return false; }
-
- cairo_surface_t* surface() const;
-
- private:
- scoped_refptr<BitmapPlatformDeviceLinuxData> data_;
-};
-
-} // namespace gfx
+// TODO(brettw) this file should be removed and the includes changed to this
+// new location.
+#include "webkit/port/platform/graphics/skia/public/BitmapPlatformDeviceLinux.h"
#endif // BASE_GFX_BITMAP_PLATFORM_DEVICE_LINUX_H_
diff --git a/base/gfx/bitmap_platform_device_mac.cc b/base/gfx/bitmap_platform_device_mac.cc
deleted file mode 100755
index 570b07e..0000000
--- a/base/gfx/bitmap_platform_device_mac.cc
+++ /dev/null
@@ -1,289 +0,0 @@
-// 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 <time.h>
-
-#include "SkMatrix.h"
-#include "SkRegion.h"
-#include "SkUtils.h"
-
-#include "base/gfx/bitmap_platform_device_mac.h"
-#include "base/gfx/skia_utils_mac.h"
-#include "base/logging.h"
-
-namespace gfx {
-
-namespace {
-
-// Constrains position and size to fit within available_size. If |size| is -1,
-// all the |available_size| is used. Returns false if the position is out of
-// |available_size|.
-bool Constrain(int available_size, int* position, int *size) {
- if (*size < -2)
- return false;
-
- if (*position < 0) {
- if (*size != -1)
- *size += *position;
- *position = 0;
- }
- if (*size == 0 || *position >= available_size)
- return false;
-
- if (*size > 0) {
- int overflow = (*position + *size) - available_size;
- if (overflow > 0) {
- *size -= overflow;
- }
- } else {
- // Fill up available size.
- *size = available_size - *position;
- }
- return true;
-}
-
-} // namespace
-
-class BitmapPlatformDeviceMac::BitmapPlatformDeviceMacData
- : public base::RefCounted<BitmapPlatformDeviceMacData> {
- public:
- explicit BitmapPlatformDeviceMacData(CGContextRef bitmap);
-
- // Create/destroy CoreGraphics context for our bitmap data.
- CGContextRef GetBitmapContext() {
- LoadConfig();
- return bitmap_context_;
- }
-
- void ReleaseBitmapContext() {
- DCHECK(bitmap_context_);
- CGContextRelease(bitmap_context_);
- bitmap_context_ = NULL;
- }
-
- // Sets the transform and clip operations. This will not update the CGContext,
- // but will mark the config as dirty. The next call of LoadConfig will
- // pick up these changes.
- void SetMatrixClip(const SkMatrix& transform, const SkRegion& region);
-
- // Loads the current transform and clip into the DC. Can be called even when
- // |bitmap_context_| is NULL (will be a NOP).
- void LoadConfig();
-
- // Lazily-created graphics context used to draw into the bitmap.
- CGContextRef bitmap_context_;
-
- // True when there is a transform or clip that has not been set to the
- // CGContext. The CGContext is retrieved for every text operation, and the
- // transform and clip do not change as much. We can save time by not loading
- // the clip and transform for every one.
- bool config_dirty_;
-
- // Translation assigned to the CGContext: we need to keep track of this
- // separately so it can be updated even if the CGContext isn't created yet.
- SkMatrix transform_;
-
- // The current clipping
- SkRegion clip_region_;
-
- private:
- friend class base::RefCounted<BitmapPlatformDeviceMacData>;
- ~BitmapPlatformDeviceMacData() {
- if (bitmap_context_)
- CGContextRelease(bitmap_context_);
- }
-
- DISALLOW_COPY_AND_ASSIGN(BitmapPlatformDeviceMacData);
-};
-
-BitmapPlatformDeviceMac::\
- BitmapPlatformDeviceMacData::BitmapPlatformDeviceMacData(
- CGContextRef bitmap)
- : bitmap_context_(bitmap),
- config_dirty_(true) { // Want to load the config next time.
- DCHECK(bitmap_context_);
- // Initialize the clip region to the entire bitmap.
-
- SkIRect rect;
- rect.set(0, 0,
- CGBitmapContextGetWidth(bitmap_context_),
- CGBitmapContextGetHeight(bitmap_context_));
- clip_region_ = SkRegion(rect);
- transform_.reset();
- CGContextRetain(bitmap_context_);
-}
-
-void BitmapPlatformDeviceMac::BitmapPlatformDeviceMacData::SetMatrixClip(
- const SkMatrix& transform,
- const SkRegion& region) {
- transform_ = transform;
- clip_region_ = region;
- config_dirty_ = true;
-}
-
-void BitmapPlatformDeviceMac::BitmapPlatformDeviceMacData::LoadConfig() {
- if (!config_dirty_ || !bitmap_context_)
- return; // Nothing to do.
- config_dirty_ = false;
-
- // Transform.
- SkMatrix t(transform_);
- LoadTransformToCGContext(bitmap_context_, t);
- t.setTranslateX(-t.getTranslateX());
- t.setTranslateY(-t.getTranslateY());
- LoadClippingRegionToCGContext(bitmap_context_, clip_region_, t);
-}
-
-
-// We use this static factory function instead of the regular constructor so
-// that we can create the pixel data before calling the constructor. This is
-// required so that we can call the base class' constructor with the pixel
-// data.
-BitmapPlatformDeviceMac* BitmapPlatformDeviceMac::Create(CGContextRef context,
- int width,
- int height,
- bool is_opaque) {
- void* data = malloc(height * width * 4);
- if (!data) return NULL;
-
- SkBitmap bitmap;
- bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
- bitmap.setPixels(data);
-
- // Note: The Windows implementation clears the Bitmap later on.
- // This bears mentioning since removal of this line makes the
- // unit tests only fail periodically (or when MallocPreScribble is set).
- bitmap.eraseARGB(0, 0, 0, 0);
-
- bitmap.setIsOpaque(is_opaque);
-
- if (is_opaque) {
-#ifndef NDEBUG
- // To aid in finding bugs, we set the background color to something
- // obviously wrong so it will be noticable when it is not cleared
- bitmap.eraseARGB(255, 0, 255, 128); // bright bluish green
-#endif
- }
-
- CGColorSpaceRef color_space =
- CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
- // allocate a bitmap context with 4 components per pixel (RGBA):
- CGContextRef bitmap_context =
- CGBitmapContextCreate(data, width, height, 8, width*4,
- color_space, kCGImageAlphaPremultipliedLast);
-
- // Change the coordinate system to match WebCore's
- CGContextTranslateCTM(bitmap_context, 0, height);
- CGContextScaleCTM(bitmap_context, 1.0, -1.0);
- CGColorSpaceRelease(color_space);
-
- // The device object will take ownership of the graphics context.
- return new BitmapPlatformDeviceMac(
- new BitmapPlatformDeviceMacData(bitmap_context), bitmap);
-}
-
-// The device will own the bitmap, which corresponds to also owning the pixel
-// data. Therefore, we do not transfer ownership to the SkDevice's bitmap.
-BitmapPlatformDeviceMac::BitmapPlatformDeviceMac(
- BitmapPlatformDeviceMacData* data, const SkBitmap& bitmap)
- : PlatformDeviceMac(bitmap),
- data_(data) {
-}
-
-// The copy constructor just adds another reference to the underlying data.
-// We use a const cast since the default Skia definitions don't define the
-// proper constedness that we expect (accessBitmap should really be const).
-BitmapPlatformDeviceMac::BitmapPlatformDeviceMac(
- const BitmapPlatformDeviceMac& other)
- : PlatformDeviceMac(
- const_cast<BitmapPlatformDeviceMac&>(other).accessBitmap(true)),
- data_(other.data_) {
-}
-
-BitmapPlatformDeviceMac::~BitmapPlatformDeviceMac() {
-}
-
-BitmapPlatformDeviceMac& BitmapPlatformDeviceMac::operator=(
- const BitmapPlatformDeviceMac& other) {
- data_ = other.data_;
- return *this;
-}
-
-CGContextRef BitmapPlatformDeviceMac::GetBitmapContext() {
- return data_->GetBitmapContext();
-}
-
-void BitmapPlatformDeviceMac::setMatrixClip(const SkMatrix& transform,
- const SkRegion& region) {
- data_->SetMatrixClip(transform, region);
-}
-
-void BitmapPlatformDeviceMac::DrawToContext(CGContextRef context, int x, int y,
- const CGRect* src_rect) {
- bool created_dc = false;
- if (!data_->bitmap_context_) {
- created_dc = true;
- GetBitmapContext();
- }
-
- // this should not make a copy of the bits, since we're not doing
- // anything to trigger copy on write
- CGImageRef image = CGBitmapContextCreateImage(data_->bitmap_context_);
- CGRect bounds;
- if (src_rect) {
- bounds = *src_rect;
- bounds.origin.x = x;
- bounds.origin.y = y;
- CGImageRef sub_image = CGImageCreateWithImageInRect(image, *src_rect);
- CGContextDrawImage(context, bounds, sub_image);
- CGImageRelease(sub_image);
- } else {
- bounds.origin.x = 0;
- bounds.origin.y = 0;
- bounds.size.width = width();
- bounds.size.height = height();
- CGContextDrawImage(context, bounds, image);
- }
- CGImageRelease(image);
-
- if (created_dc)
- data_->ReleaseBitmapContext();
-}
-
-// Returns the color value at the specified location.
-SkColor BitmapPlatformDeviceMac::getColorAt(int x, int y) {
- const SkBitmap& bitmap = accessBitmap(true);
- SkAutoLockPixels lock(bitmap);
- uint32_t* data = bitmap.getAddr32(0, 0);
- return static_cast<SkColor>(data[x + y * width()]);
-}
-
-void BitmapPlatformDeviceMac::onAccessBitmap(SkBitmap*) {
- // Not needed in CoreGraphics
-}
-
-void BitmapPlatformDeviceMac::processPixels(int x, int y,
- int width, int height,
- adjustAlpha adjustor) {
- const SkBitmap& bitmap = accessBitmap(true);
- SkMatrix& matrix = data_->transform_;
- int bitmap_start_x = SkScalarRound(matrix.getTranslateX()) + x;
- int bitmap_start_y = SkScalarRound(matrix.getTranslateY()) + y;
-
- SkAutoLockPixels lock(bitmap);
- if (Constrain(bitmap.width(), &bitmap_start_x, &width) &&
- Constrain(bitmap.height(), &bitmap_start_y, &height)) {
- uint32_t* data = bitmap.getAddr32(0, 0);
- size_t row_words = bitmap.rowBytes() / 4;
- for (int i = 0; i < height; i++) {
- size_t offset = (i + bitmap_start_y) * row_words + bitmap_start_x;
- for (int j = 0; j < width; j++) {
- adjustor(data + offset + j);
- }
- }
- }
-}
-
-} // namespace gfx
-
diff --git a/base/gfx/bitmap_platform_device_mac.h b/base/gfx/bitmap_platform_device_mac.h
index a008444..ff89741 100755
--- a/base/gfx/bitmap_platform_device_mac.h
+++ b/base/gfx/bitmap_platform_device_mac.h
@@ -5,91 +5,9 @@
#ifndef BASE_GFX_BITMAP_PLATFORM_DEVICE_MAC_H__
#define BASE_GFX_BITMAP_PLATFORM_DEVICE_MAC_H__
-#include "base/gfx/platform_device_mac.h"
-#include "base/ref_counted.h"
-
-namespace gfx {
-
-// A device is basically a wrapper around SkBitmap that provides a surface for
-// SkCanvas to draw into. Our device provides a surface CoreGraphics can also
-// write to. BitmapPlatformDeviceMac creates a bitmap using
-// CGCreateBitmapContext() in a format that Skia supports and can then use this
-// to draw text into, etc. This pixel data is provided to the bitmap that the
-// device contains so that it can be shared.
-//
-// The device owns the pixel data, when the device goes away, the pixel data
-// also becomes invalid. THIS IS DIFFERENT THAN NORMAL SKIA which uses
-// reference counting for the pixel data. In normal Skia, you could assign
-// another bitmap to this device's bitmap and everything will work properly.
-// For us, that other bitmap will become invalid as soon as the device becomes
-// invalid, which may lead to subtle bugs. Therefore, DO NOT ASSIGN THE
-// DEVICE'S PIXEL DATA TO ANOTHER BITMAP, make sure you copy instead.
-class BitmapPlatformDeviceMac : public PlatformDeviceMac {
- public:
- // Factory function. The screen DC is used to create the bitmap, and will not
- // be stored beyond this function. is_opaque should be set if the caller
- // knows the bitmap will be completely opaque and allows some optimizations.
- //
- // The shared_section parameter is optional (pass NULL for default behavior).
- // If shared_section is non-null, then it must be a handle to a file-mapping
- // object returned by CreateFileMapping. See CreateDIBSection for details.
- static BitmapPlatformDeviceMac* Create(CGContextRef context,
- int width,
- int height,
- bool is_opaque);
-
- // Copy constructor. When copied, devices duplicate their internal data, so
- // stay linked. This is because their implementation is very heavyweight
- // (lots of memory and CoreGraphics state). If a device has been copied, both
- // clip rects and other state will stay in sync.
- //
- // This means it will NOT work to duplicate a device and assign it to a
- // canvas, because the two canvases will each set their own clip rects, and
- // the resulting CoreGraphics drawing state will be unpredictable.
- //
- // Copy constucting and "=" is designed for saving the device or passing it
- // around to another routine willing to deal with the bitmap data directly.
- BitmapPlatformDeviceMac(const BitmapPlatformDeviceMac& other);
- virtual ~BitmapPlatformDeviceMac();
-
- // See warning for copy constructor above.
- BitmapPlatformDeviceMac& operator=(const BitmapPlatformDeviceMac& other);
-
- virtual CGContextRef GetBitmapContext();
- virtual void setMatrixClip(const SkMatrix& transform, const SkRegion& region);
-
- virtual void DrawToContext(CGContextRef context, int x, int y,
- const CGRect* src_rect);
- virtual bool IsVectorial() { return false; }
- virtual void fixupAlphaBeforeCompositing() { };
-
- // Returns the color value at the specified location. This does not
- // consider any transforms that may be set on the device.
- SkColor getColorAt(int x, int y);
-
- protected:
- // Reference counted data that can be shared between multiple devices. This
- // allows copy constructors and operator= for devices to work properly. The
- // bitmaps used by the base device class are already refcounted and copyable.
- class BitmapPlatformDeviceMacData;
-
- BitmapPlatformDeviceMac(BitmapPlatformDeviceMacData* data,
- const SkBitmap& bitmap);
-
- // Flushes the CoreGraphics context so that the pixel data can be accessed
- // directly by Skia. Overridden from SkDevice, this is called when Skia
- // starts accessing pixel data.
- virtual void onAccessBitmap(SkBitmap*);
-
- // Data associated with this device, guaranteed non-null.
- scoped_refptr<BitmapPlatformDeviceMacData> data_;
-
- virtual void processPixels(int x, int y,
- int width, int height,
- adjustAlpha adjustor);
-};
-
-} // namespace gfx
+// TODO(brettw) this file should be removed and the includes changed to this
+// new location.
+#include "webkit/port/platform/graphics/skia/public/BitmapPlatformDeviceMac.h"
#endif // BASE_GFX_BITMAP_PLATFORM_DEVICE_MAC_H__
diff --git a/base/gfx/bitmap_platform_device_win.cc b/base/gfx/bitmap_platform_device_win.cc
deleted file mode 100644
index 85597ae..0000000
--- a/base/gfx/bitmap_platform_device_win.cc
+++ /dev/null
@@ -1,446 +0,0 @@
-// 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 "base/gfx/bitmap_platform_device_win.h"
-
-#include "base/gfx/gdi_util.h"
-#include "base/logging.h"
-#include "SkMatrix.h"
-#include "SkRegion.h"
-#include "SkUtils.h"
-
-namespace gfx {
-
-// When Windows draws text, is sets the fourth byte (which Skia uses for alpha)
-// to zero. This means that if we try compositing with text that Windows has
-// drawn, we get invalid color values (if the alpha is 0, the other channels
-// should be 0 since Skia uses premultiplied colors) and strange results.
-//
-// HTML rendering only requires one bit of transparency. When you ask for a
-// semitransparent div, the div itself is drawn in another layer as completely
-// opaque, and then composited onto the lower layer with a transfer function.
-// The only place an alpha channel is needed is to track what has been drawn
-// and what has not been drawn.
-//
-// Therefore, when we allocate a new device, we fill it with this special
-// color. Because Skia uses premultiplied colors, any color where the alpha
-// channel is smaller than any component is impossible, so we know that no
-// legitimate drawing will produce this color. We use 1 as the alpha value
-// because 0 is produced when Windows draws text (even though it should be
-// opaque).
-//
-// When a layer is done and we want to render it to a lower layer, we use
-// fixupAlphaBeforeCompositing. This replaces all 0 alpha channels with
-// opaque (to fix the text problem), and replaces this magic color value
-// with transparency. The result is something that can be correctly
-// composited. However, once this has been done, no more can be drawn to
-// the layer because fixing the alphas *again* will result in incorrect
-// values.
-static const uint32_t kMagicTransparencyColor = 0x01FFFEFD;
-
-namespace {
-
-// Constrains position and size to fit within available_size. If |size| is -1,
-// all the available_size is used. Returns false if the position is out of
-// available_size.
-bool Constrain(int available_size, int* position, int *size) {
- if (*size < -2)
- return false;
-
- if (*position < 0) {
- if (*size != -1)
- *size += *position;
- *position = 0;
- }
- if (*size == 0 || *position >= available_size)
- return false;
-
- if (*size > 0) {
- int overflow = (*position + *size) - available_size;
- if (overflow > 0) {
- *size -= overflow;
- }
- } else {
- // Fill up available size.
- *size = available_size - *position;
- }
- return true;
-}
-
-// If the pixel value is 0, it gets set to kMagicTransparencyColor.
-void PrepareAlphaForGDI(uint32_t* pixel) {
- if (*pixel == 0) {
- *pixel = kMagicTransparencyColor;
- }
-}
-
-// If the pixel value is kMagicTransparencyColor, it gets set to 0. Otherwise
-// if the alpha is 0, the alpha is set to 255.
-void PostProcessAlphaForGDI(uint32_t* pixel) {
- if (*pixel == kMagicTransparencyColor) {
- *pixel = 0;
- } else if ((*pixel & 0xFF000000) == 0) {
- *pixel |= 0xFF000000;
- }
-}
-
-// Sets the opacity of the specified value to 0xFF.
-void MakeOpaqueAlphaAdjuster(uint32_t* pixel) {
- *pixel |= 0xFF000000;
-}
-
-// See the declaration of kMagicTransparencyColor at the top of the file.
-void FixupAlphaBeforeCompositing(uint32_t* pixel) {
- if (*pixel == kMagicTransparencyColor)
- *pixel = 0;
- else
- *pixel |= 0xFF000000;
-}
-
-} // namespace
-
-class BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData
- : public base::RefCounted<BitmapPlatformDeviceWinData> {
- public:
- explicit BitmapPlatformDeviceWinData(HBITMAP hbitmap);
-
- // Create/destroy hdc_, which is the memory DC for our bitmap data.
- HDC GetBitmapDC();
- void ReleaseBitmapDC();
- bool IsBitmapDCCreated() const;
-
- // Sets the transform and clip operations. This will not update the DC,
- // but will mark the config as dirty. The next call of LoadConfig will
- // pick up these changes.
- void SetMatrixClip(const SkMatrix& transform, const SkRegion& region);
-
- const SkMatrix& transform() const {
- return transform_;
- }
-
- protected:
- // Loads the current transform and clip into the DC. Can be called even when
- // the DC is NULL (will be a NOP).
- void LoadConfig();
-
- // Windows bitmap corresponding to our surface.
- HBITMAP hbitmap_;
-
- // Lazily-created DC used to draw into the bitmap, see getBitmapDC.
- HDC hdc_;
-
- // True when there is a transform or clip that has not been set to the DC.
- // The DC is retrieved for every text operation, and the transform and clip
- // do not change as much. We can save time by not loading the clip and
- // transform for every one.
- bool config_dirty_;
-
- // Translation assigned to the DC: we need to keep track of this separately
- // so it can be updated even if the DC isn't created yet.
- SkMatrix transform_;
-
- // The current clipping
- SkRegion clip_region_;
-
- private:
- friend class base::RefCounted<BitmapPlatformDeviceWinData>;
- ~BitmapPlatformDeviceWinData();
-
- DISALLOW_EVIL_CONSTRUCTORS(BitmapPlatformDeviceWinData);
-};
-
-BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData::BitmapPlatformDeviceWinData(
- HBITMAP hbitmap)
- : hbitmap_(hbitmap),
- hdc_(NULL),
- config_dirty_(true) { // Want to load the config next time.
- // Initialize the clip region to the entire bitmap.
- BITMAP bitmap_data;
- if (GetObject(hbitmap_, sizeof(BITMAP), &bitmap_data)) {
- SkIRect rect;
- rect.set(0, 0, bitmap_data.bmWidth, bitmap_data.bmHeight);
- clip_region_ = SkRegion(rect);
- }
-
- transform_.reset();
-}
-
-BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData::~BitmapPlatformDeviceWinData() {
- if (hdc_)
- ReleaseBitmapDC();
-
- // this will free the bitmap data as well as the bitmap handle
- DeleteObject(hbitmap_);
-}
-
-HDC BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData::GetBitmapDC() {
- if (!hdc_) {
- hdc_ = CreateCompatibleDC(NULL);
- InitializeDC(hdc_);
- HGDIOBJ old_bitmap = SelectObject(hdc_, hbitmap_);
- // When the memory DC is created, its display surface is exactly one
- // monochrome pixel wide and one monochrome pixel high. Since we select our
- // own bitmap, we must delete the previous one.
- DeleteObject(old_bitmap);
- }
-
- LoadConfig();
- return hdc_;
-}
-
-void BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData::ReleaseBitmapDC() {
- DCHECK(hdc_);
- DeleteDC(hdc_);
- hdc_ = NULL;
-}
-
-bool BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData::IsBitmapDCCreated()
- const {
- return hdc_ != NULL;
-}
-
-
-void BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData::SetMatrixClip(
- const SkMatrix& transform,
- const SkRegion& region) {
- transform_ = transform;
- clip_region_ = region;
- config_dirty_ = true;
-}
-
-void BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData::LoadConfig() {
- if (!config_dirty_ || !hdc_)
- return; // Nothing to do.
- config_dirty_ = false;
-
- // Transform.
- SkMatrix t(transform_);
- LoadTransformToDC(hdc_, t);
- // We don't use transform_ for the clipping region since the translation is
- // already applied to offset_x_ and offset_y_.
- t.reset();
- LoadClippingRegionToDC(hdc_, clip_region_, t);
-}
-
-// We use this static factory function instead of the regular constructor so
-// that we can create the pixel data before calling the constructor. This is
-// required so that we can call the base class' constructor with the pixel
-// data.
-BitmapPlatformDeviceWin* BitmapPlatformDeviceWin::create(HDC screen_dc,
- int width,
- int height,
- bool is_opaque,
- HANDLE shared_section) {
- SkBitmap bitmap;
-
- // CreateDIBSection appears to get unhappy if we create an empty bitmap, so
- // just create a minimal bitmap
- if ((width == 0) || (height == 0)) {
- width = 1;
- height = 1;
- }
-
- BITMAPINFOHEADER hdr = {0};
- CreateBitmapHeader(width, height, &hdr);
-
- void* data = NULL;
- HBITMAP hbitmap = CreateDIBSection(screen_dc,
- reinterpret_cast<BITMAPINFO*>(&hdr), 0,
- &data,
- shared_section, 0);
-
- // If we run out of GDI objects or some other error occurs, we won't get a
- // bitmap here. This will cause us to crash later because the data pointer is
- // NULL. To make sure that we can assign blame for those crashes to this code,
- // we deliberately crash here, even in release mode.
- if (!hbitmap) {
- DWORD error = GetLastError();
- LOG(ERROR) << "CreateDIBSection Failed. Error: " << error << "\n";
- return NULL;
- }
-
- bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
- bitmap.setPixels(data);
- bitmap.setIsOpaque(is_opaque);
-
- if (is_opaque) {
-#ifndef NDEBUG
- // To aid in finding bugs, we set the background color to something
- // obviously wrong so it will be noticable when it is not cleared
- bitmap.eraseARGB(255, 0, 255, 128); // bright bluish green
-#endif
- } else {
- // A transparent layer is requested: fill with our magic "transparent"
- // color, see the declaration of kMagicTransparencyColor above
- sk_memset32(static_cast<uint32_t*>(data), kMagicTransparencyColor,
- width * height);
- }
-
- // The device object will take ownership of the HBITMAP.
- return new BitmapPlatformDeviceWin(new BitmapPlatformDeviceWinData(hbitmap),
- bitmap);
-}
-
-// The device will own the HBITMAP, which corresponds to also owning the pixel
-// data. Therefore, we do not transfer ownership to the SkDevice's bitmap.
-BitmapPlatformDeviceWin::BitmapPlatformDeviceWin(
- BitmapPlatformDeviceWinData* data,
- const SkBitmap& bitmap) : PlatformDeviceWin(bitmap), data_(data) {
-}
-
-// The copy constructor just adds another reference to the underlying data.
-// We use a const cast since the default Skia definitions don't define the
-// proper constedness that we expect (accessBitmap should really be const).
-BitmapPlatformDeviceWin::BitmapPlatformDeviceWin(
- const BitmapPlatformDeviceWin& other)
- : PlatformDeviceWin(
- const_cast<BitmapPlatformDeviceWin&>(other).accessBitmap(true)),
- data_(other.data_) {
-}
-
-BitmapPlatformDeviceWin::~BitmapPlatformDeviceWin() {
-}
-
-BitmapPlatformDeviceWin& BitmapPlatformDeviceWin::operator=(
- const BitmapPlatformDeviceWin& other) {
- data_ = other.data_;
- return *this;
-}
-
-HDC BitmapPlatformDeviceWin::getBitmapDC() {
- return data_->GetBitmapDC();
-}
-
-void BitmapPlatformDeviceWin::setMatrixClip(const SkMatrix& transform,
- const SkRegion& region) {
- data_->SetMatrixClip(transform, region);
-}
-
-void BitmapPlatformDeviceWin::drawToHDC(HDC dc, int x, int y,
- const RECT* src_rect) {
- bool created_dc = !data_->IsBitmapDCCreated();
- HDC source_dc = getBitmapDC();
-
- RECT temp_rect;
- if (!src_rect) {
- temp_rect.left = 0;
- temp_rect.right = width();
- temp_rect.top = 0;
- temp_rect.bottom = height();
- src_rect = &temp_rect;
- }
-
- int copy_width = src_rect->right - src_rect->left;
- int copy_height = src_rect->bottom - src_rect->top;
-
- // We need to reset the translation for our bitmap or (0,0) won't be in the
- // upper left anymore
- SkMatrix identity;
- identity.reset();
-
- LoadTransformToDC(source_dc, identity);
- if (isOpaque()) {
- BitBlt(dc,
- x,
- y,
- copy_width,
- copy_height,
- source_dc,
- src_rect->left,
- src_rect->top,
- SRCCOPY);
- } else {
- DCHECK(copy_width != 0 && copy_height != 0);
- BLENDFUNCTION blend_function = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
- GdiAlphaBlend(dc,
- x,
- y,
- copy_width,
- copy_height,
- source_dc,
- src_rect->left,
- src_rect->top,
- copy_width,
- copy_height,
- blend_function);
- }
- LoadTransformToDC(source_dc, data_->transform());
-
- if (created_dc)
- data_->ReleaseBitmapDC();
-}
-
-void BitmapPlatformDeviceWin::prepareForGDI(int x, int y, int width,
- int height) {
- processPixels<PrepareAlphaForGDI>(x, y, width, height);
-}
-
-void BitmapPlatformDeviceWin::postProcessGDI(int x, int y, int width,
- int height) {
- processPixels<PostProcessAlphaForGDI>(x, y, width, height);
-}
-
-void BitmapPlatformDeviceWin::makeOpaque(int x, int y, int width, int height) {
- processPixels<MakeOpaqueAlphaAdjuster>(x, y, width, height);
-}
-
-void BitmapPlatformDeviceWin::fixupAlphaBeforeCompositing() {
- const SkBitmap& bitmap = accessBitmap(true);
- SkAutoLockPixels lock(bitmap);
- uint32_t* data = bitmap.getAddr32(0, 0);
-
- size_t words = bitmap.rowBytes() / sizeof(uint32_t) * bitmap.height();
- for (size_t i = 0; i < words; i++) {
- if (data[i] == kMagicTransparencyColor)
- data[i] = 0;
- else
- data[i] |= 0xFF000000;
- }
-}
-
-// Returns the color value at the specified location.
-SkColor BitmapPlatformDeviceWin::getColorAt(int x, int y) {
- const SkBitmap& bitmap = accessBitmap(false);
- SkAutoLockPixels lock(bitmap);
- uint32_t* data = bitmap.getAddr32(0, 0);
- return static_cast<SkColor>(data[x + y * width()]);
-}
-
-void BitmapPlatformDeviceWin::onAccessBitmap(SkBitmap* bitmap) {
- // FIXME(brettw) OPTIMIZATION: We should only flush if we know a GDI
- // operation has occurred on our DC.
- if (data_->IsBitmapDCCreated())
- GdiFlush();
-}
-
-template<BitmapPlatformDeviceWin::adjustAlpha adjustor>
-void BitmapPlatformDeviceWin::processPixels(int x,
- int y,
- int width,
- int height) {
- const SkBitmap& bitmap = accessBitmap(true);
- DCHECK_EQ(bitmap.config(), SkBitmap::kARGB_8888_Config);
- const SkMatrix& matrix = data_->transform();
- int bitmap_start_x = SkScalarRound(matrix.getTranslateX()) + x;
- int bitmap_start_y = SkScalarRound(matrix.getTranslateY()) + y;
-
- if (Constrain(bitmap.width(), &bitmap_start_x, &width) &&
- Constrain(bitmap.height(), &bitmap_start_y, &height)) {
- SkAutoLockPixels lock(bitmap);
- DCHECK_EQ(bitmap.rowBytes() % sizeof(uint32_t), 0u);
- size_t row_words = bitmap.rowBytes() / sizeof(uint32_t);
- // Set data to the first pixel to be modified.
- uint32_t* data = bitmap.getAddr32(0, 0) + (bitmap_start_y * row_words) +
- bitmap_start_x;
- for (int i = 0; i < height; i++) {
- for (int j = 0; j < width; j++) {
- adjustor(data + j);
- }
- data += row_words;
- }
- }
-}
-
-} // namespace gfx
-
diff --git a/base/gfx/bitmap_platform_device_win.h b/base/gfx/bitmap_platform_device_win.h
index fef7217..566e302 100644
--- a/base/gfx/bitmap_platform_device_win.h
+++ b/base/gfx/bitmap_platform_device_win.h
@@ -5,107 +5,9 @@
#ifndef BASE_GFX_BITMAP_PLATFORM_DEVICE_WIN_H_
#define BASE_GFX_BITMAP_PLATFORM_DEVICE_WIN_H_
-#include "base/gfx/platform_device_win.h"
-#include "base/ref_counted.h"
-
-namespace gfx {
-
-// A device is basically a wrapper around SkBitmap that provides a surface for
-// SkCanvas to draw into. Our device provides a surface Windows can also write
-// to. BitmapPlatformDeviceWin creates a bitmap using CreateDIBSection() in a
-// format that Skia supports and can then use this to draw ClearType into, etc.
-// This pixel data is provided to the bitmap that the device contains so that it
-// can be shared.
-//
-// The device owns the pixel data, when the device goes away, the pixel data
-// also becomes invalid. THIS IS DIFFERENT THAN NORMAL SKIA which uses
-// reference counting for the pixel data. In normal Skia, you could assign
-// another bitmap to this device's bitmap and everything will work properly.
-// For us, that other bitmap will become invalid as soon as the device becomes
-// invalid, which may lead to subtle bugs. Therefore, DO NOT ASSIGN THE
-// DEVICE'S PIXEL DATA TO ANOTHER BITMAP, make sure you copy instead.
-class BitmapPlatformDeviceWin : public PlatformDeviceWin {
- public:
- // Factory function. The screen DC is used to create the bitmap, and will not
- // be stored beyond this function. is_opaque should be set if the caller
- // knows the bitmap will be completely opaque and allows some optimizations.
- //
- // The shared_section parameter is optional (pass NULL for default behavior).
- // If shared_section is non-null, then it must be a handle to a file-mapping
- // object returned by CreateFileMapping. See CreateDIBSection for details.
- static BitmapPlatformDeviceWin* create(HDC screen_dc,
- int width,
- int height,
- bool is_opaque,
- HANDLE shared_section);
-
- // Copy constructor. When copied, devices duplicate their internal data, so
- // stay linked. This is because their implementation is very heavyweight
- // (lots of memory and some GDI objects). If a device has been copied, both
- // clip rects and other state will stay in sync.
- //
- // This means it will NOT work to duplicate a device and assign it to a
- // canvas, because the two canvases will each set their own clip rects, and
- // the resulting GDI clip rect will be random.
- //
- // Copy constucting and "=" is designed for saving the device or passing it
- // around to another routine willing to deal with the bitmap data directly.
- BitmapPlatformDeviceWin(const BitmapPlatformDeviceWin& other);
- virtual ~BitmapPlatformDeviceWin();
-
- // See warning for copy constructor above.
- BitmapPlatformDeviceWin& operator=(const BitmapPlatformDeviceWin& other);
-
- // Retrieves the bitmap DC, which is the memory DC for our bitmap data. The
- // bitmap DC is lazy created.
- virtual HDC getBitmapDC();
- virtual void setMatrixClip(const SkMatrix& transform, const SkRegion& region);
-
- virtual void drawToHDC(HDC dc, int x, int y, const RECT* src_rect);
- virtual void prepareForGDI(int x, int y, int width, int height);
- virtual void postProcessGDI(int x, int y, int width, int height);
- virtual void makeOpaque(int x, int y, int width, int height);
- virtual void fixupAlphaBeforeCompositing();
- virtual bool IsVectorial() { return false; }
-
- // Returns the color value at the specified location. This does not
- // consider any transforms that may be set on the device.
- SkColor getColorAt(int x, int y);
-
- protected:
- // Flushes the Windows device context so that the pixel data can be accessed
- // directly by Skia. Overridden from SkDevice, this is called when Skia
- // starts accessing pixel data.
- virtual void onAccessBitmap(SkBitmap* bitmap);
-
- private:
- // Function pointer used by the processPixels method for setting the alpha
- // value of a particular pixel.
- typedef void (*adjustAlpha)(uint32_t* pixel);
-
- // Reference counted data that can be shared between multiple devices. This
- // allows copy constructors and operator= for devices to work properly. The
- // bitmaps used by the base device class are already refcounted and copyable.
- class BitmapPlatformDeviceWinData;
-
- // Private constructor.
- BitmapPlatformDeviceWin(BitmapPlatformDeviceWinData* data,
- const SkBitmap& bitmap);
-
- // Loops through each of the pixels in the specified range, invoking
- // adjustor for the alpha value of each pixel. If |width| or |height| are -1,
- // the available width/height is used.
- template<adjustAlpha adjustor>
- void processPixels(int x,
- int y,
- int width,
- int height);
-
- // Data associated with this device, guaranteed non-null.
- scoped_refptr<BitmapPlatformDeviceWinData> data_;
-};
-
-} // namespace gfx
+// TODO(brettw) this file should be removed and the includes changed to this
+// new location.
+#include "webkit/port/platform/graphics/skia/public/BitmapPlatformDeviceWin.h"
#endif // BASE_GFX_BITMAP_PLATFORM_DEVICE_WIN_H_
diff --git a/base/gfx/platform_canvas.h b/base/gfx/platform_canvas.h
index d7442cc..5bf0ec1 100644
--- a/base/gfx/platform_canvas.h
+++ b/base/gfx/platform_canvas.h
@@ -2,31 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Declare a platform-neutral name for this platform's canvas class
-// that can be used by upper-level classes that just need to pass a reference
-// around.
-
-#include "build/build_config.h"
-
-#if defined(OS_WIN)
-#include "base/gfx/platform_canvas_win.h"
-namespace gfx {
-
-typedef PlatformCanvasWin PlatformCanvas;
-
-} // namespace gfx
-#elif defined(OS_MACOSX)
-#include "base/gfx/platform_canvas_mac.h"
-namespace gfx {
-
-typedef PlatformCanvasMac PlatformCanvas;
-
-} // namespace gfx
-#elif defined(OS_LINUX)
-#include "base/gfx/platform_canvas_linux.h"
-namespace gfx {
-
-typedef PlatformCanvasLinux PlatformCanvas;
-
-} // namespace gfx
-#endif
+// TODO(brettw) this file should be removed and the includes changed to this
+// new location.
+#include "webkit/port/platform/graphics/skia/public/PlatformCanvas.h"
diff --git a/base/gfx/platform_canvas_linux.cc b/base/gfx/platform_canvas_linux.cc
deleted file mode 100644
index b579536..0000000
--- a/base/gfx/platform_canvas_linux.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-// 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 "base/gfx/platform_canvas_linux.h"
-
-#include "base/gfx/platform_device_linux.h"
-#include "base/gfx/bitmap_platform_device_linux.h"
-#include "base/logging.h"
-
-namespace gfx {
-
-PlatformCanvasLinux::PlatformCanvasLinux() : SkCanvas() {
-}
-
-PlatformCanvasLinux::PlatformCanvasLinux(int width, int height, bool is_opaque)
- : SkCanvas() {
- if (!initialize(width, height, is_opaque))
- CHECK(false);
-}
-
-PlatformCanvasLinux::~PlatformCanvasLinux() {
-}
-
-bool PlatformCanvasLinux::initialize(int width, int height, bool is_opaque) {
- SkDevice* device = createPlatformDevice(width, height, is_opaque);
- if (!device)
- return false;
-
- setDevice(device);
- device->unref(); // was created with refcount 1, and setDevice also refs
- return true;
-}
-
-PlatformDeviceLinux& PlatformCanvasLinux::getTopPlatformDevice() const {
- // All of our devices should be our special PlatformDevice.
- SkCanvas::LayerIter iter(const_cast<PlatformCanvasLinux*>(this), false);
- return *static_cast<PlatformDeviceLinux*>(iter.device());
-}
-
-SkDevice* PlatformCanvasLinux::createDevice(SkBitmap::Config config,
- int width,
- int height,
- bool is_opaque, bool isForLayer) {
- DCHECK(config == SkBitmap::kARGB_8888_Config);
- return createPlatformDevice(width, height, is_opaque);
-}
-
-SkDevice* PlatformCanvasLinux::createPlatformDevice(int width,
- int height,
- bool is_opaque) {
- return BitmapPlatformDeviceLinux::Create(width, height, is_opaque);
-}
-
-} // namespace gfx
diff --git a/base/gfx/platform_canvas_linux.h b/base/gfx/platform_canvas_linux.h
index 804c6b6..dbd9fc2 100644
--- a/base/gfx/platform_canvas_linux.h
+++ b/base/gfx/platform_canvas_linux.h
@@ -5,47 +5,8 @@
#ifndef BASE_GFX_PLATFORM_CANVAS_LINUX_H_
#define BASE_GFX_PLATFORM_CANVAS_LINUX_H_
-#include "base/gfx/platform_device_linux.h"
-#include "base/basictypes.h"
-
-namespace gfx {
-
-// This class is a specialization of the regular SkCanvas that is designed to
-// work with a gfx::PlatformDevice to manage platform-specific drawing. It
-// allows using both Skia operations and platform-specific operations.
-class PlatformCanvasLinux : public SkCanvas {
- public:
- // Set is_opaque if you are going to erase the bitmap and not use
- // tranparency: this will enable some optimizations. The shared_section
- // parameter is passed to gfx::PlatformDevice::create. See it for details.
- //
- // If you use the version with no arguments, you MUST call initialize()
- PlatformCanvasLinux();
- PlatformCanvasLinux(int width, int height, bool is_opaque);
- virtual ~PlatformCanvasLinux();
-
- // For two-part init, call if you use the no-argument constructor above
- bool initialize(int width, int height, bool is_opaque);
-
- // Returns the platform device pointer of the topmost rect with a non-empty
- // clip. Both the windows and mac versions have an equivalent of this method;
- // a Linux version is added for compatibility.
- PlatformDeviceLinux& getTopPlatformDevice() const;
-
- protected:
- // Creates a device store for use by the canvas. We override this so that
- // the device is always our own so we know that we can use GDI operations
- // on it. Simply calls into createPlatformDevice().
- virtual SkDevice* createDevice(SkBitmap::Config, int width, int height,
- bool is_opaque, bool isForLayer);
-
- // Creates a device store for use by the canvas. By default, it creates a
- // BitmapPlatformDevice object. Can be overridden to change the object type.
- virtual SkDevice* createPlatformDevice(int width, int height, bool is_opaque);
-
- DISALLOW_COPY_AND_ASSIGN(PlatformCanvasLinux);
-};
-
-} // namespace gfx
+// TODO(brettw) this file should be removed and the includes changed to this
+// new location.
+#include "webkit/port/platform/graphics/skia/public/PlatformCanvasLinux.h"
#endif // BASE_GFX_PLATFORM_CANVAS_MAC_H_
diff --git a/base/gfx/platform_canvas_mac.cc b/base/gfx/platform_canvas_mac.cc
deleted file mode 100755
index 2777dee..0000000
--- a/base/gfx/platform_canvas_mac.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-// 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 "base/gfx/platform_canvas_mac.h"
-
-#include "base/gfx/bitmap_platform_device_mac.h"
-#include "base/logging.h"
-
-namespace gfx {
-
-PlatformCanvasMac::PlatformCanvasMac() : SkCanvas() {
-}
-
-PlatformCanvasMac::PlatformCanvasMac(int width, int height, bool is_opaque)
- : SkCanvas() {
- initialize(width, height, is_opaque);
-}
-
-PlatformCanvasMac::PlatformCanvasMac(int width,
- int height,
- bool is_opaque,
- CGContextRef context)
- : SkCanvas() {
- initialize(width, height, is_opaque);
-}
-
-PlatformCanvasMac::~PlatformCanvasMac() {
-}
-
-bool PlatformCanvasMac::initialize(int width,
- int height,
- bool is_opaque) {
- SkDevice* device = createPlatformDevice(width, height, is_opaque, NULL);
- if (!device)
- return false;
-
- setDevice(device);
- device->unref(); // was created with refcount 1, and setDevice also refs
- return true;
-}
-
-CGContextRef PlatformCanvasMac::beginPlatformPaint() {
- return getTopPlatformDevice().GetBitmapContext();
-}
-
-void PlatformCanvasMac::endPlatformPaint() {
- // flushing will be done in onAccessBitmap
-}
-
-PlatformDeviceMac& PlatformCanvasMac::getTopPlatformDevice() const {
- // All of our devices should be our special PlatformDeviceMac.
- SkCanvas::LayerIter iter(const_cast<PlatformCanvasMac*>(this), false);
- return *static_cast<PlatformDeviceMac*>(iter.device());
-}
-
-SkDevice* PlatformCanvasMac::createDevice(SkBitmap::Config config,
- int width,
- int height,
- bool is_opaque, bool isForLayer) {
- DCHECK(config == SkBitmap::kARGB_8888_Config);
- return createPlatformDevice(width, height, is_opaque, NULL);
-}
-
-SkDevice* PlatformCanvasMac::createPlatformDevice(int width,
- int height,
- bool is_opaque,
- CGContextRef context) {
- SkDevice* device = BitmapPlatformDeviceMac::Create(context, width, height,
- is_opaque);
- return device;
-}
-
-SkDevice* PlatformCanvasMac::setBitmapDevice(const SkBitmap&) {
- NOTREACHED();
- return NULL;
-}
-
-} // namespace gfx
-
diff --git a/base/gfx/platform_canvas_mac.h b/base/gfx/platform_canvas_mac.h
index 3f79fb3..6ee78e8 100755
--- a/base/gfx/platform_canvas_mac.h
+++ b/base/gfx/platform_canvas_mac.h
@@ -5,83 +5,9 @@
#ifndef BASE_GFX_PLATFORM_CANVAS_MAC_H__
#define BASE_GFX_PLATFORM_CANVAS_MAC_H__
-#include "base/gfx/platform_device_mac.h"
-#include "base/basictypes.h"
-
-#import "SkCanvas.h"
-
-namespace gfx {
-
-// This class is a specialization of the regular SkCanvas that is designed to
-// work with a gfx::PlatformDevice to manage platform-specific drawing. It
-// allows using both Skia operations and platform-specific operations.
-class PlatformCanvasMac : public SkCanvas {
- public:
- // Set is_opaque if you are going to erase the bitmap and not use
- // tranparency: this will enable some optimizations. The shared_section
- // parameter is passed to gfx::PlatformDevice::create. See it for details.
- //
- // If you use the version with no arguments, you MUST call initialize()
- PlatformCanvasMac();
- PlatformCanvasMac(int width, int height, bool is_opaque);
- PlatformCanvasMac(int width, int height, bool is_opaque, CGContextRef context);
- virtual ~PlatformCanvasMac();
-
- // For two-part init, call if you use the no-argument constructor above
- bool initialize(int width, int height, bool is_opaque);
-
- // These calls should surround calls to platform drawing routines. The CG
- // context returned by beginPlatformPaint is the one that can be used to
- // draw into.
- // Call endPlatformPaint when you are done and want to use Skia operations
- // again; this will synchronize the bitmap.
- virtual CGContextRef beginPlatformPaint();
- virtual void endPlatformPaint();
-
- // Returns the platform device pointer of the topmost rect with a non-empty
- // clip. In practice, this is usually either the top layer or nothing, since
- // we usually set the clip to new layers when we make them.
- //
- // If there is no layer that is not all clipped out, this will return a
- // dummy device so callers do not have to check. If you are concerned about
- // performance, check the clip before doing any painting.
- //
- // This is different than SkCanvas' getDevice, because that returns the
- // bottommost device.
- //
- // Danger: the resulting device should not be saved. It will be invalidated
- // by the next call to save() or restore().
- PlatformDeviceMac& getTopPlatformDevice() const;
-
- // Allow callers to see the non-virtual function even though we have an
- // override of a virtual one.
- using SkCanvas::clipRect;
-
- protected:
- // Creates a device store for use by the canvas. We override this so that
- // the device is always our own so we know that we can use GDI operations
- // on it. Simply calls into createPlatformDevice().
- virtual SkDevice* createDevice(SkBitmap::Config, int width, int height,
- bool is_opaque, bool isForLayer);
-
- // Creates a device store for use by the canvas. By default, it creates a
- // BitmapPlatformDevice object. Can be overridden to change the object type.
- virtual SkDevice* createPlatformDevice(int width, int height, bool is_opaque,
- CGContextRef context);
-
- private:
- // Unimplemented. This is to try to prevent people from calling this function
- // on SkCanvas. SkCanvas' version is not virtual, so we can't prevent this
- // 100%, but hopefully this will make people notice and not use the function.
- // Calling SkCanvas' version will create a new device which is not compatible
- // with us and we will crash if somebody tries to draw into it with
- // CoreGraphics.
- SkDevice* setBitmapDevice(const SkBitmap& bitmap);
-
- DISALLOW_COPY_AND_ASSIGN(PlatformCanvasMac);
-};
-
-} // namespace gfx
+// TODO(brettw) this file should be removed and the includes changed to this
+// new location.
+#include "webkit/port/platform/graphics/skia/public/PlatformCanvasMac.h"
#endif // BASE_GFX_PLATFORM_CANVAS_MAC_H__
diff --git a/base/gfx/platform_canvas_unittest.cc b/base/gfx/platform_canvas_unittest.cc
deleted file mode 100644
index 8e227ad..0000000
--- a/base/gfx/platform_canvas_unittest.cc
+++ /dev/null
@@ -1,296 +0,0 @@
-// 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.
-
-// TODO(awalker): clean up the const/non-const reference handling in this test
-
-#include "build/build_config.h"
-
-#if defined(OS_WIN)
-#include <windows.h>
-#else
-#include <unistd.h>
-#endif
-
-#include "base/gfx/platform_canvas.h"
-#include "base/gfx/platform_device.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-#include "SkColor.h"
-
-namespace gfx {
-
-namespace {
-
-// Return true if the canvas is filled to canvas_color,
-// and contains a single rectangle filled to rect_color.
-bool VerifyRect(const PlatformCanvas& canvas,
- uint32_t canvas_color, uint32_t rect_color,
- int x, int y, int w, int h) {
- PlatformDevice& device = canvas.getTopPlatformDevice();
- const SkBitmap& bitmap = device.accessBitmap(false);
- SkAutoLockPixels lock(bitmap);
-
- for (int cur_y = 0; cur_y < bitmap.height(); cur_y++) {
- for (int cur_x = 0; cur_x < bitmap.width(); cur_x++) {
- if (cur_x >= x && cur_x < x + w &&
- cur_y >= y && cur_y < y + h) {
- // Inside the square should be rect_color
- if (*bitmap.getAddr32(cur_x, cur_y) != rect_color)
- return false;
- } else {
- // Outside the square should be canvas_color
- if (*bitmap.getAddr32(cur_x, cur_y) != canvas_color)
- return false;
- }
- }
- }
- return true;
-}
-
-// Checks whether there is a white canvas with a black square at the given
-// location in pixels (not in the canvas coordinate system).
-// TODO(ericroman): rename Square to Rect
-bool VerifyBlackSquare(const PlatformCanvas& canvas, int x, int y, int w, int h) {
- return VerifyRect(canvas, SK_ColorWHITE, SK_ColorBLACK, x, y, w, h);
-}
-
-// Check that every pixel in the canvas is a single color.
-bool VerifyCanvasColor(const PlatformCanvas& canvas, uint32_t canvas_color) {
- return VerifyRect(canvas, canvas_color, 0, 0, 0, 0, 0);
-}
-
-#if defined(OS_WIN)
-void DrawNativeRect(PlatformCanvas& canvas, int x, int y, int w, int h) {
- HDC dc = canvas.beginPlatformPaint();
-
- RECT inner_rc;
- inner_rc.left = x;
- inner_rc.top = y;
- inner_rc.right = x + w;
- inner_rc.bottom = y + h;
- FillRect(dc, &inner_rc, reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH)));
-
- canvas.endPlatformPaint();
-}
-#elif defined(OS_MACOSX)
-void DrawNativeRect(PlatformCanvas& canvas, int x, int y, int w, int h) {
- CGContextRef context = canvas.beginPlatformPaint();
-
- CGRect inner_rc = CGRectMake(x, y, w, h);
- // RGBA opaque black
- CGColorRef black = CGColorCreateGenericRGB(0.0, 0.0, 0.0, 1.0);
- CGContextSetFillColorWithColor(context, black);
- CGColorRelease(black);
- CGContextFillRect(context, inner_rc);
-
- canvas.endPlatformPaint();
-}
-#else
-void DrawNativeRect(PlatformCanvas& canvas, int x, int y, int w, int h) {
- NOTIMPLEMENTED();
-}
-#endif
-
-// Clips the contents of the canvas to the given rectangle. This will be
-// intersected with any existing clip.
-void AddClip(PlatformCanvas& canvas, int x, int y, int w, int h) {
- SkRect rect;
- rect.set(SkIntToScalar(x), SkIntToScalar(y),
- SkIntToScalar(x + w), SkIntToScalar(y + h));
- canvas.clipRect(rect);
-}
-
-class LayerSaver {
- public:
- LayerSaver(PlatformCanvas& canvas, int x, int y, int w, int h)
- : canvas_(canvas),
- x_(x),
- y_(y),
- w_(w),
- h_(h) {
- SkRect bounds;
- bounds.set(SkIntToScalar(x_), SkIntToScalar(y_),
- SkIntToScalar(right()), SkIntToScalar(bottom()));
- canvas_.saveLayer(&bounds, NULL);
- }
-
- ~LayerSaver() {
- canvas_.getTopPlatformDevice().fixupAlphaBeforeCompositing();
- canvas_.restore();
- }
-
- int x() const { return x_; }
- int y() const { return y_; }
- int w() const { return w_; }
- int h() const { return h_; }
-
- // Returns the EXCLUSIVE far bounds of the layer.
- int right() const { return x_ + w_; }
- int bottom() const { return y_ + h_; }
-
- private:
- PlatformCanvas& canvas_;
- int x_, y_, w_, h_;
-};
-
-// Size used for making layers in many of the below tests.
-const int kLayerX = 2;
-const int kLayerY = 3;
-const int kLayerW = 9;
-const int kLayerH = 7;
-
-// Size used by some tests to draw a rectangle inside the layer.
-const int kInnerX = 4;
-const int kInnerY = 5;
-const int kInnerW = 2;
-const int kInnerH = 3;
-
-}
-
-// This just checks that our checking code is working properly, it just uses
-// regular skia primitives.
-TEST(PlatformCanvas, SkLayer) {
- // Create the canvas initialized to opaque white.
- PlatformCanvas canvas(16, 16, true);
- canvas.drawColor(SK_ColorWHITE);
-
- // Make a layer and fill it completely to make sure that the bounds are
- // correct.
- {
- LayerSaver layer(canvas, kLayerX, kLayerY, kLayerW, kLayerH);
- canvas.drawColor(SK_ColorBLACK);
- }
- EXPECT_TRUE(VerifyBlackSquare(canvas, kLayerX, kLayerY, kLayerW, kLayerH));
-}
-
-// Test native clipping.
-TEST(PlatformCanvas, ClipRegion) {
- // Initialize a white canvas
- PlatformCanvas canvas(16, 16, true);
- canvas.drawColor(SK_ColorWHITE);
- EXPECT_TRUE(VerifyCanvasColor(canvas, SK_ColorWHITE));
-
- // Test that initially the canvas has no clip region, by filling it
- // with a black rectangle.
- // Note: Don't use LayerSaver, since internally it sets a clip region.
- DrawNativeRect(canvas, 0, 0, 16, 16);
- canvas.getTopPlatformDevice().fixupAlphaBeforeCompositing();
- EXPECT_TRUE(VerifyCanvasColor(canvas, SK_ColorBLACK));
-
- // Test that intersecting disjoint clip rectangles sets an empty clip region
- canvas.drawColor(SK_ColorWHITE);
- EXPECT_TRUE(VerifyCanvasColor(canvas, SK_ColorWHITE));
- {
- LayerSaver layer(canvas, 0, 0, 16, 16);
- AddClip(canvas, 2, 3, 4, 5);
- AddClip(canvas, 4, 9, 10, 10);
- DrawNativeRect(canvas, 0, 0, 16, 16);
- }
- EXPECT_TRUE(VerifyCanvasColor(canvas, SK_ColorWHITE));
-}
-
-// Test the layers get filled properly by native rendering.
-TEST(PlatformCanvas, FillLayer) {
- // Create the canvas initialized to opaque white.
- PlatformCanvas canvas(16, 16, true);
-
- // Make a layer and fill it completely to make sure that the bounds are
- // correct.
- canvas.drawColor(SK_ColorWHITE);
- {
- LayerSaver layer(canvas, kLayerX, kLayerY, kLayerW, kLayerH);
- DrawNativeRect(canvas, 0, 0, 100, 100);
- }
- EXPECT_TRUE(VerifyBlackSquare(canvas, kLayerX, kLayerY, kLayerW, kLayerH));
-
- // Make a layer and fill it partially to make sure the translation is correct.
- canvas.drawColor(SK_ColorWHITE);
- {
- LayerSaver layer(canvas, kLayerX, kLayerY, kLayerW, kLayerH);
- DrawNativeRect(canvas, kInnerX, kInnerY, kInnerW, kInnerH);
- }
- EXPECT_TRUE(VerifyBlackSquare(canvas, kInnerX, kInnerY, kInnerW, kInnerH));
-
- // Add a clip on the layer and fill to make sure clip is correct.
- canvas.drawColor(SK_ColorWHITE);
- {
- LayerSaver layer(canvas, kLayerX, kLayerY, kLayerW, kLayerH);
- canvas.save();
- AddClip(canvas, kInnerX, kInnerY, kInnerW, kInnerH);
- DrawNativeRect(canvas, 0, 0, 100, 100);
- canvas.restore();
- }
- EXPECT_TRUE(VerifyBlackSquare(canvas, kInnerX, kInnerY, kInnerW, kInnerH));
-
- // Add a clip and then make the layer to make sure the clip is correct.
- canvas.drawColor(SK_ColorWHITE);
- canvas.save();
- AddClip(canvas, kInnerX, kInnerY, kInnerW, kInnerH);
- {
- LayerSaver layer(canvas, kLayerX, kLayerY, kLayerW, kLayerH);
- DrawNativeRect(canvas, 0, 0, 100, 100);
- }
- canvas.restore();
- EXPECT_TRUE(VerifyBlackSquare(canvas, kInnerX, kInnerY, kInnerW, kInnerH));
-}
-
-// Test that translation + make layer works properly.
-TEST(PlatformCanvas, TranslateLayer) {
- // Create the canvas initialized to opaque white.
- PlatformCanvas canvas(16, 16, true);
-
- // Make a layer and fill it completely to make sure that the bounds are
- // correct.
- canvas.drawColor(SK_ColorWHITE);
- canvas.save();
- canvas.translate(1, 1);
- {
- LayerSaver layer(canvas, kLayerX, kLayerY, kLayerW, kLayerH);
- DrawNativeRect(canvas, 0, 0, 100, 100);
- }
- canvas.restore();
- EXPECT_TRUE(VerifyBlackSquare(canvas, kLayerX + 1, kLayerY + 1,
- kLayerW, kLayerH));
-
- // Translate then make the layer.
- canvas.drawColor(SK_ColorWHITE);
- canvas.save();
- canvas.translate(1, 1);
- {
- LayerSaver layer(canvas, kLayerX, kLayerY, kLayerW, kLayerH);
- DrawNativeRect(canvas, kInnerX, kInnerY, kInnerW, kInnerH);
- }
- canvas.restore();
- EXPECT_TRUE(VerifyBlackSquare(canvas, kInnerX + 1, kInnerY + 1,
- kInnerW, kInnerH));
-
- // Make the layer then translate.
- canvas.drawColor(SK_ColorWHITE);
- canvas.save();
- {
- LayerSaver layer(canvas, kLayerX, kLayerY, kLayerW, kLayerH);
- canvas.translate(1, 1);
- DrawNativeRect(canvas, kInnerX, kInnerY, kInnerW, kInnerH);
- }
- canvas.restore();
- EXPECT_TRUE(VerifyBlackSquare(canvas, kInnerX + 1, kInnerY + 1,
- kInnerW, kInnerH));
-
- // Translate both before and after, and have a clip.
- canvas.drawColor(SK_ColorWHITE);
- canvas.save();
- canvas.translate(1, 1);
- {
- LayerSaver layer(canvas, kLayerX, kLayerY, kLayerW, kLayerH);
- canvas.translate(1, 1);
- AddClip(canvas, kInnerX, kInnerY, kInnerW, kInnerH);
- DrawNativeRect(canvas, 0, 0, 100, 100);
- }
- canvas.restore();
- EXPECT_TRUE(VerifyBlackSquare(canvas, kInnerX + 2, kInnerY + 2,
- kInnerW, kInnerH));
-}
-
-} // namespace
-
diff --git a/base/gfx/platform_canvas_win.cc b/base/gfx/platform_canvas_win.cc
deleted file mode 100644
index fe90c55..0000000
--- a/base/gfx/platform_canvas_win.cc
+++ /dev/null
@@ -1,122 +0,0 @@
-// 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 "base/gfx/platform_canvas_win.h"
-
-#include "base/gfx/bitmap_platform_device_win.h"
-#include "base/logging.h"
-#include "base/process_util.h"
-
-#ifdef ARCH_CPU_64_BITS
-#error This code does not work on x64. Please make sure all the base unit tests\
- pass before doing any real work.
-#endif
-
-namespace gfx {
-
-// Crashes the process. This is called when a bitmap allocation fails, and this
-// function tries to determine why it might have failed, and crash on different
-// lines. This allows us to see in crash dumps the most likely reason for the
-// failure. It takes the size of the bitmap we were trying to allocate as its
-// arguments so we can check that as well.
-void CrashForBitmapAllocationFailure(int w, int h) {
- // The maximum number of GDI objects per process is 10K. If we're very close
- // to that, it's probably the problem.
- const int kLotsOfGDIObjs = 9990;
- CHECK(GetGuiResources(GetCurrentProcess(), GR_GDIOBJECTS) < kLotsOfGDIObjs);
-
- // If the bitmap is ginormous, then we probably can't allocate it.
- // We use 64M pixels = 256MB @ 4 bytes per pixel.
- const int64 kGinormousBitmapPxl = 64000000;
- CHECK(static_cast<int64>(w) * static_cast<int64>(h) < kGinormousBitmapPxl);
-
- // If we're using a crazy amount of virtual address space, then maybe there
- // isn't enough for our bitmap.
- const int64 kLotsOfMem = 1500000000; // 1.5GB.
- scoped_ptr<base::ProcessMetrics> process_metrics(
- base::ProcessMetrics::CreateProcessMetrics(GetCurrentProcess()));
- CHECK(process_metrics->GetPagefileUsage() < kLotsOfMem);
-
- // Everything else.
- CHECK(0);
-}
-
-
-PlatformCanvasWin::PlatformCanvasWin() : SkCanvas() {
-}
-
-PlatformCanvasWin::PlatformCanvasWin(int width, int height, bool is_opaque)
- : SkCanvas() {
- bool initialized = initialize(width, height, is_opaque, NULL);
- if (!initialized)
- CrashForBitmapAllocationFailure(width, height);
-}
-
-PlatformCanvasWin::PlatformCanvasWin(int width,
- int height,
- bool is_opaque,
- HANDLE shared_section)
- : SkCanvas() {
- bool initialized = initialize(width, height, is_opaque, shared_section);
- if (!initialized)
- CrashForBitmapAllocationFailure(width, height);
-}
-
-PlatformCanvasWin::~PlatformCanvasWin() {
-}
-
-bool PlatformCanvasWin::initialize(int width,
- int height,
- bool is_opaque,
- HANDLE shared_section) {
- SkDevice* device =
- createPlatformDevice(width, height, is_opaque, shared_section);
- if (!device)
- return false;
-
- setDevice(device);
- device->unref(); // was created with refcount 1, and setDevice also refs
- return true;
-}
-
-HDC PlatformCanvasWin::beginPlatformPaint() {
- return getTopPlatformDevice().getBitmapDC();
-}
-
-void PlatformCanvasWin::endPlatformPaint() {
- // we don't clear the DC here since it will be likely to be used again
- // flushing will be done in onAccessBitmap
-}
-
-PlatformDeviceWin& PlatformCanvasWin::getTopPlatformDevice() const {
- // All of our devices should be our special PlatformDevice.
- SkCanvas::LayerIter iter(const_cast<PlatformCanvasWin*>(this), false);
- return *static_cast<PlatformDeviceWin*>(iter.device());
-}
-
-SkDevice* PlatformCanvasWin::createDevice(SkBitmap::Config config,
- int width,
- int height,
- bool is_opaque, bool isForLayer) {
- DCHECK(config == SkBitmap::kARGB_8888_Config);
- return createPlatformDevice(width, height, is_opaque, NULL);
-}
-
-SkDevice* PlatformCanvasWin::createPlatformDevice(int width,
- int height,
- bool is_opaque,
- HANDLE shared_section) {
- HDC screen_dc = GetDC(NULL);
- SkDevice* device = BitmapPlatformDeviceWin::create(screen_dc, width, height,
- is_opaque, shared_section);
- ReleaseDC(NULL, screen_dc);
- return device;
-}
-
-SkDevice* PlatformCanvasWin::setBitmapDevice(const SkBitmap&) {
- NOTREACHED();
- return NULL;
-}
-
-} // namespace gfx
diff --git a/base/gfx/platform_canvas_win.h b/base/gfx/platform_canvas_win.h
index 95ae856..8bd285b 100644
--- a/base/gfx/platform_canvas_win.h
+++ b/base/gfx/platform_canvas_win.h
@@ -5,192 +5,9 @@
#ifndef BASE_GFX_PLATFORM_CANVAS_WIN_H_
#define BASE_GFX_PLATFORM_CANVAS_WIN_H_
-#include "base/gfx/platform_device_win.h"
-#include "base/basictypes.h"
-
-#include "SkCanvas.h"
-
-namespace gfx {
-
-// This class is a specialization of the regular SkCanvas that is designed to
-// work with a gfx::PlatformDevice to manage platform-specific drawing. It
-// allows using both Skia operations and platform-specific operations.
-class PlatformCanvasWin : public SkCanvas {
- public:
- // Set is_opaque if you are going to erase the bitmap and not use
- // transparency: this will enable some optimizations. The shared_section
- // parameter is passed to gfx::PlatformDevice::create. See it for details.
- //
- // If you use the version with no arguments, you MUST call initialize()
- PlatformCanvasWin();
- PlatformCanvasWin(int width, int height, bool is_opaque);
- PlatformCanvasWin(int width, int height, bool is_opaque,
- HANDLE shared_section);
- virtual ~PlatformCanvasWin();
-
- // For two-part init, call if you use the no-argument constructor above. Note
- // that we want this to optionally match the Linux initialize if you only
- // pass 3 arguments, hence the evil default argument.
- bool initialize(int width, int height, bool is_opaque,
- HANDLE shared_section = NULL);
-
- // These calls should surround calls to platform drawing routines, the DC
- // returned by beginPlatformPaint is the DC that can be used to draw into.
- // Call endPlatformPaint when you are done and want to use Skia operations
- // again; this will synchronize the bitmap to Windows.
- virtual HDC beginPlatformPaint();
- virtual void endPlatformPaint();
-
- // Returns the platform device pointer of the topmost rect with a non-empty
- // clip. In practice, this is usually either the top layer or nothing, since
- // we usually set the clip to new layers when we make them.
- //
- // If there is no layer that is not all clipped out, this will return a
- // dummy device so callers do not have to check. If you are concerned about
- // performance, check the clip before doing any painting.
- //
- // This is different than SkCanvas' getDevice, because that returns the
- // bottommost device.
- //
- // Danger: the resulting device should not be saved. It will be invalidated
- // by the next call to save() or restore().
- PlatformDeviceWin& getTopPlatformDevice() const;
-
- protected:
- // Creates a device store for use by the canvas. We override this so that
- // the device is always our own so we know that we can use GDI operations
- // on it. Simply calls into createPlatformDevice().
- virtual SkDevice* createDevice(SkBitmap::Config, int width, int height,
- bool is_opaque, bool isForLayer);
-
- // Creates a device store for use by the canvas. By default, it creates a
- // BitmapPlatformDeviceWin. Can be overridden to change the object type.
- virtual SkDevice* createPlatformDevice(int width, int height, bool is_opaque,
- HANDLE shared_section);
-
- private:
- // Unimplemented.
- virtual SkDevice* setBitmapDevice(const SkBitmap& bitmap);
-
- DISALLOW_COPY_AND_ASSIGN(PlatformCanvasWin);
-};
-
-// A class designed to help with WM_PAINT operations on Windows. It will
-// do BeginPaint/EndPaint on init/destruction, and will create the bitmap and
-// canvas with the correct size and transform for the dirty rect. The bitmap
-// will be automatically painted to the screen on destruction.
-//
-// You MUST call isEmpty before painting to determine if anything needs
-// painting. Sometimes the dirty rect can actually be empty, and this makes
-// the bitmap functions we call unhappy. The caller should not paint in this
-// case.
-//
-// Therefore, all you need to do is:
-// case WM_PAINT: {
-// gfx::PlatformCanvasWinPaint canvas(hwnd);
-// if (!canvas.isEmpty()) {
-// ... paint to the canvas ...
-// }
-// return 0;
-// }
-template <class T>
-class CanvasPaintT : public T {
- public:
- CanvasPaintT(HWND hwnd) : hwnd_(hwnd), paint_dc_(NULL), for_paint_(true) {
- memset(&ps_, 0, sizeof(ps_));
- initPaint(true);
- }
-
- CanvasPaintT(HWND hwnd, bool opaque) : hwnd_(hwnd), paint_dc_(NULL),
- for_paint_(true) {
- memset(&ps_, 0, sizeof(ps_));
- initPaint(opaque);
- }
-
- // Creates a CanvasPaintT for the specified region that paints to the
- // specified dc. This does NOT do BeginPaint/EndPaint.
- CanvasPaintT(HDC dc, bool opaque, int x, int y, int w, int h)
- : hwnd_(NULL),
- paint_dc_(dc),
- for_paint_(false) {
- memset(&ps_, 0, sizeof(ps_));
- ps_.rcPaint.left = x;
- ps_.rcPaint.right = x + w;
- ps_.rcPaint.top = y;
- ps_.rcPaint.bottom = y + h;
- init(opaque);
- }
-
-
- virtual ~CanvasPaintT() {
- if (!isEmpty()) {
- restoreToCount(1);
- // Commit the drawing to the screen
- getTopPlatformDevice().drawToHDC(paint_dc_,
- ps_.rcPaint.left, ps_.rcPaint.top,
- NULL);
- }
- if (for_paint_)
- EndPaint(hwnd_, &ps_);
- }
-
- // Returns true if the invalid region is empty. The caller should call this
- // function to determine if anything needs painting.
- bool isEmpty() const {
- return ps_.rcPaint.right - ps_.rcPaint.left == 0 ||
- ps_.rcPaint.bottom - ps_.rcPaint.top == 0;
- }
-
- // Use to access the Windows painting parameters, especially useful for
- // getting the bounding rect for painting: paintstruct().rcPaint
- const PAINTSTRUCT& paintStruct() const {
- return ps_;
- }
-
- // Returns the DC that will be painted to
- HDC paintDC() const {
- return paint_dc_;
- }
-
- protected:
- HWND hwnd_;
- HDC paint_dc_;
- PAINTSTRUCT ps_;
-
- private:
- void initPaint(bool opaque) {
- paint_dc_ = BeginPaint(hwnd_, &ps_);
-
- init(opaque);
- }
-
- void init(bool opaque) {
- // FIXME(brettw) for ClearType, we probably want to expand the bounds of
- // painting by one pixel so that the boundaries will be correct (ClearType
- // text can depend on the adjacent pixel). Then we would paint just the
- // inset pixels to the screen.
- const int width = ps_.rcPaint.right - ps_.rcPaint.left;
- const int height = ps_.rcPaint.bottom - ps_.rcPaint.top;
- if (!initialize(width, height, opaque, NULL)) {
- // Cause a deliberate crash;
- *(char*) 0 = 0;
- }
-
- // This will bring the canvas into the screen coordinate system for the
- // dirty rect
- translate(SkIntToScalar(-ps_.rcPaint.left),
- SkIntToScalar(-ps_.rcPaint.top));
- }
-
- // If true, this canvas was created for a BeginPaint.
- const bool for_paint_;
-
- DISALLOW_COPY_AND_ASSIGN(CanvasPaintT);
-};
-
-typedef CanvasPaintT<PlatformCanvasWin> PlatformCanvasWinPaint;
-
-} // namespace gfx
+// TODO(brettw) this file should be removed and the includes changed to this
+// new location.
+#include "webkit/port/platform/graphics/skia/public/PlatformCanvasWin.h"
#endif // BASE_GFX_PLATFORM_CANVAS_WIN_H_
diff --git a/base/gfx/platform_device.h b/base/gfx/platform_device.h
index f1c890c..11202c6 100644
--- a/base/gfx/platform_device.h
+++ b/base/gfx/platform_device.h
@@ -2,26 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Declare a platform-neutral name for this platform's device class
-// that can be used by upper-level classes that just need to pass a reference
-// around.
-
-#if defined(OS_WIN)
-#include "base/gfx/platform_device_win.h"
-#elif defined(OS_MACOSX)
-#include "base/gfx/platform_device_mac.h"
-#elif defined(OS_LINUX)
-#include "base/gfx/platform_device_linux.h"
-#endif
-
-namespace gfx {
-
-#if defined(OS_WIN)
-typedef PlatformDeviceWin PlatformDevice;
-#elif defined(OS_MACOSX)
-typedef PlatformDeviceMac PlatformDevice;
-#elif defined(OS_LINUX)
-typedef PlatformDeviceLinux PlatformDevice;
-#endif
-
-} // namespace gfx
+// TODO(brettw) this file should be removed and the includes changed to this
+// new location.
+#include "webkit/port/platform/graphics/skia/public/PlatformDevice.h"
diff --git a/base/gfx/platform_device_linux.cc b/base/gfx/platform_device_linux.cc
deleted file mode 100644
index 1f948b1..0000000
--- a/base/gfx/platform_device_linux.cc
+++ /dev/null
@@ -1,18 +0,0 @@
-// 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 "base/gfx/platform_device_linux.h"
-
-#include "base/logging.h"
-#include "SkMatrix.h"
-#include "SkPath.h"
-#include "SkUtils.h"
-
-namespace gfx {
-
-PlatformDeviceLinux::PlatformDeviceLinux(const SkBitmap& bitmap)
- : SkDevice(bitmap) {
-}
-
-} // namespace gfx
diff --git a/base/gfx/platform_device_linux.h b/base/gfx/platform_device_linux.h
index 8be2e4a..ffd5a2d 100644
--- a/base/gfx/platform_device_linux.h
+++ b/base/gfx/platform_device_linux.h
@@ -5,21 +5,8 @@
#ifndef BASE_GFX_PLATFORM_DEVICE_LINUX_H_
#define BASE_GFX_PLATFORM_DEVICE_LINUX_H_
-#include "SkDevice.h"
-
-namespace gfx {
-
-// Blindly copying the mac hierarchy.
-class PlatformDeviceLinux : public SkDevice {
- public:
- // Returns if the preferred rendering engine is vectorial or bitmap based.
- virtual bool IsVectorial() = 0;
-
- protected:
- // Forwards |bitmap| to SkDevice's constructor.
- PlatformDeviceLinux(const SkBitmap& bitmap);
-};
-
-} // namespace gfx
+// TODO(brettw) this file should be removed and the includes changed to this
+// new location.
+#include "webkit/port/platform/graphics/skia/public/PlatformDeviceLinux.h"
#endif // BASE_GFX_PLATFORM_DEVICE_LINUX_H_
diff --git a/base/gfx/platform_device_mac.cc b/base/gfx/platform_device_mac.cc
deleted file mode 100755
index 93909f1..0000000
--- a/base/gfx/platform_device_mac.cc
+++ /dev/null
@@ -1,161 +0,0 @@
-// 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 "base/gfx/platform_device_mac.h"
-
-#include "base/logging.h"
-#include "base/gfx/skia_utils_mac.h"
-#include "SkMatrix.h"
-#include "SkPath.h"
-#include "SkUtils.h"
-
-namespace gfx {
-
-namespace {
-
-// Constrains position and size to fit within available_size.
-bool constrain(int available_size, int* position, int *size) {
- if (*position < 0) {
- *size += *position;
- *position = 0;
- }
- if (*size > 0 && *position < available_size) {
- int overflow = (*position + *size) - available_size;
- if (overflow > 0) {
- *size -= overflow;
- }
- return true;
- }
- return false;
-}
-
-// Sets the opacity of the specified value to 0xFF.
-void makeOpaqueAlphaAdjuster(uint32_t* pixel) {
- *pixel |= 0xFF000000;
-}
-
-} // namespace
-
-PlatformDeviceMac::PlatformDeviceMac(const SkBitmap& bitmap)
- : SkDevice(bitmap) {
-}
-
-void PlatformDeviceMac::makeOpaque(int x, int y, int width, int height) {
- processPixels(x, y, width, height, makeOpaqueAlphaAdjuster);
-}
-
-// Set up the CGContextRef for peaceful coexistence with Skia
-void PlatformDeviceMac::InitializeCGContext(CGContextRef context) {
- // CG defaults to the same settings as Skia
-}
-
-// static
-void PlatformDeviceMac::LoadPathToCGContext(CGContextRef context,
- const SkPath& path) {
- // instead of a persistent attribute of the context, CG specifies the fill
- // type per call, so we just have to load up the geometry.
- CGContextBeginPath(context);
-
- SkPoint points[4] = { {0, 0}, {0, 0}, {0, 0}, {0, 0} };
- SkPath::Iter iter(path, false);
- for (SkPath::Verb verb = iter.next(points); verb != SkPath::kDone_Verb;
- verb = iter.next(points)) {
- switch (verb) {
- case SkPath::kMove_Verb: { // iter.next returns 1 point
- CGContextMoveToPoint(context, points[0].fX, points[0].fY);
- break;
- }
- case SkPath::kLine_Verb: { // iter.next returns 2 points
- CGContextAddLineToPoint(context, points[1].fX, points[1].fY);
- break;
- }
- case SkPath::kQuad_Verb: { // iter.next returns 3 points
- CGContextAddQuadCurveToPoint(context, points[1].fX, points[1].fY,
- points[2].fX, points[2].fY);
- break;
- }
- case SkPath::kCubic_Verb: { // iter.next returns 4 points
- CGContextAddCurveToPoint(context, points[1].fX, points[1].fY,
- points[2].fX, points[2].fY,
- points[3].fX, points[3].fY);
- break;
- }
- case SkPath::kClose_Verb: { // iter.next returns 1 point (the last point)
- break;
- }
- case SkPath::kDone_Verb: // iter.next returns 0 points
- default: {
- NOTREACHED();
- break;
- }
- }
- }
- CGContextClosePath(context);
-}
-
-// static
-void PlatformDeviceMac::LoadTransformToCGContext(CGContextRef context,
- const SkMatrix& matrix) {
- // CoreGraphics can concatenate transforms, but not reset the current one.
- // So in order to get the required behavior here, we need to first make
- // the current transformation matrix identity and only then load the new one.
-
- // Reset matrix to identity.
- CGAffineTransform orig_cg_matrix = CGContextGetCTM(context);
- CGAffineTransform orig_cg_matrix_inv = CGAffineTransformInvert(orig_cg_matrix);
- CGContextConcatCTM(context, orig_cg_matrix_inv);
-
- // assert that we have indeed returned to the identity Matrix.
- DCHECK(CGAffineTransformIsIdentity(CGContextGetCTM(context)));
-
- // Convert xform to CG-land.
- // Our coordinate system is flipped to match WebKit's so we need to modify
- // the xform to match that.
- SkMatrix transformed_matrix = matrix;
- SkScalar sy = matrix.getScaleY() * (SkScalar)-1;
- transformed_matrix.setScaleY(sy);
- size_t height = CGBitmapContextGetHeight(context);
- SkScalar ty = -matrix.getTranslateY(); // y axis is flipped.
- transformed_matrix.setTranslateY(ty + (SkScalar)height);
-
- CGAffineTransform cg_matrix = SkMatrixToCGAffineTransform(transformed_matrix);
-
- // Load final transform into context.
- CGContextConcatCTM(context, cg_matrix);
-}
-
-// static
-void PlatformDeviceMac::LoadClippingRegionToCGContext(
- CGContextRef context,
- const SkRegion& region,
- const SkMatrix& transformation) {
- if (region.isEmpty()) {
- // region can be empty, in which case everything will be clipped.
- SkRect rect;
- rect.setEmpty();
- CGContextClipToRect(context, SkRectToCGRect(rect));
- } else if (region.isRect()) {
- // Do the transformation.
- SkRect rect;
- rect.set(region.getBounds());
- transformation.mapRect(&rect);
- SkIRect irect;
- rect.round(&irect);
- CGContextClipToRect(context, SkIRectToCGRect(irect));
- } else {
- // It is complex.
- SkPath path;
- region.getBoundaryPath(&path);
- // Clip. Note that windows clipping regions are not affected by the
- // transform so apply it manually.
- path.transform(transformation);
- // TODO(playmobil): Implement.
- NOTREACHED();
- // LoadPathToDC(context, path);
- // hrgn = PathToRegion(context);
- }
-}
-
-} // namespace gfx
-
diff --git a/base/gfx/platform_device_mac.h b/base/gfx/platform_device_mac.h
index 79a14be..f7b1bd0 100755
--- a/base/gfx/platform_device_mac.h
+++ b/base/gfx/platform_device_mac.h
@@ -5,82 +5,9 @@
#ifndef BASE_GFX_PLATFORM_DEVICE_MAC_H__
#define BASE_GFX_PLATFORM_DEVICE_MAC_H__
-#import <ApplicationServices/ApplicationServices.h>
-#include "SkDevice.h"
-
-class SkMatrix;
-class SkPath;
-class SkRegion;
-
-namespace gfx {
-
-// A device is basically a wrapper around SkBitmap that provides a surface for
-// SkCanvas to draw into. Our device provides a surface CoreGraphics can also
-// write to. It also provides functionality to play well with CG drawing
-// functions.
-// This class is abstract and must be subclassed. It provides the basic
-// interface to implement it either with or without a bitmap backend.
-class PlatformDeviceMac : public SkDevice {
- public:
- // The CGContext that corresponds to the bitmap, used for CoreGraphics
- // operations drawing into the bitmap. This is possibly heavyweight, so it
- // should exist only during one pass of rendering.
- virtual CGContextRef GetBitmapContext() = 0;
-
- // Draws to the given graphics context. If the bitmap context doesn't exist,
- // this will temporarily create it. However, if you have created the bitmap
- // context, it will be more efficient if you don't free it until after this
- // call so it doesn't have to be created twice. If src_rect is null, then
- // the entirety of the source device will be copied.
- virtual void DrawToContext(CGContextRef context, int x, int y,
- const CGRect* src_rect) = 0;
-
- // Sets the opacity of each pixel in the specified region to be opaque.
- void makeOpaque(int x, int y, int width, int height);
-
- // Returns if the preferred rendering engine is vectorial or bitmap based.
- virtual bool IsVectorial() = 0;
-
- // On platforms where the native rendering API does not support rendering
- // into bitmaps with a premultiplied alpha channel, this call is responsible
- // for doing any fixup necessary. It is not used on the Mac, since
- // CoreGraphics can handle premultiplied alpha just fine.
- virtual void fixupAlphaBeforeCompositing() = 0;
-
- // Initializes the default settings and colors in a device context.
- static void InitializeCGContext(CGContextRef context);
-
- // Loads a SkPath into the CG context. The path can there after be used for
- // clipping or as a stroke.
- static void LoadPathToCGContext(CGContextRef context, const SkPath& path);
-
- // Loads a SkRegion into the CG context.
- static void LoadClippingRegionToCGContext(CGContextRef context,
- const SkRegion& region,
- const SkMatrix& transformation);
-
- protected:
- // Forwards |bitmap| to SkDevice's constructor.
- PlatformDeviceMac(const SkBitmap& bitmap);
-
- // Loads the specified Skia transform into the device context
- static void LoadTransformToCGContext(CGContextRef context,
- const SkMatrix& matrix);
-
- // Function pointer used by the processPixels method for setting the alpha
- // value of a particular pixel.
- typedef void (*adjustAlpha)(uint32_t* pixel);
-
- // Loops through each of the pixels in the specified range, invoking
- // adjustor for the alpha value of each pixel.
- virtual void processPixels(int x,
- int y,
- int width,
- int height,
- adjustAlpha adjustor) = 0;
-};
-
-} // namespace gfx
+// TODO(brettw) this file should be removed and the includes changed to this
+// new location.
+#include "webkit/port/platform/graphics/skia/public/PlatformDeviceMac.h"
#endif // BASE_GFX_PLATFORM_DEVICE_MAC_H__
diff --git a/base/gfx/platform_device_win.cc b/base/gfx/platform_device_win.cc
deleted file mode 100644
index a1e8568..0000000
--- a/base/gfx/platform_device_win.cc
+++ /dev/null
@@ -1,229 +0,0 @@
-// 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 "base/gfx/platform_device_win.h"
-
-#include "base/logging.h"
-#include "base/gfx/skia_utils.h"
-#include "SkMatrix.h"
-#include "SkPath.h"
-#include "SkRegion.h"
-#include "SkUtils.h"
-
-namespace gfx {
-
-PlatformDeviceWin::PlatformDeviceWin(const SkBitmap& bitmap)
- : SkDevice(bitmap) {
-}
-
-// static
-void PlatformDeviceWin::InitializeDC(HDC context) {
- // Enables world transformation.
- // If the GM_ADVANCED graphics mode is set, GDI always draws arcs in the
- // counterclockwise direction in logical space. This is equivalent to the
- // statement that, in the GM_ADVANCED graphics mode, both arc control points
- // and arcs themselves fully respect the device context's world-to-device
- // transformation.
- BOOL res = SetGraphicsMode(context, GM_ADVANCED);
- DCHECK_NE(res, 0);
-
- // Enables dithering.
- res = SetStretchBltMode(context, HALFTONE);
- DCHECK_NE(res, 0);
- // As per SetStretchBltMode() documentation, SetBrushOrgEx() must be called
- // right after.
- res = SetBrushOrgEx(context, 0, 0, NULL);
- DCHECK_NE(res, 0);
-
- // Sets up default orientation.
- res = SetArcDirection(context, AD_CLOCKWISE);
- DCHECK_NE(res, 0);
-
- // Sets up default colors.
- res = SetBkColor(context, RGB(255, 255, 255));
- DCHECK_NE(res, CLR_INVALID);
- res = SetTextColor(context, RGB(0, 0, 0));
- DCHECK_NE(res, CLR_INVALID);
- res = SetDCBrushColor(context, RGB(255, 255, 255));
- DCHECK_NE(res, CLR_INVALID);
- res = SetDCPenColor(context, RGB(0, 0, 0));
- DCHECK_NE(res, CLR_INVALID);
-
- // Sets up default transparency.
- res = SetBkMode(context, OPAQUE);
- DCHECK_NE(res, 0);
- res = SetROP2(context, R2_COPYPEN);
- DCHECK_NE(res, 0);
-}
-
-// static
-void PlatformDeviceWin::LoadPathToDC(HDC context, const SkPath& path) {
- switch (path.getFillType()) {
- case SkPath::kWinding_FillType: {
- int res = SetPolyFillMode(context, WINDING);
- DCHECK(res != 0);
- break;
- }
- case SkPath::kEvenOdd_FillType: {
- int res = SetPolyFillMode(context, ALTERNATE);
- DCHECK(res != 0);
- break;
- }
- default: {
- NOTREACHED();
- break;
- }
- }
- BOOL res = BeginPath(context);
- DCHECK(res != 0);
-
- CubicPaths paths;
- if (!SkPathToCubicPaths(&paths, path))
- return;
-
- std::vector<POINT> points;
- for (CubicPaths::const_iterator path(paths.begin()); path != paths.end();
- ++path) {
- if (!path->size())
- continue;
- // DCHECK_EQ(points.size() % 4, 0);
- points.resize(0);
- points.reserve(path->size() * 3 / 4 + 1);
- points.push_back(SkPointToPOINT(path->front().p[0]));
- for (CubicPath::const_iterator point(path->begin()); point != path->end();
- ++point) {
- // Never add point->p[0]
- points.push_back(SkPointToPOINT(point->p[1]));
- points.push_back(SkPointToPOINT(point->p[2]));
- points.push_back(SkPointToPOINT(point->p[3]));
- }
- DCHECK_EQ((points.size() - 1) % 3, 0);
- // This is slightly inefficient since all straight line and quadratic lines
- // are "upgraded" to a cubic line.
- // TODO(maruel): http://b/1147346 We should use
- // PolyDraw/PolyBezier/Polyline whenever possible.
- res = PolyBezier(context, &points.front(),
- static_cast<DWORD>(points.size()));
- DCHECK_NE(res, 0);
- if (res == 0)
- break;
- }
- if (res == 0) {
- // Make sure the path is discarded.
- AbortPath(context);
- } else {
- res = EndPath(context);
- DCHECK(res != 0);
- }
-}
-
-// static
-void PlatformDeviceWin::LoadTransformToDC(HDC dc, const SkMatrix& matrix) {
- XFORM xf;
- xf.eM11 = matrix[SkMatrix::kMScaleX];
- xf.eM21 = matrix[SkMatrix::kMSkewX];
- xf.eDx = matrix[SkMatrix::kMTransX];
- xf.eM12 = matrix[SkMatrix::kMSkewY];
- xf.eM22 = matrix[SkMatrix::kMScaleY];
- xf.eDy = matrix[SkMatrix::kMTransY];
- SetWorldTransform(dc, &xf);
-}
-
-// static
-bool PlatformDeviceWin::SkPathToCubicPaths(CubicPaths* paths,
- const SkPath& skpath) {
- paths->clear();
- CubicPath* current_path = NULL;
- SkPoint current_points[4];
- CubicPoints points_to_add;
- SkPath::Iter iter(skpath, false);
- for (SkPath::Verb verb = iter.next(current_points);
- verb != SkPath::kDone_Verb;
- verb = iter.next(current_points)) {
- switch (verb) {
- case SkPath::kMove_Verb: { // iter.next returns 1 point
- // Ignores it since the point is copied in the next operation. See
- // SkPath::Iter::next() for reference.
- paths->push_back(CubicPath());
- current_path = &paths->back();
- // Skip point addition.
- continue;
- }
- case SkPath::kLine_Verb: { // iter.next returns 2 points
- points_to_add.p[0] = current_points[0];
- points_to_add.p[1] = current_points[0];
- points_to_add.p[2] = current_points[1];
- points_to_add.p[3] = current_points[1];
- break;
- }
- case SkPath::kQuad_Verb: { // iter.next returns 3 points
- points_to_add.p[0] = current_points[0];
- points_to_add.p[1] = current_points[1];
- points_to_add.p[2] = current_points[2];
- points_to_add.p[3] = current_points[2];
- break;
- }
- case SkPath::kCubic_Verb: { // iter.next returns 4 points
- points_to_add.p[0] = current_points[0];
- points_to_add.p[1] = current_points[1];
- points_to_add.p[2] = current_points[2];
- points_to_add.p[3] = current_points[3];
- break;
- }
- case SkPath::kClose_Verb: { // iter.next returns 1 point (the last point)
- paths->push_back(CubicPath());
- current_path = &paths->back();
- continue;
- }
- case SkPath::kDone_Verb: // iter.next returns 0 points
- default: {
- current_path = NULL;
- // Will return false.
- break;
- }
- }
- DCHECK(current_path);
- if (!current_path) {
- paths->clear();
- return false;
- }
- current_path->push_back(points_to_add);
- }
- return true;
-}
-
-// static
-void PlatformDeviceWin::LoadClippingRegionToDC(HDC context,
- const SkRegion& region,
- const SkMatrix& transformation) {
- HRGN hrgn;
- if (region.isEmpty()) {
- // region can be empty, in which case everything will be clipped.
- hrgn = CreateRectRgn(0, 0, 0, 0);
- } else if (region.isRect()) {
- // Do the transformation.
- SkRect rect;
- rect.set(region.getBounds());
- transformation.mapRect(&rect);
- SkIRect irect;
- rect.round(&irect);
- hrgn = CreateRectRgnIndirect(&SkIRectToRECT(irect));
- } else {
- // It is complex.
- SkPath path;
- region.getBoundaryPath(&path);
- // Clip. Note that windows clipping regions are not affected by the
- // transform so apply it manually.
- path.transform(transformation);
- LoadPathToDC(context, path);
- hrgn = PathToRegion(context);
- }
- int result = SelectClipRgn(context, hrgn);
- DCHECK_NE(result, ERROR);
- result = DeleteObject(hrgn);
- DCHECK_NE(result, 0);
-}
-
-} // namespace gfx
-
diff --git a/base/gfx/platform_device_win.h b/base/gfx/platform_device_win.h
index d5052a2..e39dfe1 100644
--- a/base/gfx/platform_device_win.h
+++ b/base/gfx/platform_device_win.h
@@ -5,92 +5,9 @@
#ifndef BASE_GFX_PLATFORM_DEVICE_WIN_H__
#define BASE_GFX_PLATFORM_DEVICE_WIN_H__
-#include <vector>
-
-#include "SkDevice.h"
-
-class SkMatrix;
-class SkPath;
-class SkRegion;
-
-namespace gfx {
-
-// A device is basically a wrapper around SkBitmap that provides a surface for
-// SkCanvas to draw into. Our device provides a surface Windows can also write
-// to. It also provides functionality to play well with GDI drawing functions.
-// This class is abstract and must be subclassed. It provides the basic
-// interface to implement it either with or without a bitmap backend.
-class PlatformDeviceWin : public SkDevice {
- public:
- // The DC that corresponds to the bitmap, used for GDI operations drawing
- // into the bitmap. This is possibly heavyweight, so it should be existant
- // only during one pass of rendering.
- virtual HDC getBitmapDC() = 0;
-
- // Draws to the given screen DC, if the bitmap DC doesn't exist, this will
- // temporarily create it. However, if you have created the bitmap DC, it will
- // be more efficient if you don't free it until after this call so it doesn't
- // have to be created twice. If src_rect is null, then the entirety of the
- // source device will be copied.
- virtual void drawToHDC(HDC dc, int x, int y, const RECT* src_rect) = 0;
-
- // Invoke before using GDI functions. See description in platform_device.cc
- // for specifics.
- // NOTE: x,y,width and height are relative to the current transform.
- virtual void prepareForGDI(int x, int y, int width, int height) { }
-
- // Invoke after using GDI functions. See description in platform_device.cc
- // for specifics.
- // NOTE: x,y,width and height are relative to the current transform.
- virtual void postProcessGDI(int x, int y, int width, int height) { }
-
- // Sets the opacity of each pixel in the specified region to be opaque.
- virtual void makeOpaque(int x, int y, int width, int height) { }
-
- // Call this function to fix the alpha channels before compositing this layer
- // onto another. Internally, the device uses a special alpha method to work
- // around problems with Windows. This call will put the values into what
- // Skia expects, so it can be composited onto other layers.
- //
- // After this call, no more drawing can be done because the
- // alpha channels will be "correct", which, if this function is called again
- // will make them wrong. See the implementation for more discussion.
- virtual void fixupAlphaBeforeCompositing() { }
-
- // Returns if the preferred rendering engine is vectorial or bitmap based.
- virtual bool IsVectorial() = 0;
-
- // Initializes the default settings and colors in a device context.
- static void InitializeDC(HDC context);
-
- // Loads a SkPath into the GDI context. The path can there after be used for
- // clipping or as a stroke.
- static void LoadPathToDC(HDC context, const SkPath& path);
-
- // Loads a SkRegion into the GDI context.
- static void LoadClippingRegionToDC(HDC context, const SkRegion& region,
- const SkMatrix& transformation);
-
- protected:
- // Arrays must be inside structures.
- struct CubicPoints {
- SkPoint p[4];
- };
- typedef std::vector<CubicPoints> CubicPath;
- typedef std::vector<CubicPath> CubicPaths;
-
- // Forwards |bitmap| to SkDevice's constructor.
- PlatformDeviceWin(const SkBitmap& bitmap);
-
- // Loads the specified Skia transform into the device context, excluding
- // perspective (which GDI doesn't support).
- static void LoadTransformToDC(HDC dc, const SkMatrix& matrix);
-
- // Transforms SkPath's paths into a series of cubic path.
- static bool SkPathToCubicPaths(CubicPaths* paths, const SkPath& skpath);
-};
-
-} // namespace gfx
+// TODO(brettw) this file should be removed and the includes changed to this
+// new location.
+#include "webkit/port/platform/graphics/skia/public/PlatformDeviceWin.h"
#endif // BASE_GFX_PLATFORM_DEVICE_WIN_H__
diff --git a/base/gfx/vector_canvas.cc b/base/gfx/vector_canvas.cc
deleted file mode 100644
index 440ee64..0000000
--- a/base/gfx/vector_canvas.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-// 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 "base/gfx/vector_canvas.h"
-
-#include "base/gfx/vector_device.h"
-#include "base/logging.h"
-
-namespace gfx {
-
-VectorCanvas::VectorCanvas() {
-}
-
-VectorCanvas::VectorCanvas(HDC dc, int width, int height) {
- bool initialized = initialize(dc, width, height);
- CHECK(initialized);
-}
-
-VectorCanvas::~VectorCanvas() {
-}
-
-bool VectorCanvas::initialize(HDC context, int width, int height) {
- SkDevice* device = createPlatformDevice(width, height, true, context);
- if (!device)
- return false;
-
- setDevice(device);
- device->unref(); // was created with refcount 1, and setDevice also refs
- return true;
-}
-
-SkBounder* VectorCanvas::setBounder(SkBounder* bounder) {
- if (!IsTopDeviceVectorial())
- return PlatformCanvasWin::setBounder(bounder);
-
- // This function isn't used in the code. Verify this assumption.
- NOTREACHED();
- return NULL;
-}
-
-SkDevice* VectorCanvas::createDevice(SkBitmap::Config config,
- int width, int height,
- bool is_opaque, bool isForLayer) {
- DCHECK(config == SkBitmap::kARGB_8888_Config);
- return createPlatformDevice(width, height, is_opaque, NULL);
-}
-
-SkDrawFilter* VectorCanvas::setDrawFilter(SkDrawFilter* filter) {
- // This function isn't used in the code. Verify this assumption.
- NOTREACHED();
- return NULL;
-}
-
-SkDevice* VectorCanvas::createPlatformDevice(int width,
- int height, bool is_opaque,
- HANDLE shared_section) {
- if (!is_opaque) {
- // TODO(maruel): http://b/1184002 1184002 When restoring a semi-transparent
- // layer, i.e. merging it, we need to rasterize it because GDI doesn't
- // support transparency except for AlphaBlend(). Right now, a
- // BitmapPlatformDeviceWin is created when VectorCanvas think a saveLayers()
- // call is being done. The way to save a layer would be to create an
- // EMF-based VectorDevice and have this device registers the drawing. When
- // playing back the device into a bitmap, do it at the printer's dpi instead
- // of the layout's dpi (which is much lower).
- return PlatformCanvasWin::createPlatformDevice(width, height, is_opaque,
- shared_section);
- }
-
- // TODO(maruel): http://b/1183870 Look if it would be worth to increase the
- // resolution by ~10x (any worthy factor) to increase the rendering precision
- // (think about printing) while using a relatively low dpi. This happens
- // because we receive float as input but the GDI functions works with
- // integers. The idea is to premultiply the matrix with this factor and
- // multiply each SkScalar that are passed to SkScalarRound(value) as
- // SkScalarRound(value * 10). Safari is already doing the same for text
- // rendering.
- DCHECK(shared_section);
- PlatformDeviceWin* device = VectorDevice::create(
- reinterpret_cast<HDC>(shared_section), width, height);
- return device;
-}
-
-bool VectorCanvas::IsTopDeviceVectorial() const {
- return getTopPlatformDevice().IsVectorial();
-}
-
-} // namespace gfx
-
diff --git a/base/gfx/vector_canvas_unittest.cc b/base/gfx/vector_canvas_unittest.cc
deleted file mode 100644
index 60a79ba..0000000
--- a/base/gfx/vector_canvas_unittest.cc
+++ /dev/null
@@ -1,1008 +0,0 @@
-// 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 "base/gfx/vector_canvas.h"
-
-#include <vector>
-
-#include "base/command_line.h"
-#include "base/file_util.h"
-#include "base/gfx/gdi_util.h"
-#include "base/gfx/png_decoder.h"
-#include "base/gfx/png_encoder.h"
-#include "base/gfx/size.h"
-#include "base/path_service.h"
-#include "base/string_util.h"
-#include "base/win_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-#include "SkDashPathEffect.h"
-
-namespace {
-
-const wchar_t* const kGenerateSwitch = L"vector-canvas-generate";
-
-// Base class for unit test that uses data. It initializes a directory path
-// based on the test's name.
-class DataUnitTest : public testing::Test {
- public:
- DataUnitTest(const std::wstring& base_path) : base_path_(base_path) { }
-
- protected:
- // Load the test's data path.
- virtual void SetUp() {
- const testing::TestInfo& test_info =
- *testing::UnitTest::GetInstance()->current_test_info();
- PathService::Get(base::DIR_SOURCE_ROOT, &test_dir_);
- file_util::AppendToPath(&test_dir_, base_path_);
- file_util::AppendToPath(&test_dir_, L"data");
- file_util::AppendToPath(&test_dir_,
- ASCIIToWide(test_info.test_case_name()));
- file_util::AppendToPath(&test_dir_, ASCIIToWide(test_info.name()));
-
- // Hack for a quick lowercase. We assume all the tests names are ASCII.
- std::string tmp(WideToASCII(test_dir_));
- for (size_t i = 0; i < tmp.size(); ++i)
- tmp[i] = ToLowerASCII(tmp[i]);
- test_dir_ = ASCIIToWide(tmp);
- }
-
- // Returns the fully qualified path of directory containing test data files.
- const std::wstring& test_dir() const {
- return test_dir_;
- }
-
- // Returns the fully qualified path of a data file.
- std::wstring test_file(const std::wstring& filename) const {
- // Hack for a quick lowercase. We assume all the test data file names are
- // ASCII.
- std::string tmp(WideToASCII(filename));
- for (size_t i = 0; i < tmp.size(); ++i)
- tmp[i] = ToLowerASCII(tmp[i]);
-
- std::wstring path(test_dir());
- file_util::AppendToPath(&path, ASCIIToWide(tmp));
- return path;
- }
-
- private:
- // Path where the unit test is coming from: base, net, chrome, etc.
- std::wstring base_path_;
-
- // Path to directory used to contain the test data.
- std::wstring test_dir_;
-
- DISALLOW_EVIL_CONSTRUCTORS(DataUnitTest);
-};
-
-// Lightweight HDC management.
-class Context {
- public:
- Context() : context_(CreateCompatibleDC(NULL)) {
- EXPECT_TRUE(context_);
- }
- ~Context() {
- DeleteDC(context_);
- }
-
- HDC context() const { return context_; }
-
- private:
- HDC context_;
-
- DISALLOW_EVIL_CONSTRUCTORS(Context);
-};
-
-// Lightweight HBITMAP management.
-class Bitmap {
- public:
- Bitmap(const Context& context, int x, int y) {
- BITMAPINFOHEADER hdr;
- gfx::CreateBitmapHeader(x, y, &hdr);
- bitmap_ = CreateDIBSection(context.context(),
- reinterpret_cast<BITMAPINFO*>(&hdr), 0,
- &data_, NULL, 0);
- EXPECT_TRUE(bitmap_);
- EXPECT_TRUE(SelectObject(context.context(), bitmap_));
- }
- ~Bitmap() {
- EXPECT_TRUE(DeleteObject(bitmap_));
- }
-
- private:
- HBITMAP bitmap_;
-
- void* data_;
-
- DISALLOW_EVIL_CONSTRUCTORS(Bitmap);
-};
-
-// Lightweight raw-bitmap management. The image, once initialized, is immuable.
-// It is mainly used for comparison.
-class Image {
- public:
- // Creates the image from the given filename on disk.
- Image(const std::wstring& filename) : ignore_alpha_(true) {
- std::string compressed;
- file_util::ReadFileToString(filename, &compressed);
- EXPECT_TRUE(compressed.size());
-
- int w;
- int h;
- EXPECT_TRUE(PNGDecoder::Decode(
- reinterpret_cast<const unsigned char*>(compressed.c_str()),
- compressed.size(), PNGDecoder::FORMAT_BGRA, &data_, &w, &h));
- size_.SetSize(w, h);
- row_length_ = w * sizeof(uint32);
- }
-
- // Loads the image from a canvas.
- Image(const gfx::PlatformCanvasWin& canvas) : ignore_alpha_(true) {
- // Use a different way to access the bitmap. The normal way would be to
- // query the SkBitmap.
- HDC context = canvas.getTopPlatformDevice().getBitmapDC();
- HGDIOBJ bitmap = GetCurrentObject(context, OBJ_BITMAP);
- EXPECT_TRUE(bitmap != NULL);
- // Initialize the clip region to the entire bitmap.
- BITMAP bitmap_data;
- EXPECT_EQ(GetObject(bitmap, sizeof(BITMAP), &bitmap_data),
- sizeof(BITMAP));
- size_.SetSize(bitmap_data.bmWidth, bitmap_data.bmHeight);
- row_length_ = bitmap_data.bmWidthBytes;
- size_t size = row_length_ * size_.height();
- data_.resize(size);
- memcpy(&*data_.begin(), bitmap_data.bmBits, size);
- }
-
- // Loads the image from a canvas.
- Image(const SkBitmap& bitmap) : ignore_alpha_(true) {
- SkAutoLockPixels lock(bitmap);
- size_.SetSize(bitmap.width(), bitmap.height());
- row_length_ = static_cast<int>(bitmap.rowBytes());
- size_t size = row_length_ * size_.height();
- data_.resize(size);
- memcpy(&*data_.begin(), bitmap.getAddr(0, 0), size);
- }
-
- const gfx::Size& size() const {
- return size_;
- }
-
- int row_length() const {
- return row_length_;
- }
-
- // Save the image to a png file. Used to create the initial test files.
- void SaveToFile(const std::wstring& filename) {
- std::vector<unsigned char> compressed;
- ASSERT_TRUE(PNGEncoder::Encode(&*data_.begin(),
- PNGEncoder::FORMAT_BGRA,
- size_.width(),
- size_.height(),
- row_length_,
- true,
- &compressed));
- ASSERT_TRUE(compressed.size());
- FILE* f = file_util::OpenFile(filename, "wb");
- ASSERT_TRUE(f);
- ASSERT_EQ(fwrite(&*compressed.begin(), 1, compressed.size(), f),
- compressed.size());
- file_util::CloseFile(f);
- }
-
- // Returns the percentage of the image that is different from the other,
- // between 0 and 100.
- double PercentageDifferent(const Image& rhs) const {
- if (size_ != rhs.size_ || row_length_ != rhs.row_length_ ||
- size_.width() == 0 || size_.height() == 0)
- return 100.; // When of different size or empty, they are 100% different.
-
- // Compute pixels different in the overlap
- int pixels_different = 0;
- for (int y = 0; y < size_.height(); ++y) {
- for (int x = 0; x < size_.width(); ++x) {
- uint32_t lhs_pixel = pixel_at(x, y);
- uint32_t rhs_pixel = rhs.pixel_at(x, y);
- if (lhs_pixel != rhs_pixel)
- ++pixels_different;
- }
- }
-
- // Like the WebKit ImageDiff tool, we define percentage different in terms
- // of the size of the 'actual' bitmap.
- double total_pixels = static_cast<double>(size_.width()) *
- static_cast<double>(size_.height());
- return static_cast<double>(pixels_different) / total_pixels * 100.;
- }
-
- // Returns the 0x0RGB or 0xARGB value of the pixel at the given location,
- // depending on ignore_alpha_.
- uint32 pixel_at(int x, int y) const {
- EXPECT_TRUE(x >= 0 && x < size_.width());
- EXPECT_TRUE(y >= 0 && y < size_.height());
- const uint32* data = reinterpret_cast<const uint32*>(&*data_.begin());
- const uint32* data_row = data + y * row_length_ / sizeof(uint32);
- if (ignore_alpha_)
- return data_row[x] & 0xFFFFFF; // Strip out A.
- else
- return data_row[x];
- }
-
- private:
- // Pixel dimensions of the image.
- gfx::Size size_;
-
- // Length of a line in bytes.
- int row_length_;
-
- // Actual bitmap data in arrays of RGBAs (so when loaded as uint32, it's
- // 0xABGR).
- std::vector<unsigned char> data_;
-
- // Flag to signal if the comparison functions should ignore the alpha channel.
- const bool ignore_alpha_;
-
- DISALLOW_EVIL_CONSTRUCTORS(Image);
-};
-
-// Base for tests. Capability to process an image.
-class ImageTest : public DataUnitTest {
- public:
- typedef DataUnitTest parent;
-
- // In what state is the test running.
- enum ProcessAction {
- GENERATE,
- COMPARE,
- NOOP,
- };
-
- ImageTest(const std::wstring& base_path, ProcessAction default_action)
- : parent(base_path),
- action_(default_action) {
- }
-
- protected:
- virtual void SetUp() {
- parent::SetUp();
-
- if (action_ == GENERATE) {
- // Make sure the directory exist.
- file_util::CreateDirectory(test_dir());
- }
- }
-
- // Compares or saves the bitmap currently loaded in the context, depending on
- // kGenerating value. Returns 0 on success or any positive value between ]0,
- // 100] on failure. The return value is the percentage of difference between
- // the image in the file and the image in the canvas.
- double ProcessCanvas(const gfx::PlatformCanvasWin& canvas,
- std::wstring filename) const {
- filename += L".png";
- switch (action_) {
- case GENERATE:
- SaveImage(canvas, filename);
- return 0.;
- case COMPARE:
- return CompareImage(canvas, filename);
- case NOOP:
- return 0;
- default:
- // Invalid state, returns that the image is 100 different.
- return 100.;
- }
- }
-
- // Compares the bitmap currently loaded in the context with the file. Returns
- // the percentage of pixel difference between both images, between 0 and 100.
- double CompareImage(const gfx::PlatformCanvasWin& canvas,
- const std::wstring& filename) const {
- Image image1(canvas);
- Image image2(test_file(filename));
- double diff = image1.PercentageDifferent(image2);
- return diff;
- }
-
- // Saves the bitmap currently loaded in the context into the file.
- void SaveImage(const gfx::PlatformCanvasWin& canvas,
- const std::wstring& filename) const {
- Image(canvas).SaveToFile(test_file(filename));
- }
-
- ProcessAction action_;
-
- DISALLOW_EVIL_CONSTRUCTORS(ImageTest);
-};
-
-// Premultiply the Alpha channel on the R, B and G channels.
-void Premultiply(SkBitmap bitmap) {
- SkAutoLockPixels lock(bitmap);
- for (int x = 0; x < bitmap.width(); ++x) {
- for (int y = 0; y < bitmap.height(); ++y) {
- uint32_t* pixel_addr = bitmap.getAddr32(x, y);
- uint32_t color = *pixel_addr;
- BYTE alpha = SkColorGetA(color);
- if (!alpha) {
- *pixel_addr = 0;
- } else {
- BYTE alpha_offset = alpha / 2;
- *pixel_addr = SkColorSetARGB(
- SkColorGetA(color),
- (SkColorGetR(color) * 255 + alpha_offset) / alpha,
- (SkColorGetG(color) * 255 + alpha_offset) / alpha,
- (SkColorGetB(color) * 255 + alpha_offset) / alpha);
- }
- }
- }
-}
-
-void LoadPngFileToSkBitmap(const std::wstring& file, SkBitmap* bitmap) {
- std::string compressed;
- file_util::ReadFileToString(file, &compressed);
- EXPECT_TRUE(compressed.size());
- // Extra-lame. If you care, fix it.
- std::vector<unsigned char> data;
- data.assign(reinterpret_cast<const unsigned char*>(compressed.c_str()),
- reinterpret_cast<const unsigned char*>(compressed.c_str() +
- compressed.size()));
- EXPECT_TRUE(PNGDecoder::Decode(&data, bitmap));
- EXPECT_FALSE(bitmap->isOpaque());
- Premultiply(*bitmap);
-}
-
-} // namespace
-
-// Streams an image.
-inline std::ostream& operator<<(std::ostream& out, const Image& image) {
- return out << "Image(" << image.size() << ", " << image.row_length() << ")";
-}
-
-// Runs simultaneously the same drawing commands on VectorCanvas and
-// PlatformCanvas and compare the results.
-class VectorCanvasTest : public ImageTest {
- public:
- typedef ImageTest parent;
-
- VectorCanvasTest() : parent(L"base", CurrentMode()), compare_canvas_(true) {
- }
-
- protected:
- virtual void SetUp() {
- parent::SetUp();
- Init(100);
- number_ = 0;
- }
-
- virtual void TearDown() {
- delete pcanvas_;
- pcanvas_ = NULL;
-
- delete vcanvas_;
- vcanvas_ = NULL;
-
- delete bitmap_;
- bitmap_ = NULL;
-
- delete context_;
- context_ = NULL;
-
- parent::TearDown();
- }
-
- void Init(int size) {
- size_ = size;
- context_ = new Context();
- bitmap_ = new Bitmap(*context_, size_, size_);
- vcanvas_ = new gfx::VectorCanvas(context_->context(), size_, size_);
- pcanvas_ = new gfx::PlatformCanvasWin(size_, size_, false);
-
- // Clear white.
- vcanvas_->drawARGB(255, 255, 255, 255, SkPorterDuff::kSrc_Mode);
- pcanvas_->drawARGB(255, 255, 255, 255, SkPorterDuff::kSrc_Mode);
- }
-
- // Compares both canvas and returns the pixel difference in percentage between
- // both images. 0 on success and ]0, 100] on failure.
- double ProcessImage(const std::wstring& filename) {
- std::wstring number(StringPrintf(L"%02d_", number_++));
- double diff1 = parent::ProcessCanvas(*vcanvas_, number + L"vc_" + filename);
- double diff2 = parent::ProcessCanvas(*pcanvas_, number + L"pc_" + filename);
- if (!compare_canvas_)
- return std::max(diff1, diff2);
-
- Image image1(*vcanvas_);
- Image image2(*pcanvas_);
- double diff = image1.PercentageDifferent(image2);
- return std::max(std::max(diff1, diff2), diff);
- }
-
- // Returns COMPARE, which is the default. If kGenerateSwitch command
- // line argument is used to start this process, GENERATE is returned instead.
- static ProcessAction CurrentMode() {
- return CommandLine().HasSwitch(kGenerateSwitch) ? GENERATE : COMPARE;
- }
-
- // Length in x and y of the square canvas.
- int size_;
-
- // Current image number in the current test. Used to number of test files.
- int number_;
-
- // A temporary HDC to draw into.
- Context* context_;
-
- // Bitmap created inside context_.
- Bitmap* bitmap_;
-
- // Vector based canvas.
- gfx::VectorCanvas* vcanvas_;
-
- // Pixel based canvas.
- gfx::PlatformCanvasWin* pcanvas_;
-
- // When true (default), vcanvas_ and pcanvas_ contents are compared and
- // verified to be identical.
- bool compare_canvas_;
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-// Actual tests
-
-TEST_F(VectorCanvasTest, Uninitialized) {
- // Do a little mubadumba do get uninitialized stuff.
- VectorCanvasTest::TearDown();
-
- // The goal is not to verify that have the same uninitialized data.
- compare_canvas_ = false;
-
- context_ = new Context();
- bitmap_ = new Bitmap(*context_, size_, size_);
- vcanvas_ = new gfx::VectorCanvas(context_->context(), size_, size_);
- pcanvas_ = new gfx::PlatformCanvasWin(size_, size_, false);
-
- // VectorCanvas default initialization is black.
- // PlatformCanvas default initialization is almost white 0x01FFFEFD (invalid
- // Skia color) in both Debug and Release. See magicTransparencyColor in
- // platform_device.cc
- EXPECT_EQ(0., ProcessImage(L"empty"));
-}
-
-TEST_F(VectorCanvasTest, BasicDrawing) {
- EXPECT_EQ(Image(*vcanvas_).PercentageDifferent(Image(*pcanvas_)), 0.)
- << L"clean";
- EXPECT_EQ(0., ProcessImage(L"clean"));
-
- // Clear white.
- {
- vcanvas_->drawARGB(255, 255, 255, 255, SkPorterDuff::kSrc_Mode);
- pcanvas_->drawARGB(255, 255, 255, 255, SkPorterDuff::kSrc_Mode);
- }
- EXPECT_EQ(0., ProcessImage(L"drawARGB"));
-
- // Diagonal line top-left to bottom-right.
- {
- SkPaint paint;
- // Default color is black.
- vcanvas_->drawLine(10, 10, 90, 90, paint);
- pcanvas_->drawLine(10, 10, 90, 90, paint);
- }
- EXPECT_EQ(0., ProcessImage(L"drawLine_black"));
-
- // Rect.
- {
- SkPaint paint;
- paint.setColor(SK_ColorGREEN);
- vcanvas_->drawRectCoords(25, 25, 75, 75, paint);
- pcanvas_->drawRectCoords(25, 25, 75, 75, paint);
- }
- EXPECT_EQ(0., ProcessImage(L"drawRect_green"));
-
- // A single-point rect doesn't leave any mark.
- {
- SkPaint paint;
- paint.setColor(SK_ColorBLUE);
- vcanvas_->drawRectCoords(5, 5, 5, 5, paint);
- pcanvas_->drawRectCoords(5, 5, 5, 5, paint);
- }
- EXPECT_EQ(0., ProcessImage(L"drawRect_noop"));
-
- // Rect.
- {
- SkPaint paint;
- paint.setColor(SK_ColorBLUE);
- vcanvas_->drawRectCoords(75, 50, 80, 55, paint);
- pcanvas_->drawRectCoords(75, 50, 80, 55, paint);
- }
- EXPECT_EQ(0., ProcessImage(L"drawRect_noop"));
-
- // Empty again
- {
- vcanvas_->drawPaint(SkPaint());
- pcanvas_->drawPaint(SkPaint());
- }
- EXPECT_EQ(0., ProcessImage(L"drawPaint_black"));
-
- // Horizontal line left to right.
- {
- SkPaint paint;
- paint.setColor(SK_ColorRED);
- vcanvas_->drawLine(10, 20, 90, 20, paint);
- pcanvas_->drawLine(10, 20, 90, 20, paint);
- }
- EXPECT_EQ(0., ProcessImage(L"drawLine_left_to_right"));
-
- // Vertical line downward.
- {
- SkPaint paint;
- paint.setColor(SK_ColorRED);
- vcanvas_->drawLine(30, 10, 30, 90, paint);
- pcanvas_->drawLine(30, 10, 30, 90, paint);
- }
- EXPECT_EQ(0., ProcessImage(L"drawLine_red"));
-}
-
-TEST_F(VectorCanvasTest, Circles) {
- // There is NO WAY to make them agree. At least verify that the output doesn't
- // change across versions. This test is disabled. See bug 1060231.
- compare_canvas_ = false;
-
- // Stroked Circle.
- {
- SkPaint paint;
- SkPath path;
- path.addCircle(50, 75, 10);
- paint.setStyle(SkPaint::kStroke_Style);
- paint.setColor(SK_ColorMAGENTA);
- vcanvas_->drawPath(path, paint);
- pcanvas_->drawPath(path, paint);
- }
- EXPECT_EQ(0., ProcessImage(L"circle_stroke"));
-
- // Filled Circle.
- {
- SkPaint paint;
- SkPath path;
- path.addCircle(50, 25, 10);
- paint.setStyle(SkPaint::kFill_Style);
- vcanvas_->drawPath(path, paint);
- pcanvas_->drawPath(path, paint);
- }
- EXPECT_EQ(0., ProcessImage(L"circle_fill"));
-
- // Stroked Circle over.
- {
- SkPaint paint;
- SkPath path;
- path.addCircle(50, 25, 10);
- paint.setStyle(SkPaint::kStroke_Style);
- paint.setColor(SK_ColorBLUE);
- vcanvas_->drawPath(path, paint);
- pcanvas_->drawPath(path, paint);
- }
- EXPECT_EQ(0., ProcessImage(L"circle_over_strike"));
-
- // Stroke and Fill Circle.
- {
- SkPaint paint;
- SkPath path;
- path.addCircle(12, 50, 10);
- paint.setStyle(SkPaint::kStrokeAndFill_Style);
- paint.setColor(SK_ColorRED);
- vcanvas_->drawPath(path, paint);
- pcanvas_->drawPath(path, paint);
- }
- EXPECT_EQ(0., ProcessImage(L"circle_stroke_and_fill"));
-
- // Line + Quad + Cubic.
- {
- SkPaint paint;
- SkPath path;
- paint.setStyle(SkPaint::kStroke_Style);
- paint.setColor(SK_ColorGREEN);
- path.moveTo(1, 1);
- path.lineTo(60, 40);
- path.lineTo(80, 80);
- path.quadTo(20, 50, 10, 90);
- path.quadTo(50, 20, 90, 10);
- path.cubicTo(20, 40, 50, 50, 10, 10);
- path.cubicTo(30, 20, 50, 50, 90, 10);
- path.addRect(90, 90, 95, 96);
- vcanvas_->drawPath(path, paint);
- pcanvas_->drawPath(path, paint);
- }
- EXPECT_EQ(0., ProcessImage(L"mixed_stroke"));
-}
-
-TEST_F(VectorCanvasTest, LineOrientation) {
- // There is NO WAY to make them agree. At least verify that the output doesn't
- // change across versions. This test is disabled. See bug 1060231.
- compare_canvas_ = false;
-
- // Horizontal lines.
- {
- SkPaint paint;
- paint.setColor(SK_ColorRED);
- // Left to right.
- vcanvas_->drawLine(10, 20, 90, 20, paint);
- pcanvas_->drawLine(10, 20, 90, 20, paint);
- // Right to left.
- vcanvas_->drawLine(90, 30, 10, 30, paint);
- pcanvas_->drawLine(90, 30, 10, 30, paint);
- }
- EXPECT_EQ(0., ProcessImage(L"horizontal"));
-
- // Vertical lines.
- {
- SkPaint paint;
- paint.setColor(SK_ColorRED);
- // Top down.
- vcanvas_->drawLine(20, 10, 20, 90, paint);
- pcanvas_->drawLine(20, 10, 20, 90, paint);
- // Bottom up.
- vcanvas_->drawLine(30, 90, 30, 10, paint);
- pcanvas_->drawLine(30, 90, 30, 10, paint);
- }
- EXPECT_EQ(0., ProcessImage(L"vertical"));
-
- // Try again with a 180 degres rotation.
- vcanvas_->rotate(180);
- pcanvas_->rotate(180);
-
- // Horizontal lines (rotated).
- {
- SkPaint paint;
- paint.setColor(SK_ColorRED);
- vcanvas_->drawLine(-10, -25, -90, -25, paint);
- pcanvas_->drawLine(-10, -25, -90, -25, paint);
- vcanvas_->drawLine(-90, -35, -10, -35, paint);
- pcanvas_->drawLine(-90, -35, -10, -35, paint);
- }
- EXPECT_EQ(0., ProcessImage(L"horizontal_180"));
-
- // Vertical lines (rotated).
- {
- SkPaint paint;
- paint.setColor(SK_ColorRED);
- vcanvas_->drawLine(-25, -10, -25, -90, paint);
- pcanvas_->drawLine(-25, -10, -25, -90, paint);
- vcanvas_->drawLine(-35, -90, -35, -10, paint);
- pcanvas_->drawLine(-35, -90, -35, -10, paint);
- }
- EXPECT_EQ(0., ProcessImage(L"vertical_180"));
-}
-
-TEST_F(VectorCanvasTest, PathOrientation) {
- // There is NO WAY to make them agree. At least verify that the output doesn't
- // change across versions. This test is disabled. See bug 1060231.
- compare_canvas_ = false;
-
- // Horizontal lines.
- {
- SkPaint paint;
- paint.setStyle(SkPaint::kStroke_Style);
- paint.setColor(SK_ColorRED);
- SkPath path;
- SkPoint start;
- start.set(10, 20);
- SkPoint end;
- end.set(90, 20);
- path.moveTo(start);
- path.lineTo(end);
- vcanvas_->drawPath(path, paint);
- pcanvas_->drawPath(path, paint);
- }
- EXPECT_EQ(0., ProcessImage(L"drawPath_ltr"));
-
- // Horizontal lines.
- {
- SkPaint paint;
- paint.setStyle(SkPaint::kStroke_Style);
- paint.setColor(SK_ColorRED);
- SkPath path;
- SkPoint start;
- start.set(90, 30);
- SkPoint end;
- end.set(10, 30);
- path.moveTo(start);
- path.lineTo(end);
- vcanvas_->drawPath(path, paint);
- pcanvas_->drawPath(path, paint);
- }
- EXPECT_EQ(0., ProcessImage(L"drawPath_rtl"));
-}
-
-TEST_F(VectorCanvasTest, DiagonalLines) {
- SkPaint paint;
- paint.setColor(SK_ColorRED);
-
- vcanvas_->drawLine(10, 10, 90, 90, paint);
- pcanvas_->drawLine(10, 10, 90, 90, paint);
- EXPECT_EQ(0., ProcessImage(L"nw-se"));
-
- // Starting here, there is NO WAY to make them agree. At least verify that the
- // output doesn't change across versions. This test is disabled. See bug
- // 1060231.
- compare_canvas_ = false;
-
- vcanvas_->drawLine(10, 95, 90, 15, paint);
- pcanvas_->drawLine(10, 95, 90, 15, paint);
- EXPECT_EQ(0., ProcessImage(L"sw-ne"));
-
- vcanvas_->drawLine(90, 10, 10, 90, paint);
- pcanvas_->drawLine(90, 10, 10, 90, paint);
- EXPECT_EQ(0., ProcessImage(L"ne-sw"));
-
- vcanvas_->drawLine(95, 90, 15, 10, paint);
- pcanvas_->drawLine(95, 90, 15, 10, paint);
- EXPECT_EQ(0., ProcessImage(L"se-nw"));
-}
-
-TEST_F(VectorCanvasTest, PathEffects) {
- {
- SkPaint paint;
- SkScalar intervals[] = { 1, 1 };
- SkPathEffect* effect = new SkDashPathEffect(intervals, arraysize(intervals),
- 0);
- paint.setPathEffect(effect)->unref();
- paint.setColor(SK_ColorMAGENTA);
- paint.setStyle(SkPaint::kStroke_Style);
-
- vcanvas_->drawLine(10, 10, 90, 10, paint);
- pcanvas_->drawLine(10, 10, 90, 10, paint);
- }
- EXPECT_EQ(0., ProcessImage(L"dash_line"));
-
-
- // Starting here, there is NO WAY to make them agree. At least verify that the
- // output doesn't change across versions. This test is disabled. See bug
- // 1060231.
- compare_canvas_ = false;
-
- {
- SkPaint paint;
- SkScalar intervals[] = { 3, 5 };
- SkPathEffect* effect = new SkDashPathEffect(intervals, arraysize(intervals),
- 0);
- paint.setPathEffect(effect)->unref();
- paint.setColor(SK_ColorMAGENTA);
- paint.setStyle(SkPaint::kStroke_Style);
-
- SkPath path;
- path.moveTo(10, 15);
- path.lineTo(90, 15);
- path.lineTo(90, 90);
- vcanvas_->drawPath(path, paint);
- pcanvas_->drawPath(path, paint);
- }
- EXPECT_EQ(0., ProcessImage(L"dash_path"));
-
- {
- SkPaint paint;
- SkScalar intervals[] = { 2, 1 };
- SkPathEffect* effect = new SkDashPathEffect(intervals, arraysize(intervals),
- 0);
- paint.setPathEffect(effect)->unref();
- paint.setColor(SK_ColorMAGENTA);
- paint.setStyle(SkPaint::kStroke_Style);
-
- vcanvas_->drawRectCoords(20, 20, 30, 30, paint);
- pcanvas_->drawRectCoords(20, 20, 30, 30, paint);
- }
- EXPECT_EQ(0., ProcessImage(L"dash_rect"));
-
- // This thing looks like it has been drawn by a 3 years old kid. I haven't
- // filed a bug on this since I guess nobody is expecting this to look nice.
- {
- SkPaint paint;
- SkScalar intervals[] = { 1, 1 };
- SkPathEffect* effect = new SkDashPathEffect(intervals, arraysize(intervals),
- 0);
- paint.setPathEffect(effect)->unref();
- paint.setColor(SK_ColorMAGENTA);
- paint.setStyle(SkPaint::kStroke_Style);
-
- SkPath path;
- path.addCircle(50, 75, 10);
- vcanvas_->drawPath(path, paint);
- pcanvas_->drawPath(path, paint);
- EXPECT_EQ(0., ProcessImage(L"circle"));
- }
-}
-
-TEST_F(VectorCanvasTest, Bitmaps) {
- // ICM is enabled on VectorCanvas only on Windows 2000 so bitmap-based tests
- // can't compare the pixels between PlatformCanvas and VectorCanvas. We don't
- // really care about Windows 2000 pixel colors.
- if (win_util::GetWinVersion() <= win_util::WINVERSION_2000)
- return;
- {
- SkBitmap bitmap;
- LoadPngFileToSkBitmap(test_file(L"bitmap_opaque.png"), &bitmap);
- vcanvas_->drawBitmap(bitmap, 13, 3, NULL);
- pcanvas_->drawBitmap(bitmap, 13, 3, NULL);
- EXPECT_EQ(0., ProcessImage(L"opaque"));
- }
-
- {
- SkBitmap bitmap;
- LoadPngFileToSkBitmap(test_file(L"bitmap_alpha.png"), &bitmap);
- vcanvas_->drawBitmap(bitmap, 5, 15, NULL);
- pcanvas_->drawBitmap(bitmap, 5, 15, NULL);
- EXPECT_EQ(0., ProcessImage(L"alpha"));
- }
-}
-
-TEST_F(VectorCanvasTest, ClippingRect) {
- // ICM is enabled on VectorCanvas only on Windows 2000 so bitmap-based tests
- // can't compare the pixels between PlatformCanvas and VectorCanvas. We don't
- // really care about Windows 2000 pixel colors.
- if (win_util::GetWinVersion() <= win_util::WINVERSION_2000)
- return;
- SkBitmap bitmap;
- LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap);
- SkRect rect;
- rect.fLeft = 2;
- rect.fTop = 2;
- rect.fRight = 30.5f;
- rect.fBottom = 30.5f;
- vcanvas_->clipRect(rect);
- pcanvas_->clipRect(rect);
-
- vcanvas_->drawBitmap(bitmap, 13, 3, NULL);
- pcanvas_->drawBitmap(bitmap, 13, 3, NULL);
- EXPECT_EQ(0., ProcessImage(L"rect"));
-}
-
-TEST_F(VectorCanvasTest, ClippingPath) {
- // ICM is enabled on VectorCanvas only on Windows 2000 so bitmap-based tests
- // can't compare the pixels between PlatformCanvas and VectorCanvas. We don't
- // really care about Windows 2000 pixel colors.
- if (win_util::GetWinVersion() <= win_util::WINVERSION_2000)
- return;
- SkBitmap bitmap;
- LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap);
- SkPath path;
- path.addCircle(20, 20, 10);
- vcanvas_->clipPath(path);
- pcanvas_->clipPath(path);
-
- vcanvas_->drawBitmap(bitmap, 14, 3, NULL);
- pcanvas_->drawBitmap(bitmap, 14, 3, NULL);
- EXPECT_EQ(0., ProcessImage(L"path"));
-}
-
-TEST_F(VectorCanvasTest, ClippingCombined) {
- // ICM is enabled on VectorCanvas only on Windows 2000 so bitmap-based tests
- // can't compare the pixels between PlatformCanvas and VectorCanvas. We don't
- // really care about Windows 2000 pixel colors.
- if (win_util::GetWinVersion() <= win_util::WINVERSION_2000)
- return;
- SkBitmap bitmap;
- LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap);
-
- SkRect rect;
- rect.fLeft = 2;
- rect.fTop = 2;
- rect.fRight = 30.5f;
- rect.fBottom = 30.5f;
- vcanvas_->clipRect(rect);
- pcanvas_->clipRect(rect);
- SkPath path;
- path.addCircle(20, 20, 10);
- vcanvas_->clipPath(path, SkRegion::kUnion_Op);
- pcanvas_->clipPath(path, SkRegion::kUnion_Op);
-
- vcanvas_->drawBitmap(bitmap, 15, 3, NULL);
- pcanvas_->drawBitmap(bitmap, 15, 3, NULL);
- EXPECT_EQ(0., ProcessImage(L"combined"));
-}
-
-TEST_F(VectorCanvasTest, ClippingIntersect) {
- // ICM is enabled on VectorCanvas only on Windows 2000 so bitmap-based tests
- // can't compare the pixels between PlatformCanvas and VectorCanvas. We don't
- // really care about Windows 2000 pixel colors.
- if (win_util::GetWinVersion() <= win_util::WINVERSION_2000)
- return;
- SkBitmap bitmap;
- LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap);
-
- SkRect rect;
- rect.fLeft = 2;
- rect.fTop = 2;
- rect.fRight = 30.5f;
- rect.fBottom = 30.5f;
- vcanvas_->clipRect(rect);
- pcanvas_->clipRect(rect);
- SkPath path;
- path.addCircle(23, 23, 15);
- vcanvas_->clipPath(path);
- pcanvas_->clipPath(path);
-
- vcanvas_->drawBitmap(bitmap, 15, 3, NULL);
- pcanvas_->drawBitmap(bitmap, 15, 3, NULL);
- EXPECT_EQ(0., ProcessImage(L"intersect"));
-}
-
-TEST_F(VectorCanvasTest, ClippingClean) {
- // ICM is enabled on VectorCanvas only on Windows 2000 so bitmap-based tests
- // can't compare the pixels between PlatformCanvas and VectorCanvas. We don't
- // really care about Windows 2000 pixel colors.
- if (win_util::GetWinVersion() <= win_util::WINVERSION_2000)
- return;
- SkBitmap bitmap;
- LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap);
- {
- SkRegion old_region(pcanvas_->getTotalClip());
- SkRect rect;
- rect.fLeft = 2;
- rect.fTop = 2;
- rect.fRight = 30.5f;
- rect.fBottom = 30.5f;
- vcanvas_->clipRect(rect);
- pcanvas_->clipRect(rect);
-
- vcanvas_->drawBitmap(bitmap, 15, 3, NULL);
- pcanvas_->drawBitmap(bitmap, 15, 3, NULL);
- EXPECT_EQ(0., ProcessImage(L"clipped"));
- vcanvas_->clipRegion(old_region, SkRegion::kReplace_Op);
- pcanvas_->clipRegion(old_region, SkRegion::kReplace_Op);
- }
- {
- // Verify that the clipping region has been fixed back.
- vcanvas_->drawBitmap(bitmap, 55, 3, NULL);
- pcanvas_->drawBitmap(bitmap, 55, 3, NULL);
- EXPECT_EQ(0., ProcessImage(L"unclipped"));
- }
-}
-
-TEST_F(VectorCanvasTest, Matrix) {
- // ICM is enabled on VectorCanvas only on Windows 2000 so bitmap-based tests
- // can't compare the pixels between PlatformCanvas and VectorCanvas. We don't
- // really care about Windows 2000 pixel colors.
- if (win_util::GetWinVersion() <= win_util::WINVERSION_2000)
- return;
- SkBitmap bitmap;
- LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap);
- {
- vcanvas_->translate(15, 3);
- pcanvas_->translate(15, 3);
- vcanvas_->drawBitmap(bitmap, 0, 0, NULL);
- pcanvas_->drawBitmap(bitmap, 0, 0, NULL);
- EXPECT_EQ(0., ProcessImage(L"translate1"));
- }
- {
- vcanvas_->translate(-30, -23);
- pcanvas_->translate(-30, -23);
- vcanvas_->drawBitmap(bitmap, 0, 0, NULL);
- pcanvas_->drawBitmap(bitmap, 0, 0, NULL);
- EXPECT_EQ(0., ProcessImage(L"translate2"));
- }
- vcanvas_->resetMatrix();
- pcanvas_->resetMatrix();
-
- // For scaling and rotation, they use a different algorithm (nearest
- // neighborhood vs smoothing). At least verify that the output doesn't change
- // across versions.
- compare_canvas_ = false;
-
- {
- vcanvas_->scale(SkDoubleToScalar(1.9), SkDoubleToScalar(1.5));
- pcanvas_->scale(SkDoubleToScalar(1.9), SkDoubleToScalar(1.5));
- vcanvas_->drawBitmap(bitmap, 1, 1, NULL);
- pcanvas_->drawBitmap(bitmap, 1, 1, NULL);
- EXPECT_EQ(0., ProcessImage(L"scale"));
- }
- vcanvas_->resetMatrix();
- pcanvas_->resetMatrix();
-
- {
- vcanvas_->rotate(67);
- pcanvas_->rotate(67);
- vcanvas_->drawBitmap(bitmap, 20, -50, NULL);
- pcanvas_->drawBitmap(bitmap, 20, -50, NULL);
- EXPECT_EQ(0., ProcessImage(L"rotate"));
- }
-}
-
diff --git a/base/gfx/vector_device.cc b/base/gfx/vector_device.cc
deleted file mode 100644
index 26da338..0000000
--- a/base/gfx/vector_device.cc
+++ /dev/null
@@ -1,612 +0,0 @@
-// 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 "base/gfx/vector_device.h"
-
-#include "base/gfx/gdi_util.h"
-#include "base/gfx/skia_utils.h"
-#include "base/logging.h"
-#include "base/scoped_handle.h"
-
-#include "SkUtils.h"
-
-namespace gfx {
-
-VectorDevice* VectorDevice::create(HDC dc, int width, int height) {
- InitializeDC(dc);
-
- // Link the SkBitmap to the current selected bitmap in the device context.
- SkBitmap bitmap;
- HGDIOBJ selected_bitmap = GetCurrentObject(dc, OBJ_BITMAP);
- bool succeeded = false;
- if (selected_bitmap != NULL) {
- BITMAP bitmap_data;
- if (GetObject(selected_bitmap, sizeof(BITMAP), &bitmap_data) ==
- sizeof(BITMAP)) {
- // The context has a bitmap attached. Attach our SkBitmap to it.
- // Warning: If the bitmap gets unselected from the HDC, VectorDevice has
- // no way to detect this, so the HBITMAP could be released while SkBitmap
- // still has a reference to it. Be cautious.
- if (width == bitmap_data.bmWidth &&
- height == bitmap_data.bmHeight) {
- bitmap.setConfig(SkBitmap::kARGB_8888_Config,
- bitmap_data.bmWidth,
- bitmap_data.bmHeight,
- bitmap_data.bmWidthBytes);
- bitmap.setPixels(bitmap_data.bmBits);
- succeeded = true;
- }
- }
- }
-
- if (!succeeded)
- bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
-
- return new VectorDevice(dc, bitmap);
-}
-
-VectorDevice::VectorDevice(HDC dc, const SkBitmap& bitmap)
- : PlatformDeviceWin(bitmap),
- hdc_(dc),
- previous_brush_(NULL),
- previous_pen_(NULL) {
- transform_.reset();
-}
-
-VectorDevice::~VectorDevice() {
- DCHECK(previous_brush_ == NULL);
- DCHECK(previous_pen_ == NULL);
-}
-
-
-void VectorDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
- // TODO(maruel): Bypass the current transformation matrix.
- SkRect rect;
- rect.fLeft = 0;
- rect.fTop = 0;
- rect.fRight = SkIntToScalar(width() + 1);
- rect.fBottom = SkIntToScalar(height() + 1);
- drawRect(draw, rect, paint);
-}
-
-void VectorDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
- size_t count, const SkPoint pts[],
- const SkPaint& paint) {
- if (!count)
- return;
-
- if (mode == SkCanvas::kPoints_PointMode) {
- NOTREACHED();
- return;
- }
-
- SkPaint tmp_paint(paint);
- tmp_paint.setStyle(SkPaint::kStroke_Style);
-
- // Draw a path instead.
- SkPath path;
- switch (mode) {
- case SkCanvas::kLines_PointMode:
- if (count % 2) {
- NOTREACHED();
- return;
- }
- for (size_t i = 0; i < count / 2; ++i) {
- path.moveTo(pts[2 * i]);
- path.lineTo(pts[2 * i + 1]);
- }
- break;
- case SkCanvas::kPolygon_PointMode:
- path.moveTo(pts[0]);
- for (size_t i = 1; i < count; ++i) {
- path.lineTo(pts[i]);
- }
- break;
- default:
- NOTREACHED();
- return;
- }
- // Draw the calculated path.
- drawPath(draw, path, tmp_paint);
-}
-
-void VectorDevice::drawRect(const SkDraw& draw, const SkRect& rect,
- const SkPaint& paint) {
- if (paint.getPathEffect()) {
- // Draw a path instead.
- SkPath path_orginal;
- path_orginal.addRect(rect);
-
- // Apply the path effect to the rect.
- SkPath path_modified;
- paint.getFillPath(path_orginal, &path_modified);
-
- // Removes the path effect from the temporary SkPaint object.
- SkPaint paint_no_effet(paint);
- paint_no_effet.setPathEffect(NULL)->safeUnref();
-
- // Draw the calculated path.
- drawPath(draw, path_modified, paint_no_effet);
- return;
- }
-
- if (!ApplyPaint(paint)) {
- return;
- }
- HDC dc = getBitmapDC();
- if (!Rectangle(dc, SkScalarRound(rect.fLeft),
- SkScalarRound(rect.fTop),
- SkScalarRound(rect.fRight),
- SkScalarRound(rect.fBottom))) {
- NOTREACHED();
- }
- Cleanup();
-}
-
-void VectorDevice::drawPath(const SkDraw& draw, const SkPath& path,
- const SkPaint& paint) {
- if (paint.getPathEffect()) {
- // Apply the path effect forehand.
- SkPath path_modified;
- paint.getFillPath(path, &path_modified);
-
- // Removes the path effect from the temporary SkPaint object.
- SkPaint paint_no_effet(paint);
- paint_no_effet.setPathEffect(NULL)->safeUnref();
-
- // Draw the calculated path.
- drawPath(draw, path_modified, paint_no_effet);
- return;
- }
-
- if (!ApplyPaint(paint)) {
- return;
- }
- HDC dc = getBitmapDC();
- PlatformDeviceWin::LoadPathToDC(dc, path);
- switch (paint.getStyle()) {
- case SkPaint::kFill_Style: {
- BOOL res = StrokeAndFillPath(dc);
- DCHECK(res != 0);
- break;
- }
- case SkPaint::kStroke_Style: {
- BOOL res = StrokePath(dc);
- DCHECK(res != 0);
- break;
- }
- case SkPaint::kStrokeAndFill_Style: {
- BOOL res = StrokeAndFillPath(dc);
- DCHECK(res != 0);
- break;
- }
- default:
- NOTREACHED();
- break;
- }
- Cleanup();
-}
-
-void VectorDevice::drawBitmap(const SkDraw& draw, const SkBitmap& bitmap,
- const SkMatrix& matrix, const SkPaint& paint) {
- // Load the temporary matrix. This is what will translate, rotate and resize
- // the bitmap.
- SkMatrix actual_transform(transform_);
- actual_transform.preConcat(matrix);
- LoadTransformToDC(hdc_, actual_transform);
-
- InternalDrawBitmap(bitmap, 0, 0, paint);
-
- // Restore the original matrix.
- LoadTransformToDC(hdc_, transform_);
-}
-
-void VectorDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
- int x, int y, const SkPaint& paint) {
- SkMatrix identity;
- identity.reset();
- LoadTransformToDC(hdc_, identity);
-
- InternalDrawBitmap(bitmap, x, y, paint);
-
- // Restore the original matrix.
- LoadTransformToDC(hdc_, transform_);
-}
-
-void VectorDevice::drawText(const SkDraw& draw, const void* text, size_t byteLength,
- SkScalar x, SkScalar y, const SkPaint& paint) {
- // This function isn't used in the code. Verify this assumption.
- NOTREACHED();
-}
-
-void VectorDevice::drawPosText(const SkDraw& draw, const void* text, size_t len,
- const SkScalar pos[], SkScalar constY,
- int scalarsPerPos, const SkPaint& paint) {
- // This function isn't used in the code. Verify this assumption.
- NOTREACHED();
-}
-
-void VectorDevice::drawTextOnPath(const SkDraw& draw, const void* text,
- size_t len,
- const SkPath& path, const SkMatrix* matrix,
- const SkPaint& paint) {
- // This function isn't used in the code. Verify this assumption.
- NOTREACHED();
-}
-
-void VectorDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
- int vertexCount,
- const SkPoint vertices[], const SkPoint texs[],
- const SkColor colors[], SkXfermode* xmode,
- const uint16_t indices[], int indexCount,
- const SkPaint& paint) {
- // This function isn't used in the code. Verify this assumption.
- NOTREACHED();
-}
-
-void VectorDevice::drawDevice(const SkDraw& draw, SkDevice* device, int x,
- int y, const SkPaint& paint) {
- // TODO(maruel): http://b/1183870 Playback the EMF buffer at printer's dpi if
- // it is a vectorial device.
- drawSprite(draw, device->accessBitmap(false), x, y, paint);
-}
-
-bool VectorDevice::ApplyPaint(const SkPaint& paint) {
- // Note: The goal here is to transfert the SkPaint's state to the HDC's state.
- // This function does not execute the SkPaint drawing commands. These should
- // be executed in drawPaint().
-
- SkPaint::Style style = paint.getStyle();
- if (!paint.getAlpha())
- style = SkPaint::kStyleCount;
-
- switch (style) {
- case SkPaint::kFill_Style:
- if (!CreateBrush(true, paint) ||
- !CreatePen(false, paint))
- return false;
- break;
- case SkPaint::kStroke_Style:
- if (!CreateBrush(false, paint) ||
- !CreatePen(true, paint))
- return false;
- break;
- case SkPaint::kStrokeAndFill_Style:
- if (!CreateBrush(true, paint) ||
- !CreatePen(true, paint))
- return false;
- break;
- default:
- if (!CreateBrush(false, paint) ||
- !CreatePen(false, paint))
- return false;
- break;
- }
-
- /*
- getFlags();
- isAntiAlias();
- isDither()
- isLinearText()
- isSubpixelText()
- isUnderlineText()
- isStrikeThruText()
- isFakeBoldText()
- isDevKernText()
- isFilterBitmap()
-
- // Skia's text is not used. This should be fixed.
- getTextAlign()
- getTextScaleX()
- getTextSkewX()
- getTextEncoding()
- getFontMetrics()
- getFontSpacing()
- */
-
- // BUG 1094907: Implement shaders. Shaders currently in use:
- // SkShader::CreateBitmapShader
- // SkGradientShader::CreateRadial
- // SkGradientShader::CreateLinear
- // DCHECK(!paint.getShader());
-
- // http://b/1106647 Implement loopers and mask filter. Looper currently in
- // use:
- // SkBlurDrawLooper is used for shadows.
- // DCHECK(!paint.getLooper());
- // DCHECK(!paint.getMaskFilter());
-
- // http://b/1165900 Implement xfermode.
- // DCHECK(!paint.getXfermode());
-
- // The path effect should be processed before arriving here.
- DCHECK(!paint.getPathEffect());
-
- // These aren't used in the code. Verify this assumption.
- DCHECK(!paint.getColorFilter());
- DCHECK(!paint.getRasterizer());
- // Reuse code to load Win32 Fonts.
- DCHECK(!paint.getTypeface());
- return true;
-}
-
-void VectorDevice::setMatrixClip(const SkMatrix& transform,
- const SkRegion& region) {
- transform_ = transform;
- LoadTransformToDC(hdc_, transform_);
- clip_region_ = region;
- if (!clip_region_.isEmpty())
- LoadClipRegion();
-}
-
-void VectorDevice::drawToHDC(HDC dc, int x, int y, const RECT* src_rect) {
- NOTREACHED();
-}
-
-void VectorDevice::LoadClipRegion() {
- SkMatrix t;
- t.reset();
- LoadClippingRegionToDC(hdc_, clip_region_, t);
-}
-
-bool VectorDevice::CreateBrush(bool use_brush, COLORREF color) {
- DCHECK(previous_brush_ == NULL);
- // We can't use SetDCBrushColor() or DC_BRUSH when drawing to a EMF buffer.
- // SetDCBrushColor() calls are not recorded at all and DC_BRUSH will use
- // WHITE_BRUSH instead.
-
- if (!use_brush) {
- // Set the transparency.
- if (0 == SetBkMode(hdc_, TRANSPARENT)) {
- NOTREACHED();
- return false;
- }
-
- // Select the NULL brush.
- previous_brush_ = SelectObject(GetStockObject(NULL_BRUSH));
- return previous_brush_ != NULL;
- }
-
- // Set the opacity.
- if (0 == SetBkMode(hdc_, OPAQUE)) {
- NOTREACHED();
- return false;
- }
-
- // Create and select the brush.
- previous_brush_ = SelectObject(CreateSolidBrush(color));
- return previous_brush_ != NULL;
-}
-
-bool VectorDevice::CreatePen(bool use_pen, COLORREF color, int stroke_width,
- float stroke_miter, DWORD pen_style) {
- DCHECK(previous_pen_ == NULL);
- // We can't use SetDCPenColor() or DC_PEN when drawing to a EMF buffer.
- // SetDCPenColor() calls are not recorded at all and DC_PEN will use BLACK_PEN
- // instead.
-
- // No pen case
- if (!use_pen) {
- previous_pen_ = SelectObject(GetStockObject(NULL_PEN));
- return previous_pen_ != NULL;
- }
-
- // Use the stock pen if the stroke width is 0.
- if (stroke_width == 0) {
- // Create a pen with the right color.
- previous_pen_ = SelectObject(::CreatePen(PS_SOLID, 0, color));
- return previous_pen_ != NULL;
- }
-
- // Load a custom pen.
- LOGBRUSH brush;
- brush.lbStyle = BS_SOLID;
- brush.lbColor = color;
- brush.lbHatch = 0;
- HPEN pen = ExtCreatePen(pen_style, stroke_width, &brush, 0, NULL);
- DCHECK(pen != NULL);
- previous_pen_ = SelectObject(pen);
- if (previous_pen_ == NULL)
- return false;
-
- if (!SetMiterLimit(hdc_, stroke_miter, NULL)) {
- NOTREACHED();
- return false;
- }
- return true;
-}
-
-void VectorDevice::Cleanup() {
- if (previous_brush_) {
- HGDIOBJ result = SelectObject(previous_brush_);
- previous_brush_ = NULL;
- if (result) {
- BOOL res = DeleteObject(result);
- DCHECK(res != 0);
- }
- }
- if (previous_pen_) {
- HGDIOBJ result = SelectObject(previous_pen_);
- previous_pen_ = NULL;
- if (result) {
- BOOL res = DeleteObject(result);
- DCHECK(res != 0);
- }
- }
- // Remove any loaded path from the context.
- AbortPath(hdc_);
-}
-
-HGDIOBJ VectorDevice::SelectObject(HGDIOBJ object) {
- HGDIOBJ result = ::SelectObject(hdc_, object);
- DCHECK(result != HGDI_ERROR);
- if (result == HGDI_ERROR)
- return NULL;
- return result;
-}
-
-bool VectorDevice::CreateBrush(bool use_brush, const SkPaint& paint) {
- // Make sure that for transparent color, no brush is used.
- if (paint.getAlpha() == 0) {
- // Test if it ever happen.
- NOTREACHED();
- use_brush = false;
- }
-
- return CreateBrush(use_brush, SkColorToCOLORREF(paint.getColor()));
-}
-
-bool VectorDevice::CreatePen(bool use_pen, const SkPaint& paint) {
- // Make sure that for transparent color, no pen is used.
- if (paint.getAlpha() == 0) {
- // Test if it ever happen.
- NOTREACHED();
- use_pen = false;
- }
-
- DWORD pen_style = PS_GEOMETRIC | PS_SOLID;
- switch (paint.getStrokeJoin()) {
- case SkPaint::kMiter_Join:
- // Connects path segments with a sharp join.
- pen_style |= PS_JOIN_MITER;
- break;
- case SkPaint::kRound_Join:
- // Connects path segments with a round join.
- pen_style |= PS_JOIN_ROUND;
- break;
- case SkPaint::kBevel_Join:
- // Connects path segments with a flat bevel join.
- pen_style |= PS_JOIN_BEVEL;
- break;
- default:
- NOTREACHED();
- break;
- }
- switch (paint.getStrokeCap()) {
- case SkPaint::kButt_Cap:
- // Begin/end contours with no extension.
- pen_style |= PS_ENDCAP_FLAT;
- break;
- case SkPaint::kRound_Cap:
- // Begin/end contours with a semi-circle extension.
- pen_style |= PS_ENDCAP_ROUND;
- break;
- case SkPaint::kSquare_Cap:
- // Begin/end contours with a half square extension.
- pen_style |= PS_ENDCAP_SQUARE;
- break;
- default:
- NOTREACHED();
- break;
- }
-
- return CreatePen(use_pen,
- SkColorToCOLORREF(paint.getColor()),
- SkScalarRound(paint.getStrokeWidth()),
- paint.getStrokeMiter(),
- pen_style);
-}
-
-void VectorDevice::InternalDrawBitmap(const SkBitmap& bitmap, int x, int y,
- const SkPaint& paint) {
- uint8 alpha = paint.getAlpha();
- if (alpha == 0)
- return;
-
- bool is_translucent;
- if (alpha != 255) {
- // ApplyPaint expect an opaque color.
- SkPaint tmp_paint(paint);
- tmp_paint.setAlpha(255);
- if (!ApplyPaint(tmp_paint))
- return;
- is_translucent = true;
- } else {
- if (!ApplyPaint(paint))
- return;
- is_translucent = false;
- }
- int src_size_x = bitmap.width();
- int src_size_y = bitmap.height();
- if (!src_size_x || !src_size_y)
- return;
-
- // Create a BMP v4 header that we can serialize.
- BITMAPV4HEADER bitmap_header;
- gfx::CreateBitmapV4Header(src_size_x, src_size_y, &bitmap_header);
- HDC dc = getBitmapDC();
- SkAutoLockPixels lock(bitmap);
- DCHECK_EQ(bitmap.getConfig(), SkBitmap::kARGB_8888_Config);
- const uint32_t* pixels = static_cast<const uint32_t*>(bitmap.getPixels());
- if (pixels == NULL) {
- NOTREACHED();
- return;
- }
-
- if (!is_translucent) {
- int row_length = bitmap.rowBytesAsPixels();
- // There is no quick way to determine if an image is opaque.
- for (int y2 = 0; y2 < src_size_y; ++y2) {
- for (int x2 = 0; x2 < src_size_x; ++x2) {
- if (SkColorGetA(pixels[(y2 * row_length) + x2]) != 255) {
- is_translucent = true;
- y2 = src_size_y;
- break;
- }
- }
- }
- }
-
- BITMAPINFOHEADER hdr;
- gfx::CreateBitmapHeader(src_size_x, src_size_y, &hdr);
- if (is_translucent) {
- // The image must be loaded as a bitmap inside a device context.
- ScopedHDC bitmap_dc(::CreateCompatibleDC(dc));
- void* bits = NULL;
- ScopedBitmap hbitmap(::CreateDIBSection(
- bitmap_dc, reinterpret_cast<const BITMAPINFO*>(&hdr),
- DIB_RGB_COLORS, &bits, NULL, 0));
- memcpy(bits, pixels, bitmap.getSize());
- DCHECK(hbitmap);
- HGDIOBJ old_bitmap = ::SelectObject(bitmap_dc, hbitmap);
- DeleteObject(old_bitmap);
-
- // After some analysis of IE7's behavior, this is the thing to do. I was
- // sure IE7 was doing so kind of bitmasking due to the way translucent image
- // where renderered but after some windbg tracing, it is being done by the
- // printer driver after all (mostly HP printers). IE7 always use AlphaBlend
- // for bitmasked images. The trick seems to switch the stretching mode in
- // what the driver expects.
- DWORD previous_mode = GetStretchBltMode(dc);
- BOOL result = SetStretchBltMode(dc, COLORONCOLOR);
- DCHECK(result);
- // Note that this function expect premultiplied colors (!)
- BLENDFUNCTION blend_function = {AC_SRC_OVER, 0, alpha, AC_SRC_ALPHA};
- result = GdiAlphaBlend(dc,
- x, y, // Destination origin.
- src_size_x, src_size_y, // Destination size.
- bitmap_dc,
- 0, 0, // Source origin.
- src_size_x, src_size_y, // Source size.
- blend_function);
- DCHECK(result);
- result = SetStretchBltMode(dc, previous_mode);
- DCHECK(result);
- } else {
- BOOL result = StretchDIBits(dc,
- x, y, // Destination origin.
- src_size_x, src_size_y,
- 0, 0, // Source origin.
- src_size_x, src_size_y, // Source size.
- pixels,
- reinterpret_cast<const BITMAPINFO*>(&hdr),
- DIB_RGB_COLORS,
- SRCCOPY);
- DCHECK(result);
- }
- Cleanup();
-}
-
-} // namespace gfx
-
diff --git a/base/gfx/vector_device.h b/base/gfx/vector_device.h
index 5ebc558..55fe22e 100644
--- a/base/gfx/vector_device.h
+++ b/base/gfx/vector_device.h
@@ -2,118 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef BASE_GFX_VECTOR_DEVICE_H_
-#define BASE_GFX_VECTOR_DEVICE_H_
-
-#include "base/basictypes.h"
-#include "base/gfx/platform_device_win.h"
-#include "SkMatrix.h"
-#include "SkRegion.h"
-
-namespace gfx {
-
-// A device is basically a wrapper around SkBitmap that provides a surface for
-// SkCanvas to draw into. This specific device is not not backed by a surface
-// and is thus unreadable. This is because the backend is completely vectorial.
-// This device is a simple wrapper over a Windows device context (HDC) handle.
-class VectorDevice : public PlatformDeviceWin {
- public:
- // Factory function. The DC is kept as the output context.
- static VectorDevice* create(HDC dc, int width, int height);
-
- VectorDevice(HDC dc, const SkBitmap& bitmap);
- virtual ~VectorDevice();
-
- virtual HDC getBitmapDC() {
- return hdc_;
- }
-
- virtual void drawPaint(const SkDraw& draw, const SkPaint& paint);
- virtual void drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
- size_t count, const SkPoint[], const SkPaint& paint);
- virtual void drawRect(const SkDraw& draw, const SkRect& r,
- const SkPaint& paint);
- virtual void drawPath(const SkDraw& draw, const SkPath& path,
- const SkPaint& paint);
- virtual void drawBitmap(const SkDraw& draw, const SkBitmap& bitmap,
- const SkMatrix& matrix, const SkPaint& paint);
- virtual void drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
- int x, int y, const SkPaint& paint);
- virtual void drawText(const SkDraw& draw, const void* text, size_t len,
- SkScalar x, SkScalar y, const SkPaint& paint);
- virtual void drawPosText(const SkDraw& draw, const void* text, size_t len,
- const SkScalar pos[], SkScalar constY,
- int scalarsPerPos, const SkPaint& paint);
- virtual void drawTextOnPath(const SkDraw& draw, const void* text, size_t len,
- const SkPath& path, const SkMatrix* matrix,
- const SkPaint& paint);
- virtual void drawVertices(const SkDraw& draw, SkCanvas::VertexMode,
- int vertexCount,
- const SkPoint verts[], const SkPoint texs[],
- const SkColor colors[], SkXfermode* xmode,
- const uint16_t indices[], int indexCount,
- const SkPaint& paint);
- virtual void drawDevice(const SkDraw& draw, SkDevice*, int x, int y,
- const SkPaint&);
-
-
- virtual void setMatrixClip(const SkMatrix& transform, const SkRegion& region);
- virtual void drawToHDC(HDC dc, int x, int y, const RECT* src_rect);
- virtual bool IsVectorial() { return true; }
-
- void LoadClipRegion();
-
- private:
- // Applies the SkPaint's painting properties in the current GDI context, if
- // possible. If GDI can't support all paint's properties, returns false. It
- // doesn't execute the "commands" in SkPaint.
- bool ApplyPaint(const SkPaint& paint);
-
- // Selects a new object in the device context. It can be a pen, a brush, a
- // clipping region, a bitmap or a font. Returns the old selected object.
- HGDIOBJ SelectObject(HGDIOBJ object);
-
- // Creates a brush according to SkPaint's properties.
- bool CreateBrush(bool use_brush, const SkPaint& paint);
-
- // Creates a pen according to SkPaint's properties.
- bool CreatePen(bool use_pen, const SkPaint& paint);
-
- // Restores back the previous objects (pen, brush, etc) after a paint command.
- void Cleanup();
-
- // Creates a brush according to SkPaint's properties.
- bool CreateBrush(bool use_brush, COLORREF color);
-
- // Creates a pen according to SkPaint's properties.
- bool CreatePen(bool use_pen, COLORREF color, int stroke_width,
- float stroke_miter, DWORD pen_style);
-
- // Draws a bitmap in the the device, using the currently loaded matrix.
- void InternalDrawBitmap(const SkBitmap& bitmap, int x, int y,
- const SkPaint& paint);
-
- // The Windows Device Context handle. It is the backend used with GDI drawing.
- // This backend is write-only and vectorial.
- HDC hdc_;
-
- // Translation assigned to the DC: we need to keep track of this separately
- // so it can be updated even if the DC isn't created yet.
- SkMatrix transform_;
-
- // The current clipping
- SkRegion clip_region_;
-
- // Previously selected brush before the current drawing.
- HGDIOBJ previous_brush_;
-
- // Previously selected pen before the current drawing.
- HGDIOBJ previous_pen_;
-
- DISALLOW_COPY_AND_ASSIGN(VectorDevice);
-};
-
-} // namespace gfx
-
-#endif // BASE_GFX_VECTOR_DEVICE_H_
-
+// TODO(brettw) this file should be removed and the includes changed to this
+// new location.
+#include "webkit/port/platform/graphics/skia/public/VectorDevice.h"