blob: a1958f384e08dc25581e8cd07f69b67dd46436d2 [file] [log] [blame]
senorblanco@chromium.org53333002013-12-12 23:28:52 +00001/*
2 * Copyright 2013 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 "SkPictureImageFilter.h"
9#include "SkDevice.h"
10#include "SkCanvas.h"
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000011#include "SkReadBuffer.h"
12#include "SkWriteBuffer.h"
senorblanco@chromium.org53333002013-12-12 23:28:52 +000013#include "SkValidationUtils.h"
14
robertphillipse8464992014-07-14 07:53:26 -070015SkPictureImageFilter::SkPictureImageFilter(const SkPicture* picture)
senorblanco@chromium.org53333002013-12-12 23:28:52 +000016 : INHERITED(0, 0),
17 fPicture(picture),
commit-bot@chromium.orgcac5fd52014-03-10 10:51:58 +000018 fCropRect(SkRect::MakeWH(picture ? SkIntToScalar(picture->width()) : 0,
19 picture ? SkIntToScalar(picture->height()) : 0)) {
senorblanco@chromium.org53333002013-12-12 23:28:52 +000020 SkSafeRef(fPicture);
21}
22
robertphillipse8464992014-07-14 07:53:26 -070023SkPictureImageFilter::SkPictureImageFilter(const SkPicture* picture, const SkRect& cropRect)
senorblanco@chromium.org53333002013-12-12 23:28:52 +000024 : INHERITED(0, 0),
25 fPicture(picture),
commit-bot@chromium.orgcac5fd52014-03-10 10:51:58 +000026 fCropRect(cropRect) {
senorblanco@chromium.org53333002013-12-12 23:28:52 +000027 SkSafeRef(fPicture);
28}
29
30SkPictureImageFilter::~SkPictureImageFilter() {
31 SkSafeUnref(fPicture);
32}
33
reed9fa60da2014-08-21 07:59:51 -070034#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000035SkPictureImageFilter::SkPictureImageFilter(SkReadBuffer& buffer)
senorblanco@chromium.org53333002013-12-12 23:28:52 +000036 : INHERITED(0, buffer),
37 fPicture(NULL) {
senorblanco@chromium.org97f5fc62014-05-30 20:50:56 +000038 if (!buffer.isCrossProcess()) {
39 if (buffer.readBool()) {
40 fPicture = SkPicture::CreateFromBuffer(buffer);
41 }
42 } else {
43 buffer.validate(!buffer.readBool());
commit-bot@chromium.org5e0995e2014-02-07 12:20:04 +000044 }
commit-bot@chromium.orgcac5fd52014-03-10 10:51:58 +000045 buffer.readRect(&fCropRect);
senorblanco@chromium.org53333002013-12-12 23:28:52 +000046}
reed9fa60da2014-08-21 07:59:51 -070047#endif
48
49SkFlattenable* SkPictureImageFilter::CreateProc(SkReadBuffer& buffer) {
50 SkAutoTUnref<SkPicture> picture;
51 SkRect cropRect;
52
53 if (!buffer.isCrossProcess()) {
54 if (buffer.readBool()) {
55 picture.reset(SkPicture::CreateFromBuffer(buffer));
56 }
57 } else {
58 buffer.validate(!buffer.readBool());
59 }
60 buffer.readRect(&cropRect);
61
62 return Create(picture, cropRect);
63}
senorblanco@chromium.org53333002013-12-12 23:28:52 +000064
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000065void SkPictureImageFilter::flatten(SkWriteBuffer& buffer) const {
senorblanco@chromium.org97f5fc62014-05-30 20:50:56 +000066 if (!buffer.isCrossProcess()) {
67 bool hasPicture = (fPicture != NULL);
68 buffer.writeBool(hasPicture);
69 if (hasPicture) {
70 fPicture->flatten(buffer);
71 }
72 } else {
73 buffer.writeBool(false);
commit-bot@chromium.org5e0995e2014-02-07 12:20:04 +000074 }
commit-bot@chromium.orgcac5fd52014-03-10 10:51:58 +000075 buffer.writeRect(fCropRect);
senorblanco@chromium.org53333002013-12-12 23:28:52 +000076}
77
senorblanco@chromium.org4cb543d2014-03-14 15:44:01 +000078bool SkPictureImageFilter::onFilterImage(Proxy* proxy, const SkBitmap&, const Context& ctx,
79 SkBitmap* result, SkIPoint* offset) const {
senorblanco@chromium.org53333002013-12-12 23:28:52 +000080 if (!fPicture) {
senorblanco@chromium.org6776b822014-01-03 21:48:22 +000081 offset->fX = offset->fY = 0;
senorblanco@chromium.org53333002013-12-12 23:28:52 +000082 return true;
83 }
84
85 SkRect floatBounds;
86 SkIRect bounds;
senorblanco@chromium.org4cb543d2014-03-14 15:44:01 +000087 ctx.ctm().mapRect(&floatBounds, fCropRect);
senorblanco@chromium.org53333002013-12-12 23:28:52 +000088 floatBounds.roundOut(&bounds);
senorblanco3d822c22014-07-30 14:49:31 -070089 if (!bounds.intersect(ctx.clipBounds())) {
90 return false;
91 }
senorblanco@chromium.org53333002013-12-12 23:28:52 +000092
93 if (bounds.isEmpty()) {
senorblanco@chromium.org6776b822014-01-03 21:48:22 +000094 offset->fX = offset->fY = 0;
senorblanco@chromium.org53333002013-12-12 23:28:52 +000095 return true;
96 }
97
98 SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds.height()));
99 if (NULL == device.get()) {
100 return false;
101 }
102
103 SkCanvas canvas(device.get());
104 SkPaint paint;
105
106 canvas.translate(-SkIntToScalar(bounds.fLeft), -SkIntToScalar(bounds.fTop));
senorblanco@chromium.org4cb543d2014-03-14 15:44:01 +0000107 canvas.concat(ctx.ctm());
robertphillips9b14f262014-06-04 05:40:44 -0700108 canvas.drawPicture(fPicture);
senorblanco@chromium.org53333002013-12-12 23:28:52 +0000109
110 *result = device.get()->accessBitmap(false);
senorblanco@chromium.org6776b822014-01-03 21:48:22 +0000111 offset->fX = bounds.fLeft;
112 offset->fY = bounds.fTop;
senorblanco@chromium.org53333002013-12-12 23:28:52 +0000113 return true;
114}
senorblanco@chromium.org910702b2014-05-30 20:36:15 +0000115
116bool SkPictureImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
117 SkIRect* dst) const {
118 *dst = src;
119 return true;
120}
121