0

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
This commit is contained in:
brettw@google.com
2008-11-19 18:52:38 +00:00
parent 941ac7fca4
commit 6165b4070b
51 changed files with 3423 additions and 3227 deletions

6
DEPS

@ -47,7 +47,11 @@ include_rules = [
# For now, we allow ICU to be included by specifying "unicode/...", although
# this should probably change.
"+unicode",
'+testing'
"+testing",
# Allow anybody to include files from the "public" Skia directory in the
# webkit port. This is shared between the webkit port and Chrome.
"+webkit/port/platform/graphics/skia/public",
]

@ -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)

@ -121,10 +121,6 @@
<References>
</References>
<Files>
<File
RelativePath="..\gfx\bitmap_platform_device_win.cc"
>
</File>
<File
RelativePath="..\gfx\bitmap_platform_device_win.h"
>
@ -161,18 +157,10 @@
RelativePath="..\gfx\native_theme.h"
>
</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"
>
@ -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>

@ -403,18 +403,10 @@
RelativePath="..\gfx\image_operations_unittest.cc"
>
</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>

@ -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)

@ -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"

@ -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_

@ -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__

@ -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_

@ -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"

@ -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_

@ -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__

@ -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_

@ -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"

@ -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_

@ -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__

@ -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__

@ -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"

File diff suppressed because it is too large Load Diff

@ -131,6 +131,9 @@ if env['PLATFORM'] == 'posix':
'$PORT_DIR/platform/chromium/ScrollbarThemeChromiumLinux.cpp',
'$PORT_DIR/platform/graphics/chromium/GlyphPageTreeNodeLinux.cpp',
'$PORT_DIR/platform/graphics/skia/GdkSkia.cc',
'$PORT_DIR/platform/graphics/skia/public/PlatformCanvasLinux.cpp',
'$PORT_DIR/platform/graphics/skia/public/PlatformDeviceLinux.cpp',
])
if env['PLATFORM'] == 'darwin':
@ -145,6 +148,9 @@ if env['PLATFORM'] == 'darwin':
'$PORT_DIR/platform/chromium/ScrollbarThemeChromium.cpp',
'$PORT_DIR/platform/graphics/FontCustomPlatformData.cpp',
'$PORT_DIR/platform/graphics/ImageSkia.cpp',
'$PORT_DIR/platform/graphics/skia/public/PlatformCanvasMac.cpp',
'$PORT_DIR/platform/graphics/skia/public/PlatformDeviceMac.cpp',
]
for remove in remove_files:
input_files.remove(remove)
@ -166,6 +172,12 @@ if env['PLATFORM'] == 'win32':
'$PORT_DIR/platform/graphics/ThemeHelperWin.cpp',
'$PORT_DIR/platform/graphics/UniscribeHelper.cpp',
'$PORT_DIR/platform/graphics/UniscribeHelperTextRun.cpp',
'$PORT_DIR/platform/graphics/skia/public/PlatformCanvasWin.cpp',
'$PORT_DIR/platform/graphics/skia/public/PlatformDeviceWin.cpp',
'$PORT_DIR/platform/graphics/skia/public/VectorCanvas.cpp',
'$PORT_DIR/platform/graphics/skia/public/VectorDevice.cpp',
'$PORT_DIR/rendering/RenderThemeWin.cpp',
])

@ -1066,6 +1066,66 @@
>
</File>
</Filter>
<Filter
Name="skia"
>
<Filter
Name="public"
>
<File
RelativePath="..\..\port\platform\graphics\skia\public\BitmapPlatformDevice.h"
>
</File>
<File
RelativePath="..\..\port\platform\graphics\skia\public\BitmapPlatformDeviceWin.cpp"
>
</File>
<File
RelativePath="..\..\port\platform\graphics\skia\public\BitmapPlatformDeviceWin.h"
>
</File>
<File
RelativePath="..\..\port\platform\graphics\skia\public\PlatformCanvas.h"
>
</File>
<File
RelativePath="..\..\port\platform\graphics\skia\public\PlatformCanvasWin.cpp"
>
</File>
<File
RelativePath="..\..\port\platform\graphics\skia\public\PlatformCanvasWin.h"
>
</File>
<File
RelativePath="..\..\port\platform\graphics\skia\public\PlatformDevice.h"
>
</File>
<File
RelativePath="..\..\port\platform\graphics\skia\public\PlatformDeviceWin.cpp"
>
</File>
<File
RelativePath="..\..\port\platform\graphics\skia\public\PlatformDeviceWin.h"
>
</File>
<File
RelativePath="..\..\port\platform\graphics\skia\public\VectorCanvas.cpp"
>
</File>
<File
RelativePath="..\..\port\platform\graphics\skia\public\VectorCanvas.h"
>
</File>
<File
RelativePath="..\..\port\platform\graphics\skia\public\VectorDevice.cpp"
>
</File>
<File
RelativePath="..\..\port\platform\graphics\skia\public\VectorDevice.h"
>
</File>
</Filter>
</Filter>
</Filter>
<Filter
Name="image-decoders"

