blob: b35d85262307c5d65f10355b6cb142369ecc6b45 [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
senorblanco@chromium.org4cb543d2014-03-14 15:44:01 +000019bool SkTileImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src, const SkImageFilter::Context& ctx,
commit-bot@chromium.orgae761f72014-02-05 22:32:02 +000020 SkBitmap* dst, SkIPoint* offset) const {
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000021 SkBitmap source = src;
22 SkImageFilter* input = getInput(0);
senorblanco@chromium.org6776b822014-01-03 21:48:22 +000023 SkIPoint srcOffset = SkIPoint::Make(0, 0);
senorblanco@chromium.org4cb543d2014-03-14 15:44:01 +000024 if (input && !input->filterImage(proxy, src, ctx, &source, &srcOffset)) {
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000025 return false;
26 }
27
senorblanco@chromium.orge93e1db2013-12-09 18:31:42 +000028 SkRect dstRect;
senorblanco@chromium.org4cb543d2014-03-14 15:44:01 +000029 ctx.ctm().mapRect(&dstRect, fDstRect);
senorblanco@chromium.org6776b822014-01-03 21:48:22 +000030 SkIRect dstIRect;
31 dstRect.roundOut(&dstIRect);
32 int w = dstIRect.width();
33 int h = dstIRect.height();
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000034 if (!fSrcRect.width() || !fSrcRect.height() || !w || !h) {
35 return false;
36 }
37
senorblanco@chromium.orge93e1db2013-12-09 18:31:42 +000038 SkRect srcRect;
senorblanco@chromium.org4cb543d2014-03-14 15:44:01 +000039 ctx.ctm().mapRect(&srcRect, fSrcRect);
senorblanco@chromium.orge93e1db2013-12-09 18:31:42 +000040 SkIRect srcIRect;
41 srcRect.roundOut(&srcIRect);
senorblanco@chromium.org6776b822014-01-03 21:48:22 +000042 srcIRect.offset(-srcOffset);
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000043 SkBitmap subset;
senorblanco@chromium.orge93e1db2013-12-09 18:31:42 +000044 SkIRect bounds;
45 source.getBounds(&bounds);
senorblanco@chromium.org6776b822014-01-03 21:48:22 +000046
senorblanco@chromium.orge93e1db2013-12-09 18:31:42 +000047 if (!srcIRect.intersect(bounds)) {
senorblanco@chromium.org6776b822014-01-03 21:48:22 +000048 offset->fX = offset->fY = 0;
senorblanco@chromium.orge93e1db2013-12-09 18:31:42 +000049 return true;
50 } else if (!source.extractSubset(&subset, srcIRect)) {
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000051 return false;
52 }
53
54 SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(w, h));
commit-bot@chromium.orgcd3b15c2013-12-04 17:06:49 +000055 if (NULL == device.get()) {
56 return false;
57 }
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000058 SkCanvas canvas(device);
59 SkPaint paint;
60 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
61
skia.committer@gmail.com65caeaf2013-09-27 07:01:29 +000062 SkAutoTUnref<SkShader> shader(SkShader::CreateBitmapShader(subset,
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000063 SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode));
senorblanco@chromium.org6776b822014-01-03 21:48:22 +000064 SkMatrix shaderMatrix;
65 shaderMatrix.setTranslate(SkIntToScalar(srcOffset.fX),
66 SkIntToScalar(srcOffset.fY));
67 shader->setLocalMatrix(shaderMatrix);
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000068 paint.setShader(shader);
senorblanco@chromium.org6776b822014-01-03 21:48:22 +000069 canvas.translate(-dstRect.fLeft, -dstRect.fTop);
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000070 canvas.drawRect(dstRect, paint);
71 *dst = device->accessBitmap(false);
senorblanco@chromium.org6776b822014-01-03 21:48:22 +000072 offset->fX = dstIRect.fLeft;
73 offset->fY = dstIRect.fTop;
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000074 return true;
75}
76
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000077SkTileImageFilter::SkTileImageFilter(SkReadBuffer& buffer)
commit-bot@chromium.orgce33d602013-11-25 21:46:31 +000078 : INHERITED(1, buffer) {
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000079 buffer.readRect(&fSrcRect);
80 buffer.readRect(&fDstRect);
commit-bot@chromium.orgc2e9db32013-12-06 20:14:46 +000081 buffer.validate(buffer.isValid() && SkIsValidRect(fSrcRect) && SkIsValidRect(fDstRect));
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000082}
83
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000084void SkTileImageFilter::flatten(SkWriteBuffer& buffer) const {
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000085 this->INHERITED::flatten(buffer);
86 buffer.writeRect(fSrcRect);
87 buffer.writeRect(fDstRect);
88}