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 "SkDrawLooper.h"
9#include "SkCanvas.h"
10#include "SkMatrix.h"
11#include "SkPaint.h"
12#include "SkRect.h"
13#include "SkSmallAllocator.h"
14
15bool SkDrawLooper::canComputeFastBounds(const SkPaint& paint) const {
16    SkCanvas canvas;
17    SkSmallAllocator<1, 32> allocator;
18    void* buffer = allocator.reserveT<SkDrawLooper::Context>(this->contextSize());
19
20    SkDrawLooper::Context* context = this->createContext(&canvas, buffer);
21    for (;;) {
22        SkPaint p(paint);
23        if (context->next(&canvas, &p)) {
24            p.setLooper(NULL);
25            if (!p.canComputeFastBounds()) {
26                return false;
27            }
28        } else {
29            break;
30        }
31    }
32    return true;
33}
34
35void SkDrawLooper::computeFastBounds(const SkPaint& paint, const SkRect& s,
36                                     SkRect* dst) const {
37    // src and dst rects may alias and we need to keep the original src, so copy it.
38    const SkRect src = s;
39
40    SkCanvas canvas;
41    SkSmallAllocator<1, 32> allocator;
42    void* buffer = allocator.reserveT<SkDrawLooper::Context>(this->contextSize());
43
44    *dst = src;   // catch case where there are no loops
45    SkDrawLooper::Context* context = this->createContext(&canvas, buffer);
46    for (bool firstTime = true;; firstTime = false) {
47        SkPaint p(paint);
48        if (context->next(&canvas, &p)) {
49            SkRect r(src);
50
51            p.setLooper(NULL);
52            p.computeFastBounds(r, &r);
53            canvas.getTotalMatrix().mapRect(&r);
54
55            if (firstTime) {
56                *dst = r;
57            } else {
58                dst->join(r);
59            }
60        } else {
61            break;
62        }
63    }
64}
65
66bool SkDrawLooper::asABlurShadow(BlurShadowRec*) const {
67    return false;
68}
69