void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsContext*& context, unsigned short resourceMode, const Path*) { ASSERT(object); ASSERT(context); #ifndef NDEBUG ASSERT(resourceMode == ApplyToDefaultMode); #else UNUSED_PARAM(resourceMode); #endif if (!m_filter.contains(object)) return; FilterData* filterData = m_filter.get(object); if (!filterData->builded) { if (!filterData->savedContext) { removeClientFromCache(object); return; } context = filterData->savedContext; filterData->savedContext = 0; #if !PLATFORM(CG) if (filterData->sourceGraphicBuffer) filterData->sourceGraphicBuffer->transformColorSpace(ColorSpaceDeviceRGB, ColorSpaceLinearRGB); #endif } FilterEffect* lastEffect = filterData->builder->lastEffect(); if (lastEffect && !filterData->boundaries.isEmpty() && !lastEffect->filterPrimitiveSubregion().isEmpty()) { // This is the real filtering of the object. It just needs to be called on the // initial filtering process. We just take the stored filter result on a // second drawing. if (!filterData->builded) { filterData->filter->setSourceImage(filterData->sourceGraphicBuffer.release()); lastEffect->apply(); #if !PLATFORM(CG) ImageBuffer* resultImage = lastEffect->asImageBuffer(); if (resultImage) resultImage->transformColorSpace(ColorSpaceLinearRGB, ColorSpaceDeviceRGB); #endif filterData->builded = true; } ImageBuffer* resultImage = lastEffect->asImageBuffer(); if (resultImage) { context->concatCTM(filterData->shearFreeAbsoluteTransform.inverse()); context->scale(FloatSize(1 / filterData->filter->filterResolution().width(), 1 / filterData->filter->filterResolution().height())); context->clip(lastEffect->maxEffectRect()); context->drawImageBuffer(resultImage, object->style()->colorSpace(), lastEffect->absolutePaintRect()); context->scale(filterData->filter->filterResolution()); context->concatCTM(filterData->shearFreeAbsoluteTransform); } } filterData->sourceGraphicBuffer.clear(); }
void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsContext*& context, unsigned short resourceMode) { ASSERT(object); ASSERT(context); #ifndef NDEBUG ASSERT(resourceMode == ApplyToDefaultMode); #else UNUSED_PARAM(resourceMode); #endif if (!m_filter.contains(object)) return; FilterData* filterData = m_filter.get(object); if (!filterData->builded) { if (!filterData->savedContext) { removeClientFromCache(object); return; } context = filterData->savedContext; filterData->savedContext = 0; #if !PLATFORM(CG) filterData->sourceGraphicBuffer->transformColorSpace(DeviceRGB, LinearRGB); #endif } FilterEffect* lastEffect = filterData->builder->lastEffect(); if (lastEffect && !filterData->boundaries.isEmpty() && !lastEffect->subRegion().isEmpty()) { // This is the real filtering of the object. It just needs to be called on the // initial filtering process. We just take the stored filter result on a // second drawing. if (!filterData->builded) { filterData->filter->setSourceImage(filterData->sourceGraphicBuffer.release()); lastEffect->apply(filterData->filter.get()); #if !PLATFORM(CG) ImageBuffer* resultImage = lastEffect->resultImage(); if (resultImage) resultImage->transformColorSpace(LinearRGB, DeviceRGB); #endif filterData->builded = true; } ImageBuffer* resultImage = lastEffect->resultImage(); if (resultImage) context->drawImageBuffer(resultImage, object->style()->colorSpace(), lastEffect->subRegion()); } filterData->sourceGraphicBuffer.clear(); }
void RenderSVGResourceFilter::postApplyResource(RenderElement& renderer, GraphicsContext*& context, unsigned short resourceMode, const Path*, const RenderSVGShape*) { ASSERT(context); ASSERT_UNUSED(resourceMode, resourceMode == ApplyToDefaultMode); FilterData* filterData = m_filter.get(&renderer); if (!filterData) return; switch (filterData->state) { case FilterData::MarkedForRemoval: m_filter.remove(&renderer); return; case FilterData::CycleDetected: case FilterData::Applying: // We have a cycle if we are already applying the data. // This can occur due to FeImage referencing a source that makes use of the FEImage itself. // This is the first place we've hit the cycle, so set the state back to PaintingSource so the return stack // will continue correctly. filterData->state = FilterData::PaintingSource; return; case FilterData::PaintingSource: if (!filterData->savedContext) { removeClientFromCache(renderer); return; } context = filterData->savedContext; filterData->savedContext = 0; break; case FilterData::Built: { } // Empty } FilterEffect* lastEffect = filterData->builder->lastEffect(); if (lastEffect && !filterData->boundaries.isEmpty() && !lastEffect->filterPrimitiveSubregion().isEmpty()) { // This is the real filtering of the object. It just needs to be called on the // initial filtering process. We just take the stored filter result on a // second drawing. if (filterData->state != FilterData::Built) filterData->filter->setSourceImage(WTF::move(filterData->sourceGraphicBuffer)); // Always true if filterData is just built (filterData->state == FilterData::Built). if (!lastEffect->hasResult()) { filterData->state = FilterData::Applying; lastEffect->applyAll(); lastEffect->correctFilterResultIfNeeded(); lastEffect->transformResultColorSpace(ColorSpaceDeviceRGB); } filterData->state = FilterData::Built; ImageBuffer* resultImage = lastEffect->asImageBuffer(); if (resultImage) { context->concatCTM(filterData->shearFreeAbsoluteTransform.inverse()); context->scale(FloatSize(1 / filterData->filter->filterResolution().width(), 1 / filterData->filter->filterResolution().height())); context->drawImageBuffer(resultImage, renderer.style().colorSpace(), lastEffect->absolutePaintRect()); context->scale(filterData->filter->filterResolution()); context->concatCTM(filterData->shearFreeAbsoluteTransform); } } filterData->sourceGraphicBuffer.reset(); }
void RenderSVGResourceContainer::removeClient(RenderObject* client) { ASSERT(client); removeClientFromCache(client, false); m_clients.remove(client); }
void LayoutSVGResourceContainer::removeClient(LayoutObject* client) { ASSERT(client); removeClientFromCache(client, false); m_clients.remove(client); }
void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsContext*& context, unsigned short resourceMode, const Path*, const RenderSVGShape*) { ASSERT(object); ASSERT(context); ASSERT_UNUSED(resourceMode, resourceMode == ApplyToDefaultMode); FilterData* filterData = m_filter.get(object); if (!filterData) return; if (filterData->markedForRemoval) { delete m_filter.take(object); return; } // We have a cycle if we are already applying the data. // This can occur due to FeImage referencing a source that makes use of the FEImage itself. if (filterData->isApplying) return; if (!filterData->isBuilt) { if (!filterData->savedContext) { removeClientFromCache(object); return; } context = filterData->savedContext; filterData->savedContext = 0; } ApplyingFilterEffectGuard isApplyingGuard(filterData); FilterEffect* lastEffect = filterData->builder->lastEffect(); if (lastEffect && !filterData->boundaries.isEmpty() && !lastEffect->filterPrimitiveSubregion().isEmpty()) { // This is the real filtering of the object. It just needs to be called on the // initial filtering process. We just take the stored filter result on a // second drawing. if (!filterData->isBuilt) filterData->filter->setSourceImage(filterData->sourceGraphicBuffer.release()); // Always true if filterData is just built (filterData->isBuilt is false). if (!lastEffect->hasResult()) { lastEffect->apply(); lastEffect->correctFilterResultIfNeeded(); #if !USE(CG) ImageBuffer* resultImage = lastEffect->asImageBuffer(); if (resultImage) resultImage->transformColorSpace(lastEffect->colorSpace(), ColorSpaceDeviceRGB); #endif } filterData->isBuilt = true; ImageBuffer* resultImage = lastEffect->asImageBuffer(); if (resultImage) { context->concatCTM(filterData->shearFreeAbsoluteTransform.inverse()); context->scale(FloatSize(1 / filterData->filter->filterResolution().width(), 1 / filterData->filter->filterResolution().height())); context->drawImageBuffer(resultImage, object->style()->colorSpace(), lastEffect->absolutePaintRect()); context->scale(filterData->filter->filterResolution()); context->concatCTM(filterData->shearFreeAbsoluteTransform); } } filterData->sourceGraphicBuffer.clear(); }