1533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org/*
2533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org * Copyright 2013 The Android Open Source Project
3533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org *
4533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org * Use of this source code is governed by a BSD-style license that can be
5533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org * found in the LICENSE file.
6533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org */
7533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org
8533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org#include "SkPictureImageFilter.h"
9533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org#include "SkDevice.h"
10533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org#include "SkCanvas.h"
118b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h"
128b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkWriteBuffer.h"
13533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org#include "SkValidationUtils.h"
14533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org
15533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.orgSkPictureImageFilter::SkPictureImageFilter(SkPicture* picture)
16533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org  : INHERITED(0, 0),
17533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org    fPicture(picture),
18cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org    fCropRect(SkRect::MakeWH(picture ? SkIntToScalar(picture->width()) : 0,
19cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org                             picture ? SkIntToScalar(picture->height()) : 0)) {
20533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org    SkSafeRef(fPicture);
21533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org}
22533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org
23cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.orgSkPictureImageFilter::SkPictureImageFilter(SkPicture* picture, const SkRect& cropRect)
24533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org  : INHERITED(0, 0),
25533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org    fPicture(picture),
26cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org    fCropRect(cropRect) {
27533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org    SkSafeRef(fPicture);
28533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org}
29533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org
30533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.orgSkPictureImageFilter::~SkPictureImageFilter() {
31533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org    SkSafeUnref(fPicture);
32533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org}
33533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org
348b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgSkPictureImageFilter::SkPictureImageFilter(SkReadBuffer& buffer)
35533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org  : INHERITED(0, buffer),
36533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org    fPicture(NULL) {
3797f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org    if (!buffer.isCrossProcess()) {
3897f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org        if (buffer.readBool()) {
3997f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org            fPicture = SkPicture::CreateFromBuffer(buffer);
4097f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org        }
4197f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org    } else {
4297f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org        buffer.validate(!buffer.readBool());
435e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org    }
44cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org    buffer.readRect(&fCropRect);
45533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org}
46533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org
478b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkPictureImageFilter::flatten(SkWriteBuffer& buffer) const {
48533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org    this->INHERITED::flatten(buffer);
4997f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org    if (!buffer.isCrossProcess()) {
5097f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org        bool hasPicture = (fPicture != NULL);
5197f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org        buffer.writeBool(hasPicture);
5297f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org        if (hasPicture) {
5397f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org            fPicture->flatten(buffer);
5497f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org        }
5597f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org    } else {
5697f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org        buffer.writeBool(false);
575e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org    }
58cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org    buffer.writeRect(fCropRect);
59533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org}
60533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org
614cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.orgbool SkPictureImageFilter::onFilterImage(Proxy* proxy, const SkBitmap&, const Context& ctx,
624cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org                                         SkBitmap* result, SkIPoint* offset) const {
63533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org    if (!fPicture) {
646776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org        offset->fX = offset->fY = 0;
65533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org        return true;
66533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org    }
67533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org
68533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org    SkRect floatBounds;
69533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org    SkIRect bounds;
704cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org    ctx.ctm().mapRect(&floatBounds, fCropRect);
71533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org    floatBounds.roundOut(&bounds);
72533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org
73533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org    if (bounds.isEmpty()) {
746776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org        offset->fX = offset->fY = 0;
75533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org        return true;
76533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org    }
77533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org
78533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org    SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds.height()));
79533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org    if (NULL == device.get()) {
80533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org        return false;
81533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org    }
82533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org
83533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org    SkCanvas canvas(device.get());
84533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org    SkPaint paint;
85533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org
86533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org    canvas.translate(-SkIntToScalar(bounds.fLeft), -SkIntToScalar(bounds.fTop));
874cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org    canvas.concat(ctx.ctm());
889b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips    canvas.drawPicture(fPicture);
89533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org
90533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org    *result = device.get()->accessBitmap(false);
916776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org    offset->fX = bounds.fLeft;
926776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org    offset->fY = bounds.fTop;
93533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org    return true;
94533330065a28b51808e5bf564ae45e56f8d9956asenorblanco@chromium.org}
95910702b564048d77e36a68b0f8dda7cc48a8fcffsenorblanco@chromium.org
96910702b564048d77e36a68b0f8dda7cc48a8fcffsenorblanco@chromium.orgbool SkPictureImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
97910702b564048d77e36a68b0f8dda7cc48a8fcffsenorblanco@chromium.org                                          SkIRect* dst) const {
98910702b564048d77e36a68b0f8dda7cc48a8fcffsenorblanco@chromium.org    *dst = src;
99910702b564048d77e36a68b0f8dda7cc48a8fcffsenorblanco@chromium.org    return true;
100910702b564048d77e36a68b0f8dda7cc48a8fcffsenorblanco@chromium.org}
101910702b564048d77e36a68b0f8dda7cc48a8fcffsenorblanco@chromium.org
102