Home | History | Annotate | Download | only in effects
      1 /*
      2  * Copyright 2013 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 "SkRectShaderImageFilter.h"
      9 #include "SkBitmap.h"
     10 #include "SkCanvas.h"
     11 #include "SkDevice.h"
     12 #include "SkReadBuffer.h"
     13 #include "SkWriteBuffer.h"
     14 #include "SkShader.h"
     15 
     16 SkRectShaderImageFilter* SkRectShaderImageFilter::Create(SkShader* s, const SkRect& rect) {
     17     SkASSERT(s);
     18     uint32_t flags = CropRect::kHasAll_CropEdge;
     19     if (rect.width() == 0 || rect.height() == 0) {
     20         flags = 0x0;
     21     }
     22     CropRect cropRect(rect, flags);
     23     return SkNEW_ARGS(SkRectShaderImageFilter, (s, &cropRect));
     24 }
     25 
     26 SkRectShaderImageFilter* SkRectShaderImageFilter::Create(SkShader* s, const CropRect* cropRect) {
     27     SkASSERT(s);
     28     return SkNEW_ARGS(SkRectShaderImageFilter, (s, cropRect));
     29 }
     30 
     31 SkRectShaderImageFilter::SkRectShaderImageFilter(SkShader* s, const CropRect* cropRect)
     32   : INHERITED(NULL, cropRect)
     33   , fShader(s) {
     34     SkASSERT(s);
     35     s->ref();
     36 }
     37 
     38 SkRectShaderImageFilter::SkRectShaderImageFilter(SkReadBuffer& buffer)
     39   : INHERITED(1, buffer) {
     40     fShader = buffer.readShader();
     41 }
     42 
     43 void SkRectShaderImageFilter::flatten(SkWriteBuffer& buffer) const {
     44     this->INHERITED::flatten(buffer);
     45 
     46     buffer.writeFlattenable(fShader);
     47 }
     48 
     49 SkRectShaderImageFilter::~SkRectShaderImageFilter() {
     50     SkSafeUnref(fShader);
     51 }
     52 
     53 bool SkRectShaderImageFilter::onFilterImage(Proxy* proxy,
     54                                             const SkBitmap& source,
     55                                             const Context& ctx,
     56                                             SkBitmap* result,
     57                                             SkIPoint* offset) const {
     58     SkIRect bounds;
     59     if (!this->applyCropRect(ctx, source, SkIPoint::Make(0, 0), &bounds)) {
     60         return false;
     61     }
     62 
     63     SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(),
     64                                                           bounds.height()));
     65     if (NULL == device.get()) {
     66         return false;
     67     }
     68     SkCanvas canvas(device.get());
     69 
     70     SkPaint paint;
     71     SkMatrix matrix(ctx.ctm());
     72     matrix.postTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top()));
     73     paint.setShader(SkShader::CreateLocalMatrixShader(fShader, matrix))->unref();
     74 
     75     SkRect rect = SkRect::MakeWH(SkIntToScalar(bounds.width()), SkIntToScalar(bounds.height()));
     76     canvas.drawRect(rect, paint);
     77 
     78     *result = device.get()->accessBitmap(false);
     79     offset->fX = bounds.fLeft;
     80     offset->fY = bounds.fTop;
     81     return true;
     82 }
     83