aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/effects/imagefilters/SkMergeImageFilter.cpp
diff options
context:
space:
mode:
authorGravatar Mike Reed <reed@google.com>2018-06-19 10:17:30 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-06-19 20:16:38 +0000
commit0917fad2c6339b6452e6eb58d4a8485d291d8d43 (patch)
treea277034a104bf9617dedda3cc5114353d86fe6a0 /src/effects/imagefilters/SkMergeImageFilter.cpp
parent386d9cf40278bb026ebfbbc6077144c2d8ed4dd2 (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.cpp124
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);
+}
+