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