blob: 63edc3a6b24be3c493ae95570f9634439e1c998b [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CC_OUTPUT_FILTER_OPERATION_H_
#define CC_OUTPUT_FILTER_OPERATION_H_
#include <memory>
#include "base/logging.h"
#include "cc/base/cc_export.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkImageFilter.h"
#include "third_party/skia/include/core/SkRegion.h"
#include "third_party/skia/include/core/SkScalar.h"
#include "ui/gfx/geometry/point.h"
namespace base {
namespace trace_event {
class TracedValue;
}
}
namespace gfx {
class Rect;
}
namespace cc {
class CC_EXPORT FilterOperation {
public:
enum FilterType {
GRAYSCALE,
SEPIA,
SATURATE,
HUE_ROTATE,
INVERT,
BRIGHTNESS,
CONTRAST,
OPACITY,
BLUR,
DROP_SHADOW,
COLOR_MATRIX,
ZOOM,
REFERENCE,
SATURATING_BRIGHTNESS, // Not used in CSS/SVG.
ALPHA_THRESHOLD, // Not used in CSS/SVG.
FILTER_TYPE_LAST = ALPHA_THRESHOLD
};
FilterOperation();
FilterOperation(const FilterOperation& other);
~FilterOperation();
FilterType type() const { return type_; }
float amount() const {
DCHECK_NE(type_, COLOR_MATRIX);
DCHECK_NE(type_, REFERENCE);
return amount_;
}
float outer_threshold() const {
DCHECK_EQ(type_, ALPHA_THRESHOLD);
return outer_threshold_;
}
gfx::Point drop_shadow_offset() const {
DCHECK_EQ(type_, DROP_SHADOW);
return drop_shadow_offset_;
}
SkColor drop_shadow_color() const {
DCHECK_EQ(type_, DROP_SHADOW);
return drop_shadow_color_;
}
const sk_sp<SkImageFilter>& image_filter() const {
DCHECK_EQ(type_, REFERENCE);
return image_filter_;
}
const SkScalar* matrix() const {
DCHECK_EQ(type_, COLOR_MATRIX);
return matrix_;
}
int zoom_inset() const {
DCHECK_EQ(type_, ZOOM);
return zoom_inset_;
}
const SkRegion& region() const {
DCHECK_EQ(type_, ALPHA_THRESHOLD);
return region_;
}
static FilterOperation CreateGrayscaleFilter(float amount) {
return FilterOperation(GRAYSCALE, amount);
}
static FilterOperation CreateSepiaFilter(float amount) {
return FilterOperation(SEPIA, amount);
}
static FilterOperation CreateSaturateFilter(float amount) {
return FilterOperation(SATURATE, amount);
}
static FilterOperation CreateHueRotateFilter(float amount) {
return FilterOperation(HUE_ROTATE, amount);
}
static FilterOperation CreateInvertFilter(float amount) {
return FilterOperation(INVERT, amount);
}
static FilterOperation CreateBrightnessFilter(float amount) {
return FilterOperation(BRIGHTNESS, amount);
}
static FilterOperation CreateContrastFilter(float amount) {
return FilterOperation(CONTRAST, amount);
}
static FilterOperation CreateOpacityFilter(float amount) {
return FilterOperation(OPACITY, amount);
}
static FilterOperation CreateBlurFilter(float amount) {
return FilterOperation(BLUR, amount);
}
static FilterOperation CreateDropShadowFilter(const gfx::Point& offset,
float std_deviation,
SkColor color) {
return FilterOperation(DROP_SHADOW, offset, std_deviation, color);
}
static FilterOperation CreateColorMatrixFilter(SkScalar matrix[20]) {
return FilterOperation(COLOR_MATRIX, matrix);
}
static FilterOperation CreateZoomFilter(float amount, int inset) {
return FilterOperation(ZOOM, amount, inset);
}
static FilterOperation CreateReferenceFilter(
sk_sp<SkImageFilter> image_filter) {
return FilterOperation(REFERENCE, std::move(image_filter));
}
static FilterOperation CreateSaturatingBrightnessFilter(float amount) {
return FilterOperation(SATURATING_BRIGHTNESS, amount);
}
static FilterOperation CreateAlphaThresholdFilter(const SkRegion& region,
float inner_threshold,
float outer_threshold) {
return FilterOperation(ALPHA_THRESHOLD, region,
inner_threshold, outer_threshold);
}
bool operator==(const FilterOperation& other) const;
bool operator!=(const FilterOperation& other) const {
return !(*this == other);
}
// Methods for restoring a FilterOperation.
static FilterOperation CreateEmptyFilter() {
return FilterOperation(GRAYSCALE, 0.f);
}
void set_type(FilterType type) { type_ = type; }
void set_amount(float amount) {
DCHECK_NE(type_, COLOR_MATRIX);
DCHECK_NE(type_, REFERENCE);
amount_ = amount;
}
void set_outer_threshold(float outer_threshold) {
DCHECK_EQ(type_, ALPHA_THRESHOLD);
outer_threshold_ = outer_threshold;
}
void set_drop_shadow_offset(const gfx::Point& offset) {
DCHECK_EQ(type_, DROP_SHADOW);
drop_shadow_offset_ = offset;
}
void set_drop_shadow_color(SkColor color) {
DCHECK_EQ(type_, DROP_SHADOW);
drop_shadow_color_ = color;
}
void set_image_filter(sk_sp<SkImageFilter> image_filter) {
DCHECK_EQ(type_, REFERENCE);
image_filter_ = std::move(image_filter);
}
void set_matrix(const SkScalar matrix[20]) {
DCHECK_EQ(type_, COLOR_MATRIX);
for (unsigned i = 0; i < 20; ++i)
matrix_[i] = matrix[i];
}
void set_zoom_inset(int inset) {
DCHECK_EQ(type_, ZOOM);
zoom_inset_ = inset;
}
void set_region(const SkRegion& region) {
DCHECK_EQ(type_, ALPHA_THRESHOLD);
region_ = region;
}
// Given two filters of the same type, returns a filter operation created by
// linearly interpolating a |progress| fraction from |from| to |to|. If either
// |from| or |to| (but not both) is null, it is treated as a no-op filter of
// the same type as the other given filter. If both |from| and |to| are null,
// or if |from| and |to| are non-null but of different types, returns a
// no-op filter.
static FilterOperation Blend(const FilterOperation* from,
const FilterOperation* to,
double progress);
void AsValueInto(base::trace_event::TracedValue* value) const;
// Maps "forward" to determine which pixels in a destination rect are affected
// by pixels in the source rect.
gfx::Rect MapRect(const gfx::Rect& rect, const SkMatrix& matrix) const;
// Maps "backward" to determine which pixels in the source affect the pixels
// in the destination rect.
gfx::Rect MapRectReverse(const gfx::Rect& rect, const SkMatrix& matrix) const;
private:
FilterOperation(FilterType type, float amount);
FilterOperation(FilterType type,
const gfx::Point& offset,
float stdDeviation,
SkColor color);
FilterOperation(FilterType, SkScalar matrix[20]);
FilterOperation(FilterType type, float amount, int inset);
FilterOperation(FilterType type, sk_sp<SkImageFilter> image_filter);
FilterOperation(FilterType type,
const SkRegion& region,
float inner_threshold,
float outer_threshold);
FilterType type_;
float amount_;
float outer_threshold_;
gfx::Point drop_shadow_offset_;
SkColor drop_shadow_color_;
sk_sp<SkImageFilter> image_filter_;
SkScalar matrix_[20];
int zoom_inset_;
SkRegion region_;
};
} // namespace cc
#endif // CC_OUTPUT_FILTER_OPERATION_H_