#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 "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->asImageBuffer();
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, ColorSpaceSRGB, 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.x() - maxEffectLocation.x(), inMaxEffectLocation.y() - maxEffectLocation.y());
pattern.get().setPatternSpaceTransform(patternTransform);
GraphicsContext& filterContext = resultImage->context();
filterContext.setFillPattern(WTFMove(pattern));
filterContext.fillRect(FloatRect(FloatPoint(), absolutePaintRect().size()));
}
void FETile::dump()
{
}
TextStream& FETile::externalRepresentation(TextStream& ts, int indent) const
{
writeIndent(ts, indent);
ts << "[feTile";
FilterEffect::externalRepresentation(ts);
ts << "]\n";
inputEffect(0)->externalRepresentation(ts, indent + 1);
return ts;
}
}