• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2012 The Android Open Source Project
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 "SkOffsetImageFilter.h"
9 #include "SkBitmap.h"
10 #include "SkCanvas.h"
11 #include "SkDevice.h"
12 #include "SkReadBuffer.h"
13 #include "SkWriteBuffer.h"
14 #include "SkMatrix.h"
15 #include "SkPaint.h"
16 
onFilterImageDeprecated(Proxy * proxy,const SkBitmap & source,const Context & ctx,SkBitmap * result,SkIPoint * offset) const17 bool SkOffsetImageFilter::onFilterImageDeprecated(Proxy* proxy, const SkBitmap& source,
18                                                   const Context& ctx,
19                                                   SkBitmap* result,
20                                                   SkIPoint* offset) const {
21     SkBitmap src = source;
22     SkIPoint srcOffset = SkIPoint::Make(0, 0);
23     if (!cropRectIsSet()) {
24         if (!this->filterInputDeprecated(0, proxy, source, ctx, &src, &srcOffset)) {
25             return false;
26         }
27 
28         SkVector vec;
29         ctx.ctm().mapVectors(&vec, &fOffset, 1);
30 
31         offset->fX = srcOffset.fX + SkScalarRoundToInt(vec.fX);
32         offset->fY = srcOffset.fY + SkScalarRoundToInt(vec.fY);
33         *result = src;
34     } else {
35         if (!this->filterInputDeprecated(0, proxy, source, ctx, &src, &srcOffset)) {
36             return false;
37         }
38 
39         SkIRect bounds;
40         SkIRect srcBounds = src.bounds();
41         srcBounds.offset(srcOffset);
42         if (!this->applyCropRect(ctx, srcBounds, &bounds)) {
43             return false;
44         }
45 
46         SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds.height()));
47         if (nullptr == device.get()) {
48             return false;
49         }
50         SkCanvas canvas(device);
51         SkPaint paint;
52         paint.setXfermodeMode(SkXfermode::kSrc_Mode);
53         canvas.translate(SkIntToScalar(srcOffset.fX - bounds.fLeft),
54                          SkIntToScalar(srcOffset.fY - bounds.fTop));
55         SkVector vec;
56         ctx.ctm().mapVectors(&vec, &fOffset, 1);
57         canvas.drawBitmap(src, vec.x(), vec.y(), &paint);
58         *result = device->accessBitmap(false);
59         offset->fX = bounds.fLeft;
60         offset->fY = bounds.fTop;
61     }
62     return true;
63 }
64 
computeFastBounds(const SkRect & src,SkRect * dst) const65 void SkOffsetImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const {
66     if (getInput(0)) {
67         getInput(0)->computeFastBounds(src, dst);
68     } else {
69         *dst = src;
70     }
71     dst->offset(fOffset.fX, fOffset.fY);
72 }
73 
onFilterNodeBounds(const SkIRect & src,const SkMatrix & ctm,SkIRect * dst,MapDirection direction) const74 void SkOffsetImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
75                                              SkIRect* dst, MapDirection direction) const {
76     SkVector vec;
77     ctm.mapVectors(&vec, &fOffset, 1);
78     if (kReverse_MapDirection == direction) {
79         vec.negate();
80     }
81 
82     *dst = src;
83     dst->offset(SkScalarCeilToInt(vec.fX), SkScalarCeilToInt(vec.fY));
84 }
85 
CreateProc(SkReadBuffer & buffer)86 SkFlattenable* SkOffsetImageFilter::CreateProc(SkReadBuffer& buffer) {
87     SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
88     SkPoint offset;
89     buffer.readPoint(&offset);
90     return Create(offset.x(), offset.y(), common.getInput(0), &common.cropRect());
91 }
92 
flatten(SkWriteBuffer & buffer) const93 void SkOffsetImageFilter::flatten(SkWriteBuffer& buffer) const {
94     this->INHERITED::flatten(buffer);
95     buffer.writePoint(fOffset);
96 }
97 
SkOffsetImageFilter(SkScalar dx,SkScalar dy,SkImageFilter * input,const CropRect * cropRect)98 SkOffsetImageFilter::SkOffsetImageFilter(SkScalar dx, SkScalar dy, SkImageFilter* input,
99                                          const CropRect* cropRect)
100   : INHERITED(1, &input, cropRect) {
101     fOffset.set(dx, dy);
102 }
103 
104 #ifndef SK_IGNORE_TO_STRING
toString(SkString * str) const105 void SkOffsetImageFilter::toString(SkString* str) const {
106     str->appendf("SkOffsetImageFilter: (");
107     str->appendf("offset: (%f, %f) ", fOffset.fX, fOffset.fY);
108     str->append("input: (");
109     if (this->getInput(0)) {
110         this->getInput(0)->toString(str);
111     }
112     str->append("))");
113 }
114 #endif
115