@ -0,0 +1,30 @@
// 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.
// 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(WIN32)
#include "BitmapPlatformDeviceWin.h"
namespace gfx {
typedef BitmapPlatformDeviceWin BitmapPlatformDevice;
} // namespace gfx
#elif defined(__APPLE__)
#include "BitmapPlatformDeviceMac.h"
namespace gfx {
typedef BitmapPlatformDeviceMac BitmapPlatformDevice;
} // namespace gfx
#elif defined(__linux__)
#include "BitmapPlatformDeviceLinux.h"
namespace gfx {
typedef BitmapPlatformDeviceLinux BitmapPlatformDevice;
} // namespace gfx
#endif

@ -10,31 +10,6 @@
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
@ -58,37 +33,28 @@ BitmapPlatformDeviceLinux* BitmapPlatformDeviceLinux::Create(
#endif
// The device object will take ownership of the graphics context.
return new BitmapPlatformDeviceLinux
(bitmap, new BitmapPlatformDeviceLinuxData(surface));
return new BitmapPlatformDeviceLinux(bitmap, 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)
BitmapPlatformDeviceLinux::BitmapPlatformDeviceLinux(const SkBitmap& bitmap,
cairo_surface_t* surface)
: PlatformDeviceLinux(bitmap),
data_(data) {
surface_(surface) {
}
BitmapPlatformDeviceLinux::BitmapPlatformDeviceLinux(
const BitmapPlatformDeviceLinux& other)
: PlatformDeviceLinux(const_cast<BitmapPlatformDeviceLinux&>(
other).accessBitmap(true)),
data_(other.data_) {
other).accessBitmap(true)) {
}
BitmapPlatformDeviceLinux::~BitmapPlatformDeviceLinux() {
}
cairo_surface_t* BitmapPlatformDeviceLinux::surface() const {
return data_->surface();
}
BitmapPlatformDeviceLinux& BitmapPlatformDeviceLinux::operator=(
const BitmapPlatformDeviceLinux& other) {
data_ = other.data_;
return *this;
if (surface_) {
cairo_surface_destroy(surface_);
surface_ = NULL;
}
}
} // namespace gfx

@ -0,0 +1,91 @@
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BitmapPlatformDeviceLinux_h
#define BitmapPlatformDeviceLinux_h
#include "PLatformDeviceLinux.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
#endif // BitmapPlatformDeviceLinux_h

@ -0,0 +1,95 @@
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BitmapPlatformDeviceMac_h
#define BitmapPlatformDeviceMac_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
#endif // BitmapPlatformDeviceMac_h

@ -2,7 +2,7 @@
// 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 "BitmapPlatformDeviceWin.h"
#include "base/gfx/gdi_util.h"
#include "base/logging.h"

@ -0,0 +1,111 @@
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BitmapPlatformDeviceWin_h
#define BitmapPlatformDeviceWin_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
#endif // BASE_GFX_BITMAP_PLATFORM_DEVICE_WIN_H_

@ -0,0 +1,30 @@
// 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.
// 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.
#if defined(WIN32)
#include "PlatformCanvasWin.h"
namespace gfx {
typedef PlatformCanvasWin PlatformCanvas;
} // namespace gfx
#elif defined(__APPLE__)
#include "PlatformCanvasMac.h"
namespace gfx {
typedef PlatformCanvasMac PlatformCanvas;
} // namespace gfx
#elif defined(__linux__)
#include "PlatformCanvasLinux.h"
namespace gfx {
typedef PlatformCanvasLinux PlatformCanvas;
} // namespace gfx
#endif

@ -38,11 +38,8 @@ PlatformDeviceLinux& PlatformCanvasLinux::getTopPlatformDevice() const {
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);
SkDevice* PlatformCanvasLinux::createDevice(SkBitmap::Config, int width,
int height, bool is_opaque) {
return createPlatformDevice(width, height, is_opaque);
}

@ -0,0 +1,52 @@
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef PlatformCanvasLinux_h
#define PlatformCanvasLinux_h
#include "PlatformCanvasLinux.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);
// 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(const PlatformCanvasLinux&);
PlatformCanvasLinux& operator=(const PlatformCanvasLinux&);
};
} // namespace gfx
#endif // PlatformCanvasLinux_h

@ -2,7 +2,7 @@
// 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 "PlatformCanvasMac.h"
#include "base/gfx/bitmap_platform_device_mac.h"
#include "base/logging.h"

