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 "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   , fFilterQuality(kHigh_SkFilterQuality) {
     22 }
     23 
     24 SkBitmapSource::SkBitmapSource(const SkBitmap& bitmap,
     25                                const SkRect& srcRect, const SkRect& dstRect,
     26                                SkFilterQuality filterQuality)
     27   : INHERITED(0, 0)
     28   , fBitmap(bitmap)
     29   , fSrcRect(srcRect)
     30   , fDstRect(dstRect)
     31   , fFilterQuality(filterQuality) {
     32 }
     33 
     34 SkFlattenable* SkBitmapSource::CreateProc(SkReadBuffer& buffer) {
     35     SkFilterQuality filterQuality;
     36     if (buffer.isVersionLT(SkReadBuffer::kBitmapSourceFilterQuality_Version)) {
     37         filterQuality = kHigh_SkFilterQuality;
     38     } else {
     39         filterQuality = (SkFilterQuality)buffer.readInt();
     40     }
     41     SkRect src, dst;
     42     buffer.readRect(&src);
     43     buffer.readRect(&dst);
     44     SkBitmap bitmap;
     45     if (!buffer.readBitmap(&bitmap)) {
     46         return NULL;
     47     }
     48     return SkBitmapSource::Create(bitmap, src, dst, filterQuality);
     49 }
     50 
     51 void SkBitmapSource::flatten(SkWriteBuffer& buffer) const {
     52     buffer.writeInt(fFilterQuality);
     53     buffer.writeRect(fSrcRect);
     54     buffer.writeRect(fDstRect);
     55     buffer.writeBitmap(fBitmap);
     56 }
     57 
     58 bool SkBitmapSource::onFilterImage(Proxy* proxy, const SkBitmap&, const Context& ctx,
     59                                    SkBitmap* result, SkIPoint* offset) const {
     60     SkRect bounds, dstRect;
     61     fBitmap.getBounds(&bounds);
     62     ctx.ctm().mapRect(&dstRect, fDstRect);
     63     if (fSrcRect == bounds && dstRect == bounds) {
     64         // No regions cropped out or resized; return entire bitmap.
     65         *result = fBitmap;
     66         offset->fX = offset->fY = 0;
     67         return true;
     68     }
     69 
     70     const SkIRect dstIRect = dstRect.roundOut();
     71     SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(dstIRect.width(), dstIRect.height()));
     72     if (NULL == device.get()) {
     73         return false;
     74     }
     75 
     76     SkCanvas canvas(device.get());
     77     SkPaint paint;
     78 
     79     // Subtract off the integer component of the translation (will be applied in loc, below).
     80     dstRect.offset(-SkIntToScalar(dstIRect.fLeft), -SkIntToScalar(dstIRect.fTop));
     81     paint.setXfermodeMode(SkXfermode::kSrc_Mode);
     82     // FIXME: this probably shouldn't be necessary, but drawBitmapRectToRect asserts
     83     // None filtering when it's translate-only
     84     paint.setFilterQuality(
     85         fSrcRect.width() == dstRect.width() && fSrcRect.height() == dstRect.height() ?
     86                kNone_SkFilterQuality : fFilterQuality);
     87     canvas.drawBitmapRectToRect(fBitmap, &fSrcRect, dstRect, &paint);
     88 
     89     *result = device.get()->accessBitmap(false);
     90     offset->fX = dstIRect.fLeft;
     91     offset->fY = dstIRect.fTop;
     92 
     93     return true;
     94 }
     95 
     96 void SkBitmapSource::computeFastBounds(const SkRect&, SkRect* dst) const {
     97     *dst = fDstRect;
     98 }
     99 
    100 #ifndef SK_IGNORE_TO_STRING
    101 void SkBitmapSource::toString(SkString* str) const {
    102     str->appendf("SkBitmapSource: (");
    103     str->appendf("src: (%f,%f,%f,%f) dst: (%f,%f,%f,%f) ",
    104                  fSrcRect.fLeft, fSrcRect.fTop, fSrcRect.fRight, fSrcRect.fBottom,
    105                  fDstRect.fLeft, fDstRect.fTop, fDstRect.fRight, fDstRect.fBottom);
    106     str->appendf("bitmap: (%d,%d)",
    107                  fBitmap.width(), fBitmap.height());
    108     str->append(")");
    109 }
    110 #endif
    111