blob: 208053b90edf00eefcd2c997a8d830d198a43bb6 [file] [log] [blame]
/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SkTestImageFilters.h"
#include "SkCanvas.h"
#include "SkReadBuffer.h"
#include "SkSpecialImage.h"
#include "SkSpecialSurface.h"
#include "SkWriteBuffer.h"
///////////////////////////////////////////////////////////////////////////////
sk_sp<SkImageFilter> SkDownSampleImageFilter::Make(SkScalar scale, sk_sp<SkImageFilter> input) {
if (!SkScalarIsFinite(scale)) {
return nullptr;
}
// we don't support scale in this range
if (scale > SK_Scalar1 || scale <= 0) {
return nullptr;
}
return sk_sp<SkImageFilter>(new SkDownSampleImageFilter(scale, std::move(input)));
}
sk_sp<SkSpecialImage> SkDownSampleImageFilter::onFilterImage(SkSpecialImage* source,
const Context& ctx,
SkIPoint* offset) const {
if (fScale > SK_Scalar1 || fScale <= 0) {
return nullptr;
}
int dstW = SkScalarRoundToInt(source->width() * fScale);
int dstH = SkScalarRoundToInt(source->height() * fScale);
if (dstW < 1) {
dstW = 1;
}
if (dstH < 1) {
dstH = 1;
}
sk_sp<SkSpecialImage> tmp;
// downsample
{
const SkImageInfo info = SkImageInfo::MakeN32Premul(dstW, dstH);
sk_sp<SkSpecialSurface> surf(source->makeSurface(info));
if (!surf) {
return nullptr;
}
SkCanvas* canvas = surf->getCanvas();
SkASSERT(canvas);
canvas->clear(0x0);
SkPaint paint;
paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
paint.setFilterQuality(kLow_SkFilterQuality);
canvas->scale(fScale, fScale);
source->draw(canvas, 0, 0, &paint);
tmp = surf->makeImageSnapshot();
}
// upscale
{
const SkImageInfo info = SkImageInfo::MakeN32Premul(source->width(), source->height());
sk_sp<SkSpecialSurface> surf(source->makeSurface(info));
if (!surf) {
return nullptr;
}
SkCanvas* canvas = surf->getCanvas();
SkASSERT(canvas);
canvas->clear(0x0);
SkPaint paint;
paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
canvas->scale(SkScalarInvert(fScale), SkScalarInvert(fScale));
tmp->draw(canvas, 0, 0, &paint);
return surf->makeImageSnapshot();
}
}
sk_sp<SkFlattenable> SkDownSampleImageFilter::CreateProc(SkReadBuffer& buffer) {
SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
return Make(buffer.readScalar(), common.getInput(0));
}
void SkDownSampleImageFilter::flatten(SkWriteBuffer& buffer) const {
this->INHERITED::flatten(buffer);
buffer.writeScalar(fScale);
}
#ifndef SK_IGNORE_TO_STRING
void SkDownSampleImageFilter::toString(SkString* str) const {
str->appendf("SkDownSampleImageFilter: (");
str->append(")");
}
#endif