blob: 0c95b328c0f8d44f4d6e7f76b34288effa5767ef [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
senorblanco5e5f9482014-08-26 12:27:12 -070015SkPictureImageFilter::SkPictureImageFilter(const SkPicture* picture, uint32_t uniqueID)
robertphillipsa8d7f0b2014-08-29 08:03:56 -070016 : INHERITED(0, 0, NULL, uniqueID)
17 , fPicture(SkSafeRef(picture))
bsalomon49f085d2014-09-05 13:34:00 -070018 , fCropRect(picture ? picture->cullRect() : SkRect::MakeEmpty()) {
senorblanco@chromium.org53333002013-12-12 23:28:52 +000019}
20
senorblanco5e5f9482014-08-26 12:27:12 -070021SkPictureImageFilter::SkPictureImageFilter(const SkPicture* picture, const SkRect& cropRect,
22 uint32_t uniqueID)
robertphillipsa8d7f0b2014-08-29 08:03:56 -070023 : INHERITED(0, 0, NULL, uniqueID)
24 , fPicture(SkSafeRef(picture))
25 , fCropRect(cropRect) {
senorblanco@chromium.org53333002013-12-12 23:28:52 +000026}
27
28SkPictureImageFilter::~SkPictureImageFilter() {
29 SkSafeUnref(fPicture);
30}
31
reed9fa60da2014-08-21 07:59:51 -070032#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000033SkPictureImageFilter::SkPictureImageFilter(SkReadBuffer& buffer)
senorblanco@chromium.org53333002013-12-12 23:28:52 +000034 : INHERITED(0, buffer),
35 fPicture(NULL) {
senorblanco@chromium.org97f5fc62014-05-30 20:50:56 +000036 if (!buffer.isCrossProcess()) {
37 if (buffer.readBool()) {
38 fPicture = SkPicture::CreateFromBuffer(buffer);
39 }
40 } else {
41 buffer.validate(!buffer.readBool());
commit-bot@chromium.org5e0995e2014-02-07 12:20:04 +000042 }
commit-bot@chromium.orgcac5fd52014-03-10 10:51:58 +000043 buffer.readRect(&fCropRect);
senorblanco@chromium.org53333002013-12-12 23:28:52 +000044}
reed9fa60da2014-08-21 07:59:51 -070045#endif
46
47SkFlattenable* SkPictureImageFilter::CreateProc(SkReadBuffer& buffer) {
48 SkAutoTUnref<SkPicture> picture;
49 SkRect cropRect;
50
51 if (!buffer.isCrossProcess()) {
52 if (buffer.readBool()) {
53 picture.reset(SkPicture::CreateFromBuffer(buffer));
54 }
55 } else {
56 buffer.validate(!buffer.readBool());
57 }
58 buffer.readRect(&cropRect);
59
60 return Create(picture, cropRect);
61}
senorblanco@chromium.org53333002013-12-12 23:28:52 +000062
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000063void SkPictureImageFilter::flatten(SkWriteBuffer& buffer) const {
senorblanco@chromium.org97f5fc62014-05-30 20:50:56 +000064 if (!buffer.isCrossProcess()) {
65 bool hasPicture = (fPicture != NULL);
66 buffer.writeBool(hasPicture);
67 if (hasPicture) {
68 fPicture->flatten(buffer);
69 }
70 } else {
71 buffer.writeBool(false);
commit-bot@chromium.org5e0995e2014-02-07 12:20:04 +000072 }
commit-bot@chromium.orgcac5fd52014-03-10 10:51:58 +000073 buffer.writeRect(fCropRect);
senorblanco@chromium.org53333002013-12-12 23:28:52 +000074}
75
senorblanco@chromium.org4cb543d2014-03-14 15:44:01 +000076bool SkPictureImageFilter::onFilterImage(Proxy* proxy, const SkBitmap&, const Context& ctx,
77 SkBitmap* result, SkIPoint* offset) const {
senorblanco@chromium.org53333002013-12-12 23:28:52 +000078 if (!fPicture) {
senorblanco@chromium.org6776b822014-01-03 21:48:22 +000079 offset->fX = offset->fY = 0;
senorblanco@chromium.org53333002013-12-12 23:28:52 +000080 return true;
81 }
82
83 SkRect floatBounds;
senorblanco@chromium.org4cb543d2014-03-14 15:44:01 +000084 ctx.ctm().mapRect(&floatBounds, fCropRect);
reedb07a94f2014-11-19 05:03:18 -080085 SkIRect bounds = floatBounds.roundOut();
senorblanco3d822c22014-07-30 14:49:31 -070086 if (!bounds.intersect(ctx.clipBounds())) {
87 return false;
88 }
senorblanco@chromium.org53333002013-12-12 23:28:52 +000089
90 if (bounds.isEmpty()) {
senorblanco@chromium.org6776b822014-01-03 21:48:22 +000091 offset->fX = offset->fY = 0;
senorblanco@chromium.org53333002013-12-12 23:28:52 +000092 return true;
93 }
94
95 SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds.height()));
96 if (NULL == device.get()) {
97 return false;
98 }
99
100 SkCanvas canvas(device.get());
101 SkPaint paint;
102
103 canvas.translate(-SkIntToScalar(bounds.fLeft), -SkIntToScalar(bounds.fTop));
senorblanco@chromium.org4cb543d2014-03-14 15:44:01 +0000104 canvas.concat(ctx.ctm());
robertphillips9b14f262014-06-04 05:40:44 -0700105 canvas.drawPicture(fPicture);
senorblanco@chromium.org53333002013-12-12 23:28:52 +0000106
107 *result = device.get()->accessBitmap(false);
senorblanco@chromium.org6776b822014-01-03 21:48:22 +0000108 offset->fX = bounds.fLeft;
109 offset->fY = bounds.fTop;
senorblanco@chromium.org53333002013-12-12 23:28:52 +0000110 return true;
111}