#include "config.h"
#include "FETile.h"
#include "AffineTransform.h"
#include "Filter.h"
#include "GraphicsContext.h"
#include "Pattern.h"
#include "RenderTreeAsText.h"
#include "SVGRenderingContext.h"
#include <wtf/text/TextStream.h>
namespace WebCore {
FETile::FETile(Filter& filter)
: FilterEffect(filter)
{
}
Ref<FETile> FETile::create(Filter& filter)
{
return adoptRef(*new FETile(filter));
}
void FETile::platformApplySoftware()
{
FilterEffect* in = inputEffect(0);
ImageBuffer* resultImage = createImageBufferResult();
ImageBuffer* inBuffer = in->imageBufferResult();
if (!resultImage || !inBuffer)
return;
setIsAlphaImage(in->isAlphaImage());
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());
}
auto tileImage = SVGRenderingContext::createImageBuffer(tileRect, tileRect, ColorSpace::SRGB, filter().renderingMode());
if (!tileImage)
return;
GraphicsContext& tileImageContext = tileImage->context();
tileImageContext.translate(-inMaxEffectLocation.x(), -inMaxEffectLocation.y());
tileImageContext.drawImageBuffer(*inBuffer, in->absolutePaintRect().location());
auto tileImageCopy = ImageBuffer::sinkIntoImage(WTFMove(tileImage));
if (!tileImageCopy)
return;
auto pattern = Pattern::create(tileImageCopy.releaseNonNull(), true, true);
AffineTransform patternTransform;
patternTransform.translate(inMaxEffectLocation - maxEffectLocation);
pattern.get().setPatternSpaceTransform(patternTransform);
GraphicsContext& filterContext = resultImage->context();
filterContext.setFillPattern(WTFMove(pattern));
filterContext.fillRect(FloatRect(FloatPoint(), absolutePaintRect().size()));
}
TextStream& FETile::externalRepresentation(TextStream& ts, RepresentationType representation) const
{
ts << indent << "[feTile";
FilterEffect::externalRepresentation(ts, representation);
ts << "]\n";
TextStream::IndentScope indentScope(ts);
inputEffect(0)->externalRepresentation(ts, representation);
return ts;
}
}