15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org> 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2005 Eric Seidel <eric@webkit.org> 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2010 Dirk Schulze <krit@webkit.org> 653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Copyright (C) 2013 Google Inc. All rights reserved. 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version. 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful, 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details. 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB. If not, write to 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA. 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/svg/graphics/filters/SVGFEImage.h" 2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 2893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "SkBitmapSource.h" 2909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "SkPictureImageFilter.h" 3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderObject.h" 3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/svg/SVGRenderingContext.h" 32f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#include "core/svg/SVGElement.h" 3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/svg/SVGURIReference.h" 3409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "platform/graphics/DisplayList.h" 35a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/GraphicsContext.h" 36a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/filters/Filter.h" 3709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "platform/graphics/filters/SkiaImageFilterBuilder.h" 381e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/text/TextStream.h" 391e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/transforms/AffineTransform.h" 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 41c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)FEImage::FEImage(Filter* filter, PassRefPtr<Image> image, PassRefPtr<SVGPreserveAspectRatio> preserveAspectRatio) 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : FilterEffect(filter) 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_image(image) 4610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch , m_treeScope(0) 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_preserveAspectRatio(preserveAspectRatio) 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5110f88d5669dbd969c059d61ba09fa37dd72ac559Ben MurdochFEImage::FEImage(Filter* filter, TreeScope& treeScope, const String& href, PassRefPtr<SVGPreserveAspectRatio> preserveAspectRatio) 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : FilterEffect(filter) 5310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch , m_treeScope(&treeScope) 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_href(href) 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_preserveAspectRatio(preserveAspectRatio) 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)PassRefPtr<FEImage> FEImage::createWithImage(Filter* filter, PassRefPtr<Image> image, PassRefPtr<SVGPreserveAspectRatio> preserveAspectRatio) 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return adoptRef(new FEImage(filter, image, preserveAspectRatio)); 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6410f88d5669dbd969c059d61ba09fa37dd72ac559Ben MurdochPassRefPtr<FEImage> FEImage::createWithIRIReference(Filter* filter, TreeScope& treeScope, const String& href, PassRefPtr<SVGPreserveAspectRatio> preserveAspectRatio) 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 6610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch return adoptRef(new FEImage(filter, treeScope, href, preserveAspectRatio)); 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)static FloatRect getRendererRepaintRect(RenderObject* renderer) 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 7109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return renderer->localToParentTransform().mapRect( 725d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) renderer->paintInvalidationRectInLocalCoordinates()); 7309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciAffineTransform makeMapBetweenRects(const FloatRect& source, const FloatRect& dest) 767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 777242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci AffineTransform transform; 787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci transform.translate(dest.x() - source.x(), dest.y() - source.y()); 797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci transform.scale(dest.width() / source.width(), dest.height() / source.height()); 807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return transform; 817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 8309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)FloatRect FEImage::determineAbsolutePaintRect(const FloatRect& originalRequestedRect) 8409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){ 8509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) RenderObject* renderer = referencedRenderer(); 8609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (!m_image && !renderer) 8709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return FloatRect(); 8809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 8909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) FloatRect requestedRect = originalRequestedRect; 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (clipsToBounds()) 9109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) requestedRect.intersect(maxEffectRect()); 9209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 9309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) FloatRect destRect = filter()->mapLocalRectToAbsoluteRect(filterPrimitiveSubregion()); 9409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) FloatRect srcRect; 9509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (renderer) { 9609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) srcRect = getRendererRepaintRect(renderer); 9709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) SVGElement* contextNode = toSVGElement(renderer->node()); 9809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 9909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (contextNode->hasRelativeLengths()) { 10009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // FIXME: This fixes relative lengths but breaks non-relative ones (see crbug/260709). 10109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) SVGLengthContext lengthContext(contextNode); 10209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) FloatSize viewportSize; 10309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (lengthContext.determineViewport(viewportSize)) { 10409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) srcRect = makeMapBetweenRects(FloatRect(FloatPoint(), viewportSize), destRect).mapRect(srcRect); 10509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 10609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } else { 10709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) srcRect = filter()->mapLocalRectToAbsoluteRect(srcRect); 10809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) srcRect.move(destRect.x(), destRect.y()); 10909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 11009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) destRect.intersect(srcRect); 11109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } else { 11209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) srcRect = FloatRect(FloatPoint(), m_image->size()); 11309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) m_preserveAspectRatio->transformRect(destRect, srcRect); 11409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 11509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 11609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) destRect.intersect(requestedRect); 11709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) addAbsolutePaintRect(destRect); 11809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return destRect; 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderObject* FEImage::referencedRenderer() const 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 12310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch if (!m_treeScope) 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 12510f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch Element* hrefElement = SVGURIReference::targetElementFromIRIString(m_href, *m_treeScope); 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!hrefElement || !hrefElement->isSVGElement()) 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return hrefElement->renderer(); 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void FEImage::applySoftware() 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderObject* renderer = referencedRenderer(); 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_image && !renderer) 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ImageBuffer* resultImage = createImageBufferResult(); 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!resultImage) 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntPoint paintLocation = absolutePaintRect().location(); 14109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) resultImage->context()->translate(-paintLocation.x(), -paintLocation.y()); 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 143926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // FEImage results are always in ColorSpaceDeviceRGB 144926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) setResultColorSpace(ColorSpaceDeviceRGB); 145926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 14609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) FloatRect destRect = filter()->mapLocalRectToAbsoluteRect(filterPrimitiveSubregion()); 14709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) FloatRect srcRect; 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (!renderer) { 15009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) srcRect = FloatRect(FloatPoint(), m_image->size()); 15109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) m_preserveAspectRatio->transformRect(destRect, srcRect); 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) resultImage->context()->drawImage(m_image.get(), destRect, srcRect); 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) SVGElement* contextNode = toSVGElement(renderer->node()); 15809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (contextNode->hasRelativeLengths()) { 15909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // FIXME: This fixes relative lengths but breaks non-relative ones (see crbug/260709). 16009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) SVGLengthContext lengthContext(contextNode); 16109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) FloatSize viewportSize; 16209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 16309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // If we're referencing an element with percentage units, eg. <rect with="30%"> those values were resolved against the viewport. 16409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // Build up a transformation that maps from the viewport space to the filter primitive subregion. 16509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (lengthContext.determineViewport(viewportSize)) 16609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) resultImage->context()->concatCTM(makeMapBetweenRects(FloatRect(FloatPoint(), viewportSize), destRect)); 16709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } else { 16809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) resultImage->context()->translate(destRect.x(), destRect.y()); 16909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) resultImage->context()->concatCTM(filter()->absoluteTransform()); 17009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 17109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 17209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) AffineTransform contentTransformation; 17309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) SVGRenderingContext::renderSubtree(resultImage->context(), renderer, contentTransformation); 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TextStream& FEImage::externalRepresentation(TextStream& ts, int indent) const 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntSize imageSize; 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_image) 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) imageSize = m_image->size(); 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (RenderObject* renderer = referencedRenderer()) 18209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) imageSize = enclosingIntRect(getRendererRepaintRect(renderer)).size(); 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) writeIndent(ts, indent); 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ts << "[feImage"; 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FilterEffect::externalRepresentation(ts); 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ts << " image-size=\"" << imageSize.width() << "x" << imageSize.height() << "\"]\n"; 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: should this dump also object returned by SVGFEImage::image() ? 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return ts; 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 19109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)PassRefPtr<SkImageFilter> FEImage::createImageFilterForRenderer(RenderObject* renderer, SkiaImageFilterBuilder* builder) 19209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){ 19309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) FloatRect dstRect = filterPrimitiveSubregion(); 19409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 19509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) AffineTransform transform; 19609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) SVGElement* contextNode = toSVGElement(renderer->node()); 19709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 19809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (contextNode->hasRelativeLengths()) { 19909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) SVGLengthContext lengthContext(contextNode); 20009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) FloatSize viewportSize; 20109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 20209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // If we're referencing an element with percentage units, eg. <rect with="30%"> those values were resolved against the viewport. 20309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // Build up a transformation that maps from the viewport space to the filter primitive subregion. 20409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (lengthContext.determineViewport(viewportSize)) 20509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) transform = makeMapBetweenRects(FloatRect(FloatPoint(), viewportSize), dstRect); 20609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } else { 20709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) transform.translate(dstRect.x(), dstRect.y()); 20809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 20909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 21009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) GraphicsContext* context = builder->context(); 21109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (!context) 21210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch return adoptRef(SkBitmapSource::Create(SkBitmap())); 21309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) AffineTransform contentTransformation; 2147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci FloatRect bounds(FloatPoint(), dstRect.size()); 21509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) context->save(); 2167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci context->beginRecording(bounds); 21709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) context->concatCTM(transform); 21809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) SVGRenderingContext::renderSubtree(context, renderer, contentTransformation); 21909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) RefPtr<DisplayList> displayList = context->endRecording(); 22009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) context->restore(); 22110f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch RefPtr<SkImageFilter> result = adoptRef(SkPictureImageFilter::Create(displayList->picture(), dstRect)); 22209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return result.release(); 22309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 22409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 2253c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben MurdochPassRefPtr<SkImageFilter> FEImage::createImageFilter(SkiaImageFilterBuilder* builder) 22693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){ 22709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) RenderObject* renderer = referencedRenderer(); 22809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (!m_image && !renderer) 22910f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch return adoptRef(SkBitmapSource::Create(SkBitmap())); 23009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 23109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) setOperatingColorSpace(ColorSpaceDeviceRGB); 23209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 23309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (renderer) 23409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return createImageFilterForRenderer(renderer, builder); 23509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 23609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) FloatRect srcRect = FloatRect(FloatPoint(), m_image->size()); 23709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) FloatRect dstRect = filterPrimitiveSubregion(); 23809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 23909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // FIXME: CSS image filters currently do not seem to set filter primitive 24009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // subregion correctly if unspecified. So default to srcRect size if so. 24109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (dstRect.isEmpty()) 24209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) dstRect = srcRect; 24309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 24409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) m_preserveAspectRatio->transformRect(dstRect, srcRect); 24593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 24693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (!m_image->nativeImageForCurrentFrame()) 24710f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch return adoptRef(SkBitmapSource::Create(SkBitmap())); 24893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 24910f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch RefPtr<SkImageFilter> result = adoptRef(SkBitmapSource::Create(m_image->nativeImageForCurrentFrame()->bitmap(), srcRect, dstRect)); 25009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return result.release(); 25193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 253c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 254