@ -0,0 +1,88 @@
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef PlatformCanvasMac_h
#define PlatformCanvasMac_h
#include "PlatformDeviceMac.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 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(const PlatformCanvasMac&);
PlatformCanvasMac& operator=(const PlatformCanvasMac&);
};
} // namespace gfx
#endif // PlatformCanvasMac_h

@ -2,17 +2,13 @@
// 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 "PlatformCanvasWin.h"
#include "BitmapPlatformDeviceWin.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
@ -49,17 +45,17 @@ PlatformCanvasWin::PlatformCanvasWin() : SkCanvas() {
PlatformCanvasWin::PlatformCanvasWin(int width, int height, bool is_opaque)
: SkCanvas() {
bool initialized = initialize(width, height, is_opaque, NULL);
if (!initialized)
if (!initialized)
CrashForBitmapAllocationFailure(width, height);
}
PlatformCanvasWin::PlatformCanvasWin(int width,
int height,
bool is_opaque,
HANDLE shared_section)
int height,
bool is_opaque,
HANDLE shared_section)
: SkCanvas() {
bool initialized = initialize(width, height, is_opaque, shared_section);
if (!initialized)
if (!initialized)
CrashForBitmapAllocationFailure(width, height);
}
@ -96,17 +92,17 @@ PlatformDeviceWin& PlatformCanvasWin::getTopPlatformDevice() const {
}
SkDevice* PlatformCanvasWin::createDevice(SkBitmap::Config config,
int width,
int height,
bool is_opaque, bool isForLayer) {
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) {
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);

@ -0,0 +1,202 @@
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef PlatformCanvasWin_h
#define PlatformCanvasWin_h
#include <windows.h>
#include "PlatformDeviceWin.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(const PlatformCanvasWin&);
PlatformCanvasWin& operator=(const 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(const CanvasPaintT&);
CanvasPaintT& operator=(const CanvasPaintT&);
};
typedef CanvasPaintT<PlatformCanvasWin> PlatformCanvasWinPaint;
} // namespace gfx
#endif // PlatformCanvasWin_h

@ -0,0 +1,27 @@
// 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.
// 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(WIN32)
#include "PlatformDeviceWin.h"
#elif defined(__APPLE__)
#include "PlatformDeviceMac.h"
#elif defined(__linux__)
#include "PlatformDeviceLinux.h"
#endif
namespace gfx {
#if defined(WIN32)
typedef PlatformDeviceWin PlatformDevice;
#elif defined(__APPLE__)
typedef PlatformDeviceMac PlatformDevice;
#elif defined(__linux__)
typedef PlatformDeviceLinux PlatformDevice;
#endif
} // namespace gfx

@ -2,12 +2,7 @@
// 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"
#include "PlatformDeviceLinux.h"
namespace gfx {

@ -0,0 +1,25 @@
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef PlatformDeviceLinux_h
#define PlatformDeviceLinux_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
#endif // PlatformDeviceLinux_h

@ -2,7 +2,7 @@
// 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 "PlatformDeviceMac.h"
#include "base/logging.h"
#include "base/gfx/skia_utils_mac.h"
@ -100,15 +100,15 @@ void PlatformDeviceMac::LoadTransformToCGContext(CGContextRef context,
// 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.
@ -118,9 +118,9 @@ void PlatformDeviceMac::LoadTransformToCGContext(CGContextRef context,
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);
}
@ -156,6 +156,6 @@ void PlatformDeviceMac::LoadClippingRegionToCGContext(
// hrgn = PathToRegion(context);
}
}
} // namespace gfx

@ -0,0 +1,86 @@
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef PlatformDeviceMac_h
#define PlatformDeviceMac_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
#endif // PlatformDeviceMac_h

