diff options
author | 2018-06-19 10:17:30 -0400 | |
---|---|---|
committer | 2018-06-19 20:16:38 +0000 | |
commit | 0917fad2c6339b6452e6eb58d4a8485d291d8d43 (patch) | |
tree | a277034a104bf9617dedda3cc5114353d86fe6a0 /src/effects/imagefilters/SkMergeImageFilter.cpp | |
parent | 386d9cf40278bb026ebfbbc6077144c2d8ed4dd2 (diff) |
move imagefilters into separate dir and flag for build.gn
Requires https://chromium-review.googlesource.com/c/chromium/src/+/1105062
Bug: skia:
Change-Id: I948056234efa57c0f727a61d5fb3258034de5199
Reviewed-on: https://skia-review.googlesource.com/135566
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Mike Reed <reed@google.com>
Diffstat (limited to 'src/effects/imagefilters/SkMergeImageFilter.cpp')
-rw-r--r-- | src/effects/imagefilters/SkMergeImageFilter.cpp | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/src/effects/imagefilters/SkMergeImageFilter.cpp b/src/effects/imagefilters/SkMergeImageFilter.cpp new file mode 100644 index 0000000000..3225ba8821 --- /dev/null +++ b/src/effects/imagefilters/SkMergeImageFilter.cpp @@ -0,0 +1,124 @@ +/* + * Copyright 2012 The Android Open Source Project + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkMergeImageFilter.h" + +#include "SkCanvas.h" +#include "SkColorSpaceXformer.h" +#include "SkFlattenablePriv.h" +#include "SkReadBuffer.h" +#include "SkSpecialImage.h" +#include "SkSpecialSurface.h" +#include "SkWriteBuffer.h" +#include "SkValidationUtils.h" + +sk_sp<SkImageFilter> SkMergeImageFilter::Make(sk_sp<SkImageFilter>* const filters, int count, + const CropRect* cropRect) { + return sk_sp<SkImageFilter>(new SkMergeImageFilter(filters, count, cropRect)); +} + +/////////////////////////////////////////////////////////////////////////////// + +SkMergeImageFilter::SkMergeImageFilter(sk_sp<SkImageFilter>* const filters, int count, + const CropRect* cropRect) + : INHERITED(filters, count, cropRect) { + SkASSERT(count >= 0); +} + +sk_sp<SkSpecialImage> SkMergeImageFilter::onFilterImage(SkSpecialImage* source, const Context& ctx, + SkIPoint* offset) const { + int inputCount = this->countInputs(); + if (inputCount < 1) { + return nullptr; + } + + SkIRect bounds; + bounds.setEmpty(); + + std::unique_ptr<sk_sp<SkSpecialImage>[]> inputs(new sk_sp<SkSpecialImage>[inputCount]); + std::unique_ptr<SkIPoint[]> offsets(new SkIPoint[inputCount]); + + // Filter all of the inputs. + for (int i = 0; i < inputCount; ++i) { + offsets[i] = { 0, 0 }; + inputs[i] = this->filterInput(i, source, ctx, &offsets[i]); + if (!inputs[i]) { + continue; + } + const SkIRect inputBounds = SkIRect::MakeXYWH(offsets[i].fX, offsets[i].fY, + inputs[i]->width(), inputs[i]->height()); + bounds.join(inputBounds); + } + if (bounds.isEmpty()) { + return nullptr; + } + + // Apply the crop rect to the union of the inputs' bounds. + // Note that the crop rect can only reduce the bounds, since this + // filter does not affect transparent black. + bool embiggen = false; + this->getCropRect().applyTo(bounds, ctx.ctm(), embiggen, &bounds); + if (!bounds.intersect(ctx.clipBounds())) { + return nullptr; + } + + const int x0 = bounds.left(); + const int y0 = bounds.top(); + + sk_sp<SkSpecialSurface> surf(source->makeSurface(ctx.outputProperties(), bounds.size())); + if (!surf) { + return nullptr; + } + + SkCanvas* canvas = surf->getCanvas(); + SkASSERT(canvas); + + canvas->clear(0x0); + + // Composite all of the filter inputs. + for (int i = 0; i < inputCount; ++i) { + if (!inputs[i]) { + continue; + } + + inputs[i]->draw(canvas, + SkIntToScalar(offsets[i].x() - x0), SkIntToScalar(offsets[i].y() - y0), + nullptr); + } + + offset->fX = bounds.left(); + offset->fY = bounds.top(); + return surf->makeImageSnapshot(); +} + +sk_sp<SkImageFilter> SkMergeImageFilter::onMakeColorSpace(SkColorSpaceXformer* xformer) const { + SkSTArray<5, sk_sp<SkImageFilter>> inputs(this->countInputs()); + bool changed = false; + for (int i = 0; i < this->countInputs(); i++) { + inputs.push_back(xformer->apply(this->getInput(i))); + changed |= (inputs[i].get() != this->getInput(i)); + } + + if (changed) { + return SkMergeImageFilter::Make(inputs.begin(), this->countInputs(), + this->getCropRectIfSet()); + } + return this->refMe(); +} + +sk_sp<SkFlattenable> SkMergeImageFilter::CreateProc(SkReadBuffer& buffer) { + Common common; + if (!common.unflatten(buffer, -1) || !buffer.isValid()) { + return nullptr; + } + return Make(common.inputs(), common.inputCount(), &common.cropRect()); +} + +void SkMergeImageFilter::flatten(SkWriteBuffer& buffer) const { + this->INHERITED::flatten(buffer); +} + |