This source file includes following definitions.
- createMatrixImageFilter
- build
- transformColorSpace
- buildFilterOperations
- buildTransform
#include "config.h"
#include "platform/graphics/filters/SkiaImageFilterBuilder.h"
#include "SkBlurImageFilter.h"
#include "SkColorFilterImageFilter.h"
#include "SkColorMatrixFilter.h"
#include "SkDropShadowImageFilter.h"
#include "SkMatrixImageFilter.h"
#include "SkTableColorFilter.h"
#include "platform/graphics/ImageBuffer.h"
#include "platform/graphics/filters/FilterEffect.h"
#include "platform/graphics/filters/FilterOperations.h"
#include "platform/graphics/filters/SourceGraphic.h"
#include "public/platform/WebPoint.h"
namespace {
PassRefPtr<SkImageFilter> createMatrixImageFilter(SkScalar matrix[20], SkImageFilter* input)
{
RefPtr<SkColorFilter> colorFilter(adoptRef(new SkColorMatrixFilter(matrix)));
return adoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), input));
}
};
namespace WebCore {
SkiaImageFilterBuilder::SkiaImageFilterBuilder()
: m_context(0)
{
}
SkiaImageFilterBuilder::SkiaImageFilterBuilder(GraphicsContext* context)
: m_context(context)
{
}
SkiaImageFilterBuilder::~SkiaImageFilterBuilder()
{
}
PassRefPtr<SkImageFilter> SkiaImageFilterBuilder::build(FilterEffect* effect, ColorSpace colorSpace)
{
if (!effect)
return nullptr;
FilterColorSpacePair key(effect, colorSpace);
FilterBuilderHashMap::iterator it = m_map.find(key);
if (it != m_map.end()) {
return it->value;
} else {
RefPtr<SkImageFilter> origFilter = effect->createImageFilter(this);
RefPtr<SkImageFilter> filter = transformColorSpace(origFilter.get(), effect->operatingColorSpace(), colorSpace);
m_map.set(key, filter);
return filter.release();
}
}
PassRefPtr<SkImageFilter> SkiaImageFilterBuilder::transformColorSpace(
SkImageFilter* input, ColorSpace srcColorSpace, ColorSpace dstColorSpace) {
RefPtr<SkColorFilter> colorFilter = ImageBuffer::createColorSpaceFilter(srcColorSpace, dstColorSpace);
if (!colorFilter)
return input;
return adoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), input));
}
bool SkiaImageFilterBuilder::buildFilterOperations(const FilterOperations& operations, blink::WebFilterOperations* filters)
{
if (!filters)
return false;
ColorSpace currentColorSpace = ColorSpaceDeviceRGB;
RefPtr<SkImageFilter> noopFilter;
SkScalar matrix[20];
memset(matrix, 0, 20 * sizeof(SkScalar));
matrix[0] = matrix[6] = matrix[12] = matrix[18] = 1.f;
noopFilter = createMatrixImageFilter(matrix, 0);
for (size_t i = 0; i < operations.size(); ++i) {
const FilterOperation& op = *operations.at(i);
switch (op.type()) {
case FilterOperation::REFERENCE: {
RefPtr<SkImageFilter> filter;
ReferenceFilter* referenceFilter = toReferenceFilterOperation(op).filter();
if (referenceFilter && referenceFilter->lastEffect()) {
FilterEffect* filterEffect = referenceFilter->lastEffect();
FilterColorSpacePair deviceKey(referenceFilter->sourceGraphic(), ColorSpaceDeviceRGB);
FilterColorSpacePair linearKey(referenceFilter->sourceGraphic(), ColorSpaceLinearRGB);
m_map.set(deviceKey, transformColorSpace(noopFilter.get(), currentColorSpace, ColorSpaceDeviceRGB));
m_map.set(linearKey, transformColorSpace(noopFilter.get(), currentColorSpace, ColorSpaceLinearRGB));
currentColorSpace = filterEffect->operatingColorSpace();
filter = SkiaImageFilterBuilder::build(filterEffect, currentColorSpace);
m_map.remove(deviceKey);
m_map.remove(linearKey);
filters->appendReferenceFilter(filter.get());
}
break;
}
case FilterOperation::GRAYSCALE:
case FilterOperation::SEPIA:
case FilterOperation::SATURATE:
case FilterOperation::HUE_ROTATE: {
float amount = toBasicColorMatrixFilterOperation(op).amount();
switch (op.type()) {
case FilterOperation::GRAYSCALE:
filters->appendGrayscaleFilter(amount);
break;
case FilterOperation::SEPIA:
filters->appendSepiaFilter(amount);
break;
case FilterOperation::SATURATE:
filters->appendSaturateFilter(amount);
break;
case FilterOperation::HUE_ROTATE:
filters->appendHueRotateFilter(amount);
break;
default:
ASSERT_NOT_REACHED();
}
break;
}
case FilterOperation::INVERT:
case FilterOperation::OPACITY:
case FilterOperation::BRIGHTNESS:
case FilterOperation::CONTRAST: {
float amount = toBasicComponentTransferFilterOperation(op).amount();
switch (op.type()) {
case FilterOperation::INVERT:
filters->appendInvertFilter(amount);
break;
case FilterOperation::OPACITY:
filters->appendOpacityFilter(amount);
break;
case FilterOperation::BRIGHTNESS:
filters->appendBrightnessFilter(amount);
break;
case FilterOperation::CONTRAST:
filters->appendContrastFilter(amount);
break;
default:
ASSERT_NOT_REACHED();
}
break;
}
case FilterOperation::BLUR: {
float pixelRadius = toBlurFilterOperation(op).stdDeviation().getFloatValue();
filters->appendBlurFilter(pixelRadius);
break;
}
case FilterOperation::DROP_SHADOW: {
const DropShadowFilterOperation& drop = toDropShadowFilterOperation(op);
filters->appendDropShadowFilter(blink::WebPoint(drop.x(), drop.y()), drop.stdDeviation(), drop.color().rgb());
break;
}
case FilterOperation::VALIDATED_CUSTOM:
case FilterOperation::CUSTOM:
return false;
case FilterOperation::NONE:
break;
}
}
if (currentColorSpace != ColorSpaceDeviceRGB) {
RefPtr<SkImageFilter> filter;
filter = transformColorSpace(noopFilter.get(), currentColorSpace, ColorSpaceDeviceRGB);
if (filter != noopFilter)
filters->appendReferenceFilter(filter.get());
}
return true;
}
PassRefPtr<SkImageFilter> SkiaImageFilterBuilder::buildTransform(const AffineTransform& transform, SkImageFilter* input)
{
return adoptRef(SkMatrixImageFilter::Create(affineTransformToSkMatrix(transform), SkPaint::kHigh_FilterLevel, input));
}
};