blob: ddc8be8f95ae6aa258d6f1f358e2d25033eec394 [file] [log] [blame]
senorblanco@chromium.org9daf96a2012-11-06 20:29:39 +00001/*
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"
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000010#include "SkCanvas.h"
11#include "SkDevice.h"
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000012#include "SkReadBuffer.h"
13#include "SkWriteBuffer.h"
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000014#include "SkMatrix.h"
15#include "SkPaint.h"
senorblanco@chromium.org9daf96a2012-11-06 20:29:39 +000016
robertphillips48e78462016-02-17 13:57:16 -080017bool SkOffsetImageFilter::onFilterImageDeprecated(Proxy* proxy, const SkBitmap& source,
18 const Context& ctx,
19 SkBitmap* result,
20 SkIPoint* offset) const {
senorblanco@chromium.org68400762013-05-24 15:04:07 +000021 SkBitmap src = source;
senorblanco@chromium.org6776b822014-01-03 21:48:22 +000022 SkIPoint srcOffset = SkIPoint::Make(0, 0);
senorblanco@chromium.orgb295fb62013-10-10 13:51:19 +000023 if (!cropRectIsSet()) {
robertphillips48e78462016-02-17 13:57:16 -080024 if (!this->filterInputDeprecated(0, proxy, source, ctx, &src, &srcOffset)) {
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000025 return false;
26 }
27
28 SkVector vec;
senorblanco@chromium.org4cb543d2014-03-14 15:44:01 +000029 ctx.ctm().mapVectors(&vec, &fOffset, 1);
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000030
senorblanco@chromium.org6776b822014-01-03 21:48:22 +000031 offset->fX = srcOffset.fX + SkScalarRoundToInt(vec.fX);
32 offset->fY = srcOffset.fY + SkScalarRoundToInt(vec.fY);
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000033 *result = src;
34 } else {
robertphillips48e78462016-02-17 13:57:16 -080035 if (!this->filterInputDeprecated(0, proxy, source, ctx, &src, &srcOffset)) {
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000036 return false;
37 }
38
39 SkIRect bounds;
senorblancoafec27f2016-02-16 09:11:18 -080040 SkIRect srcBounds = src.bounds();
41 srcBounds.offset(srcOffset);
42 if (!this->applyCropRect(ctx, srcBounds, &bounds)) {
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000043 return false;
44 }
45
46 SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds.height()));
halcanary96fcdcc2015-08-27 07:41:13 -070047 if (nullptr == device.get()) {
commit-bot@chromium.orgcd3b15c2013-12-04 17:06:49 +000048 return false;
49 }
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000050 SkCanvas canvas(device);
51 SkPaint paint;
52 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
senorblanco@chromium.org6776b822014-01-03 21:48:22 +000053 canvas.translate(SkIntToScalar(srcOffset.fX - bounds.fLeft),
54 SkIntToScalar(srcOffset.fY - bounds.fTop));
senorblanco@chromium.orge09244d2014-03-04 19:05:25 +000055 SkVector vec;
senorblanco@chromium.org4cb543d2014-03-14 15:44:01 +000056 ctx.ctm().mapVectors(&vec, &fOffset, 1);
senorblanco@chromium.orge09244d2014-03-04 19:05:25 +000057 canvas.drawBitmap(src, vec.x(), vec.y(), &paint);
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000058 *result = device->accessBitmap(false);
senorblanco@chromium.org6776b822014-01-03 21:48:22 +000059 offset->fX = bounds.fLeft;
60 offset->fY = bounds.fTop;
senorblanco@chromium.org68400762013-05-24 15:04:07 +000061 }
senorblanco@chromium.org9daf96a2012-11-06 20:29:39 +000062 return true;
63}
64
senorblanco@chromium.org336d1d72014-01-27 21:03:17 +000065void 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
senorblancodb64af32015-12-09 10:11:43 -080074void SkOffsetImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
75 SkIRect* dst, MapDirection direction) const {
senorblanco@chromium.org9daf96a2012-11-06 20:29:39 +000076 SkVector vec;
77 ctm.mapVectors(&vec, &fOffset, 1);
senorblancodb64af32015-12-09 10:11:43 -080078 if (kReverse_MapDirection == direction) {
79 vec.negate();
senorblanco@chromium.org29ac34e2014-05-28 19:29:25 +000080 }
senorblancodb64af32015-12-09 10:11:43 -080081
82 *dst = src;
83 dst->offset(SkScalarCeilToInt(vec.fX), SkScalarCeilToInt(vec.fY));
senorblanco@chromium.org9daf96a2012-11-06 20:29:39 +000084}
85
reed9fa60da2014-08-21 07:59:51 -070086SkFlattenable* SkOffsetImageFilter::CreateProc(SkReadBuffer& buffer) {
87 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
88 SkPoint offset;
89 buffer.readPoint(&offset);
senorblanco24e06d52015-03-18 12:11:33 -070090 return Create(offset.x(), offset.y(), common.getInput(0), &common.cropRect());
reed9fa60da2014-08-21 07:59:51 -070091}
92
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000093void SkOffsetImageFilter::flatten(SkWriteBuffer& buffer) const {
senorblanco@chromium.org9daf96a2012-11-06 20:29:39 +000094 this->INHERITED::flatten(buffer);
95 buffer.writePoint(fOffset);
96}
97
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000098SkOffsetImageFilter::SkOffsetImageFilter(SkScalar dx, SkScalar dy, SkImageFilter* input,
senorblanco24e06d52015-03-18 12:11:33 -070099 const CropRect* cropRect)
100 : INHERITED(1, &input, cropRect) {
senorblanco@chromium.org9daf96a2012-11-06 20:29:39 +0000101 fOffset.set(dx, dy);
102}
robertphillipsf3f5bad2014-12-19 13:49:15 -0800103
104#ifndef SK_IGNORE_TO_STRING
105void 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