SkTileImageFilter.cpp revision c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cf
1/*
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"
12#include "SkFlattenableBuffers.h"
13#include "SkMatrix.h"
14#include "SkPaint.h"
15#include "SkShader.h"
16#include "SkValidationUtils.h"
17
18bool SkTileImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src, const SkMatrix& ctm,
19                                      SkBitmap* dst, SkIPoint* offset) {
20    SkBitmap source = src;
21    SkImageFilter* input = getInput(0);
22    SkIPoint localOffset = SkIPoint::Make(0, 0);
23    if (input && !input->filterImage(proxy, src, ctm, &source, &localOffset)) {
24        return false;
25    }
26
27    int w = SkScalarTruncToInt(fDstRect.width());
28    int h = SkScalarTruncToInt(fDstRect.height());
29    if (!fSrcRect.width() || !fSrcRect.height() || !w || !h) {
30        return false;
31    }
32
33    SkIRect srcRect;
34    fSrcRect.roundOut(&srcRect);
35    SkBitmap subset;
36    if (!source.extractSubset(&subset, srcRect)) {
37        return false;
38    }
39
40    SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(w, h));
41    SkIRect bounds;
42    source.getBounds(&bounds);
43    SkCanvas canvas(device);
44    SkPaint paint;
45    paint.setXfermodeMode(SkXfermode::kSrc_Mode);
46
47    SkAutoTUnref<SkShader> shader(SkShader::CreateBitmapShader(subset,
48                                  SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode));
49    paint.setShader(shader);
50    SkRect dstRect = fDstRect;
51    dstRect.offset(SkIntToScalar(localOffset.fX), SkIntToScalar(localOffset.fY));
52    canvas.drawRect(dstRect, paint);
53    *dst = device->accessBitmap(false);
54    return true;
55}
56
57SkTileImageFilter::SkTileImageFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {
58    buffer.readRect(&fSrcRect);
59    buffer.readRect(&fDstRect);
60    buffer.validate(SkIsValidRect(fSrcRect) && SkIsValidRect(fDstRect));
61}
62
63void SkTileImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const {
64    this->INHERITED::flatten(buffer);
65    buffer.writeRect(fSrcRect);
66    buffer.writeRect(fDstRect);
67}
68