| Index: src/effects/SkImageSource.cpp
|
| diff --git a/src/effects/SkImageSource.cpp b/src/effects/SkImageSource.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..8f8c72b75c3a18f8b0f74926546b3eef98a0c35c
|
| --- /dev/null
|
| +++ b/src/effects/SkImageSource.cpp
|
| @@ -0,0 +1,118 @@
|
| +/*
|
| + * Copyright 2015 Google Inc.
|
| + *
|
| + * Use of this source code is governed by a BSD-style license that can be
|
| + * found in the LICENSE file.
|
| + */
|
| +
|
| +#include "SkImageSource.h"
|
| +
|
| +#include "SkCanvas.h"
|
| +#include "SkDevice.h"
|
| +#include "SkImage.h"
|
| +#include "SkReadBuffer.h"
|
| +#include "SkWriteBuffer.h"
|
| +#include "SkString.h"
|
| +
|
| +SkImageFilter* SkImageSource::Create(const SkImage* image) {
|
| + return image ? SkNEW_ARGS(SkImageSource, (image)) : nullptr;
|
| +}
|
| +
|
| +SkImageFilter* SkImageSource::Create(const SkImage* image,
|
| + const SkRect& srcRect,
|
| + const SkRect& dstRect,
|
| + SkFilterQuality filterQuality) {
|
| + return image ? SkNEW_ARGS(SkImageSource, (image, srcRect, dstRect, filterQuality)) : nullptr;
|
| +}
|
| +
|
| +SkImageSource::SkImageSource(const SkImage* image)
|
| + : INHERITED(0, nullptr)
|
| + , fImage(SkRef(image))
|
| + , fSrcRect(SkRect::MakeIWH(image->width(), image->height()))
|
| + , fDstRect(fSrcRect)
|
| + , fFilterQuality(kHigh_SkFilterQuality) { }
|
| +
|
| +SkImageSource::SkImageSource(const SkImage* image,
|
| + const SkRect& srcRect,
|
| + const SkRect& dstRect,
|
| + SkFilterQuality filterQuality)
|
| + : INHERITED(0, nullptr)
|
| + , fImage(SkRef(image))
|
| + , fSrcRect(srcRect)
|
| + , fDstRect(dstRect)
|
| + , fFilterQuality(filterQuality) { }
|
| +
|
| +SkFlattenable* SkImageSource::CreateProc(SkReadBuffer& buffer) {
|
| + SkFilterQuality filterQuality = (SkFilterQuality)buffer.readInt();
|
| +
|
| + SkRect src, dst;
|
| + buffer.readRect(&src);
|
| + buffer.readRect(&dst);
|
| +
|
| + SkAutoTUnref<SkImage> image(buffer.readImage());
|
| + if (!image) {
|
| + return nullptr;
|
| + }
|
| +
|
| + return SkImageSource::Create(image, src, dst, filterQuality);
|
| +}
|
| +
|
| +void SkImageSource::flatten(SkWriteBuffer& buffer) const {
|
| + buffer.writeInt(fFilterQuality);
|
| + buffer.writeRect(fSrcRect);
|
| + buffer.writeRect(fDstRect);
|
| + buffer.writeImage(fImage);
|
| +}
|
| +
|
| +bool SkImageSource::onFilterImage(Proxy* proxy, const SkBitmap& src, const Context& ctx,
|
| + SkBitmap* result, SkIPoint* offset) const {
|
| + SkRect dstRect;
|
| + ctx.ctm().mapRect(&dstRect, fDstRect);
|
| + SkRect bounds = SkRect::MakeIWH(fImage->width(), fImage->height());
|
| + if (fSrcRect == bounds && dstRect == bounds) {
|
| + // No regions cropped out or resized; return entire image.
|
| + offset->fX = offset->fY = 0;
|
| + return fImage->asLegacyBitmap(result, SkImage::kRO_LegacyBitmapMode);
|
| + }
|
| +
|
| + const SkIRect dstIRect = dstRect.roundOut();
|
| + SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(dstIRect.width(), dstIRect.height()));
|
| + if (nullptr == device.get()) {
|
| + return false;
|
| + }
|
| +
|
| + SkCanvas canvas(device.get());
|
| + SkPaint paint;
|
| +
|
| + // Subtract off the integer component of the translation (will be applied in loc, below).
|
| + dstRect.offset(-SkIntToScalar(dstIRect.fLeft), -SkIntToScalar(dstIRect.fTop));
|
| + paint.setXfermodeMode(SkXfermode::kSrc_Mode);
|
| + // FIXME: this probably shouldn't be necessary, but drawImageRect asserts
|
| + // None filtering when it's translate-only
|
| + paint.setFilterQuality(
|
| + fSrcRect.width() == dstRect.width() && fSrcRect.height() == dstRect.height() ?
|
| + kNone_SkFilterQuality : fFilterQuality);
|
| + canvas.drawImageRect(fImage, fSrcRect, dstRect, &paint, SkCanvas::kStrict_SrcRectConstraint);
|
| +
|
| + *result = device.get()->accessBitmap(false);
|
| + offset->fX = dstIRect.fLeft;
|
| + offset->fY = dstIRect.fTop;
|
| +
|
| + return true;
|
| +}
|
| +
|
| +void SkImageSource::computeFastBounds(const SkRect& src, SkRect* dst) const {
|
| + *dst = fDstRect;
|
| +}
|
| +
|
| +#ifndef SK_IGNORE_TO_STRING
|
| +void SkImageSource::toString(SkString* str) const {
|
| + str->appendf("SkImageSource: (");
|
| + str->appendf("src: (%f,%f,%f,%f) dst: (%f,%f,%f,%f) ",
|
| + fSrcRect.fLeft, fSrcRect.fTop, fSrcRect.fRight, fSrcRect.fBottom,
|
| + fDstRect.fLeft, fDstRect.fTop, fDstRect.fRight, fDstRect.fBottom);
|
| + str->appendf("image: (%d,%d)",
|
| + fImage->width(), fImage->height());
|
| + str->append(")");
|
| +}
|
| +#endif
|
|
|