1/*
2 * Copyright 2016 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#ifndef SkBitmapKey_DEFINED
8#define SkBitmapKey_DEFINED
9
10#include "SkBitmap.h"
11#include "SkImage.h"
12#include "SkCanvas.h"
13
14struct SkBitmapKey {
15    SkIRect fSubset;
16    uint32_t fID;
17    bool operator==(const SkBitmapKey& rhs) const {
18        return fID == rhs.fID && fSubset == rhs.fSubset;
19    }
20    bool operator!=(const SkBitmapKey& rhs) const { return !(*this == rhs); }
21};
22
23/**
24   This class has all the advantages of SkBitmaps and SkImages.
25 */
26class SkImageSubset {
27public:
28    SkImageSubset(sk_sp<SkImage> i, SkIRect subset = {0, 0, 0, 0})
29        : fImage(std::move(i)) {
30        if (!fImage) {
31            fSubset = {0, 0, 0, 0};
32            fID = 0;
33            return;
34        }
35        fID = fImage->uniqueID();
36        if (subset.isEmpty()) {
37            fSubset = fImage->bounds();
38            // SkImage always has a non-zero dimensions.
39            SkASSERT(!fSubset.isEmpty());
40        } else {
41            fSubset = subset;
42            if (!fSubset.intersect(fImage->bounds())) {
43                fImage = nullptr;
44                fSubset = {0, 0, 0, 0};
45                fID = 0;
46            }
47        }
48    }
49
50    void setID(uint32_t id) { fID = id; }
51
52    bool isValid() const { return fImage != nullptr; }
53
54    SkIRect bounds() const { return SkIRect::MakeSize(this->dimensions()); }
55
56    SkISize dimensions() const { return fSubset.size(); }
57
58    sk_sp<SkImage> makeImage() const {
59        return fSubset == fImage->bounds() ? fImage : fImage->makeSubset(fSubset);
60    }
61
62    SkBitmapKey getKey() const { return SkBitmapKey{fSubset, fID}; }
63
64    void draw(SkCanvas* canvas, SkPaint* paint) const {
65        SkASSERT(this->isValid());
66        SkRect src = SkRect::Make(fSubset),
67               dst = SkRect::Make(this->bounds());
68        canvas->drawImageRect(fImage.get(), src, dst, paint);
69    }
70
71private:
72    SkIRect fSubset;
73    sk_sp<SkImage> fImage;
74    uint32_t fID;
75};
76
77#endif  // SkBitmapKey_DEFINED
78