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