1 /* 2 * Copyright (C) 2008 Alex Mathews <possessedpenguinbob (at) gmail.com> 3 * Copyright (C) 2009 Dirk Schulze <krit (at) webkit.org> 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Library General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Library General Public License for more details. 14 * 15 * You should have received a copy of the GNU Library General Public License 16 * along with this library; see the file COPYING.LIB. If not, write to 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 * Boston, MA 02110-1301, USA. 19 */ 20 21 #include "config.h" 22 23 #if ENABLE(FILTERS) 24 #include "FETile.h" 25 26 #include "AffineTransform.h" 27 #include "Filter.h" 28 #include "GraphicsContext.h" 29 #include "Pattern.h" 30 #include "RenderTreeAsText.h" 31 #include "SVGImageBufferTools.h" 32 #include "TextStream.h" 33 34 namespace WebCore { 35 36 FETile::FETile(Filter* filter) 37 : FilterEffect(filter) 38 { 39 } 40 41 PassRefPtr<FETile> FETile::create(Filter* filter) 42 { 43 return adoptRef(new FETile(filter)); 44 } 45 46 void FETile::apply() 47 { 48 // FIXME: See bug 47315. This is a hack to work around a compile failure, but is incorrect behavior otherwise. 49 #if ENABLE(SVG) 50 if (hasResult()) 51 return; 52 FilterEffect* in = inputEffect(0); 53 in->apply(); 54 if (!in->hasResult()) 55 return; 56 57 ImageBuffer* resultImage = createImageBufferResult(); 58 if (!resultImage) 59 return; 60 61 setIsAlphaImage(in->isAlphaImage()); 62 63 // Source input needs more attention. It has the size of the filterRegion but gives the 64 // size of the cutted sourceImage back. This is part of the specification and optimization. 65 FloatRect tileRect = in->maxEffectRect(); 66 FloatPoint inMaxEffectLocation = tileRect.location(); 67 FloatPoint maxEffectLocation = maxEffectRect().location(); 68 if (in->filterEffectType() == FilterEffectTypeSourceInput) { 69 Filter* filter = this->filter(); 70 tileRect = filter->filterRegion(); 71 tileRect.scale(filter->filterResolution().width(), filter->filterResolution().height()); 72 } 73 74 OwnPtr<ImageBuffer> tileImage; 75 if (!SVGImageBufferTools::createImageBuffer(tileRect, tileRect, tileImage, ColorSpaceDeviceRGB)) 76 return; 77 78 GraphicsContext* tileImageContext = tileImage->context(); 79 tileImageContext->translate(-inMaxEffectLocation.x(), -inMaxEffectLocation.y()); 80 tileImageContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, in->absolutePaintRect().location()); 81 82 RefPtr<Pattern> pattern = Pattern::create(tileImage->copyImage(), true, true); 83 84 AffineTransform patternTransform; 85 patternTransform.translate(inMaxEffectLocation.x() - maxEffectLocation.x(), inMaxEffectLocation.y() - maxEffectLocation.y()); 86 pattern->setPatternSpaceTransform(patternTransform); 87 GraphicsContext* filterContext = resultImage->context(); 88 filterContext->setFillPattern(pattern); 89 filterContext->fillRect(FloatRect(FloatPoint(), absolutePaintRect().size())); 90 #endif 91 } 92 93 void FETile::dump() 94 { 95 } 96 97 TextStream& FETile::externalRepresentation(TextStream& ts, int indent) const 98 { 99 writeIndent(ts, indent); 100 ts << "[feTile"; 101 FilterEffect::externalRepresentation(ts); 102 ts << "]\n"; 103 inputEffect(0)->externalRepresentation(ts, indent + 1); 104 105 return ts; 106 } 107 108 } // namespace WebCore 109 110 #endif // ENABLE(FILTERS) 111