1f1369ce607adf55ffffe58fb93893bafb6ff6ebesenorblanco@chromium.org/* 2f1369ce607adf55ffffe58fb93893bafb6ff6ebesenorblanco@chromium.org * Copyright 2012 The Android Open Source Project 3f1369ce607adf55ffffe58fb93893bafb6ff6ebesenorblanco@chromium.org * 4f1369ce607adf55ffffe58fb93893bafb6ff6ebesenorblanco@chromium.org * Use of this source code is governed by a BSD-style license that can be 5f1369ce607adf55ffffe58fb93893bafb6ff6ebesenorblanco@chromium.org * found in the LICENSE file. 6f1369ce607adf55ffffe58fb93893bafb6ff6ebesenorblanco@chromium.org */ 7f1369ce607adf55ffffe58fb93893bafb6ff6ebesenorblanco@chromium.org 8f1369ce607adf55ffffe58fb93893bafb6ff6ebesenorblanco@chromium.org#include "SkBitmapSource.h" 9e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org#include "SkDevice.h" 10e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org#include "SkCanvas.h" 118b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h" 128b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkWriteBuffer.h" 13e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org#include "SkValidationUtils.h" 14f1369ce607adf55ffffe58fb93893bafb6ff6ebesenorblanco@chromium.org 159f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.orgSkBitmapSource::SkBitmapSource(const SkBitmap& bitmap) 16ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org : INHERITED(0, 0), 17e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org fBitmap(bitmap), 18e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org fSrcRect(SkRect::MakeWH(SkIntToScalar(bitmap.width()), 19e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org SkIntToScalar(bitmap.height()))), 20e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org fDstRect(fSrcRect) { 21e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org} 22e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org 23e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.orgSkBitmapSource::SkBitmapSource(const SkBitmap& bitmap, const SkRect& srcRect, const SkRect& dstRect) 24968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org : INHERITED(0, 0) 25968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org , fBitmap(bitmap) 26968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org , fSrcRect(srcRect) 27968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org , fDstRect(dstRect) {} 28f1369ce607adf55ffffe58fb93893bafb6ff6ebesenorblanco@chromium.org 29968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.orgSkBitmapSource::SkBitmapSource(SkReadBuffer& buffer) : INHERITED(0, buffer) { 30968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org if (buffer.isVersionLT(SkReadBuffer::kNoMoreBitmapFlatten_Version)) { 31851155c28e18e3f5b702ef15ee7bfb12f3cbacdacommit-bot@chromium.org fBitmap.legacyUnflatten(buffer); 32968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org } else { 33968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org buffer.readBitmap(&fBitmap); 34968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org } 35e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org buffer.readRect(&fSrcRect); 36e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org buffer.readRect(&fDstRect); 37658e1b38b94fd3b31edcafe1aa226ca7da9b80d2commit-bot@chromium.org buffer.validate(buffer.isValid() && SkIsValidRect(fSrcRect) && SkIsValidRect(fDstRect)); 38f1369ce607adf55ffffe58fb93893bafb6ff6ebesenorblanco@chromium.org} 39f1369ce607adf55ffffe58fb93893bafb6ff6ebesenorblanco@chromium.org 408b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkBitmapSource::flatten(SkWriteBuffer& buffer) const { 41f1369ce607adf55ffffe58fb93893bafb6ff6ebesenorblanco@chromium.org this->INHERITED::flatten(buffer); 42968edcafa61442dc4f7f8ed8f89523d0f353e9fbcommit-bot@chromium.org buffer.writeBitmap(fBitmap); 43e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org buffer.writeRect(fSrcRect); 44e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org buffer.writeRect(fDstRect); 45f1369ce607adf55ffffe58fb93893bafb6ff6ebesenorblanco@chromium.org} 46f1369ce607adf55ffffe58fb93893bafb6ff6ebesenorblanco@chromium.org 474cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.orgbool SkBitmapSource::onFilterImage(Proxy* proxy, const SkBitmap&, const Context& ctx, 48ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org SkBitmap* result, SkIPoint* offset) const { 49e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org SkRect bounds, dstRect; 50e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org fBitmap.getBounds(&bounds); 514cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org ctx.ctm().mapRect(&dstRect, fDstRect); 52e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org if (fSrcRect == bounds && dstRect == bounds) { 53e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org // No regions cropped out or resized; return entire bitmap. 54e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org *result = fBitmap; 556776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org offset->fX = offset->fY = 0; 56e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org return true; 57e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org } 58e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org SkIRect dstIRect; 59e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org dstRect.roundOut(&dstIRect); 60e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org 61e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(dstIRect.width(), dstIRect.height())); 62e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org if (NULL == device.get()) { 63e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org return false; 64e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org } 65e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org 66e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org SkCanvas canvas(device.get()); 67e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org SkPaint paint; 68e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org 69e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org // Subtract off the integer component of the translation (will be applied in loc, below). 70e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org dstRect.offset(-SkIntToScalar(dstIRect.fLeft), -SkIntToScalar(dstIRect.fTop)); 71e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org paint.setXfermodeMode(SkXfermode::kSrc_Mode); 72e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org // FIXME: this probably shouldn't be necessary, but drawBitmapRectToRect asserts 73e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org // None filtering when it's translate-only 74e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org paint.setFilterLevel( 75e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org fSrcRect.width() == dstRect.width() && fSrcRect.height() == dstRect.height() ? 76dcfaa73e68f54f19c7900577b71f585fb8a7e1aecommit-bot@chromium.org SkPaint::kNone_FilterLevel : SkPaint::kHigh_FilterLevel); 77e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org canvas.drawBitmapRectToRect(fBitmap, &fSrcRect, dstRect, &paint); 78e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org 79e93e1dbf0eced1e1b9aeed7c0c170961e2d61e32senorblanco@chromium.org *result = device.get()->accessBitmap(false); 806776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org offset->fX = dstIRect.fLeft; 816776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org offset->fY = dstIRect.fTop; 82f1369ce607adf55ffffe58fb93893bafb6ff6ebesenorblanco@chromium.org return true; 83f1369ce607adf55ffffe58fb93893bafb6ff6ebesenorblanco@chromium.org} 84336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org 85336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.orgvoid SkBitmapSource::computeFastBounds(const SkRect&, SkRect* dst) const { 86336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org *dst = fDstRect; 87336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org} 88c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org 89c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.orgbool SkBitmapSource::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, 90c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org SkIRect* dst) const { 91c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org *dst = src; 92c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org return true; 93c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org} 94