diff options
Diffstat (limited to 'skia/ext')
31 files changed, 331 insertions, 205 deletions
diff --git a/skia/ext/bitmap_platform_device.cc b/skia/ext/bitmap_platform_device.cc index bec8a63..05037c6 100644 --- a/skia/ext/bitmap_platform_device.cc +++ b/skia/ext/bitmap_platform_device.cc @@ -40,7 +40,7 @@ bool Constrain(int available_size, int* position, int *size) { namespace skia { -void BitmapPlatformDevice::makeOpaque(int x, int y, int width, int height) { +void BitmapPlatformDevice::MakeOpaque(int x, int y, int width, int height) { const SkBitmap& bitmap = accessBitmap(true); SkASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config); diff --git a/skia/ext/bitmap_platform_device_linux.h b/skia/ext/bitmap_platform_device_linux.h index 37695f1..927bd43 100644 --- a/skia/ext/bitmap_platform_device_linux.h +++ b/skia/ext/bitmap_platform_device_linux.h @@ -88,7 +88,7 @@ class BitmapPlatformDevice : public PlatformDevice { static BitmapPlatformDevice* Create(int width, int height, bool is_opaque, uint8_t* data); - virtual void makeOpaque(int x, int y, int width, int height); + virtual void MakeOpaque(int x, int y, int width, int height); // Overridden from SkDevice: virtual void setMatrixClip(const SkMatrix& transform, const SkRegion& region, diff --git a/skia/ext/bitmap_platform_device_mac.cc b/skia/ext/bitmap_platform_device_mac.cc index 543fc38..8276545 100644 --- a/skia/ext/bitmap_platform_device_mac.cc +++ b/skia/ext/bitmap_platform_device_mac.cc @@ -226,8 +226,8 @@ void BitmapPlatformDevice::setMatrixClip(const SkMatrix& transform, data_->SetMatrixClip(transform, region); } -void BitmapPlatformDevice::DrawToContext(CGContextRef context, int x, int y, - const CGRect* src_rect) { +void BitmapPlatformDevice::DrawToNativeContext(CGContextRef context, int x, + int y, const CGRect* src_rect) { bool created_dc = false; if (!data_->bitmap_context()) { created_dc = true; @@ -261,14 +261,6 @@ bool BitmapPlatformDevice::IsVectorial() { return false; } -// Returns the color value at the specified location. -SkColor BitmapPlatformDevice::getColorAt(int x, int y) { - const SkBitmap& bitmap = accessBitmap(true); - SkAutoLockPixels lock(bitmap); - uint32_t* data = bitmap.getAddr32(0, 0); - return static_cast<SkColor>(data[x + y * width()]); -} - void BitmapPlatformDevice::onAccessBitmap(SkBitmap*) { // Not needed in CoreGraphics } diff --git a/skia/ext/bitmap_platform_device_mac.h b/skia/ext/bitmap_platform_device_mac.h index f126adc..565bbcf 100644 --- a/skia/ext/bitmap_platform_device_mac.h +++ b/skia/ext/bitmap_platform_device_mac.h @@ -61,18 +61,16 @@ class BitmapPlatformDevice : public PlatformDevice { // See warning for copy constructor above. BitmapPlatformDevice& operator=(const BitmapPlatformDevice& other); + // PlatformDevice overrides virtual CGContextRef GetBitmapContext(); - virtual void setMatrixClip(const SkMatrix& transform, const SkRegion& region, - const SkClipStack&); - - virtual void DrawToContext(CGContextRef context, int x, int y, - const CGRect* src_rect); - virtual void makeOpaque(int x, int y, int width, int height); + virtual void DrawToNativeContext(CGContextRef context, int x, int y, + const CGRect* src_rect); + virtual void MakeOpaque(int x, int y, int width, int height); virtual bool IsVectorial(); - // 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); + // SkDevice overrides + virtual void setMatrixClip(const SkMatrix& transform, const SkRegion& region, + const SkClipStack&); protected: // Reference counted data that can be shared between multiple devices. This diff --git a/skia/ext/bitmap_platform_device_win.cc b/skia/ext/bitmap_platform_device_win.cc index 5678b9b..dcc395d 100644 --- a/skia/ext/bitmap_platform_device_win.cc +++ b/skia/ext/bitmap_platform_device_win.cc @@ -220,8 +220,8 @@ void BitmapPlatformDevice::setMatrixClip(const SkMatrix& transform, data_->SetMatrixClip(transform, region); } -void BitmapPlatformDevice::drawToHDC(HDC dc, int x, int y, - const RECT* src_rect) { +void BitmapPlatformDevice::DrawToNativeContext(HDC dc, int x, int y, + const RECT* src_rect) { bool created_dc = !data_->IsBitmapDCCreated(); HDC source_dc = BeginPlatformPaint(); @@ -275,14 +275,6 @@ void BitmapPlatformDevice::drawToHDC(HDC dc, int x, int y, data_->ReleaseBitmapDC(); } -// Returns the color value at the specified location. -SkColor BitmapPlatformDevice::getColorAt(int x, int y) { - const SkBitmap& bitmap = accessBitmap(false); - SkAutoLockPixels lock(bitmap); - uint32_t* data = bitmap.getAddr32(0, 0); - return static_cast<SkColor>(data[x + y * width()]); -} - void BitmapPlatformDevice::onAccessBitmap(SkBitmap* bitmap) { // FIXME(brettw) OPTIMIZATION: We should only flush if we know a GDI // operation has occurred on our DC. diff --git a/skia/ext/bitmap_platform_device_win.h b/skia/ext/bitmap_platform_device_win.h index 7f901f5..7197d16 100644 --- a/skia/ext/bitmap_platform_device_win.h +++ b/skia/ext/bitmap_platform_device_win.h @@ -69,24 +69,21 @@ class SK_API BitmapPlatformDevice : public PlatformDevice { // See warning for copy constructor above. BitmapPlatformDevice& operator=(const BitmapPlatformDevice& other); + // PlatformDevice overrides // Retrieves the bitmap DC, which is the memory DC for our bitmap data. The // bitmap DC is lazy created. virtual PlatformSurface BeginPlatformPaint(); virtual void EndPlatformPaint(); + virtual void DrawToNativeContext(HDC dc, int x, int y, const RECT* src_rect); + virtual void MakeOpaque(int x, int y, int width, int height); + virtual bool IsVectorial() { return false; } + // Loads the given transform and clipping region into the HDC. This is // overridden from SkDevice. virtual void setMatrixClip(const SkMatrix& transform, const SkRegion& region, const SkClipStack&); - virtual void drawToHDC(HDC dc, int x, int y, const RECT* src_rect); - virtual void makeOpaque(int x, int y, int width, int height); - 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 diff --git a/skia/ext/canvas_paint_linux.h b/skia/ext/canvas_paint_linux.h index 73d9617..608350f 100644 --- a/skia/ext/canvas_paint_linux.h +++ b/skia/ext/canvas_paint_linux.h @@ -92,7 +92,7 @@ class CanvasPaintT : public T { // surface. T::translate(-SkIntToScalar(bounds.x), -SkIntToScalar(bounds.y)); - context_ = T::getTopPlatformDevice().BeginPlatformPaint(); + context_ = BeginPlatformPaint(GetTopDevice(*this)); } cairo_t* context_; diff --git a/skia/ext/canvas_paint_mac.h b/skia/ext/canvas_paint_mac.h index 6cef9ba..c4f45b2 100644 --- a/skia/ext/canvas_paint_mac.h +++ b/skia/ext/canvas_paint_mac.h @@ -92,7 +92,7 @@ class CanvasPaintT : public T { T::translate(-SkDoubleToScalar(rectangle_.origin.x), -SkDoubleToScalar(rectangle_.origin.y)); - context_ = T::getTopPlatformDevice().GetBitmapContext(); + context_ = GetBitmapContext(GetTopDevice(*this)); } CGContext* context_; diff --git a/skia/ext/canvas_paint_win.h b/skia/ext/canvas_paint_win.h index 478f285..5fe22fc 100644 --- a/skia/ext/canvas_paint_win.h +++ b/skia/ext/canvas_paint_win.h @@ -62,9 +62,8 @@ class CanvasPaintT : public T { if (!isEmpty()) { restoreToCount(1); // Commit the drawing to the screen - getTopPlatformDevice().drawToHDC(paint_dc_, - ps_.rcPaint.left, ps_.rcPaint.top, - NULL); + skia::DrawToNativeContext(this, paint_dc_, ps_.rcPaint.left, + ps_.rcPaint.top, NULL); } if (for_paint_) EndPaint(hwnd_, &ps_); diff --git a/skia/ext/platform_canvas.cc b/skia/ext/platform_canvas.cc index c48cce4..c6fd17e 100644 --- a/skia/ext/platform_canvas.cc +++ b/skia/ext/platform_canvas.cc @@ -7,14 +7,6 @@ #include "skia/ext/bitmap_platform_device.h" #include "third_party/skia/include/core/SkTypes.h" -namespace { -skia::PlatformDevice* GetTopPlatformDevice(const SkCanvas* canvas) { - // All of our devices should be our special PlatformDevice. - SkCanvas::LayerIter iter(const_cast<SkCanvas*>(canvas), false); - return static_cast<skia::PlatformDevice*>(iter.device()); -} -} - namespace skia { PlatformCanvas::PlatformCanvas() { @@ -29,10 +21,6 @@ SkDevice* PlatformCanvas::setBitmapDevice(const SkBitmap&) { return NULL; } -PlatformDevice& PlatformCanvas::getTopPlatformDevice() const { - return *GetTopPlatformDevice(this); -} - // static size_t PlatformCanvas::StrideForWidth(unsigned width) { return 4 * width; @@ -51,18 +39,32 @@ SkCanvas* CreateBitmapCanvas(int width, int height, bool is_opaque) { return new PlatformCanvas(width, height, is_opaque); } +SkDevice* GetTopDevice(const SkCanvas& canvas) { + SkCanvas::LayerIter iter(const_cast<SkCanvas*>(&canvas), false); + return iter.device(); +} + bool SupportsPlatformPaint(const SkCanvas* canvas) { - // TODO(alokp): Rename PlatformDevice::IsNativeFontRenderingAllowed after - // removing these calls from WebKit. - return GetTopPlatformDevice(canvas)->IsNativeFontRenderingAllowed(); + // TODO(alokp): Rename IsNativeFontRenderingAllowed after removing these + // calls from WebKit. + return IsNativeFontRenderingAllowed(GetTopDevice(*canvas)); } -PlatformDevice::PlatformSurface BeginPlatformPaint(SkCanvas* canvas) { - return GetTopPlatformDevice(canvas)->BeginPlatformPaint(); +PlatformSurface BeginPlatformPaint(SkCanvas* canvas) { + return BeginPlatformPaint(GetTopDevice(*canvas)); } void EndPlatformPaint(SkCanvas* canvas) { - GetTopPlatformDevice(canvas)->EndPlatformPaint(); + EndPlatformPaint(GetTopDevice(*canvas)); +} + +void DrawToNativeContext(SkCanvas* canvas, PlatformSurface context, int x, + int y, const PlatformRect* src_rect) { + DrawToNativeContext(GetTopDevice(*canvas), context, x, y, src_rect); +} + +void MakeOpaque(SkCanvas* canvas, int x, int y, int width, int height) { + MakeOpaque(GetTopDevice(*canvas), x, y, width, height); } } // namespace skia diff --git a/skia/ext/platform_canvas.h b/skia/ext/platform_canvas.h index 24f613a..58049e6 100644 --- a/skia/ext/platform_canvas.h +++ b/skia/ext/platform_canvas.h @@ -63,30 +63,6 @@ class SK_API PlatformCanvas : public SkCanvas { // Shared -------------------------------------------------------------------- - // These calls should surround calls to platform drawing routines, the - // surface returned here can be used with the native platform routines - // - // Call endPlatformPaint when you are done and want to use Skia operations - // after calling the platform-specific beginPlatformPaint; this will - // synchronize the bitmap to OS if necessary. - PlatformDevice::PlatformSurface beginPlatformPaint() const; - void endPlatformPaint() const; - - // 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(). - PlatformDevice& getTopPlatformDevice() const; - // Return the stride (length of a line in bytes) for the given width. Because // we use 32-bits per pixel, this will be roughly 4*width. However, for // alignment reasons we may wish to increase that. @@ -109,11 +85,26 @@ class SK_API PlatformCanvas : public SkCanvas { // CoreGraphics. virtual SkDevice* setBitmapDevice(const SkBitmap& bitmap); - // Disallow copy and assign. + // Disallow copy and assign PlatformCanvas(const PlatformCanvas&); PlatformCanvas& operator=(const PlatformCanvas&); }; +// Returns the SkDevice 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(). +SkDevice* GetTopDevice(const SkCanvas& canvas); + // Creates a canvas with raster bitmap backing. // Set is_opaque if you are going to erase the bitmap and not use // transparency: this will enable some optimizations. @@ -124,18 +115,45 @@ SK_API SkCanvas* CreateBitmapCanvas(int width, int height, bool is_opaque); // return NULL PlatformSurface. SK_API bool SupportsPlatformPaint(const SkCanvas* canvas); +// Draws into the a native platform surface, |context|. Forwards to +// DrawToNativeContext on a PlatformDevice instance bound to the top device. +// If no PlatformDevice instance is bound, is a no-operation. +SK_API void DrawToNativeContext(SkCanvas* canvas, PlatformSurface context, + int x, int y, const PlatformRect* src_rect); + +// Sets the opacity of each pixel in the specified region to be opaque. +SK_API void MakeOpaque(SkCanvas* canvas, int x, int y, int width, int height); + // These calls should surround calls to platform drawing routines, the // surface returned here can be used with the native platform routines. // // Call EndPlatformPaint when you are done and want to use skia operations // after calling the platform-specific BeginPlatformPaint; this will // synchronize the bitmap to OS if necessary. -// -// Note: These functions will eventually replace -// PlatformCanvas::beginPlatformPaint and PlatformCanvas::endPlatformPaint. -SK_API PlatformDevice::PlatformSurface BeginPlatformPaint(SkCanvas* canvas); +SK_API PlatformSurface BeginPlatformPaint(SkCanvas* canvas); SK_API void EndPlatformPaint(SkCanvas* canvas); +// Helper class for pairing calls to BeginPlatformPaint and EndPlatformPaint. +// Upon construction invokes BeginPlatformPaint, and upon destruction invokes +// EndPlatformPaint. +class ScopedPlatformPaint { + public: + explicit ScopedPlatformPaint(SkCanvas* canvas) : canvas_(canvas) { + platform_surface_ = BeginPlatformPaint(canvas); + } + ~ScopedPlatformPaint() { EndPlatformPaint(canvas_); } + + // Returns the PlatformSurface to use for native platform drawing calls. + PlatformSurface GetPlatformSurface() { return platform_surface_; } + private: + SkCanvas* canvas_; + PlatformSurface platform_surface_; + + // Disallow copy and assign + ScopedPlatformPaint(const ScopedPlatformPaint&); + ScopedPlatformPaint& operator=(const ScopedPlatformPaint&); +}; + } // namespace skia #endif // SKIA_EXT_PLATFORM_CANVAS_H_ diff --git a/skia/ext/platform_canvas_linux.cc b/skia/ext/platform_canvas_linux.cc index c059544..ea0f0c8 100644 --- a/skia/ext/platform_canvas_linux.cc +++ b/skia/ext/platform_canvas_linux.cc @@ -6,8 +6,8 @@ #include <cairo/cairo.h> -#include "skia/ext/platform_device_linux.h" -#include "skia/ext/bitmap_platform_device_linux.h" +#include "skia/ext/bitmap_platform_device.h" +#include "skia/ext/platform_device.h" #include "third_party/skia/include/core/SkTypes.h" namespace skia { @@ -33,12 +33,4 @@ bool PlatformCanvas::initialize(int width, int height, bool is_opaque, width, height, is_opaque, data)); } -cairo_t* PlatformCanvas::beginPlatformPaint() const { - return getTopPlatformDevice().BeginPlatformPaint(); -} - -void PlatformCanvas::endPlatformPaint() const { - getTopPlatformDevice().EndPlatformPaint(); -} - } // namespace skia diff --git a/skia/ext/platform_canvas_mac.cc b/skia/ext/platform_canvas_mac.cc index bf6843f..fba49f2 100644 --- a/skia/ext/platform_canvas_mac.cc +++ b/skia/ext/platform_canvas_mac.cc @@ -4,7 +4,7 @@ #include "skia/ext/platform_canvas.h" -#include "skia/ext/bitmap_platform_device_mac.h" +#include "skia/ext/bitmap_platform_device.h" #include "third_party/skia/include/core/SkTypes.h" namespace skia { @@ -49,12 +49,4 @@ bool PlatformCanvas::initialize(CGContextRef context, context, width, height, is_opaque)); } -CGContextRef PlatformCanvas::beginPlatformPaint() const { - return getTopPlatformDevice().BeginPlatformPaint(); -} - -void PlatformCanvas::endPlatformPaint() const { - getTopPlatformDevice().EndPlatformPaint(); -} - } // namespace skia diff --git a/skia/ext/platform_canvas_unittest.cc b/skia/ext/platform_canvas_unittest.cc index 6e43be2..40cdc70 100644 --- a/skia/ext/platform_canvas_unittest.cc +++ b/skia/ext/platform_canvas_unittest.cc @@ -31,8 +31,8 @@ namespace { bool VerifyRect(const PlatformCanvas& canvas, uint32_t canvas_color, uint32_t rect_color, int x, int y, int w, int h) { - PlatformDevice& device = canvas.getTopPlatformDevice(); - const SkBitmap& bitmap = device.accessBitmap(false); + SkDevice* device = skia::GetTopDevice(canvas); + const SkBitmap& bitmap = device->accessBitmap(false); SkAutoLockPixels lock(bitmap); // For masking out the alpha values. @@ -70,8 +70,8 @@ bool IsOfColor(const SkBitmap& bitmap, int x, int y, uint32_t color) { bool VerifyRoundedRect(const PlatformCanvas& canvas, uint32_t canvas_color, uint32_t rect_color, int x, int y, int w, int h) { - PlatformDevice& device = canvas.getTopPlatformDevice(); - const SkBitmap& bitmap = device.accessBitmap(false); + SkDevice* device = skia::GetTopDevice(canvas); + const SkBitmap& bitmap = device->accessBitmap(false); SkAutoLockPixels lock(bitmap); // Check corner points first. They should be of canvas_color. @@ -103,7 +103,8 @@ bool VerifyCanvasColor(const PlatformCanvas& canvas, uint32_t canvas_color) { #if defined(OS_WIN) void DrawNativeRect(PlatformCanvas& canvas, int x, int y, int w, int h) { - HDC dc = canvas.beginPlatformPaint(); + skia::ScopedPlatformPaint scoped_platform_paint(&canvas); + HDC dc = scoped_platform_paint.GetPlatformSurface(); RECT inner_rc; inner_rc.left = x; @@ -111,21 +112,18 @@ void DrawNativeRect(PlatformCanvas& canvas, int x, int y, int w, int h) { inner_rc.right = x + w; inner_rc.bottom = y + h; FillRect(dc, &inner_rc, reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH))); - - canvas.endPlatformPaint(); } #elif defined(OS_MACOSX) void DrawNativeRect(PlatformCanvas& canvas, int x, int y, int w, int h) { - CGContextRef context = canvas.beginPlatformPaint(); - + skia::ScopedPlatformPaint scoped_platform_paint(&canvas); + CGContextRef context = scoped_platform_paint.GetPlatformSurface(); + CGRect inner_rc = CGRectMake(x, y, w, h); // RGBA opaque black CGColorRef black = CGColorCreateGenericRGB(0.0, 0.0, 0.0, 1.0); CGContextSetFillColorWithColor(context, black); CGColorRelease(black); CGContextFillRect(context, inner_rc); - - canvas.endPlatformPaint(); } #else void DrawNativeRect(PlatformCanvas& canvas, int x, int y, int w, int h) { @@ -244,7 +242,7 @@ TEST(PlatformCanvas, FillLayer) { LayerSaver layer(canvas, kLayerX, kLayerY, kLayerW, kLayerH); DrawNativeRect(canvas, 0, 0, 100, 100); #if defined(OS_WIN) - canvas.getTopPlatformDevice().makeOpaque(0, 0, 100, 100); + MakeOpaque(&canvas, 0, 0, 100, 100); #endif } EXPECT_TRUE(VerifyBlackRect(canvas, kLayerX, kLayerY, kLayerW, kLayerH)); @@ -255,8 +253,7 @@ TEST(PlatformCanvas, FillLayer) { LayerSaver layer(canvas, kLayerX, kLayerY, kLayerW, kLayerH); DrawNativeRect(canvas, kInnerX, kInnerY, kInnerW, kInnerH); #if defined(OS_WIN) - canvas.getTopPlatformDevice().makeOpaque(kInnerX, kInnerY, - kInnerW, kInnerH); + MakeOpaque(&canvas, kInnerX, kInnerY, kInnerW, kInnerH); #endif } EXPECT_TRUE(VerifyBlackRect(canvas, kInnerX, kInnerY, kInnerW, kInnerH)); @@ -269,8 +266,7 @@ TEST(PlatformCanvas, FillLayer) { AddClip(canvas, kInnerX, kInnerY, kInnerW, kInnerH); DrawNativeRect(canvas, 0, 0, 100, 100); #if defined(OS_WIN) - canvas.getTopPlatformDevice().makeOpaque( - kInnerX, kInnerY, kInnerW, kInnerH); + MakeOpaque(&canvas, kInnerX, kInnerY, kInnerW, kInnerH); #endif canvas.restore(); } @@ -284,7 +280,7 @@ TEST(PlatformCanvas, FillLayer) { LayerSaver layer(canvas, kLayerX, kLayerY, kLayerW, kLayerH); DrawNativeRect(canvas, 0, 0, 100, 100); #if defined(OS_WIN) - canvas.getTopPlatformDevice().makeOpaque(0, 0, 100, 100); + MakeOpaque(&canvas, 0, 0, 100, 100); #endif } canvas.restore(); @@ -305,7 +301,7 @@ TEST(PlatformCanvas, TranslateLayer) { LayerSaver layer(canvas, kLayerX, kLayerY, kLayerW, kLayerH); DrawNativeRect(canvas, 0, 0, 100, 100); #if defined(OS_WIN) - canvas.getTopPlatformDevice().makeOpaque(0, 0, 100, 100); + MakeOpaque(&canvas, 0, 0, 100, 100); #endif } canvas.restore(); @@ -320,8 +316,7 @@ TEST(PlatformCanvas, TranslateLayer) { LayerSaver layer(canvas, kLayerX, kLayerY, kLayerW, kLayerH); DrawNativeRect(canvas, kInnerX, kInnerY, kInnerW, kInnerH); #if defined(OS_WIN) - canvas.getTopPlatformDevice().makeOpaque(kInnerX, kInnerY, - kInnerW, kInnerH); + MakeOpaque(&canvas, kInnerX, kInnerY, kInnerW, kInnerH); #endif } canvas.restore(); @@ -336,8 +331,7 @@ TEST(PlatformCanvas, TranslateLayer) { canvas.translate(1, 1); DrawNativeRect(canvas, kInnerX, kInnerY, kInnerW, kInnerH); #if defined(OS_WIN) - canvas.getTopPlatformDevice().makeOpaque(kInnerX, kInnerY, - kInnerW, kInnerH); + MakeOpaque(&canvas, kInnerX, kInnerY, kInnerW, kInnerH); #endif } canvas.restore(); @@ -355,8 +349,7 @@ TEST(PlatformCanvas, TranslateLayer) { AddClip(canvas, kInnerX + 1, kInnerY + 1, kInnerW - 1, kInnerH - 1); DrawNativeRect(canvas, 0, 0, 100, 100); #if defined(OS_WIN) - canvas.getTopPlatformDevice().makeOpaque(kLayerX, kLayerY, - kLayerW, kLayerH); + MakeOpaque(&canvas, kLayerX, kLayerY, kLayerW, kLayerH); #endif } canvas.restore(); @@ -384,8 +377,7 @@ TEST(PlatformCanvas, TranslateLayer) { DrawNativeRect(canvas, 0, 0, 100, 100); #if defined(OS_WIN) - canvas.getTopPlatformDevice().makeOpaque(kLayerX, kLayerY, - kLayerW, kLayerH); + MakeOpaque(&canvas, kLayerX, kLayerY, kLayerW, kLayerH); #endif } canvas.restore(); diff --git a/skia/ext/platform_canvas_win.cc b/skia/ext/platform_canvas_win.cc index a6381ed..116ba66 100644 --- a/skia/ext/platform_canvas_win.cc +++ b/skia/ext/platform_canvas_win.cc @@ -106,12 +106,4 @@ bool PlatformCanvas::initialize(int width, width, height, is_opaque, shared_section)); } -HDC PlatformCanvas::beginPlatformPaint() const { - return getTopPlatformDevice().BeginPlatformPaint(); -} - -void PlatformCanvas::endPlatformPaint() const { - return getTopPlatformDevice().EndPlatformPaint(); -} - } // namespace skia diff --git a/skia/ext/platform_device.cc b/skia/ext/platform_device.cc new file mode 100644 index 0000000..eff5d4f --- /dev/null +++ b/skia/ext/platform_device.cc @@ -0,0 +1,74 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "skia/ext/platform_device.h" + +#include "third_party/skia/include/core/SkMetaData.h" + +namespace skia { + +namespace { +const char* kDevicePlatformBehaviour = "CrDevicePlatformBehaviour"; +} + +void SetPlatformDevice(SkDevice* device, PlatformDevice* platform_behaviour) { + SkMetaData& meta_data = device->getMetaData(); + meta_data.setPtr(kDevicePlatformBehaviour, platform_behaviour); +} + +PlatformDevice* GetPlatformDevice(SkDevice* device) { + SkMetaData& meta_data = device->getMetaData(); + PlatformDevice* device_behaviour = NULL; + if (meta_data.findPtr(kDevicePlatformBehaviour, + reinterpret_cast<void**>(&device_behaviour))) + return device_behaviour; + + return NULL; +} + +PlatformSurface BeginPlatformPaint(SkDevice* device) { + PlatformDevice* platform_device = GetPlatformDevice(device); + if (platform_device) + return platform_device->BeginPlatformPaint(); + + return 0; +} + +void EndPlatformPaint(SkDevice* device) { + PlatformDevice* platform_device = GetPlatformDevice(device); + if (platform_device) + return platform_device->EndPlatformPaint(); +} + +bool IsVectorial(SkDevice* device) { + PlatformDevice* platform_device = GetPlatformDevice(device); + if (platform_device) + return platform_device->IsVectorial(); + + return device->getDeviceCapabilities() & SkDevice::kVector_Capability; +} + +bool IsNativeFontRenderingAllowed(SkDevice* device) { + PlatformDevice* platform_device = GetPlatformDevice(device); + if (platform_device) + return platform_device->IsNativeFontRenderingAllowed(); + + return false; +} + +void DrawToNativeContext(SkDevice* device, PlatformSurface context, + int x, int y, const PlatformRect* src_rect) { + PlatformDevice* platform_device = GetPlatformDevice(device); + if (platform_device) + platform_device->DrawToNativeContext(context, x, y, src_rect); +} + +void MakeOpaque(SkDevice* device, int x, int y, int width, int height) { + PlatformDevice* platform_device = GetPlatformDevice(device); + if (platform_device) + platform_device->MakeOpaque(x, y, width, height); +} + +} // namespace skia + diff --git a/skia/ext/platform_device.h b/skia/ext/platform_device.h index 971c0a7..4f876d9 100644 --- a/skia/ext/platform_device.h +++ b/skia/ext/platform_device.h @@ -10,6 +10,81 @@ // header file for your platform. #if defined(WIN32) +#include <windows.h> +#endif + +#include "third_party/skia/include/core/SkPreConfig.h" +#include "third_party/skia/include/core/SkColor.h" + + +class SkDevice; +struct SkIRect; + +#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) +typedef struct _cairo cairo_t; +typedef struct _cairo_rectangle cairo_rectangle_t; +#elif defined(__APPLE__) +typedef struct CGContext* CGContextRef; +typedef struct CGRect CGRect; +#endif + +namespace skia { + +class PlatformDevice; + +#if defined(WIN32) +typedef HDC PlatformSurface; +typedef RECT PlatformRect; +#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) +typedef cairo_t* PlatformSurface; +typedef cairo_rectangle_t PlatformRect; +#elif defined(__APPLE__) +typedef CGContextRef PlatformSurface; +typedef CGRect PlatformRect; +#endif + +// The following routines provide accessor points for the functionality +// exported by the various PlatformDevice ports. The PlatformDevice, and +// BitmapPlatformDevice classes inherit directly from SkDevice, which is no +// longer a supported usage-pattern for skia. In preparation of the removal of +// these classes, all calls to PlatformDevice::* should be routed through these +// helper functions. + +// Bind a PlatformDevice instance, |platform_device| to |device|. Subsequent +// calls to the functions exported below will forward the request to the +// corresponding method on the bound PlatformDevice instance. If no +// PlatformDevice has been bound to the SkDevice passed, then the routines are +// NOPS. +SK_API void SetPlatformDevice(SkDevice* device, + PlatformDevice* platform_device); +SK_API PlatformDevice* GetPlatformDevice(SkDevice* device); + +// Returns if the preferred rendering engine is vectorial or bitmap based. +// Forwards to PlatformDevice::IsVectorial, if a PlatformDevice is bound, +// otherwise falls-back to the SkDevice::getDeviceCapabilities routine. +SK_API bool IsVectorial(SkDevice* device); + +// Returns if the native font rendering engine is allowed to render text to +// this device. +SK_API bool IsNativeFontRenderingAllowed(SkDevice* device); + +// Returns the PlatformSurface used for native rendering into the device. +SK_API PlatformSurface BeginPlatformPaint(SkDevice* device); + +// Finish a previous call to BeginPlatformPaint. +SK_API void EndPlatformPaint(SkDevice* device); + +// Draws to the given PlatformSurface, |context|. Forwards to the +// PlatformDevice bound to |device|. Otherwise is a NOP. +SK_API void DrawToNativeContext(SkDevice* device, PlatformSurface context, + int x, int y, const PlatformRect* src_rect); + +// Sets the opacity of each pixel in the specified region to be opaque. +SK_API void MakeOpaque(SkDevice* device, int x, int y, int width, int height); + +} // namespace skia + +#if defined(WIN32) #include "skia/ext/platform_device_win.h" #elif defined(__APPLE__) #include "skia/ext/platform_device_mac.h" diff --git a/skia/ext/platform_device_linux.cc b/skia/ext/platform_device_linux.cc index b943120..675d19f 100644 --- a/skia/ext/platform_device_linux.cc +++ b/skia/ext/platform_device_linux.cc @@ -2,12 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "skia/ext/platform_device_linux.h" +#include "skia/ext/platform_device.h" namespace skia { PlatformDevice::PlatformDevice(const SkBitmap& bitmap) : SkDevice(NULL, bitmap, /*isForLayer=*/false) { + SetPlatformDevice(this, this); } bool PlatformDevice::IsNativeFontRenderingAllowed() { @@ -18,4 +19,10 @@ void PlatformDevice::EndPlatformPaint() { // We don't need to do anything on Linux here. } +void PlatformDevice::DrawToNativeContext(PlatformSurface surface, int x, int y, + const PlatformRect* src_rect) { + // Should never be called on Linux. + SkASSERT(false); +} + } // namespace skia diff --git a/skia/ext/platform_device_linux.h b/skia/ext/platform_device_linux.h index 718560c..d10d795 100644 --- a/skia/ext/platform_device_linux.h +++ b/skia/ext/platform_device_linux.h @@ -6,10 +6,9 @@ #define SKIA_EXT_PLATFORM_DEVICE_LINUX_H_ #pragma once +#include "skia/ext/platform_device.h" #include "third_party/skia/include/core/SkDevice.h" -typedef struct _cairo cairo_t; - namespace skia { // Blindly copying the mac hierarchy. @@ -26,6 +25,12 @@ class PlatformDevice : public SkDevice { virtual PlatformSurface BeginPlatformPaint() = 0; virtual void EndPlatformPaint(); + virtual void DrawToNativeContext(PlatformSurface surface, int x, int y, + const PlatformRect* src_rect ); + + // Sets the opacity of each pixel in the specified region to be opaque. + virtual void MakeOpaque(int x, int y, int width, int height) { } + protected: // Forwards |bitmap| to SkDevice's constructor. explicit PlatformDevice(const SkBitmap& bitmap); diff --git a/skia/ext/platform_device_mac.cc b/skia/ext/platform_device_mac.cc index 73e814e..da66dbe 100644 --- a/skia/ext/platform_device_mac.cc +++ b/skia/ext/platform_device_mac.cc @@ -2,7 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "skia/ext/bitmap_platform_device_mac.h" +#include "skia/ext/platform_device.h" +#include "skia/ext/bitmap_platform_device.h" #import <ApplicationServices/ApplicationServices.h> #include "skia/ext/skia_utils_mac.h" @@ -13,28 +14,17 @@ namespace skia { -namespace { +CGContextRef GetBitmapContext(SkDevice* device) { + PlatformDevice* platform_device = GetPlatformDevice(device); + if (platform_device) + return platform_device->GetBitmapContext(); -// Constrains position and size to fit within available_size. -bool constrain(int available_size, int* position, int *size) { - if (*position < 0) { - *size += *position; - *position = 0; - } - if (*size > 0 && *position < available_size) { - int overflow = (*position + *size) - available_size; - if (overflow > 0) { - *size -= overflow; - } - return true; - } - return false; + return NULL; } -} // namespace - PlatformDevice::PlatformDevice(const SkBitmap& bitmap) : SkDevice(NULL, bitmap, /*isForLayer=*/false) { + SetPlatformDevice(this, this); } bool PlatformDevice::IsNativeFontRenderingAllowed() { diff --git a/skia/ext/platform_device_mac.h b/skia/ext/platform_device_mac.h index b65d791..0aa8d9d 100644 --- a/skia/ext/platform_device_mac.h +++ b/skia/ext/platform_device_mac.h @@ -17,6 +17,10 @@ class SkRegion; namespace skia { +// Returns the CGContext that backing the SkDevice. Forwards to the bound +// PlatformDevice. Returns NULL if no PlatformDevice is bound. +CGContextRef GetBitmapContext(SkDevice* device); + // 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 @@ -37,8 +41,11 @@ class PlatformDevice : public SkDevice { // 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; + virtual void DrawToNativeContext(CGContextRef context, int x, int y, + const CGRect* src_rect) = 0; + + // Sets the opacity of each pixel in the specified region to be opaque. + virtual 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; diff --git a/skia/ext/platform_device_win.cc b/skia/ext/platform_device_win.cc index dd79ab3..7fbb746 100644 --- a/skia/ext/platform_device_win.cc +++ b/skia/ext/platform_device_win.cc @@ -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 "skia/ext/platform_device_win.h" +#include "skia/ext/platform_device.h" #include "skia/ext/skia_utils_win.h" #include "third_party/skia/include/core/SkMatrix.h" @@ -12,17 +12,7 @@ namespace skia { -PlatformDevice::PlatformDevice(const SkBitmap& bitmap) - : SkDevice(NULL, bitmap, /*isForLayer=*/false) { -} - -void PlatformDevice::EndPlatformPaint() { - // We don't clear the DC here since it will be likely to be used again. - // Flushing will be done in onAccessBitmap. -} - -// static -void PlatformDevice::InitializeDC(HDC context) { +void InitializeDC(HDC context) { // Enables world transformation. // If the GM_ADVANCED graphics mode is set, GDI always draws arcs in the // counterclockwise direction in logical space. This is equivalent to the @@ -61,6 +51,16 @@ void PlatformDevice::InitializeDC(HDC context) { SkASSERT(res != 0); } +PlatformDevice::PlatformDevice(const SkBitmap& bitmap) + : SkDevice(NULL, bitmap, /*isForLayer=*/false) { + SetPlatformDevice(this, this); +} + +void PlatformDevice::EndPlatformPaint() { + // We don't clear the DC here since it will be likely to be used again. + // Flushing will be done in onAccessBitmap. +} + // static void PlatformDevice::LoadPathToDC(HDC context, const SkPath& path) { switch (path.getFillType()) { diff --git a/skia/ext/platform_device_win.h b/skia/ext/platform_device_win.h index 5523ef9..2452fc2 100644 --- a/skia/ext/platform_device_win.h +++ b/skia/ext/platform_device_win.h @@ -18,6 +18,9 @@ class SkRegion; namespace skia { +// Initializes the default settings and colors in a device context. +SK_API void InitializeDC(HDC context); + // 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. @@ -40,10 +43,11 @@ class SK_API PlatformDevice : public SkDevice { // 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; + virtual void DrawToNativeContext(HDC dc, int x, int y, + const RECT* src_rect) = 0; // Sets the opacity of each pixel in the specified region to be opaque. - virtual void makeOpaque(int x, int y, int width, int height) { } + virtual 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; @@ -51,9 +55,6 @@ class SK_API PlatformDevice : public SkDevice { // Returns if GDI is allowed to render text to this device. virtual bool IsNativeFontRenderingAllowed() { return true; } - // 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); diff --git a/skia/ext/skia_utils_mac.mm b/skia/ext/skia_utils_mac.mm index ecb30ca..3c955bb 100644 --- a/skia/ext/skia_utils_mac.mm +++ b/skia/ext/skia_utils_mac.mm @@ -193,10 +193,10 @@ SkBitmap CGImageToSkBitmap(CGImageRef image) { int width = CGImageGetWidth(image); int height = CGImageGetHeight(image); - scoped_ptr<skia::BitmapPlatformDevice> device( + scoped_ptr<SkDevice> device( skia::BitmapPlatformDevice::Create(NULL, width, height, false)); - CGContextRef context = device->GetBitmapContext(); + CGContextRef context = skia::GetBitmapContext(device.get()); // We need to invert the y-axis of the canvas so that Core Graphics drawing // happens right-side up. Skia has an upper-left origin and CG has a lower- diff --git a/skia/ext/vector_canvas.cc b/skia/ext/vector_canvas.cc index 524ebbc..dbf303f 100644 --- a/skia/ext/vector_canvas.cc +++ b/skia/ext/vector_canvas.cc @@ -3,10 +3,11 @@ // found in the LICENSE file. #include "skia/ext/vector_canvas.h" +#include "third_party/skia/include/core/SkDevice.h" namespace skia { -VectorCanvas::VectorCanvas(PlatformDevice* device) +VectorCanvas::VectorCanvas(SkDevice* device) : PlatformCanvas(device->getDeviceFactory()) { setDevice(device)->unref(); // Created with refcount 1, and setDevice refs. } @@ -30,7 +31,7 @@ SkDrawFilter* VectorCanvas::setDrawFilter(SkDrawFilter* filter) { } bool VectorCanvas::IsTopDeviceVectorial() const { - return getTopPlatformDevice().IsVectorial(); + return IsVectorial(GetTopDevice(*this)); } } // namespace skia diff --git a/skia/ext/vector_canvas.h b/skia/ext/vector_canvas.h index 4b4419d..aac0400 100644 --- a/skia/ext/vector_canvas.h +++ b/skia/ext/vector_canvas.h @@ -8,9 +8,9 @@ #include "skia/ext/platform_canvas.h" -namespace skia { +class SkDevice; -class PlatformDevice; +namespace skia { // This class is a specialization of the regular PlatformCanvas. It is designed // to work with a VectorDevice to manage platform-specific drawing. It allows @@ -19,7 +19,7 @@ class PlatformDevice; class SK_API VectorCanvas : public PlatformCanvas { public: // Ownership of |device| is transfered to VectorCanvas. - explicit VectorCanvas(PlatformDevice* device); + explicit VectorCanvas(SkDevice* device); virtual ~VectorCanvas(); virtual SkBounder* setBounder(SkBounder* bounder); diff --git a/skia/ext/vector_canvas_unittest.cc b/skia/ext/vector_canvas_unittest.cc index ec8fb38..627c1d9 100644 --- a/skia/ext/vector_canvas_unittest.cc +++ b/skia/ext/vector_canvas_unittest.cc @@ -96,10 +96,11 @@ class Image { } // Loads the image from a canvas. - Image(const skia::PlatformCanvas& canvas) : ignore_alpha_(true) { + Image(skia::PlatformCanvas& canvas) : ignore_alpha_(true) { // Use a different way to access the bitmap. The normal way would be to // query the SkBitmap. - HDC context = canvas.beginPlatformPaint(); + skia::ScopedPlatformPaint scoped_platform_paint(&canvas); + HDC context = scoped_platform_paint.GetPlatformSurface(); HGDIOBJ bitmap = GetCurrentObject(context, OBJ_BITMAP); EXPECT_TRUE(bitmap != NULL); // Initialize the clip region to the entire bitmap. @@ -111,7 +112,6 @@ class Image { size_t size = row_length_ * height_; data_.resize(size); memcpy(&*data_.begin(), bitmap_data.bmBits, size); - canvas.endPlatformPaint(); } // Loads the image from a canvas. @@ -267,7 +267,7 @@ class ImageTest : public testing::Test { // kGenerating value. Returns 0 on success or any positive value between ]0, // 100] on failure. The return value is the percentage of difference between // the image in the file and the image in the canvas. - double ProcessCanvas(const skia::PlatformCanvas& canvas, + double ProcessCanvas(skia::PlatformCanvas& canvas, FilePath::StringType filename) const { filename = filename + FILE_PATH_LITERAL(".png"); switch (action_) { @@ -286,7 +286,7 @@ class ImageTest : public testing::Test { // Compares the bitmap currently loaded in the context with the file. Returns // the percentage of pixel difference between both images, between 0 and 100. - double CompareImage(const skia::PlatformCanvas& canvas, + double CompareImage(skia::PlatformCanvas& canvas, const FilePath::StringType& filename) const { Image image1(canvas); Image image2(test_file(filename)); @@ -295,7 +295,7 @@ class ImageTest : public testing::Test { } // Saves the bitmap currently loaded in the context into the file. - void SaveImage(const skia::PlatformCanvas& canvas, + void SaveImage(skia::PlatformCanvas& canvas, const FilePath::StringType& filename) const { Image(canvas).SaveToFile(test_file(filename)); } diff --git a/skia/ext/vector_platform_device_emf_win.cc b/skia/ext/vector_platform_device_emf_win.cc index d13ee4d..8b181bf 100644 --- a/skia/ext/vector_platform_device_emf_win.cc +++ b/skia/ext/vector_platform_device_emf_win.cc @@ -435,8 +435,8 @@ void VectorPlatformDeviceEmf::setMatrixClip(const SkMatrix& transform, LoadClipRegion(); } -void VectorPlatformDeviceEmf::drawToHDC(HDC dc, int x, int y, - const RECT* src_rect) { +void VectorPlatformDeviceEmf::DrawToNativeContext(HDC dc, int x, int y, + const RECT* src_rect) { SkASSERT(false); } diff --git a/skia/ext/vector_platform_device_emf_win.h b/skia/ext/vector_platform_device_emf_win.h index 4662475..1a27041 100644 --- a/skia/ext/vector_platform_device_emf_win.h +++ b/skia/ext/vector_platform_device_emf_win.h @@ -73,7 +73,7 @@ class VectorPlatformDeviceEmf : public PlatformDevice { virtual void setMatrixClip(const SkMatrix& transform, const SkRegion& region, const SkClipStack&); - virtual void drawToHDC(HDC dc, int x, int y, const RECT* src_rect); + virtual void DrawToNativeContext(HDC dc, int x, int y, const RECT* src_rect); virtual bool IsVectorial() { return true; } void LoadClipRegion(); diff --git a/skia/ext/vector_platform_device_skia.cc b/skia/ext/vector_platform_device_skia.cc index 9421b0b..ab99873 100644 --- a/skia/ext/vector_platform_device_skia.cc +++ b/skia/ext/vector_platform_device_skia.cc @@ -209,10 +209,10 @@ void VectorPlatformDeviceSkia::drawDevice(const SkDraw& draw, } #if defined(OS_WIN) -void VectorPlatformDeviceSkia::drawToHDC(HDC dc, - int x, - int y, - const RECT* src_rect) { +void VectorPlatformDeviceSkia::DrawToNativeContext(HDC dc, + int x, + int y, + const RECT* src_rect) { SkASSERT(false); } #endif diff --git a/skia/ext/vector_platform_device_skia.h b/skia/ext/vector_platform_device_skia.h index 53c711d..4a126e5 100644 --- a/skia/ext/vector_platform_device_skia.h +++ b/skia/ext/vector_platform_device_skia.h @@ -84,7 +84,7 @@ class VectorPlatformDeviceSkia : public PlatformDevice { const SkPaint&); #if defined(OS_WIN) - virtual void drawToHDC(HDC dc, int x, int y, const RECT* src_rect); + virtual void DrawToNativeContext(HDC dc, int x, int y, const RECT* src_rect); #endif protected: |