static PassRefPtr<FECustomFilter> createCustomFilterEffect(Filter* filter, Document* document, ValidatedCustomFilterOperation* operation) { CustomFilterGlobalContext* globalContext = document->renderView()->customFilterGlobalContext(); globalContext->prepareContextIfNeeded(document->view()->hostWindow()); if (!globalContext->context()) return 0; return FECustomFilter::create(filter, globalContext->context(), operation->validatedProgram(), operation->parameters(), operation->meshRows(), operation->meshColumns(), operation->meshType()); }
static PassRefPtr<FECustomFilter> createCustomFilterEffect(Filter* filter, Document* document, CustomFilterOperation* operation) { if (!isCSSCustomFilterEnabled(document)) return 0; RefPtr<CustomFilterProgram> program = operation->program(); if (!program->isLoaded()) return 0; CustomFilterGlobalContext* globalContext = document->renderView()->customFilterGlobalContext(); globalContext->prepareContextIfNeeded(document->view()->hostWindow()); RefPtr<CustomFilterValidatedProgram> validatedProgram = globalContext->getValidatedProgram(program->programInfo()); if (!validatedProgram->isInitialized()) return 0; return FECustomFilter::create(filter, globalContext, validatedProgram, operation->parameters(), operation->meshRows(), operation->meshColumns(), operation->meshBoxType(), operation->meshType()); }
bool FilterEffectRenderer::build(Document* document, const FilterOperations& operations) { #if !ENABLE(CSS_SHADERS) || !ENABLE(WEBGL) UNUSED_PARAM(document); #endif #if ENABLE(CSS_SHADERS) m_hasCustomShaderFilter = false; #endif m_hasFilterThatMovesPixels = operations.hasFilterThatMovesPixels(); if (m_hasFilterThatMovesPixels) operations.getOutsets(m_topOutset, m_rightOutset, m_bottomOutset, m_leftOutset); m_effects.clear(); RefPtr<FilterEffect> previousEffect; for (size_t i = 0; i < operations.operations().size(); ++i) { RefPtr<FilterEffect> effect; FilterOperation* filterOperation = operations.operations().at(i).get(); switch (filterOperation->getOperationType()) { case FilterOperation::REFERENCE: { // FIXME: Not yet implemented. // https://bugs.webkit.org/show_bug.cgi?id=72443 break; } case FilterOperation::GRAYSCALE: { BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation); Vector<float> inputParameters; double oneMinusAmount = clampTo(1 - colorMatrixOperation->amount(), 0.0, 1.0); // See https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#grayscaleEquivalent // for information on parameters. inputParameters.append(narrowPrecisionToFloat(0.2126 + 0.7874 * oneMinusAmount)); inputParameters.append(narrowPrecisionToFloat(0.7152 - 0.7152 * oneMinusAmount)); inputParameters.append(narrowPrecisionToFloat(0.0722 - 0.0722 * oneMinusAmount)); endMatrixRow(inputParameters); inputParameters.append(narrowPrecisionToFloat(0.2126 - 0.2126 * oneMinusAmount)); inputParameters.append(narrowPrecisionToFloat(0.7152 + 0.2848 * oneMinusAmount)); inputParameters.append(narrowPrecisionToFloat(0.0722 - 0.0722 * oneMinusAmount)); endMatrixRow(inputParameters); inputParameters.append(narrowPrecisionToFloat(0.2126 - 0.2126 * oneMinusAmount)); inputParameters.append(narrowPrecisionToFloat(0.7152 - 0.7152 * oneMinusAmount)); inputParameters.append(narrowPrecisionToFloat(0.0722 + 0.9278 * oneMinusAmount)); endMatrixRow(inputParameters); lastMatrixRow(inputParameters); effect = FEColorMatrix::create(this, FECOLORMATRIX_TYPE_MATRIX, inputParameters); break; } case FilterOperation::SEPIA: { BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation); Vector<float> inputParameters; double oneMinusAmount = clampTo(1 - colorMatrixOperation->amount(), 0.0, 1.0); // See https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#sepiaEquivalent // for information on parameters. inputParameters.append(narrowPrecisionToFloat(0.393 + 0.607 * oneMinusAmount)); inputParameters.append(narrowPrecisionToFloat(0.769 - 0.769 * oneMinusAmount)); inputParameters.append(narrowPrecisionToFloat(0.189 - 0.189 * oneMinusAmount)); endMatrixRow(inputParameters); inputParameters.append(narrowPrecisionToFloat(0.349 - 0.349 * oneMinusAmount)); inputParameters.append(narrowPrecisionToFloat(0.686 + 0.314 * oneMinusAmount)); inputParameters.append(narrowPrecisionToFloat(0.168 - 0.168 * oneMinusAmount)); endMatrixRow(inputParameters); inputParameters.append(narrowPrecisionToFloat(0.272 - 0.272 * oneMinusAmount)); inputParameters.append(narrowPrecisionToFloat(0.534 - 0.534 * oneMinusAmount)); inputParameters.append(narrowPrecisionToFloat(0.131 + 0.869 * oneMinusAmount)); endMatrixRow(inputParameters); lastMatrixRow(inputParameters); effect = FEColorMatrix::create(this, FECOLORMATRIX_TYPE_MATRIX, inputParameters); break; } case FilterOperation::SATURATE: { BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation); Vector<float> inputParameters; inputParameters.append(narrowPrecisionToFloat(colorMatrixOperation->amount())); effect = FEColorMatrix::create(this, FECOLORMATRIX_TYPE_SATURATE, inputParameters); break; } case FilterOperation::HUE_ROTATE: { BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation); Vector<float> inputParameters; inputParameters.append(narrowPrecisionToFloat(colorMatrixOperation->amount())); effect = FEColorMatrix::create(this, FECOLORMATRIX_TYPE_HUEROTATE, inputParameters); break; } case FilterOperation::INVERT: { BasicComponentTransferFilterOperation* componentTransferOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation); ComponentTransferFunction transferFunction; transferFunction.type = FECOMPONENTTRANSFER_TYPE_TABLE; Vector<float> transferParameters; transferParameters.append(narrowPrecisionToFloat(componentTransferOperation->amount())); transferParameters.append(narrowPrecisionToFloat(1 - componentTransferOperation->amount())); transferFunction.tableValues = transferParameters; ComponentTransferFunction nullFunction; effect = FEComponentTransfer::create(this, transferFunction, transferFunction, transferFunction, nullFunction); break; } case FilterOperation::OPACITY: { BasicComponentTransferFilterOperation* componentTransferOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation); ComponentTransferFunction transferFunction; transferFunction.type = FECOMPONENTTRANSFER_TYPE_TABLE; Vector<float> transferParameters; transferParameters.append(0); transferParameters.append(narrowPrecisionToFloat(componentTransferOperation->amount())); transferFunction.tableValues = transferParameters; ComponentTransferFunction nullFunction; effect = FEComponentTransfer::create(this, nullFunction, nullFunction, nullFunction, transferFunction); break; } case FilterOperation::BRIGHTNESS: { BasicComponentTransferFilterOperation* componentTransferOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation); ComponentTransferFunction transferFunction; transferFunction.type = FECOMPONENTTRANSFER_TYPE_LINEAR; transferFunction.slope = 1; transferFunction.intercept = narrowPrecisionToFloat(componentTransferOperation->amount()); ComponentTransferFunction nullFunction; effect = FEComponentTransfer::create(this, transferFunction, transferFunction, transferFunction, nullFunction); break; } case FilterOperation::CONTRAST: { BasicComponentTransferFilterOperation* componentTransferOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation); ComponentTransferFunction transferFunction; transferFunction.type = FECOMPONENTTRANSFER_TYPE_LINEAR; float amount = narrowPrecisionToFloat(componentTransferOperation->amount()); transferFunction.slope = amount; transferFunction.intercept = -0.5 * amount + 0.5; ComponentTransferFunction nullFunction; effect = FEComponentTransfer::create(this, transferFunction, transferFunction, transferFunction, nullFunction); break; } case FilterOperation::BLUR: { BlurFilterOperation* blurOperation = static_cast<BlurFilterOperation*>(filterOperation); float stdDeviation = floatValueForLength(blurOperation->stdDeviation(), 0); effect = FEGaussianBlur::create(this, stdDeviation, stdDeviation); break; } case FilterOperation::DROP_SHADOW: { DropShadowFilterOperation* dropShadowOperation = static_cast<DropShadowFilterOperation*>(filterOperation); effect = FEDropShadow::create(this, dropShadowOperation->stdDeviation(), dropShadowOperation->stdDeviation(), dropShadowOperation->x(), dropShadowOperation->y(), dropShadowOperation->color(), 1); break; } #if ENABLE(CSS_SHADERS) case FilterOperation::CUSTOM: { #if ENABLE(WEBGL) if (!isCSSCustomFilterEnabled(document)) continue; CustomFilterOperation* customFilterOperation = static_cast<CustomFilterOperation*>(filterOperation); RefPtr<CustomFilterProgram> program = customFilterOperation->program(); if (program->isLoaded()) { CustomFilterGlobalContext* globalContext = document->renderView()->customFilterGlobalContext(); globalContext->prepareContextIfNeeded(document->view()->hostWindow()); effect = FECustomFilter::create(this, globalContext, program, customFilterOperation->parameters(), customFilterOperation->meshRows(), customFilterOperation->meshColumns(), customFilterOperation->meshBoxType(), customFilterOperation->meshType()); m_hasCustomShaderFilter = true; } #endif break; } #endif default: break; } if (effect) { // Unlike SVG, filters applied here should not clip to their primitive subregions. effect->setClipsToBounds(false); if (previousEffect) effect->inputEffects().append(previousEffect); m_effects.append(effect); previousEffect = effect.release(); } } // If we didn't make any effects, tell our caller we are not valid if (!previousEffect) return false; m_effects.first()->inputEffects().append(m_sourceGraphic); setMaxEffectRects(m_sourceDrawingRegion); return true; }