| Index: src/effects/SkMergeImageFilter.cpp
|
| diff --git a/src/effects/SkMergeImageFilter.cpp b/src/effects/SkMergeImageFilter.cpp
|
| index d6f0eaa794bcacaa7801d993bb15fe3cece0e98b..2ae8b35cd023140f5fe62f74348f25e9281916cf 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]));
|
| }
|
| }
|
|
|
|
|