• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 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 "SkImageSource.h"
9 
10 #include "SkCanvas.h"
11 #include "SkDevice.h"
12 #include "SkImage.h"
13 #include "SkReadBuffer.h"
14 #include "SkWriteBuffer.h"
15 #include "SkString.h"
16 
Create(const SkImage * image)17 SkImageFilter* SkImageSource::Create(const SkImage* image) {
18     return image ? new SkImageSource(image) : nullptr;
19 }
20 
Create(const SkImage * image,const SkRect & srcRect,const SkRect & dstRect,SkFilterQuality filterQuality)21 SkImageFilter* SkImageSource::Create(const SkImage* image,
22                                      const SkRect& srcRect,
23                                      const SkRect& dstRect,
24                                      SkFilterQuality filterQuality) {
25     return image ? new SkImageSource(image, srcRect, dstRect, filterQuality) : nullptr;
26 }
27 
SkImageSource(const SkImage * image)28 SkImageSource::SkImageSource(const SkImage* image)
29     : INHERITED(0, nullptr)
30     , fImage(SkRef(image))
31     , fSrcRect(SkRect::MakeIWH(image->width(), image->height()))
32     , fDstRect(fSrcRect)
33     , fFilterQuality(kHigh_SkFilterQuality) { }
34 
SkImageSource(const SkImage * image,const SkRect & srcRect,const SkRect & dstRect,SkFilterQuality filterQuality)35 SkImageSource::SkImageSource(const SkImage* image,
36                              const SkRect& srcRect,
37                              const SkRect& dstRect,
38                              SkFilterQuality filterQuality)
39     : INHERITED(0, nullptr)
40     , fImage(SkRef(image))
41     , fSrcRect(srcRect)
42     , fDstRect(dstRect)
43     , fFilterQuality(filterQuality) { }
44 
CreateProc(SkReadBuffer & buffer)45 SkFlattenable* SkImageSource::CreateProc(SkReadBuffer& buffer) {
46     SkFilterQuality filterQuality = (SkFilterQuality)buffer.readInt();
47 
48     SkRect src, dst;
49     buffer.readRect(&src);
50     buffer.readRect(&dst);
51 
52     SkAutoTUnref<SkImage> image(buffer.readImage());
53     if (!image) {
54         return nullptr;
55     }
56 
57     return SkImageSource::Create(image, src, dst, filterQuality);
58 }
59 
flatten(SkWriteBuffer & buffer) const60 void SkImageSource::flatten(SkWriteBuffer& buffer) const {
61     buffer.writeInt(fFilterQuality);
62     buffer.writeRect(fSrcRect);
63     buffer.writeRect(fDstRect);
64     buffer.writeImage(fImage);
65 }
66 
onFilterImageDeprecated(Proxy * proxy,const SkBitmap & src,const Context & ctx,SkBitmap * result,SkIPoint * offset) const67 bool SkImageSource::onFilterImageDeprecated(Proxy* proxy, const SkBitmap& src, const Context& ctx,
68                                             SkBitmap* result, SkIPoint* offset) const {
69     SkRect dstRect;
70     ctx.ctm().mapRect(&dstRect, fDstRect);
71     SkRect bounds = SkRect::MakeIWH(fImage->width(), fImage->height());
72     if (fSrcRect == bounds && dstRect == bounds) {
73         // No regions cropped out or resized; return entire image.
74         offset->fX = offset->fY = 0;
75         return fImage->asLegacyBitmap(result, SkImage::kRO_LegacyBitmapMode);
76     }
77 
78     const SkIRect dstIRect = dstRect.roundOut();
79     SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(dstIRect.width(), dstIRect.height()));
80     if (nullptr == device.get()) {
81         return false;
82     }
83 
84     SkCanvas canvas(device.get());
85     SkPaint paint;
86 
87     // Subtract off the integer component of the translation (will be applied in loc, below).
88     dstRect.offset(-SkIntToScalar(dstIRect.fLeft), -SkIntToScalar(dstIRect.fTop));
89     paint.setXfermodeMode(SkXfermode::kSrc_Mode);
90     // FIXME: this probably shouldn't be necessary, but drawImageRect asserts
91     // None filtering when it's translate-only
92     paint.setFilterQuality(
93         fSrcRect.width() == dstRect.width() && fSrcRect.height() == dstRect.height() ?
94                kNone_SkFilterQuality : fFilterQuality);
95     canvas.drawImageRect(fImage, fSrcRect, dstRect, &paint, SkCanvas::kStrict_SrcRectConstraint);
96 
97     *result = device.get()->accessBitmap(false);
98     offset->fX = dstIRect.fLeft;
99     offset->fY = dstIRect.fTop;
100 
101     return true;
102 }
103 
computeFastBounds(const SkRect & src,SkRect * dst) const104 void SkImageSource::computeFastBounds(const SkRect& src, SkRect* dst) const {
105     *dst = fDstRect;
106 }
107 
108 #ifndef SK_IGNORE_TO_STRING
toString(SkString * str) const109 void SkImageSource::toString(SkString* str) const {
110     str->appendf("SkImageSource: (");
111     str->appendf("src: (%f,%f,%f,%f) dst: (%f,%f,%f,%f) ",
112                  fSrcRect.fLeft, fSrcRect.fTop, fSrcRect.fRight, fSrcRect.fBottom,
113                  fDstRect.fLeft, fDstRect.fTop, fDstRect.fRight, fDstRect.fBottom);
114     str->appendf("image: (%d,%d)",
115                  fImage->width(), fImage->height());
116     str->append(")");
117 }
118 #endif
119