blob: 7684c13d7d42975824c168830ce316254966618e [file] [log] [blame]
/*
* Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
* Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
* Copyright (C) 2005 Eric Seidel <eric@webkit.org>
* Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
* Copyright (C) 2010 Renata Hodovan <reni@inf.u-szeged.hu>
* Copyright (C) 2011 Gabor Loki <loki@webkit.org>
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "third_party/blink/renderer/platform/graphics/filters/fe_turbulence.h"
#include "third_party/blink/renderer/platform/graphics/filters/filter.h"
#include "third_party/blink/renderer/platform/wtf/text/text_stream.h"
namespace blink {
FETurbulence::FETurbulence(Filter* filter,
TurbulenceType type,
float base_frequency_x,
float base_frequency_y,
int num_octaves,
float seed,
bool stitch_tiles)
: FilterEffect(filter),
type_(type),
base_frequency_x_(base_frequency_x),
base_frequency_y_(base_frequency_y),
num_octaves_(num_octaves),
seed_(seed),
stitch_tiles_(stitch_tiles) {}
TurbulenceType FETurbulence::GetType() const {
return type_;
}
bool FETurbulence::SetType(TurbulenceType type) {
if (type_ == type)
return false;
type_ = type;
return true;
}
float FETurbulence::BaseFrequencyY() const {
return base_frequency_y_;
}
bool FETurbulence::SetBaseFrequencyY(float base_frequency_y) {
if (base_frequency_y_ == base_frequency_y)
return false;
base_frequency_y_ = base_frequency_y;
return true;
}
float FETurbulence::BaseFrequencyX() const {
return base_frequency_x_;
}
bool FETurbulence::SetBaseFrequencyX(float base_frequency_x) {
if (base_frequency_x_ == base_frequency_x)
return false;
base_frequency_x_ = base_frequency_x;
return true;
}
float FETurbulence::Seed() const {
return seed_;
}
bool FETurbulence::SetSeed(float seed) {
if (seed_ == seed)
return false;
seed_ = seed;
return true;
}
int FETurbulence::NumOctaves() const {
return num_octaves_;
}
bool FETurbulence::SetNumOctaves(int num_octaves) {
if (num_octaves_ == num_octaves)
return false;
num_octaves_ = num_octaves;
return true;
}
bool FETurbulence::StitchTiles() const {
return stitch_tiles_;
}
bool FETurbulence::SetStitchTiles(bool stitch) {
if (stitch_tiles_ == stitch)
return false;
stitch_tiles_ = stitch;
return true;
}
sk_sp<PaintFilter> FETurbulence::CreateImageFilter() {
float base_frequency_x = base_frequency_x_;
float base_frequency_y = base_frequency_y_;
if (base_frequency_x < 0 || base_frequency_y < 0) {
// Negative values are unsupported which means it should be treated as
// if they hadn't been specified. So, it implies "0 0"(the initial
// value).
base_frequency_x = base_frequency_y = 0;
}
base::Optional<PaintFilter::CropRect> crop_rect = GetCropRect();
TurbulencePaintFilter::TurbulenceType type =
GetType() == FETURBULENCE_TYPE_FRACTALNOISE
? TurbulencePaintFilter::TurbulenceType::kFractalNoise
: TurbulencePaintFilter::TurbulenceType::kTurbulence;
const SkISize size = SkISize::Make(FilterPrimitiveSubregion().Width(),
FilterPrimitiveSubregion().Height());
// Frequency should be scaled by page zoom, but not by primitiveUnits.
// So we apply only the transform scale (as Filter::apply*Scale() do)
// and not the target bounding box scale (as SVGFilter::apply*Scale()
// would do). Note also that we divide by the scale since this is
// a frequency, not a period.
base_frequency_x /= GetFilter()->Scale();
base_frequency_y /= GetFilter()->Scale();
// Cap the number of octaves to the maximum detectable when rendered with
// 8 bits per pixel, plus one for higher bit depth.
int capped_num_octaves = std::min(NumOctaves(), 9);
return sk_make_sp<TurbulencePaintFilter>(
type, SkFloatToScalar(base_frequency_x),
SkFloatToScalar(base_frequency_y), capped_num_octaves,
SkFloatToScalar(Seed()), StitchTiles() ? &size : nullptr,
base::OptionalOrNullptr(crop_rect));
}
static WTF::TextStream& operator<<(WTF::TextStream& ts,
const TurbulenceType& type) {
switch (type) {
case FETURBULENCE_TYPE_UNKNOWN:
ts << "UNKNOWN";
break;
case FETURBULENCE_TYPE_TURBULENCE:
ts << "TURBULENCE";
break;
case FETURBULENCE_TYPE_FRACTALNOISE:
ts << "NOISE";
break;
}
return ts;
}
WTF::TextStream& FETurbulence::ExternalRepresentation(WTF::TextStream& ts,
int indent) const {
WriteIndent(ts, indent);
ts << "[feTurbulence";
FilterEffect::ExternalRepresentation(ts);
ts << " type=\"" << GetType() << "\" "
<< "baseFrequency=\"" << BaseFrequencyX() << ", " << BaseFrequencyY()
<< "\" "
<< "seed=\"" << Seed() << "\" "
<< "numOctaves=\"" << NumOctaves() << "\" "
<< "stitchTiles=\"" << StitchTiles() << "\"]\n";
return ts;
}
} // namespace blink