Home | History | Annotate | Download | only in effects
      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 
     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 
     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 
     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 
     37 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 
     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