|
1 /* |
|
2 * Copyright 2012 The Android Open Source Project |
|
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 "SkBitmapSource.h" |
|
9 #include "SkDevice.h" |
|
10 #include "SkCanvas.h" |
|
11 #include "SkReadBuffer.h" |
|
12 #include "SkWriteBuffer.h" |
|
13 #include "SkValidationUtils.h" |
|
14 |
|
15 SkBitmapSource::SkBitmapSource(const SkBitmap& bitmap) |
|
16 : INHERITED(0, 0), |
|
17 fBitmap(bitmap), |
|
18 fSrcRect(SkRect::MakeWH(SkIntToScalar(bitmap.width()), |
|
19 SkIntToScalar(bitmap.height()))), |
|
20 fDstRect(fSrcRect) { |
|
21 } |
|
22 |
|
23 SkBitmapSource::SkBitmapSource(const SkBitmap& bitmap, const SkRect& srcRect, const SkRect& dstRect) |
|
24 : INHERITED(0, 0), |
|
25 fBitmap(bitmap), |
|
26 fSrcRect(srcRect), |
|
27 fDstRect(dstRect) { |
|
28 } |
|
29 |
|
30 SkBitmapSource::SkBitmapSource(SkReadBuffer& buffer) |
|
31 : INHERITED(0, buffer) { |
|
32 fBitmap.unflatten(buffer); |
|
33 buffer.readRect(&fSrcRect); |
|
34 buffer.readRect(&fDstRect); |
|
35 buffer.validate(buffer.isValid() && SkIsValidRect(fSrcRect) && SkIsValidRect(fDstRect)); |
|
36 } |
|
37 |
|
38 void SkBitmapSource::flatten(SkWriteBuffer& buffer) const { |
|
39 this->INHERITED::flatten(buffer); |
|
40 fBitmap.flatten(buffer); |
|
41 buffer.writeRect(fSrcRect); |
|
42 buffer.writeRect(fDstRect); |
|
43 } |
|
44 |
|
45 bool SkBitmapSource::onFilterImage(Proxy* proxy, const SkBitmap&, const Context& ctx, |
|
46 SkBitmap* result, SkIPoint* offset) const { |
|
47 SkRect bounds, dstRect; |
|
48 fBitmap.getBounds(&bounds); |
|
49 ctx.ctm().mapRect(&dstRect, fDstRect); |
|
50 if (fSrcRect == bounds && dstRect == bounds) { |
|
51 // No regions cropped out or resized; return entire bitmap. |
|
52 *result = fBitmap; |
|
53 offset->fX = offset->fY = 0; |
|
54 return true; |
|
55 } |
|
56 SkIRect dstIRect; |
|
57 dstRect.roundOut(&dstIRect); |
|
58 |
|
59 SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(dstIRect.width(), dstIRect.height())); |
|
60 if (NULL == device.get()) { |
|
61 return false; |
|
62 } |
|
63 |
|
64 SkCanvas canvas(device.get()); |
|
65 SkPaint paint; |
|
66 |
|
67 // Subtract off the integer component of the translation (will be applied in loc, below). |
|
68 dstRect.offset(-SkIntToScalar(dstIRect.fLeft), -SkIntToScalar(dstIRect.fTop)); |
|
69 paint.setXfermodeMode(SkXfermode::kSrc_Mode); |
|
70 // FIXME: this probably shouldn't be necessary, but drawBitmapRectToRect asserts |
|
71 // None filtering when it's translate-only |
|
72 paint.setFilterLevel( |
|
73 fSrcRect.width() == dstRect.width() && fSrcRect.height() == dstRect.height() ? |
|
74 SkPaint::kNone_FilterLevel : SkPaint::kHigh_FilterLevel); |
|
75 canvas.drawBitmapRectToRect(fBitmap, &fSrcRect, dstRect, &paint); |
|
76 |
|
77 *result = device.get()->accessBitmap(false); |
|
78 offset->fX = dstIRect.fLeft; |
|
79 offset->fY = dstIRect.fTop; |
|
80 return true; |
|
81 } |
|
82 |
|
83 void SkBitmapSource::computeFastBounds(const SkRect&, SkRect* dst) const { |
|
84 *dst = fDstRect; |
|
85 } |
|
86 |
|
87 bool SkBitmapSource::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, |
|
88 SkIRect* dst) const { |
|
89 *dst = src; |
|
90 return true; |
|
91 } |