1 /* 2 * Copyright 2016 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "SkPaintImageFilter.h" 9 #include "SkCanvas.h" 10 #include "SkColorSpaceXformer.h" 11 #include "SkImageFilterPriv.h" 12 #include "SkReadBuffer.h" 13 #include "SkSpecialImage.h" 14 #include "SkSpecialSurface.h" 15 #include "SkWriteBuffer.h" 16 17 sk_sp<SkImageFilter> SkPaintImageFilter::Make(const SkPaint& paint, 18 const CropRect* cropRect) { 19 return sk_sp<SkImageFilter>(new SkPaintImageFilter(paint, cropRect)); 20 } 21 22 SkPaintImageFilter::SkPaintImageFilter(const SkPaint& paint, const CropRect* cropRect) 23 : INHERITED(nullptr, 0, cropRect) 24 , fPaint(paint) { 25 } 26 27 sk_sp<SkFlattenable> SkPaintImageFilter::CreateProc(SkReadBuffer& buffer) { 28 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 0); 29 SkPaint paint; 30 buffer.readPaint(&paint); 31 return SkPaintImageFilter::Make(paint, &common.cropRect()); 32 } 33 34 void SkPaintImageFilter::flatten(SkWriteBuffer& buffer) const { 35 this->INHERITED::flatten(buffer); 36 buffer.writePaint(fPaint); 37 } 38 39 sk_sp<SkSpecialImage> SkPaintImageFilter::onFilterImage(SkSpecialImage* source, 40 const Context& ctx, 41 SkIPoint* offset) const { 42 SkIRect bounds; 43 const SkIRect srcBounds = SkIRect::MakeWH(source->width(), source->height()); 44 if (!this->applyCropRect(ctx, srcBounds, &bounds)) { 45 return nullptr; 46 } 47 48 sk_sp<SkSpecialSurface> surf(source->makeSurface(ctx.outputProperties(), bounds.size())); 49 if (!surf) { 50 return nullptr; 51 } 52 53 SkCanvas* canvas = surf->getCanvas(); 54 SkASSERT(canvas); 55 56 canvas->clear(0x0); 57 58 SkMatrix matrix(ctx.ctm()); 59 matrix.postTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top())); 60 SkRect rect = SkRect::MakeIWH(bounds.width(), bounds.height()); 61 SkMatrix inverse; 62 if (matrix.invert(&inverse)) { 63 inverse.mapRect(&rect); 64 } 65 canvas->setMatrix(matrix); 66 canvas->drawRect(rect, fPaint); 67 68 offset->fX = bounds.fLeft; 69 offset->fY = bounds.fTop; 70 return surf->makeImageSnapshot(); 71 } 72 73 sk_sp<SkImageFilter> SkPaintImageFilter::onMakeColorSpace(SkColorSpaceXformer* xformer) const { 74 SkPaint paint = xformer->apply(fPaint); 75 if (paint != fPaint) { 76 return SkPaintImageFilter::Make(paint, this->getCropRectIfSet()); 77 } 78 return this->refMe(); 79 } 80 81 bool SkPaintImageFilter::affectsTransparentBlack() const { 82 return true; 83 } 84 85 #ifndef SK_IGNORE_TO_STRING 86 void SkPaintImageFilter::toString(SkString* str) const { 87 str->appendf("SkPaintImageFilter: ("); 88 fPaint.toString(str); 89 str->append(")"); 90 } 91 #endif 92