aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/effects/SkMergeImageFilter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/effects/SkMergeImageFilter.cpp')
-rwxr-xr-xsrc/effects/SkMergeImageFilter.cpp60
1 files changed, 39 insertions, 21 deletions
diff --git a/src/effects/SkMergeImageFilter.cpp b/src/effects/SkMergeImageFilter.cpp
index d6f0eaa794..2ae8b35cd0 100755
--- a/src/effects/SkMergeImageFilter.cpp
+++ b/src/effects/SkMergeImageFilter.cpp
@@ -15,7 +15,7 @@
///////////////////////////////////////////////////////////////////////////////
void SkMergeImageFilter::initAllocModes() {
- int inputCount = countInputs();
+ int inputCount = this->countInputs();
if (inputCount) {
size_t size = sizeof(uint8_t) * inputCount;
if (size <= sizeof(fStorage)) {
@@ -31,7 +31,7 @@ void SkMergeImageFilter::initAllocModes() {
void SkMergeImageFilter::initModes(const SkXfermode::Mode modes[]) {
if (modes) {
this->initAllocModes();
- int inputCount = countInputs();
+ int inputCount = this->countInputs();
for (int i = 0; i < inputCount; ++i) {
fModes[i] = SkToU8(modes[i]);
}
@@ -58,46 +58,64 @@ SkMergeImageFilter::~SkMergeImageFilter() {
bool SkMergeImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src,
const Context& ctx,
SkBitmap* result, SkIPoint* offset) const {
- if (countInputs() < 1) {
+ int inputCount = this->countInputs();
+ if (inputCount < 1) {
return false;
}
SkIRect bounds;
- if (!this->applyCropRect(ctx, src, SkIPoint::Make(0, 0), &bounds)) {
+
+ SkAutoTDeleteArray<SkBitmap> inputs(new SkBitmap[inputCount]);
+ SkAutoTDeleteArray<SkIPoint> offsets(new SkIPoint[inputCount]);
+ bool didProduceResult = false;
+
+ // Filter all of the inputs.
+ for (int i = 0; i < inputCount; ++i) {
+ inputs[i] = src;
+ offsets[i].setZero();
+ if (!this->filterInput(i, proxy, src, ctx, &inputs[i], &offsets[i])) {
+ inputs[i].reset();
+ continue;
+ }
+ SkIRect srcBounds;
+ inputs[i].getBounds(&srcBounds);
+ srcBounds.offset(offsets[i]);
+ if (!didProduceResult) {
+ bounds = srcBounds;
+ didProduceResult = true;
+ } else {
+ bounds.join(srcBounds);
+ }
+ }
+ if (!didProduceResult) {
+ return false;
+ }
+
+ // Apply the crop rect to the union of the inputs' bounds.
+ if (!this->getCropRect().applyTo(bounds, ctx, &bounds)) {
return false;
}
const int x0 = bounds.left();
const int y0 = bounds.top();
+ // Allocate the destination buffer.
SkAutoTUnref<SkBaseDevice> dst(proxy->createDevice(bounds.width(), bounds.height()));
if (nullptr == dst) {
return false;
}
SkCanvas canvas(dst);
- SkPaint paint;
- bool didProduceResult = false;
- int inputCount = countInputs();
+ // Composite all of the filter inputs.
for (int i = 0; i < inputCount; ++i) {
- SkBitmap tmp;
- SkBitmap input = src;
- SkIPoint pos = SkIPoint::Make(0, 0);
- if (!this->filterInput(i, proxy, src, ctx, &input, &pos)) {
- continue;
- }
+ SkPaint paint;
if (fModes) {
paint.setXfermodeMode((SkXfermode::Mode)fModes[i]);
- } else {
- paint.setXfermode(nullptr);
}
- canvas.drawBitmap(input, SkIntToScalar(pos.x() - x0), SkIntToScalar(pos.y() - y0), &paint);
- didProduceResult = true;
+ canvas.drawBitmap(inputs[i], SkIntToScalar(offsets[i].x() - x0),
+ SkIntToScalar(offsets[i].y() - y0), &paint);
}
- if (!didProduceResult)
- return false;
-
offset->fX = bounds.left();
offset->fY = bounds.top();
*result = dst->accessBitmap(false);
@@ -134,7 +152,7 @@ void SkMergeImageFilter::flatten(SkWriteBuffer& buffer) const {
this->INHERITED::flatten(buffer);
buffer.writeBool(fModes != nullptr);
if (fModes) {
- buffer.writeByteArray(fModes, countInputs() * sizeof(fModes[0]));
+ buffer.writeByteArray(fModes, this->countInputs() * sizeof(fModes[0]));
}
}