SkDrawLooper.cpp revision 79fbb40bca9d815ef79b896b31ba6ee736817e0f
18b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org/*
28b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org * Copyright 2013 Google Inc.
38b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org *
48b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org * Use of this source code is governed by a BSD-style license that can be
58b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org * found in the LICENSE file.
68b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org */
78b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org
88b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org#include "SkDrawLooper.h"
98b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org#include "SkCanvas.h"
108b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org#include "SkMatrix.h"
118b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org#include "SkPaint.h"
128b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org#include "SkRect.h"
1379fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org#include "SkSmallAllocator.h"
148b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org
1579fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.orgbool SkDrawLooper::canComputeFastBounds(const SkPaint& paint) const {
168b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org    SkCanvas canvas;
1779fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org    SkSmallAllocator<1, 32> allocator;
1879fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org    void* buffer = allocator.reserveT<SkDrawLooper::Context>(this->contextSize());
198b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org
2079fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org    SkDrawLooper::Context* context = this->createContext(&canvas, buffer);
218b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org    for (;;) {
228b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org        SkPaint p(paint);
2379fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org        if (context->next(&canvas, &p)) {
248b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org            p.setLooper(NULL);
258b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org            if (!p.canComputeFastBounds()) {
268b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org                return false;
278b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org            }
288b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org        } else {
298b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org            break;
308b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org        }
318b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org    }
328b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org    return true;
338b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org}
348b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org
358b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.orgvoid SkDrawLooper::computeFastBounds(const SkPaint& paint, const SkRect& src,
3679fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org                                     SkRect* dst) const {
378b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org    SkCanvas canvas;
3879fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org    SkSmallAllocator<1, 32> allocator;
3979fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org    void* buffer = allocator.reserveT<SkDrawLooper::Context>(this->contextSize());
408b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org
41135ece137b471219eea06a652069b86a3b6ec349robertphillips@google.com    *dst = src;   // catch case where there are no loops
4279fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org    SkDrawLooper::Context* context = this->createContext(&canvas, buffer);
438b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org    for (bool firstTime = true;; firstTime = false) {
448b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org        SkPaint p(paint);
4579fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org        if (context->next(&canvas, &p)) {
468b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org            SkRect r(src);
478b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org
488b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org            p.setLooper(NULL);
498b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org            p.computeFastBounds(r, &r);
508b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org            canvas.getTotalMatrix().mapRect(&r);
518b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org
528b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org            if (firstTime) {
538b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org                *dst = r;
548b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org            } else {
558b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org                dst->join(r);
568b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org            }
578b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org        } else {
588b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org            break;
598b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org        }
608b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org    }
618b79028d27653fafcde6901affba48b987b52e43commit-bot@chromium.org}
62