blob: 5496f3003215a5f7254f4489239b8820d3c30483 [file] [log] [blame]
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +00001/*
2 * Copyright 2013 Google Inc.
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 "SkTileImageFilter.h"
9#include "SkBitmap.h"
10#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"
16#include "SkShader.h"
commit-bot@chromium.orgc0b7e102013-10-23 17:06:21 +000017#include "SkValidationUtils.h"
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000018
commit-bot@chromium.orgf7efa502014-04-11 18:57:00 +000019bool SkTileImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src,
20 const Context& ctx,
commit-bot@chromium.orgae761f72014-02-05 22:32:02 +000021 SkBitmap* dst, SkIPoint* offset) const {
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000022 SkBitmap source = src;
23 SkImageFilter* input = getInput(0);
senorblanco@chromium.org6776b822014-01-03 21:48:22 +000024 SkIPoint srcOffset = SkIPoint::Make(0, 0);
senorblanco@chromium.org4cb543d2014-03-14 15:44:01 +000025 if (input && !input->filterImage(proxy, src, ctx, &source, &srcOffset)) {
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000026 return false;
27 }
28
senorblanco@chromium.orge93e1db2013-12-09 18:31:42 +000029 SkRect dstRect;
senorblanco@chromium.org4cb543d2014-03-14 15:44:01 +000030 ctx.ctm().mapRect(&dstRect, fDstRect);
senorblanco@chromium.org6776b822014-01-03 21:48:22 +000031 SkIRect dstIRect;
32 dstRect.roundOut(&dstIRect);
33 int w = dstIRect.width();
34 int h = dstIRect.height();
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000035 if (!fSrcRect.width() || !fSrcRect.height() || !w || !h) {
36 return false;
37 }
38
senorblanco@chromium.orge93e1db2013-12-09 18:31:42 +000039 SkRect srcRect;
senorblanco@chromium.org4cb543d2014-03-14 15:44:01 +000040 ctx.ctm().mapRect(&srcRect, fSrcRect);
senorblanco@chromium.orge93e1db2013-12-09 18:31:42 +000041 SkIRect srcIRect;
42 srcRect.roundOut(&srcIRect);
senorblanco@chromium.org6776b822014-01-03 21:48:22 +000043 srcIRect.offset(-srcOffset);
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000044 SkBitmap subset;
senorblanco@chromium.orge93e1db2013-12-09 18:31:42 +000045 SkIRect bounds;
46 source.getBounds(&bounds);
senorblanco@chromium.org6776b822014-01-03 21:48:22 +000047
senorblanco@chromium.orge93e1db2013-12-09 18:31:42 +000048 if (!srcIRect.intersect(bounds)) {
senorblanco@chromium.org6776b822014-01-03 21:48:22 +000049 offset->fX = offset->fY = 0;
senorblanco@chromium.orge93e1db2013-12-09 18:31:42 +000050 return true;
51 } else if (!source.extractSubset(&subset, srcIRect)) {
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000052 return false;
53 }
54
55 SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(w, h));
commit-bot@chromium.orgcd3b15c2013-12-04 17:06:49 +000056 if (NULL == device.get()) {
57 return false;
58 }
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000059 SkCanvas canvas(device);
60 SkPaint paint;
61 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
62
skia.committer@gmail.com65caeaf2013-09-27 07:01:29 +000063 SkAutoTUnref<SkShader> shader(SkShader::CreateBitmapShader(subset,
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000064 SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode));
senorblanco@chromium.org6776b822014-01-03 21:48:22 +000065 SkMatrix shaderMatrix;
66 shaderMatrix.setTranslate(SkIntToScalar(srcOffset.fX),
67 SkIntToScalar(srcOffset.fY));
68 shader->setLocalMatrix(shaderMatrix);
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000069 paint.setShader(shader);
senorblanco@chromium.org6776b822014-01-03 21:48:22 +000070 canvas.translate(-dstRect.fLeft, -dstRect.fTop);
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000071 canvas.drawRect(dstRect, paint);
72 *dst = device->accessBitmap(false);
senorblanco@chromium.org6776b822014-01-03 21:48:22 +000073 offset->fX = dstIRect.fLeft;
74 offset->fY = dstIRect.fTop;
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000075 return true;
76}
77
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000078SkTileImageFilter::SkTileImageFilter(SkReadBuffer& buffer)
commit-bot@chromium.orgce33d602013-11-25 21:46:31 +000079 : INHERITED(1, buffer) {
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000080 buffer.readRect(&fSrcRect);
81 buffer.readRect(&fDstRect);
commit-bot@chromium.orgc2e9db32013-12-06 20:14:46 +000082 buffer.validate(buffer.isValid() && SkIsValidRect(fSrcRect) && SkIsValidRect(fDstRect));
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000083}
84
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000085void SkTileImageFilter::flatten(SkWriteBuffer& buffer) const {
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000086 this->INHERITED::flatten(buffer);
87 buffer.writeRect(fSrcRect);
88 buffer.writeRect(fDstRect);
89}