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