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

Side by Side 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 unified diff | 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "build/build_config.h"
6 #include "skia/ext/bitmap_platform_device_cairo.h"
7 #include "skia/ext/platform_canvas.h"
8
9 #if defined(OS_OPENBSD)
10 #include <cairo.h>
11 #else
12 #include <cairo/cairo.h>
13 #endif
14
15 namespace skia {
16
17 namespace {
18
19 void CairoSurfaceReleaseProc(void*, void* context) {
20 SkASSERT(context);
21 cairo_surface_destroy(static_cast<cairo_surface_t*>(context));
22 }
23
24 // Back the destination bitmap by a Cairo surface. The bitmap's
25 // pixelRef takes ownership of the passed-in surface and will call
26 // cairo_surface_destroy() upon destruction.
27 //
28 // Note: it may immediately destroy the surface, if it fails to create a bitmap
29 // with pixels, thus the caller must either ref() the surface before hand, or
30 // it must not refer to the surface after this call.
31 bool InstallCairoSurfacePixels(SkBitmap* dst,
32 cairo_surface_t* surface,
33 bool is_opaque) {
34 SkASSERT(dst);
35 if (!surface) {
36 return false;
37 }
38 SkImageInfo info
39 = SkImageInfo::MakeN32(cairo_image_surface_get_width(surface),
40 cairo_image_surface_get_height(surface),
41 is_opaque ? kOpaque_SkAlphaType
42 : kPremul_SkAlphaType);
43 return dst->installPixels(info,
44 cairo_image_surface_get_data(surface),
45 cairo_image_surface_get_stride(surface),
46 NULL,
47 &CairoSurfaceReleaseProc,
48 static_cast<void*>(surface));
49 }
50
51 void LoadMatrixToContext(cairo_t* context, const SkMatrix& matrix) {
52 cairo_matrix_t cairo_matrix;
53 cairo_matrix_init(&cairo_matrix,
54 SkScalarToFloat(matrix.getScaleX()),
55 SkScalarToFloat(matrix.getSkewY()),
56 SkScalarToFloat(matrix.getSkewX()),
57 SkScalarToFloat(matrix.getScaleY()),
58 SkScalarToFloat(matrix.getTranslateX()),
59 SkScalarToFloat(matrix.getTranslateY()));
60 cairo_set_matrix(context, &cairo_matrix);
61 }
62
63 void LoadClipToContext(cairo_t* context, const SkIRect& clip_bounds) {
64 cairo_reset_clip(context);
65
66 cairo_rectangle(context, clip_bounds.fLeft, clip_bounds.fTop,
67 clip_bounds.width(), clip_bounds.height());
68 cairo_clip(context);
69 }
70
71 } // namespace
72
73 void BitmapPlatformDevice::LoadConfig(const SkMatrix& transform,
74 const SkIRect& clip_bounds) {
75 if (!cairo_)
76 return; // Nothing to do.
77
78 LoadClipToContext(cairo_, clip_bounds);
79 LoadMatrixToContext(cairo_, transform);
80 }
81
82 // We use this static factory function instead of the regular constructor so
83 // that we can create the pixel data before calling the constructor. This is
84 // required so that we can call the base class' constructor with the pixel
85 // data.
86 BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height,
87 bool is_opaque,
88 cairo_surface_t* surface) {
89 if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
90 cairo_surface_destroy(surface);
91 return NULL;
92 }
93
94 // must call this before trying to install the surface, since that may result
95 // in the surface being destroyed.
96 cairo_t* cairo = cairo_create(surface);
97
98 SkBitmap bitmap;
99 if (!InstallCairoSurfacePixels(&bitmap, surface, is_opaque)) {
100 cairo_destroy(cairo);
101 return NULL;
102 }
103
104 // The device object will take ownership of the graphics context.
105 return new BitmapPlatformDevice(bitmap, cairo);
106 }
107
108 BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height,
109 bool is_opaque) {
110 // This initializes the bitmap to all zeros.
111 cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
112 width, height);
113
114 BitmapPlatformDevice* device = Create(width, height, is_opaque, surface);
115
116 #ifndef NDEBUG
117 if (device && is_opaque) // Fill with bright bluish green
118 SkCanvas(device).drawColor(0xFF00FF80);
119 #endif
120
121 return device;
122 }
123
124 BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height,
125 bool is_opaque,
126 uint8_t* data) {
127 cairo_surface_t* surface = cairo_image_surface_create_for_data(
128 data, CAIRO_FORMAT_ARGB32, width, height,
129 cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width));
130
131 return Create(width, height, is_opaque, surface);
132 }
133
134 // Ownership of the cairo object is transferred.
135 BitmapPlatformDevice::BitmapPlatformDevice(
136 const SkBitmap& bitmap,
137 cairo_t* cairo)
138 : SkBitmapDevice(bitmap),
139 cairo_(cairo) {
140 SetPlatformDevice(this, this);
141 }
142
143 BitmapPlatformDevice::~BitmapPlatformDevice() {
144 cairo_destroy(cairo_);
145 }
146
147 SkBaseDevice* BitmapPlatformDevice::onCreateDevice(const CreateInfo& info,
148 const SkPaint*) {
149 SkASSERT(info.fInfo.colorType() == kN32_SkColorType);
150 return BitmapPlatformDevice::Create(info.fInfo.width(), info.fInfo.height(),
151 info.fInfo.isOpaque());
152 }
153
154 cairo_t* BitmapPlatformDevice::BeginPlatformPaint(
155 const SkMatrix& transform,
156 const SkIRect& clip_bounds) {
157 LoadConfig(transform, clip_bounds);
158 cairo_surface_t* surface = cairo_get_target(cairo_);
159 // Tell cairo to flush anything it has pending.
160 cairo_surface_flush(surface);
161 // Tell Cairo that we (probably) modified (actually, will modify) its pixel
162 // buffer directly.
163 cairo_surface_mark_dirty(surface);
164 return cairo_;
165 }
166
167 // PlatformCanvas impl
168
169 std::unique_ptr<SkCanvas> CreatePlatformCanvasWithPixels(
170 int width,
171 int height,
172 bool is_opaque,
173 uint8_t* data,
174 OnFailureType failureType) {
175 sk_sp<SkBaseDevice> dev(
176 BitmapPlatformDevice::Create(width, height, is_opaque, data));
177 return CreateCanvas(dev, failureType);
178 }
179
180 } // namespace skia
OLDNEW
« 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