• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "SkFlattenableBuffers.h"
12 #include "SkValidationUtils.h"
13 
SkBitmapSource(const SkBitmap & bitmap)14 SkBitmapSource::SkBitmapSource(const SkBitmap& bitmap)
15   : INHERITED(0, 0),
16     fBitmap(bitmap),
17     fSrcRect(SkRect::MakeWH(SkIntToScalar(bitmap.width()),
18                             SkIntToScalar(bitmap.height()))),
19     fDstRect(fSrcRect) {
20 }
21 
SkBitmapSource(const SkBitmap & bitmap,const SkRect & srcRect,const SkRect & dstRect)22 SkBitmapSource::SkBitmapSource(const SkBitmap& bitmap, const SkRect& srcRect, const SkRect& dstRect)
23   : INHERITED(0, 0),
24     fBitmap(bitmap),
25     fSrcRect(srcRect),
26     fDstRect(dstRect) {
27 }
28 
SkBitmapSource(SkFlattenableReadBuffer & buffer)29 SkBitmapSource::SkBitmapSource(SkFlattenableReadBuffer& buffer)
30   : INHERITED(0, buffer) {
31     fBitmap.unflatten(buffer);
32     buffer.readRect(&fSrcRect);
33     buffer.readRect(&fDstRect);
34     buffer.validate(SkIsValidRect(fSrcRect) && SkIsValidRect(fDstRect));
35 }
36 
flatten(SkFlattenableWriteBuffer & buffer) const37 void SkBitmapSource::flatten(SkFlattenableWriteBuffer& buffer) const {
38     this->INHERITED::flatten(buffer);
39     fBitmap.flatten(buffer);
40     buffer.writeRect(fSrcRect);
41     buffer.writeRect(fDstRect);
42 }
43 
onFilterImage(Proxy * proxy,const SkBitmap &,const SkMatrix & matrix,SkBitmap * result,SkIPoint * offset)44 bool SkBitmapSource::onFilterImage(Proxy* proxy, const SkBitmap&, const SkMatrix& matrix,
45                                    SkBitmap* result, SkIPoint* offset) {
46     SkRect bounds, dstRect;
47     fBitmap.getBounds(&bounds);
48     matrix.mapRect(&dstRect, fDstRect);
49     if (fSrcRect == bounds && dstRect == bounds) {
50         // No regions cropped out or resized; return entire bitmap.
51         *result = fBitmap;
52         return true;
53     }
54     SkIRect dstIRect;
55     dstRect.roundOut(&dstIRect);
56 
57     SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(dstIRect.width(), dstIRect.height()));
58     if (NULL == device.get()) {
59         return false;
60     }
61 
62     SkCanvas canvas(device.get());
63     SkPaint paint;
64 
65     // Subtract off the integer component of the translation (will be applied in loc, below).
66     dstRect.offset(-SkIntToScalar(dstIRect.fLeft), -SkIntToScalar(dstIRect.fTop));
67     paint.setXfermodeMode(SkXfermode::kSrc_Mode);
68     // FIXME: this probably shouldn't be necessary, but drawBitmapRectToRect asserts
69     // None filtering when it's translate-only
70     paint.setFilterLevel(
71         fSrcRect.width() == dstRect.width() && fSrcRect.height() == dstRect.height() ?
72         SkPaint::kNone_FilterLevel : SkPaint::kMedium_FilterLevel);
73     canvas.drawBitmapRectToRect(fBitmap, &fSrcRect, dstRect, &paint);
74 
75     *result = device.get()->accessBitmap(false);
76     offset->fX += dstIRect.fLeft;
77     offset->fY += dstIRect.fTop;
78     return true;
79 }
80