| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "build/build_config.h" | 5 #include "build/build_config.h" |
| 6 #include "skia/ext/bitmap_platform_device_cairo.h" | 6 #include "skia/ext/bitmap_platform_device_cairo.h" |
| 7 #include "skia/ext/platform_canvas.h" | 7 #include "skia/ext/platform_canvas.h" |
| 8 | 8 |
| 9 #if defined(OS_OPENBSD) | 9 #if defined(OS_OPENBSD) |
| 10 #include <cairo.h> | 10 #include <cairo.h> |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 cairo_matrix_init(&cairo_matrix, | 53 cairo_matrix_init(&cairo_matrix, |
| 54 SkScalarToFloat(matrix.getScaleX()), | 54 SkScalarToFloat(matrix.getScaleX()), |
| 55 SkScalarToFloat(matrix.getSkewY()), | 55 SkScalarToFloat(matrix.getSkewY()), |
| 56 SkScalarToFloat(matrix.getSkewX()), | 56 SkScalarToFloat(matrix.getSkewX()), |
| 57 SkScalarToFloat(matrix.getScaleY()), | 57 SkScalarToFloat(matrix.getScaleY()), |
| 58 SkScalarToFloat(matrix.getTranslateX()), | 58 SkScalarToFloat(matrix.getTranslateX()), |
| 59 SkScalarToFloat(matrix.getTranslateY())); | 59 SkScalarToFloat(matrix.getTranslateY())); |
| 60 cairo_set_matrix(context, &cairo_matrix); | 60 cairo_set_matrix(context, &cairo_matrix); |
| 61 } | 61 } |
| 62 | 62 |
| 63 void LoadClipToContext(cairo_t* context, const SkRegion& clip) { | 63 void LoadClipToContext(cairo_t* context, const SkIRect& clip_bounds) { |
| 64 cairo_reset_clip(context); | 64 cairo_reset_clip(context); |
| 65 | 65 |
| 66 // TODO(brettw) support non-rect clips. | 66 cairo_rectangle(context, clip_bounds.fLeft, clip_bounds.fTop, |
| 67 SkIRect bounding = clip.getBounds(); | 67 clip_bounds.width(), clip_bounds.height()); |
| 68 cairo_rectangle(context, bounding.fLeft, bounding.fTop, | |
| 69 bounding.fRight - bounding.fLeft, | |
| 70 bounding.fBottom - bounding.fTop); | |
| 71 cairo_clip(context); | 68 cairo_clip(context); |
| 72 } | 69 } |
| 73 | 70 |
| 74 } // namespace | 71 } // namespace |
| 75 | 72 |
| 76 void BitmapPlatformDevice::SetMatrixClip( | 73 void BitmapPlatformDevice::LoadConfig(const SkMatrix& transform, |
| 77 const SkMatrix& transform, | 74 const SkIRect& clip_bounds) { |
| 78 const SkRegion& region) { | 75 if (!cairo_) |
| 79 transform_ = transform; | 76 return; // Nothing to do. |
| 80 clip_region_ = region; | |
| 81 config_dirty_ = true; | |
| 82 } | |
| 83 | 77 |
| 84 void BitmapPlatformDevice::LoadConfig() { | 78 LoadClipToContext(cairo_, clip_bounds); |
| 85 if (!config_dirty_ || !cairo_) | 79 LoadMatrixToContext(cairo_, transform); |
| 86 return; // Nothing to do. | |
| 87 config_dirty_ = false; | |
| 88 | |
| 89 // Load the identity matrix since this is what our clip is relative to. | |
| 90 cairo_matrix_t cairo_matrix; | |
| 91 cairo_matrix_init_identity(&cairo_matrix); | |
| 92 cairo_set_matrix(cairo_, &cairo_matrix); | |
| 93 | |
| 94 LoadClipToContext(cairo_, clip_region_); | |
| 95 LoadMatrixToContext(cairo_, transform_); | |
| 96 } | 80 } |
| 97 | 81 |
| 98 // We use this static factory function instead of the regular constructor so | 82 // We use this static factory function instead of the regular constructor so |
| 99 // that we can create the pixel data before calling the constructor. This is | 83 // that we can create the pixel data before calling the constructor. This is |
| 100 // required so that we can call the base class' constructor with the pixel | 84 // required so that we can call the base class' constructor with the pixel |
| 101 // data. | 85 // data. |
| 102 BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height, | 86 BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height, |
| 103 bool is_opaque, | 87 bool is_opaque, |
| 104 cairo_surface_t* surface) { | 88 cairo_surface_t* surface) { |
| 105 if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) { | 89 if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width)); | 129 cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width)); |
| 146 | 130 |
| 147 return Create(width, height, is_opaque, surface); | 131 return Create(width, height, is_opaque, surface); |
| 148 } | 132 } |
| 149 | 133 |
| 150 // Ownership of the cairo object is transferred. | 134 // Ownership of the cairo object is transferred. |
| 151 BitmapPlatformDevice::BitmapPlatformDevice( | 135 BitmapPlatformDevice::BitmapPlatformDevice( |
| 152 const SkBitmap& bitmap, | 136 const SkBitmap& bitmap, |
| 153 cairo_t* cairo) | 137 cairo_t* cairo) |
| 154 : SkBitmapDevice(bitmap), | 138 : SkBitmapDevice(bitmap), |
| 155 cairo_(cairo), | 139 cairo_(cairo) { |
| 156 config_dirty_(true), | |
| 157 transform_(SkMatrix::I()) { // Want to load the config next time. | |
| 158 SetPlatformDevice(this, this); | 140 SetPlatformDevice(this, this); |
| 159 } | 141 } |
| 160 | 142 |
| 161 BitmapPlatformDevice::~BitmapPlatformDevice() { | 143 BitmapPlatformDevice::~BitmapPlatformDevice() { |
| 162 cairo_destroy(cairo_); | 144 cairo_destroy(cairo_); |
| 163 } | 145 } |
| 164 | 146 |
| 165 SkBaseDevice* BitmapPlatformDevice::onCreateDevice(const CreateInfo& info, | 147 SkBaseDevice* BitmapPlatformDevice::onCreateDevice(const CreateInfo& info, |
| 166 const SkPaint*) { | 148 const SkPaint*) { |
| 167 SkASSERT(info.fInfo.colorType() == kN32_SkColorType); | 149 SkASSERT(info.fInfo.colorType() == kN32_SkColorType); |
| 168 return BitmapPlatformDevice::Create(info.fInfo.width(), info.fInfo.height(), | 150 return BitmapPlatformDevice::Create(info.fInfo.width(), info.fInfo.height(), |
| 169 info.fInfo.isOpaque()); | 151 info.fInfo.isOpaque()); |
| 170 } | 152 } |
| 171 | 153 |
| 172 cairo_t* BitmapPlatformDevice::BeginPlatformPaint() { | 154 cairo_t* BitmapPlatformDevice::BeginPlatformPaint( |
| 173 LoadConfig(); | 155 const SkMatrix& transform, |
| 156 const SkIRect& clip_bounds) { |
| 157 LoadConfig(transform, clip_bounds); |
| 174 cairo_surface_t* surface = cairo_get_target(cairo_); | 158 cairo_surface_t* surface = cairo_get_target(cairo_); |
| 175 // Tell cairo to flush anything it has pending. | 159 // Tell cairo to flush anything it has pending. |
| 176 cairo_surface_flush(surface); | 160 cairo_surface_flush(surface); |
| 177 // Tell Cairo that we (probably) modified (actually, will modify) its pixel | 161 // Tell Cairo that we (probably) modified (actually, will modify) its pixel |
| 178 // buffer directly. | 162 // buffer directly. |
| 179 cairo_surface_mark_dirty(surface); | 163 cairo_surface_mark_dirty(surface); |
| 180 return cairo_; | 164 return cairo_; |
| 181 } | 165 } |
| 182 | 166 |
| 183 void BitmapPlatformDevice::setMatrixClip(const SkMatrix& transform, | |
| 184 const SkRegion& region, | |
| 185 const SkClipStack&) { | |
| 186 SetMatrixClip(transform, region); | |
| 187 } | |
| 188 | |
| 189 // PlatformCanvas impl | 167 // PlatformCanvas impl |
| 190 | 168 |
| 191 SkCanvas* CreatePlatformCanvas(int width, int height, bool is_opaque, | 169 SkCanvas* CreatePlatformCanvas(int width, int height, bool is_opaque, |
| 192 uint8_t* data, OnFailureType failureType) { | 170 uint8_t* data, OnFailureType failureType) { |
| 193 sk_sp<SkBaseDevice> dev( | 171 sk_sp<SkBaseDevice> dev( |
| 194 BitmapPlatformDevice::Create(width, height, is_opaque, data)); | 172 BitmapPlatformDevice::Create(width, height, is_opaque, data)); |
| 195 return CreateCanvas(dev, failureType); | 173 return CreateCanvas(dev, failureType); |
| 196 } | 174 } |
| 197 | 175 |
| 198 } // namespace skia | 176 } // namespace skia |
| OLD | NEW |