| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "skia/ext/bitmap_platform_device_linux.h" | 5 #include "skia/ext/bitmap_platform_device_linux.h" |
| 6 | 6 |
| 7 #include "skia/ext/bitmap_platform_device_data.h" |
| 8 |
| 7 #include <cairo/cairo.h> | 9 #include <cairo/cairo.h> |
| 8 | 10 |
| 9 namespace skia { | 11 namespace skia { |
| 10 | 12 |
| 11 namespace { | 13 namespace { |
| 12 | 14 |
| 13 void LoadMatrixToContext(cairo_t* context, const SkMatrix& matrix) { | 15 void LoadMatrixToContext(cairo_t* context, const SkMatrix& matrix) { |
| 14 cairo_matrix_t cairo_matrix; | 16 cairo_matrix_t cairo_matrix; |
| 15 cairo_matrix_init(&cairo_matrix, | 17 cairo_matrix_init(&cairo_matrix, |
| 16 SkScalarToFloat(matrix.getScaleX()), | 18 SkScalarToFloat(matrix.getScaleX()), |
| (...skipping 11 matching lines...) Expand all Loading... |
| 28 // TODO(brettw) support non-rect clips. | 30 // TODO(brettw) support non-rect clips. |
| 29 SkIRect bounding = clip.getBounds(); | 31 SkIRect bounding = clip.getBounds(); |
| 30 cairo_rectangle(context, bounding.fLeft, bounding.fTop, | 32 cairo_rectangle(context, bounding.fLeft, bounding.fTop, |
| 31 bounding.fRight - bounding.fLeft, | 33 bounding.fRight - bounding.fLeft, |
| 32 bounding.fBottom - bounding.fTop); | 34 bounding.fBottom - bounding.fTop); |
| 33 cairo_clip(context); | 35 cairo_clip(context); |
| 34 } | 36 } |
| 35 | 37 |
| 36 } // namespace | 38 } // namespace |
| 37 | 39 |
| 38 // ----------------------------------------------------------------------------- | |
| 39 // These objects are reference counted and own a Cairo surface. The surface is | |
| 40 // the backing store for a Skia bitmap and we reference count it so that we can | |
| 41 // copy BitmapPlatformDevice objects without having to copy all the image | |
| 42 // data. | |
| 43 // ----------------------------------------------------------------------------- | |
| 44 class BitmapPlatformDevice::BitmapPlatformDeviceData | |
| 45 : public base::RefCounted<BitmapPlatformDeviceData> { | |
| 46 public: | |
| 47 explicit BitmapPlatformDeviceData(cairo_surface_t* surface); | |
| 48 | |
| 49 cairo_t* GetContext(); | |
| 50 | |
| 51 // Sets the transform and clip operations. This will not update the Cairo | |
| 52 // surface, but will mark the config as dirty. The next call of LoadConfig | |
| 53 // will pick up these changes. | |
| 54 void SetMatrixClip(const SkMatrix& transform, const SkRegion& region); | |
| 55 | |
| 56 protected: | |
| 57 void LoadConfig(); | |
| 58 | |
| 59 // The Cairo surface inside this DC. | |
| 60 cairo_t* context_; | |
| 61 cairo_surface_t *const surface_; | |
| 62 | |
| 63 // True when there is a transform or clip that has not been set to the | |
| 64 // surface. The surface is retrieved for every text operation, and the | |
| 65 // transform and clip do not change as much. We can save time by not loading | |
| 66 // the clip and transform for every one. | |
| 67 bool config_dirty_; | |
| 68 | |
| 69 // Translation assigned to the DC: we need to keep track of this separately | |
| 70 // so it can be updated even if the DC isn't created yet. | |
| 71 SkMatrix transform_; | |
| 72 | |
| 73 // The current clipping | |
| 74 SkRegion clip_region_; | |
| 75 | |
| 76 // Disallow copy & assign. | |
| 77 BitmapPlatformDeviceData(const BitmapPlatformDeviceData&); | |
| 78 BitmapPlatformDeviceData& operator=( | |
| 79 const BitmapPlatformDeviceData&); | |
| 80 | |
| 81 private: | |
| 82 friend class base::RefCounted<BitmapPlatformDeviceData>; | |
| 83 | |
| 84 ~BitmapPlatformDeviceData(); | |
| 85 }; | |
| 86 | |
| 87 BitmapPlatformDevice::BitmapPlatformDeviceData::BitmapPlatformDeviceData( | 40 BitmapPlatformDevice::BitmapPlatformDeviceData::BitmapPlatformDeviceData( |
| 88 cairo_surface_t* surface) | 41 cairo_surface_t* surface) |
| 89 : surface_(surface), | 42 : surface_(surface), |
| 90 config_dirty_(true) { // Want to load the config next time. | 43 config_dirty_(true) { // Want to load the config next time. |
| 91 context_ = cairo_create(surface); | 44 bitmap_context_ = cairo_create(surface); |
| 92 } | 45 } |
| 93 | 46 |
| 94 BitmapPlatformDevice::BitmapPlatformDeviceData::~BitmapPlatformDeviceData() { | 47 BitmapPlatformDevice::BitmapPlatformDeviceData::~BitmapPlatformDeviceData() { |
| 95 cairo_destroy(context_); | 48 cairo_destroy(bitmap_context_); |
| 96 cairo_surface_destroy(surface_); | 49 cairo_surface_destroy(surface_); |
| 97 } | 50 } |
| 98 | 51 |
| 99 cairo_t* BitmapPlatformDevice::BitmapPlatformDeviceData::GetContext() { | |
| 100 LoadConfig(); | |
| 101 return context_; | |
| 102 } | |
| 103 | |
| 104 void BitmapPlatformDevice::BitmapPlatformDeviceData::SetMatrixClip( | 52 void BitmapPlatformDevice::BitmapPlatformDeviceData::SetMatrixClip( |
| 105 const SkMatrix& transform, | 53 const SkMatrix& transform, |
| 106 const SkRegion& region) { | 54 const SkRegion& region) { |
| 107 transform_ = transform; | 55 transform_ = transform; |
| 108 clip_region_ = region; | 56 clip_region_ = region; |
| 109 config_dirty_ = true; | 57 config_dirty_ = true; |
| 110 } | 58 } |
| 111 | 59 |
| 112 void BitmapPlatformDevice::BitmapPlatformDeviceData::LoadConfig() { | 60 void BitmapPlatformDevice::BitmapPlatformDeviceData::LoadConfig() { |
| 113 if (!config_dirty_ || !context_) | 61 if (!config_dirty_ || !bitmap_context_) |
| 114 return; // Nothing to do. | 62 return; // Nothing to do. |
| 115 config_dirty_ = false; | 63 config_dirty_ = false; |
| 116 | 64 |
| 117 // Load the identity matrix since this is what our clip is relative to. | 65 // Load the identity matrix since this is what our clip is relative to. |
| 118 cairo_matrix_t cairo_matrix; | 66 cairo_matrix_t cairo_matrix; |
| 119 cairo_matrix_init_identity(&cairo_matrix); | 67 cairo_matrix_init_identity(&cairo_matrix); |
| 120 cairo_set_matrix(context_, &cairo_matrix); | 68 cairo_set_matrix(bitmap_context_, &cairo_matrix); |
| 121 | 69 |
| 122 LoadClipToContext(context_, clip_region_); | 70 LoadClipToContext(bitmap_context_, clip_region_); |
| 123 LoadMatrixToContext(context_, transform_); | 71 LoadMatrixToContext(bitmap_context_, transform_); |
| 124 } | 72 } |
| 125 | 73 |
| 126 // We use this static factory function instead of the regular constructor so | 74 // We use this static factory function instead of the regular constructor so |
| 127 // that we can create the pixel data before calling the constructor. This is | 75 // that we can create the pixel data before calling the constructor. This is |
| 128 // required so that we can call the base class' constructor with the pixel | 76 // required so that we can call the base class' constructor with the pixel |
| 129 // data. | 77 // data. |
| 130 BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height, | 78 BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height, |
| 131 bool is_opaque, | 79 bool is_opaque, |
| 132 cairo_surface_t* surface) { | 80 cairo_surface_t* surface) { |
| 133 SkBitmap bitmap; | 81 SkBitmap bitmap; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 const BitmapPlatformDevice& other) | 128 const BitmapPlatformDevice& other) |
| 181 : PlatformDevice(const_cast<BitmapPlatformDevice&>( | 129 : PlatformDevice(const_cast<BitmapPlatformDevice&>( |
| 182 other).accessBitmap(true)), | 130 other).accessBitmap(true)), |
| 183 data_(other.data_) { | 131 data_(other.data_) { |
| 184 } | 132 } |
| 185 | 133 |
| 186 BitmapPlatformDevice::~BitmapPlatformDevice() { | 134 BitmapPlatformDevice::~BitmapPlatformDevice() { |
| 187 } | 135 } |
| 188 | 136 |
| 189 cairo_t* BitmapPlatformDevice::beginPlatformPaint() { | 137 cairo_t* BitmapPlatformDevice::beginPlatformPaint() { |
| 190 cairo_t* cairo = data_->GetContext(); | 138 data_->LoadConfig(); |
| 139 cairo_t* cairo = data_->bitmap_context(); |
| 191 // Tell Cairo that we've (probably) modified its pixel buffer without | 140 // Tell Cairo that we've (probably) modified its pixel buffer without |
| 192 // its knowledge. | 141 // its knowledge. |
| 193 cairo_surface_mark_dirty(cairo_get_target(cairo)); | 142 cairo_surface_mark_dirty(cairo_get_target(cairo)); |
| 194 return cairo; | 143 return cairo; |
| 195 } | 144 } |
| 196 | 145 |
| 197 void BitmapPlatformDevice::setMatrixClip(const SkMatrix& transform, | 146 void BitmapPlatformDevice::setMatrixClip(const SkMatrix& transform, |
| 198 const SkRegion& region) { | 147 const SkRegion& region) { |
| 199 data_->SetMatrixClip(transform, region); | 148 data_->SetMatrixClip(transform, region); |
| 200 } | 149 } |
| 201 | 150 |
| 202 BitmapPlatformDevice& BitmapPlatformDevice::operator=( | 151 BitmapPlatformDevice& BitmapPlatformDevice::operator=( |
| 203 const BitmapPlatformDevice& other) { | 152 const BitmapPlatformDevice& other) { |
| 204 data_ = other.data_; | 153 data_ = other.data_; |
| 205 return *this; | 154 return *this; |
| 206 } | 155 } |
| 207 | 156 |
| 208 } // namespace skia | 157 } // namespace skia |
| OLD | NEW |