1 /*
2 * Copyright 2023 Google LLC
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 "include/core/SkTiledImageUtils.h"
9
10 #include "include/core/SkBitmap.h"
11 #include "include/core/SkPaint.h"
12 #include "include/core/SkPixelRef.h"
13 #include "include/private/base/SkAssert.h"
14 #include "include/private/base/SkTFitsIn.h"
15 #include "src/core/SkCanvasPriv.h"
16 #include "src/core/SkDevice.h"
17 #include "src/image/SkImage_Base.h"
18 #include "src/image/SkImage_Picture.h"
19
20 #include <string.h>
21
22 namespace SkTiledImageUtils {
23
DrawImageRect(SkCanvas * canvas,const SkImage * image,const SkRect & src,const SkRect & dst,const SkSamplingOptions & sampling,const SkPaint * paint,SkCanvas::SrcRectConstraint constraint)24 void DrawImageRect(SkCanvas* canvas,
25 const SkImage* image,
26 const SkRect& src,
27 const SkRect& dst,
28 const SkSamplingOptions& sampling,
29 const SkPaint* paint,
30 SkCanvas::SrcRectConstraint constraint) {
31 if (!image || !canvas) {
32 return;
33 }
34
35 SkPaint p;
36 if (paint) {
37 p = *paint;
38 }
39 if (!SkCanvasPriv::TopDevice(canvas)->drawAsTiledImageRect(
40 canvas, image, &src, dst, sampling, p, constraint)) {
41 // Either the image didn't require tiling or this is a raster-backed
42 // canvas. In either case fall back to a default draw.
43 canvas->drawImageRect(image, src, dst, sampling, paint, constraint);
44 }
45 }
46
GetImageKeyValues(const SkImage * image,uint32_t keyValues[kNumImageKeyValues])47 void GetImageKeyValues(const SkImage* image, uint32_t keyValues[kNumImageKeyValues]) {
48 if (!image || !keyValues) {
49 if (keyValues) {
50 memset(keyValues, 0, kNumImageKeyValues * sizeof(uint32_t));
51 }
52 return;
53 }
54
55 const SkImage_Base* imageBase = as_IB(image);
56 if (const SkBitmap* bm = imageBase->onPeekBitmap()) {
57 keyValues[0] = bm->pixelRef()->getGenerationID();
58 SkIRect subset = image->bounds();
59 subset.offset(bm->pixelRefOrigin());
60
61 SkASSERT(SkTFitsIn<uint32_t>(subset.fLeft));
62 SkASSERT(SkTFitsIn<uint32_t>(subset.fTop));
63 SkASSERT(SkTFitsIn<uint32_t>(subset.fRight));
64 SkASSERT(SkTFitsIn<uint32_t>(subset.fBottom));
65
66 keyValues[1] = 0; // This empty slot is to disambiguate picture IDs
67 keyValues[2] = subset.fLeft;
68 keyValues[3] = subset.fTop;
69 keyValues[4] = subset.fRight;
70 keyValues[5] = subset.fBottom;
71 return;
72 }
73
74 if (imageBase->type() == SkImage_Base::Type::kLazyPicture) {
75 const SkImage_Picture* pictureImage = static_cast<const SkImage_Picture*>(imageBase);
76 if (pictureImage->getImageKeyValues(keyValues)) {
77 return;
78 }
79 }
80
81 keyValues[0] = image->uniqueID();
82 memset(&keyValues[1], 0, (kNumImageKeyValues-1) * sizeof(uint32_t));
83 }
84
85 } // namespace SkTiledImageUtils
86