| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkBitmapDevice.h" | 8 #include "SkBitmapDevice.h" |
| 9 #include "SkCanvas.h" | 9 #include "SkCanvas.h" |
| 10 #include "SkData.h" | 10 #include "SkData.h" |
| 11 #include "SkNoSaveLayerCanvas.h" |
| 11 #include "SkPictureUtils.h" | 12 #include "SkPictureUtils.h" |
| 12 #include "SkPixelRef.h" | 13 #include "SkPixelRef.h" |
| 13 #include "SkRRect.h" | 14 #include "SkRRect.h" |
| 14 #include "SkShader.h" | 15 #include "SkShader.h" |
| 15 | 16 |
| 16 class PixelRefSet { | 17 class PixelRefSet { |
| 17 public: | 18 public: |
| 18 PixelRefSet(SkTDArray<SkPixelRef*>* array) : fArray(array) {} | 19 PixelRefSet(SkTDArray<SkPixelRef*>* array) : fArray(array) {} |
| 19 | 20 |
| 20 // This does a linear search on existing pixelrefs, so if this list gets big | 21 // This does a linear search on existing pixelrefs, so if this list gets big |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 | 58 |
| 58 virtual uint32_t getDeviceCapabilities() SK_OVERRIDE { return 0; } | 59 virtual uint32_t getDeviceCapabilities() SK_OVERRIDE { return 0; } |
| 59 virtual int width() const SK_OVERRIDE { return fSize.width(); } | 60 virtual int width() const SK_OVERRIDE { return fSize.width(); } |
| 60 virtual int height() const SK_OVERRIDE { return fSize.height(); } | 61 virtual int height() const SK_OVERRIDE { return fSize.height(); } |
| 61 virtual bool isOpaque() const SK_OVERRIDE { return false; } | 62 virtual bool isOpaque() const SK_OVERRIDE { return false; } |
| 62 virtual SkBitmap::Config config() const SK_OVERRIDE { | 63 virtual SkBitmap::Config config() const SK_OVERRIDE { |
| 63 return SkBitmap::kNo_Config; | 64 return SkBitmap::kNo_Config; |
| 64 } | 65 } |
| 65 virtual GrRenderTarget* accessRenderTarget() SK_OVERRIDE { return NULL; } | 66 virtual GrRenderTarget* accessRenderTarget() SK_OVERRIDE { return NULL; } |
| 66 virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) SK_OVERRIDE { | 67 virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) SK_OVERRIDE { |
| 67 return true; | 68 return false; |
| 68 } | 69 } |
| 69 // TODO: allow this call to return failure, or move to SkBitmapDevice only. | 70 // TODO: allow this call to return failure, or move to SkBitmapDevice only. |
| 70 virtual const SkBitmap& onAccessBitmap() SK_OVERRIDE { | 71 virtual const SkBitmap& onAccessBitmap() SK_OVERRIDE { |
| 71 return fEmptyBitmap; | 72 return fEmptyBitmap; |
| 72 } | 73 } |
| 73 virtual void lockPixels() SK_OVERRIDE { nothing_to_do(); } | 74 virtual void lockPixels() SK_OVERRIDE { nothing_to_do(); } |
| 74 virtual void unlockPixels() SK_OVERRIDE { nothing_to_do(); } | 75 virtual void unlockPixels() SK_OVERRIDE { nothing_to_do(); } |
| 75 virtual bool allowImageFilter(SkImageFilter*) SK_OVERRIDE { return false; } | 76 virtual bool allowImageFilter(SkImageFilter*) SK_OVERRIDE { return false; } |
| 76 virtual bool canHandleImageFilter(SkImageFilter*) SK_OVERRIDE { return false
; } | 77 virtual bool canHandleImageFilter(SkImageFilter*) SK_OVERRIDE { return false
; } |
| 77 virtual bool filterImage(SkImageFilter*, const SkBitmap&, const SkMatrix&, | 78 virtual bool filterImage(SkImageFilter*, const SkBitmap&, const SkMatrix&, |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 if (SkShader::kNone_GradientType == shader->asAGradient(NULL) && | 193 if (SkShader::kNone_GradientType == shader->asAGradient(NULL) && |
| 193 shader->asABitmap(&bm, NULL, NULL)) { | 194 shader->asABitmap(&bm, NULL, NULL)) { |
| 194 fPRSet->add(bm.pixelRef()); | 195 fPRSet->add(bm.pixelRef()); |
| 195 } | 196 } |
| 196 } | 197 } |
| 197 } | 198 } |
| 198 | 199 |
| 199 typedef SkBaseDevice INHERITED; | 200 typedef SkBaseDevice INHERITED; |
| 200 }; | 201 }; |
| 201 | 202 |
| 202 class NoSaveLayerCanvas : public SkCanvas { | |
| 203 public: | |
| 204 NoSaveLayerCanvas(SkBaseDevice* device) : INHERITED(device) {} | |
| 205 | |
| 206 // turn saveLayer() into save() for speed, should not affect correctness. | |
| 207 virtual int saveLayer(const SkRect* bounds, const SkPaint* paint, | |
| 208 SaveFlags flags) SK_OVERRIDE { | |
| 209 | |
| 210 // Like SkPictureRecord, we don't want to create layers, but we do need | |
| 211 // to respect the save and (possibly) its rect-clip. | |
| 212 | |
| 213 int count = this->INHERITED::save(flags); | |
| 214 if (bounds) { | |
| 215 this->INHERITED::clipRectBounds(bounds, flags, NULL); | |
| 216 } | |
| 217 return count; | |
| 218 } | |
| 219 | |
| 220 // disable aa for speed | |
| 221 virtual bool clipRect(const SkRect& rect, SkRegion::Op op, | |
| 222 bool doAA) SK_OVERRIDE { | |
| 223 return this->INHERITED::clipRect(rect, op, false); | |
| 224 } | |
| 225 | |
| 226 // for speed, just respect the bounds, and disable AA. May give us a few | |
| 227 // false positives and negatives. | |
| 228 virtual bool clipPath(const SkPath& path, SkRegion::Op op, | |
| 229 bool doAA) SK_OVERRIDE { | |
| 230 return this->updateClipConservativelyUsingBounds(path.getBounds(), op, p
ath.isInverseFillType()); | |
| 231 } | |
| 232 virtual bool clipRRect(const SkRRect& rrect, SkRegion::Op op, | |
| 233 bool doAA) SK_OVERRIDE { | |
| 234 return this->updateClipConservativelyUsingBounds(rrect.getBounds(), op,
false); | |
| 235 } | |
| 236 | |
| 237 private: | |
| 238 typedef SkCanvas INHERITED; | |
| 239 }; | |
| 240 | |
| 241 SkData* SkPictureUtils::GatherPixelRefs(SkPicture* pict, const SkRect& area) { | 203 SkData* SkPictureUtils::GatherPixelRefs(SkPicture* pict, const SkRect& area) { |
| 242 if (NULL == pict) { | 204 if (NULL == pict) { |
| 243 return NULL; | 205 return NULL; |
| 244 } | 206 } |
| 245 | 207 |
| 246 // this test also handles if either area or pict's width/height are empty | 208 // this test also handles if either area or pict's width/height are empty |
| 247 if (!SkRect::Intersects(area, | 209 if (!SkRect::Intersects(area, |
| 248 SkRect::MakeWH(SkIntToScalar(pict->width()), | 210 SkRect::MakeWH(SkIntToScalar(pict->width()), |
| 249 SkIntToScalar(pict->height())))) { | 211 SkIntToScalar(pict->height())))) { |
| 250 return NULL; | 212 return NULL; |
| 251 } | 213 } |
| 252 | 214 |
| 253 SkTDArray<SkPixelRef*> array; | 215 SkTDArray<SkPixelRef*> array; |
| 254 PixelRefSet prset(&array); | 216 PixelRefSet prset(&array); |
| 255 | 217 |
| 256 GatherPixelRefDevice device(pict->width(), pict->height(), &prset); | 218 GatherPixelRefDevice device(pict->width(), pict->height(), &prset); |
| 257 NoSaveLayerCanvas canvas(&device); | 219 SkNoSaveLayerCanvas canvas(&device); |
| 258 | 220 |
| 259 canvas.clipRect(area, SkRegion::kIntersect_Op, false); | 221 canvas.clipRect(area, SkRegion::kIntersect_Op, false); |
| 260 canvas.drawPicture(*pict); | 222 canvas.drawPicture(*pict); |
| 261 | 223 |
| 262 SkData* data = NULL; | 224 SkData* data = NULL; |
| 263 int count = array.count(); | 225 int count = array.count(); |
| 264 if (count > 0) { | 226 if (count > 0) { |
| 265 data = SkData::NewFromMalloc(array.detach(), count * sizeof(SkPixelRef*)
); | 227 data = SkData::NewFromMalloc(array.detach(), count * sizeof(SkPixelRef*)
); |
| 266 } | 228 } |
| 267 return data; | 229 return data; |
| 268 } | 230 } |
| OLD | NEW |