bool SkMergeImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
                                        SkIRect* dst) {
    if (countInputs() < 1) {
        return false;
    }

    SkIRect totalBounds;

    int inputCount = countInputs();
    for (int i = 0; i < inputCount; ++i) {
        SkImageFilter* filter = getInput(i);
        SkIRect r;
        if (filter) {
            if (!filter->filterBounds(src, ctm, &r)) {
                return false;
            }
        } else {
            r = src;
        }
        if (0 == i) {
            totalBounds = r;
        } else {
            totalBounds.join(r);
        }
    }

    // don't modify dst until now, so we don't accidentally change it in the
    // loop, but then return false on the next filter.
    *dst = totalBounds;
    return true;
}
Example #2
0
bool SkMergeImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src,
                                       const Context& ctx,
                                       SkBitmap* result, SkIPoint* offset) const {
    if (countInputs() < 1) {
        return false;
    }

    SkIRect bounds;
    if (!this->applyCropRect(ctx, src, SkIPoint::Make(0, 0), &bounds)) {
        return false;
    }

    const int x0 = bounds.left();
    const int y0 = bounds.top();

    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();
    for (int i = 0; i < inputCount; ++i) {
        SkBitmap tmp;
        const SkBitmap* srcPtr;
        SkIPoint pos = SkIPoint::Make(0, 0);
        SkImageFilter* filter = getInput(i);
        if (filter) {
            if (!filter->filterImage(proxy, src, ctx, &tmp, &pos)) {
                continue;
            }
            srcPtr = &tmp;
        } else {
            srcPtr = &src;
        }

        if (fModes) {
            paint.setXfermodeMode((SkXfermode::Mode)fModes[i]);
        } else {
            paint.setXfermode(nullptr);
        }
        canvas.drawSprite(*srcPtr, pos.x() - x0, pos.y() - y0, &paint);
        didProduceResult = true;
    }

    if (!didProduceResult)
        return false;

    offset->fX = bounds.left();
    offset->fY = bounds.top();
    *result = dst->accessBitmap(false);
    return true;
}
bool SkMergeImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src,
                                       const SkMatrix& ctm,
                                       SkBitmap* result, SkIPoint* loc) {
    if (countInputs() < 1) {
        return false;
    }

    const SkIRect srcBounds = SkIRect::MakeXYWH(loc->x(), loc->y(),
                                                src.width(), src.height());
    SkIRect bounds;
    if (!this->filterBounds(srcBounds, ctm, &bounds)) {
        return false;
    }

    const int x0 = bounds.left();
    const int y0 = bounds.top();

    SkAutoTUnref<SkDevice> dst(proxy->createDevice(bounds.width(), bounds.height()));
    if (NULL == dst) {
        return false;
    }
    SkCanvas canvas(dst);
    SkPaint paint;

    int inputCount = countInputs();
    for (int i = 0; i < inputCount; ++i) {
        SkBitmap tmp;
        const SkBitmap* srcPtr;
        SkIPoint pos = *loc;
        SkImageFilter* filter = getInput(i);
        if (filter) {
            if (!filter->filterImage(proxy, src, ctm, &tmp, &pos)) {
                return false;
            }
            srcPtr = &tmp;
        } else {
            srcPtr = &src;
        }

        if (fModes) {
            paint.setXfermodeMode((SkXfermode::Mode)fModes[i]);
        } else {
            paint.setXfermode(NULL);
        }
        canvas.drawSprite(*srcPtr, pos.x() - x0, pos.y() - y0, &paint);
    }

    loc->set(bounds.left(), bounds.top());
    *result = dst->accessBitmap(false);
    return true;
}
Example #4
0
void SkMergeImageFilter::flatten(SkWriteBuffer& buffer) const {
    this->INHERITED::flatten(buffer);
    buffer.writeBool(fModes != NULL);
    if (fModes) {
        buffer.writeByteArray(fModes, countInputs() * sizeof(fModes[0]));
    }
}
SkMergeImageFilter::SkMergeImageFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {
    bool hasModes = buffer.readBool();
    if (hasModes) {
        this->initAllocModes();
        SkASSERT(buffer.getArrayCount() == countInputs() * sizeof(fModes[0]));
        buffer.readByteArray(fModes);
    } else {
        fModes = 0;
    }
}
void SkMergeImageFilter::initModes(const SkXfermode::Mode modes[]) {
    if (modes) {
        this->initAllocModes();
        int inputCount = countInputs();
        for (int i = 0; i < inputCount; ++i) {
            fModes[i] = SkToU8(modes[i]);
        }
    } else {
        fModes = NULL;
    }
}
void SkMergeImageFilter::initAllocModes() {
    int inputCount = countInputs();
    if (inputCount) {
        size_t size = sizeof(uint8_t) * inputCount;
        if (size <= sizeof(fStorage)) {
            fModes = SkTCast<uint8_t*>(fStorage);
        } else {
            fModes = SkTCast<uint8_t*>(sk_malloc_throw(size));
        }
    } else {
        fModes = NULL;
    }
}
Example #8
0
SkMergeImageFilter::SkMergeImageFilter(SkReadBuffer& buffer)
  : INHERITED(-1, buffer) {
    bool hasModes = buffer.readBool();
    if (hasModes) {
        this->initAllocModes();
        int nbInputs = countInputs();
        size_t size = nbInputs * sizeof(fModes[0]);
        SkASSERT(buffer.getArrayCount() == size);
        if (buffer.validate(buffer.getArrayCount() == size) &&
            buffer.readByteArray(fModes, size)) {
            for (int i = 0; i < nbInputs; ++i) {
                buffer.validate(SkIsValidMode((SkXfermode::Mode)fModes[i]));
            }
        }
    } else {
        fModes = 0;
    }
}