@ -2,7 +2,7 @@
// 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 "PlatformDeviceWin.h"
#include "base/logging.h"
#include "base/gfx/skia_utils.h"
@ -132,7 +132,7 @@ void PlatformDeviceWin::LoadTransformToDC(HDC dc, const SkMatrix& matrix) {
// static
bool PlatformDeviceWin::SkPathToCubicPaths(CubicPaths* paths,
const SkPath& skpath) {
const SkPath& skpath) {
paths->clear();
CubicPath* current_path = NULL;
SkPoint current_points[4];
@ -195,8 +195,8 @@ bool PlatformDeviceWin::SkPathToCubicPaths(CubicPaths* paths,
// static
void PlatformDeviceWin::LoadClippingRegionToDC(HDC context,
const SkRegion& region,
const SkMatrix& transformation) {
const SkRegion& region,
const SkMatrix& transformation) {
HRGN hrgn;
if (region.isEmpty()) {
// region can be empty, in which case everything will be clipped.

@ -0,0 +1,98 @@
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef PlatformDeviceWin_h
#define PlatformDeviceWin_h
#include <windows.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
#endif // PlatformDeviceWin_h

@ -0,0 +1,3 @@
The files in this directory must not depend on WebKit types since they are used
by both the port and the Chromium application layer. They may only depend on
Skia and the system libraries.

@ -0,0 +1,46 @@
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_GFX_VECTOR_CANVAS_H_
#define BASE_GFX_VECTOR_CANVAS_H_
#include "base/gfx/platform_canvas_win.h"
#include "base/gfx/vector_device.h"
namespace gfx {
// This class is a specialization of the regular PlatformCanvas. It is designed
// to work with a VectorDevice to manage platform-specific drawing. It allows
// using both Skia operations and platform-specific operations. It *doesn't*
// support reading back from the bitmap backstore since it is not used.
class VectorCanvas : public PlatformCanvasWin {
public:
VectorCanvas();
VectorCanvas(HDC dc, int width, int height);
virtual ~VectorCanvas();
// For two-part init, call if you use the no-argument constructor above
bool initialize(HDC context, int width, int height);
virtual SkBounder* setBounder(SkBounder*);
virtual SkDevice* createDevice(SkBitmap::Config config,
int width, int height,
bool is_opaque, bool isForLayer);
virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter);
private:
// |is_opaque| is unused. |shared_section| is in fact the HDC used for output.
virtual SkDevice* createPlatformDevice(int width, int height, bool is_opaque,
HANDLE shared_section);
// Returns true if the top device is vector based and not bitmap based.
bool IsTopDeviceVectorial() const;
DISALLOW_COPY_AND_ASSIGN(VectorCanvas);
};
} // namespace gfx
#endif // BASE_GFX_VECTOR_CANVAS_H_

@ -2,7 +2,7 @@
// 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 "VectorCanvas.h"
#include <vector>
@ -355,7 +355,8 @@ void LoadPngFileToSkBitmap(const std::wstring& file, SkBitmap* bitmap) {
// Streams an image.
inline std::ostream& operator<<(std::ostream& out, const Image& image) {
return out << "Image(" << image.size() << ", " << image.row_length() << ")";
return out << "Image(" << image.size().width() << ", "
<< image.size().height() << ", " << image.row_length() << ")";
}
// Runs simultaneously the same drawing commands on VectorCanvas and

@ -2,7 +2,7 @@
// 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 "VectorDevice.h"
#include "base/gfx/gdi_util.h"
#include "base/gfx/skia_utils.h"

@ -0,0 +1,119 @@
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef VectorDevice_h
#define VectorDevice_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 // VectorDevice_h

@ -176,6 +176,7 @@ test_files = [
'$WEBKIT_DIR/glue/resource_fetcher_unittest.cc',
'$WEBKIT_DIR/glue/webframe_unittest.cc',
'$WEBKIT_DIR/port/platform/GKURL_unittest.cpp',
'$WEBKIT_DIR/port/platform/graphics/skia/public/PlatformCanvas_unittest.cpp',
'$WEBKIT_DIR/port/platform/image-decoders/bmp/BMPImageDecoder_unittest.cpp',
'$WEBKIT_DIR/port/platform/image-decoders/ico/ICOImageDecoder_unittest.cpp',
'$WEBKIT_DIR/port/platform/image-decoders/xbm/XBMImageDecoder_unittest.cpp',
@ -190,6 +191,7 @@ if env['PLATFORM'] == 'win32':
#'$WEBKIT_DIR/glue/stringimpl_unittest.cc',
'$WEBKIT_DIR/glue/webplugin_impl_unittest.cc',
'$WEBKIT_DIR/port/platform/graphics/UniscribeHelper_unittest.cpp',
'$WEBKIT_DIR/port/platform/graphics/skia/public/VectorCanvas_unittest.cpp',
])
test_shell_tests = env.ChromeTestProgram('test_shell_tests',

@ -366,6 +366,10 @@
RelativePath="..\..\glue\password_autocomplete_listener_unittest.cc"
>
</File>
<File
RelativePath="..\..\port\platform\graphics\skia\public\PlatformCanvas_unittest.cpp"
>
</File>
<File
RelativePath=".\plugin_tests.cc"
>
@ -386,6 +390,10 @@
RelativePath="..\..\port\platform\graphics\UniscribeHelper_unittest.cpp"
>
</File>
<File
RelativePath="..\..\port\platform\graphics\skia\public\VectorCanvas_unittest.cpp"
>
</File>
<File
RelativePath="..\..\glue\webframe_unittest.cc"
>