• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "SkFlattenableBuffers.h"
13 #include "SkShader.h"
14 
Create(SkShader * s,const SkRect & rect)15 SkRectShaderImageFilter* SkRectShaderImageFilter::Create(SkShader* s, const SkRect& rect) {
16     SkASSERT(s);
17     uint32_t flags = CropRect::kHasAll_CropEdge;
18     if (rect.width() == 0 || rect.height() == 0) {
19         flags = 0x0;
20     }
21     CropRect cropRect(rect, flags);
22     return SkNEW_ARGS(SkRectShaderImageFilter, (s, &cropRect));
23 }
24 
Create(SkShader * s,const CropRect * cropRect)25 SkRectShaderImageFilter* SkRectShaderImageFilter::Create(SkShader* s, const CropRect* cropRect) {
26     SkASSERT(s);
27     return SkNEW_ARGS(SkRectShaderImageFilter, (s, cropRect));
28 }
29 
SkRectShaderImageFilter(SkShader * s,const CropRect * cropRect)30 SkRectShaderImageFilter::SkRectShaderImageFilter(SkShader* s, const CropRect* cropRect)
31   : INHERITED(NULL, cropRect)
32   , fShader(s) {
33     SkASSERT(s);
34     s->ref();
35 }
36 
SkRectShaderImageFilter(SkFlattenableReadBuffer & buffer)37 SkRectShaderImageFilter::SkRectShaderImageFilter(SkFlattenableReadBuffer& buffer)
38   : INHERITED(1, buffer) {
39     fShader = buffer.readShader();
40 }
41 
flatten(SkFlattenableWriteBuffer & buffer) const42 void SkRectShaderImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const {
43     this->INHERITED::flatten(buffer);
44 
45     buffer.writeFlattenable(fShader);
46 }
47 
~SkRectShaderImageFilter()48 SkRectShaderImageFilter::~SkRectShaderImageFilter() {
49     SkSafeUnref(fShader);
50 }
51 
onFilterImage(Proxy * proxy,const SkBitmap & source,const SkMatrix & ctm,SkBitmap * result,SkIPoint * offset)52 bool SkRectShaderImageFilter::onFilterImage(Proxy* proxy,
53                                             const SkBitmap& source,
54                                             const SkMatrix& ctm,
55                                             SkBitmap* result,
56                                             SkIPoint* offset) {
57     SkIRect bounds;
58     source.getBounds(&bounds);
59     if (!this->applyCropRect(&bounds, ctm)) {
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     SkPaint paint;
70     paint.setShader(fShader);
71     SkMatrix matrix;
72     matrix.setTranslate(-SkIntToScalar(bounds.fLeft), -SkIntToScalar(bounds.fTop));
73     fShader->setLocalMatrix(matrix);
74     SkRect rect = SkRect::MakeWH(SkIntToScalar(bounds.width()), SkIntToScalar(bounds.height()));
75     canvas.drawRect(rect, paint);
76     *result = device.get()->accessBitmap(false);
77     offset->fX += bounds.fLeft;
78     offset->fY += bounds.fTop;
79     return true;
80 }
81