Exemple #1
0
void FEComponentTransfer::apply()
{
    FilterEffect* in = inputEffect(0);
    in->apply();
    if (!in->resultImage())
        return;

    if (!effectContext())
        return;

    unsigned char rValues[256], gValues[256], bValues[256], aValues[256];
    for (unsigned i = 0; i < 256; ++i)
        rValues[i] = gValues[i] = bValues[i] = aValues[i] = i;
    unsigned char* tables[] = { rValues, gValues, bValues, aValues };
    ComponentTransferFunction transferFunction[] = {m_redFunc, m_greenFunc, m_blueFunc, m_alphaFunc};
    TransferType callEffect[] = {identity, identity, table, discrete, linear, gamma};

    for (unsigned channel = 0; channel < 4; channel++)
        (*callEffect[transferFunction[channel].type])(tables[channel], transferFunction[channel]);

    IntRect drawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
    RefPtr<ImageData> imageData = in->resultImage()->getUnmultipliedImageData(drawingRect);
    ByteArray* pixelArray = imageData->data()->data();

    unsigned pixelArrayLength = pixelArray->length();
    for (unsigned pixelOffset = 0; pixelOffset < pixelArrayLength; pixelOffset += 4) {
        for (unsigned channel = 0; channel < 4; ++channel) {
            unsigned char c = pixelArray->get(pixelOffset + channel);
            pixelArray->set(pixelOffset + channel, tables[channel][c]);
        }
    }

    resultImage()->putUnmultipliedImageData(imageData.get(), IntRect(IntPoint(), resultImage()->size()), IntPoint());
}
Exemple #2
0
void FEFlood::apply(Filter* filter)
{
    GraphicsContext* filterContext = effectContext(filter);
    if (!filterContext)
        return;

    Color color = colorWithOverrideAlpha(floodColor().rgb(), floodOpacity());
    filterContext->fillRect(FloatRect(FloatPoint(), absolutePaintRect().size()), color, DeviceColorSpace);
}
Exemple #3
0
void SourceAlpha::apply(Filter* filter)
{
    GraphicsContext* filterContext = effectContext(filter);
    if (!filterContext || !filter->sourceImage())
        return;

    setIsAlphaImage(true);

    FloatRect imageRect(FloatPoint(), absolutePaintRect().size());
    filterContext->save();
    filterContext->clipToImageBuffer(filter->sourceImage(), imageRect);
    filterContext->fillRect(imageRect, Color::black, DeviceColorSpace);
    filterContext->restore();
}
Exemple #4
0
void FEOffset::apply()
{
    FilterEffect* in = inputEffect(0);
    in->apply();
    if (!in->resultImage())
        return;

    GraphicsContext* filterContext = effectContext();
    if (!filterContext)
        return;

    setIsAlphaImage(in->isAlphaImage());

    FloatRect drawingRegion = drawingRegionOfInputImage(in->absolutePaintRect());
    Filter* filter = this->filter();
    drawingRegion.move(filter->applyHorizontalScale(m_dx), filter->applyVerticalScale(m_dy));
    filterContext->drawImageBuffer(in->resultImage(), ColorSpaceDeviceRGB, drawingRegion);
}
Exemple #5
0
void FEImage::apply(Filter* filter)
{
    if (!m_image.get())
        return;

    GraphicsContext* filterContext = effectContext(filter);
    if (!filterContext)
        return;

    FloatRect srcRect(FloatPoint(), m_image->size());
    FloatRect destRect(m_absoluteSubregion);
    m_preserveAspectRatio.transformRect(destRect, srcRect);

    IntPoint paintLocation = absolutePaintRect().location();
    destRect.move(-paintLocation.x(), -paintLocation.y());

    filterContext->drawImage(m_image.get(), DeviceColorSpace, destRect, srcRect);
}
Exemple #6
0
void FEBlend::apply(Filter* filter)
{
    FilterEffect* in = inputEffect(0);
    FilterEffect* in2 = inputEffect(1);
    in->apply(filter);
    in2->apply(filter);
    if (!in->resultImage() || !in2->resultImage())
        return;

    if (m_mode == FEBLEND_MODE_UNKNOWN)
        return;

    if (!effectContext(filter))
        return;

    IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
    RefPtr<CanvasPixelArray> srcPixelArrayA(in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data());

    IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->absolutePaintRect());
    RefPtr<CanvasPixelArray> srcPixelArrayB(in2->resultImage()->getPremultipliedImageData(effectBDrawingRect)->data());

    IntRect imageRect(IntPoint(), resultImage()->size());
    RefPtr<ImageData> imageData = ImageData::create(imageRect.width(), imageRect.height());

    // Keep synchronized with BlendModeType
    static const BlendType callEffect[] = {unknown, normal, multiply, screen, darken, lighten};

    ASSERT(srcPixelArrayA->length() == srcPixelArrayB->length());
    for (unsigned pixelOffset = 0; pixelOffset < srcPixelArrayA->length(); pixelOffset += 4) {
        unsigned char alphaA = srcPixelArrayA->get(pixelOffset + 3);
        unsigned char alphaB = srcPixelArrayB->get(pixelOffset + 3);
        for (unsigned channel = 0; channel < 3; ++channel) {
            unsigned char colorA = srcPixelArrayA->get(pixelOffset + channel);
            unsigned char colorB = srcPixelArrayB->get(pixelOffset + channel);

            unsigned char result = (*callEffect[m_mode])(colorA, colorB, alphaA, alphaB);
            imageData->data()->set(pixelOffset + channel, result);
        }
        unsigned char alphaR = 255 - ((255 - alphaA) * (255 - alphaB)) / 255;
        imageData->data()->set(pixelOffset + 3, alphaR);
    }

    resultImage()->putPremultipliedImageData(imageData.get(), imageRect, IntPoint());
}
Exemple #7
0
void FETile::apply()
{
// FIXME: See bug 47315. This is a hack to work around a compile failure, but is incorrect behavior otherwise.
#if ENABLE(SVG)
    FilterEffect* in = inputEffect(0);
    in->apply();
    if (!in->resultImage())
        return;

    GraphicsContext* filterContext = effectContext();
    if (!filterContext)
        return;

    setIsAlphaImage(in->isAlphaImage());

    // Source input needs more attention. It has the size of the filterRegion but gives the
    // size of the cutted sourceImage back. This is part of the specification and optimization.
    FloatRect tileRect = in->maxEffectRect();
    FloatPoint inMaxEffectLocation = tileRect.location();
    FloatPoint maxEffectLocation = maxEffectRect().location();
    if (in->filterEffectType() == FilterEffectTypeSourceInput) {
        Filter* filter = this->filter();
        tileRect = filter->filterRegion();
        tileRect.scale(filter->filterResolution().width(), filter->filterResolution().height());
    }

    OwnPtr<ImageBuffer> tileImage;
    if (!SVGImageBufferTools::createImageBuffer(tileRect, tileRect, tileImage, ColorSpaceDeviceRGB))
        return;

    GraphicsContext* tileImageContext = tileImage->context();
    tileImageContext->translate(-inMaxEffectLocation.x(), -inMaxEffectLocation.y());
    tileImageContext->drawImageBuffer(in->resultImage(), ColorSpaceDeviceRGB, in->absolutePaintRect().location());

    RefPtr<Pattern> pattern = Pattern::create(tileImage->copyImage(), true, true);

    AffineTransform patternTransform;
    patternTransform.translate(inMaxEffectLocation.x() - maxEffectLocation.x(), inMaxEffectLocation.y() - maxEffectLocation.y());
    pattern->setPatternSpaceTransform(patternTransform);
    filterContext->setFillPattern(pattern);
    filterContext->fillRect(FloatRect(FloatPoint(), absolutePaintRect().size()));
#endif
}
Exemple #8
0
void FEColorMatrix::apply()
{
    FilterEffect* in = inputEffect(0);
    in->apply();
    if (!in->resultImage())
        return;

    GraphicsContext* filterContext = effectContext();
    if (!filterContext)
        return;

    filterContext->drawImageBuffer(in->resultImage(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()));

    IntRect imageRect(IntPoint(), resultImage()->size());
    RefPtr<ImageData> imageData = resultImage()->getUnmultipliedImageData(imageRect);
    ByteArray* pixelArray = imageData->data()->data();

    switch (m_type) {
        case FECOLORMATRIX_TYPE_UNKNOWN:
            break;
        case FECOLORMATRIX_TYPE_MATRIX:
            effectType<FECOLORMATRIX_TYPE_MATRIX>(pixelArray, m_values);
            break;
        case FECOLORMATRIX_TYPE_SATURATE: 
            effectType<FECOLORMATRIX_TYPE_SATURATE>(pixelArray, m_values);
            break;
        case FECOLORMATRIX_TYPE_HUEROTATE:
            effectType<FECOLORMATRIX_TYPE_HUEROTATE>(pixelArray, m_values);
            break;
        case FECOLORMATRIX_TYPE_LUMINANCETOALPHA:
            effectType<FECOLORMATRIX_TYPE_LUMINANCETOALPHA>(pixelArray, m_values);
            setIsAlphaImage(true);
            break;
    }

    resultImage()->putUnmultipliedImageData(imageData.get(), imageRect, IntPoint());
}