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& src,
36                                     SkRect* dst) const {
37    SkCanvas canvas;
38    SkSmallAllocator<1, 32> allocator;
39    void* buffer = allocator.reserveT<SkDrawLooper::Context>(this->contextSize());
40
41    *dst = src;   // catch case where there are no loops
42    SkDrawLooper::Context* context = this->createContext(&canvas, buffer);
43    for (bool firstTime = true;; firstTime = false) {
44        SkPaint p(paint);
45        if (context->next(&canvas, &p)) {
46            SkRect r(src);
47
48            p.setLooper(NULL);
49            p.computeFastBounds(r, &r);
50            canvas.getTotalMatrix().mapRect(&r);
51
52            if (firstTime) {
53                *dst = r;
54            } else {
55                dst->join(r);
56            }
57        } else {
58            break;
59        }
60    }
61}
62
63bool SkDrawLooper::asABlurShadow(BlurShadowRec*) const {
64    return false;
65}
66