• 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 "SkFlattenableBuffers.h"
13 #include "SkMatrix.h"
14 #include "SkPaint.h"
15 
onFilterImage(Proxy * proxy,const SkBitmap & source,const SkMatrix & matrix,SkBitmap * result,SkIPoint * loc)16 bool SkOffsetImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source,
17                                         const SkMatrix& matrix,
18                                         SkBitmap* result,
19                                         SkIPoint* loc) {
20     SkImageFilter* input = getInput(0);
21     SkBitmap src = source;
22 #ifdef SK_DISABLE_OFFSETIMAGEFILTER_OPTIMIZATION
23     if (false) {
24 #else
25     if (!cropRectIsSet()) {
26 #endif
27         if (input && !input->filterImage(proxy, source, matrix, &src, loc)) {
28             return false;
29         }
30 
31         SkVector vec;
32         matrix.mapVectors(&vec, &fOffset, 1);
33 
34         loc->fX += SkScalarRoundToInt(vec.fX);
35         loc->fY += SkScalarRoundToInt(vec.fY);
36         *result = src;
37     } else {
38         SkIPoint srcOffset = SkIPoint::Make(0, 0);
39         if (input && !input->filterImage(proxy, source, matrix, &src, &srcOffset)) {
40             return false;
41         }
42 
43         SkIRect bounds;
44         src.getBounds(&bounds);
45 
46         if (!applyCropRect(&bounds, matrix)) {
47             return false;
48         }
49 
50         SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds.height()));
51         if (NULL == device.get()) {
52             return false;
53         }
54         SkCanvas canvas(device);
55         SkPaint paint;
56         paint.setXfermodeMode(SkXfermode::kSrc_Mode);
57         canvas.drawBitmap(src, fOffset.fX - bounds.left(), fOffset.fY - bounds.top(), &paint);
58         *result = device->accessBitmap(false);
59         loc->fX += bounds.left();
60         loc->fY += bounds.top();
61     }
62     return true;
63 }
64 
65 bool SkOffsetImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
66                                          SkIRect* dst) {
67     SkVector vec;
68     ctm.mapVectors(&vec, &fOffset, 1);
69 
70     *dst = src;
71     dst->offset(SkScalarRoundToInt(vec.fX), SkScalarRoundToInt(vec.fY));
72     return true;
73 }
74 
75 void SkOffsetImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const {
76     this->INHERITED::flatten(buffer);
77     buffer.writePoint(fOffset);
78 }
79 
80 SkOffsetImageFilter::SkOffsetImageFilter(SkScalar dx, SkScalar dy, SkImageFilter* input,
81                                          const CropRect* cropRect) : INHERITED(input, cropRect) {
82     fOffset.set(dx, dy);
83 }
84 
85 SkOffsetImageFilter::SkOffsetImageFilter(SkFlattenableReadBuffer& buffer)
86   : INHERITED(1, buffer) {
87     buffer.readPoint(&fOffset);
88     buffer.validate(SkScalarIsFinite(fOffset.fX) &&
89                     SkScalarIsFinite(fOffset.fY));
90 }
91