Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1109)

Unified Diff: skia/ext/bitmap_platform_device_cairo.cc

Issue 2616003003: Revert of Delete Mac & Cairo skia::BitmapPlatformDevice impls (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « skia/ext/bitmap_platform_device_cairo.h ('k') | skia/ext/bitmap_platform_device_mac.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: skia/ext/bitmap_platform_device_cairo.cc
diff --git a/skia/ext/bitmap_platform_device_cairo.cc b/skia/ext/bitmap_platform_device_cairo.cc
new file mode 100644
index 0000000000000000000000000000000000000000..261228b938c287e25528e3e12a9a8cb55503f39f
--- /dev/null
+++ b/skia/ext/bitmap_platform_device_cairo.cc
@@ -0,0 +1,180 @@
+// Copyright 2013 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 "build/build_config.h"
+#include "skia/ext/bitmap_platform_device_cairo.h"
+#include "skia/ext/platform_canvas.h"
+
+#if defined(OS_OPENBSD)
+#include <cairo.h>
+#else
+#include <cairo/cairo.h>
+#endif
+
+namespace skia {
+
+namespace {
+
+void CairoSurfaceReleaseProc(void*, void* context) {
+ SkASSERT(context);
+ cairo_surface_destroy(static_cast<cairo_surface_t*>(context));
+}
+
+// Back the destination bitmap by a Cairo surface. The bitmap's
+// pixelRef takes ownership of the passed-in surface and will call
+// cairo_surface_destroy() upon destruction.
+//
+// Note: it may immediately destroy the surface, if it fails to create a bitmap
+// with pixels, thus the caller must either ref() the surface before hand, or
+// it must not refer to the surface after this call.
+bool InstallCairoSurfacePixels(SkBitmap* dst,
+ cairo_surface_t* surface,
+ bool is_opaque) {
+ SkASSERT(dst);
+ if (!surface) {
+ return false;
+ }
+ SkImageInfo info
+ = SkImageInfo::MakeN32(cairo_image_surface_get_width(surface),
+ cairo_image_surface_get_height(surface),
+ is_opaque ? kOpaque_SkAlphaType
+ : kPremul_SkAlphaType);
+ return dst->installPixels(info,
+ cairo_image_surface_get_data(surface),
+ cairo_image_surface_get_stride(surface),
+ NULL,
+ &CairoSurfaceReleaseProc,
+ static_cast<void*>(surface));
+}
+
+void LoadMatrixToContext(cairo_t* context, const SkMatrix& matrix) {
+ cairo_matrix_t cairo_matrix;
+ cairo_matrix_init(&cairo_matrix,
+ SkScalarToFloat(matrix.getScaleX()),
+ SkScalarToFloat(matrix.getSkewY()),
+ SkScalarToFloat(matrix.getSkewX()),
+ SkScalarToFloat(matrix.getScaleY()),
+ SkScalarToFloat(matrix.getTranslateX()),
+ SkScalarToFloat(matrix.getTranslateY()));
+ cairo_set_matrix(context, &cairo_matrix);
+}
+
+void LoadClipToContext(cairo_t* context, const SkIRect& clip_bounds) {
+ cairo_reset_clip(context);
+
+ cairo_rectangle(context, clip_bounds.fLeft, clip_bounds.fTop,
+ clip_bounds.width(), clip_bounds.height());
+ cairo_clip(context);
+}
+
+} // namespace
+
+void BitmapPlatformDevice::LoadConfig(const SkMatrix& transform,
+ const SkIRect& clip_bounds) {
+ if (!cairo_)
+ return; // Nothing to do.
+
+ LoadClipToContext(cairo_, clip_bounds);
+ LoadMatrixToContext(cairo_, transform);
+}
+
+// We use this static factory function instead of the regular constructor so
+// that we can create the pixel data before calling the constructor. This is
+// required so that we can call the base class' constructor with the pixel
+// data.
+BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height,
+ bool is_opaque,
+ cairo_surface_t* surface) {
+ if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
+ cairo_surface_destroy(surface);
+ return NULL;
+ }
+
+ // must call this before trying to install the surface, since that may result
+ // in the surface being destroyed.
+ cairo_t* cairo = cairo_create(surface);
+
+ SkBitmap bitmap;
+ if (!InstallCairoSurfacePixels(&bitmap, surface, is_opaque)) {
+ cairo_destroy(cairo);
+ return NULL;
+ }
+
+ // The device object will take ownership of the graphics context.
+ return new BitmapPlatformDevice(bitmap, cairo);
+}
+
+BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height,
+ bool is_opaque) {
+ // This initializes the bitmap to all zeros.
+ cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
+ width, height);
+
+ BitmapPlatformDevice* device = Create(width, height, is_opaque, surface);
+
+#ifndef NDEBUG
+ if (device && is_opaque) // Fill with bright bluish green
+ SkCanvas(device).drawColor(0xFF00FF80);
+#endif
+
+ return device;
+}
+
+BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height,
+ bool is_opaque,
+ uint8_t* data) {
+ cairo_surface_t* surface = cairo_image_surface_create_for_data(
+ data, CAIRO_FORMAT_ARGB32, width, height,
+ cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width));
+
+ return Create(width, height, is_opaque, surface);
+}
+
+// Ownership of the cairo object is transferred.
+BitmapPlatformDevice::BitmapPlatformDevice(
+ const SkBitmap& bitmap,
+ cairo_t* cairo)
+ : SkBitmapDevice(bitmap),
+ cairo_(cairo) {
+ SetPlatformDevice(this, this);
+}
+
+BitmapPlatformDevice::~BitmapPlatformDevice() {
+ cairo_destroy(cairo_);
+}
+
+SkBaseDevice* BitmapPlatformDevice::onCreateDevice(const CreateInfo& info,
+ const SkPaint*) {
+ SkASSERT(info.fInfo.colorType() == kN32_SkColorType);
+ return BitmapPlatformDevice::Create(info.fInfo.width(), info.fInfo.height(),
+ info.fInfo.isOpaque());
+}
+
+cairo_t* BitmapPlatformDevice::BeginPlatformPaint(
+ const SkMatrix& transform,
+ const SkIRect& clip_bounds) {
+ LoadConfig(transform, clip_bounds);
+ cairo_surface_t* surface = cairo_get_target(cairo_);
+ // Tell cairo to flush anything it has pending.
+ cairo_surface_flush(surface);
+ // Tell Cairo that we (probably) modified (actually, will modify) its pixel
+ // buffer directly.
+ cairo_surface_mark_dirty(surface);
+ return cairo_;
+}
+
+// PlatformCanvas impl
+
+std::unique_ptr<SkCanvas> CreatePlatformCanvasWithPixels(
+ int width,
+ int height,
+ bool is_opaque,
+ uint8_t* data,
+ OnFailureType failureType) {
+ sk_sp<SkBaseDevice> dev(
+ BitmapPlatformDevice::Create(width, height, is_opaque, data));
+ return CreateCanvas(dev, failureType);
+}
+
+} // namespace skia
« no previous file with comments | « skia/ext/bitmap_platform_device_cairo.h ('k') | skia/ext/bitmap_platform_device_mac.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698