1/*
2 * Copyright 2014 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 "SkAtomics.h"
9#include "SkCanvas.h"
10#include "SkDrawable.h"
11
12static int32_t next_generation_id() {
13    static int32_t gCanvasDrawableGenerationID;
14
15    // do a loop in case our global wraps around, as we never want to
16    // return a 0
17    int32_t genID;
18    do {
19        genID = sk_atomic_inc(&gCanvasDrawableGenerationID) + 1;
20    } while (0 == genID);
21    return genID;
22}
23
24SkDrawable::SkDrawable() : fGenerationID(0) {}
25
26static void draw_bbox(SkCanvas* canvas, const SkRect& r) {
27    SkPaint paint;
28    paint.setStyle(SkPaint::kStroke_Style);
29    paint.setColor(0xFFFF7088);
30    canvas->drawRect(r, paint);
31    canvas->drawLine(r.left(), r.top(), r.right(), r.bottom(), paint);
32    canvas->drawLine(r.left(), r.bottom(), r.right(), r.top(), paint);
33}
34
35void SkDrawable::draw(SkCanvas* canvas, const SkMatrix* matrix) {
36    SkAutoCanvasRestore acr(canvas, true);
37    if (matrix) {
38        canvas->concat(*matrix);
39    }
40    this->onDraw(canvas);
41
42    if (false) {
43        draw_bbox(canvas, this->getBounds());
44    }
45}
46
47void SkDrawable::draw(SkCanvas* canvas, SkScalar x, SkScalar y) {
48    SkMatrix matrix = SkMatrix::MakeTrans(x, y);
49    this->draw(canvas, &matrix);
50}
51
52SkPicture* SkDrawable::newPictureSnapshot() {
53    return this->onNewPictureSnapshot();
54}
55
56uint32_t SkDrawable::getGenerationID() {
57    if (0 == fGenerationID) {
58        fGenerationID = next_generation_id();
59    }
60    return fGenerationID;
61}
62
63SkRect SkDrawable::getBounds() {
64    return this->onGetBounds();
65}
66
67void SkDrawable::notifyDrawingChanged() {
68    fGenerationID = 0;
69}
70
71/////////////////////////////////////////////////////////////////////////////////////////
72
73#include "SkPictureRecorder.h"
74
75SkPicture* SkDrawable::onNewPictureSnapshot() {
76    SkPictureRecorder recorder;
77
78    const SkRect bounds = this->getBounds();
79    SkCanvas* canvas = recorder.beginRecording(bounds, nullptr, 0);
80    this->draw(canvas);
81    if (false) {
82        draw_bbox(canvas, bounds);
83    }
84    return recorder.finishRecordingAsPicture().release();
85}
86