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 16SkRectShaderImageFilter* 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 26SkRectShaderImageFilter* SkRectShaderImageFilter::Create(SkShader* s, const CropRect* cropRect, uint32_t uniqueID) { 27 SkASSERT(s); 28 return SkNEW_ARGS(SkRectShaderImageFilter, (s, cropRect, uniqueID)); 29} 30 31SkRectShaderImageFilter::SkRectShaderImageFilter(SkShader* s, const CropRect* cropRect, 32 uint32_t uniqueID) 33 : INHERITED(0, NULL, cropRect, uniqueID) 34 , fShader(s) { 35 SkASSERT(s); 36 s->ref(); 37} 38 39#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING 40SkRectShaderImageFilter::SkRectShaderImageFilter(SkReadBuffer& buffer) 41 : INHERITED(0, buffer) { 42 fShader = buffer.readShader(); 43} 44#endif 45 46SkFlattenable* SkRectShaderImageFilter::CreateProc(SkReadBuffer& buffer) { 47 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 0); 48 SkAutoTUnref<SkShader> shader(buffer.readShader()); 49 return Create(shader.get(), &common.cropRect(), common.uniqueID()); 50} 51 52void SkRectShaderImageFilter::flatten(SkWriteBuffer& buffer) const { 53 this->INHERITED::flatten(buffer); 54 buffer.writeFlattenable(fShader); 55} 56 57SkRectShaderImageFilter::~SkRectShaderImageFilter() { 58 SkSafeUnref(fShader); 59} 60 61bool SkRectShaderImageFilter::onFilterImage(Proxy* proxy, 62 const SkBitmap& source, 63 const Context& ctx, 64 SkBitmap* result, 65 SkIPoint* offset) const { 66 SkIRect bounds; 67 if (!this->applyCropRect(ctx, source, SkIPoint::Make(0, 0), &bounds)) { 68 return false; 69 } 70 71 SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), 72 bounds.height())); 73 if (NULL == device.get()) { 74 return false; 75 } 76 SkCanvas canvas(device.get()); 77 78 SkPaint paint; 79 SkMatrix matrix(ctx.ctm()); 80 matrix.postTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top())); 81 paint.setShader(SkShader::CreateLocalMatrixShader(fShader, matrix))->unref(); 82 83 SkRect rect = SkRect::MakeWH(SkIntToScalar(bounds.width()), SkIntToScalar(bounds.height())); 84 canvas.drawRect(rect, paint); 85 86 *result = device.get()->accessBitmap(false); 87 offset->fX = bounds.fLeft; 88 offset->fY = bounds.fTop; 89 return true; 90} 91