Home | History | Annotate | Download | only in effects
      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