• Home
  • History
  • Annotate
  • 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 "SkReadBuffer.h"
13 #include "SkWriteBuffer.h"
14 #include "SkShader.h"
15 
Create(SkShader * s,const SkRect & rect)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 
Create(SkShader * s,const CropRect * cropRect,uint32_t uniqueID)26 SkRectShaderImageFilter* SkRectShaderImageFilter::Create(SkShader* s, const CropRect* cropRect, uint32_t uniqueID) {
27     SkASSERT(s);
28     return SkNEW_ARGS(SkRectShaderImageFilter, (s, cropRect, uniqueID));
29 }
30 
SkRectShaderImageFilter(SkShader * s,const CropRect * cropRect,uint32_t uniqueID)31 SkRectShaderImageFilter::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
SkRectShaderImageFilter(SkReadBuffer & buffer)40 SkRectShaderImageFilter::SkRectShaderImageFilter(SkReadBuffer& buffer)
41   : INHERITED(0, buffer) {
42     fShader = buffer.readShader();
43 }
44 #endif
45 
CreateProc(SkReadBuffer & buffer)46 SkFlattenable* 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 
flatten(SkWriteBuffer & buffer) const52 void SkRectShaderImageFilter::flatten(SkWriteBuffer& buffer) const {
53     this->INHERITED::flatten(buffer);
54     buffer.writeFlattenable(fShader);
55 }
56 
~SkRectShaderImageFilter()57 SkRectShaderImageFilter::~SkRectShaderImageFilter() {
58     SkSafeUnref(fShader);
59 }
60 
onFilterImage(Proxy * proxy,const SkBitmap & source,const Context & ctx,SkBitmap * result,SkIPoint * offset) const61 bool 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