1 /*
2  * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
3  * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
4  * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
5  * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
6  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
7  * Copyright (C) 2013 Google Inc. All rights reserved.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public License
20  * along with this library; see the file COPYING.LIB.  If not, write to
21  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  * Boston, MA 02110-1301, USA.
23  */
24 
25 #include "third_party/blink/renderer/platform/graphics/filters/fe_morphology.h"
26 
27 #include "third_party/blink/renderer/platform/graphics/filters/filter.h"
28 #include "third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.h"
29 #include "third_party/blink/renderer/platform/wtf/text/text_stream.h"
30 #include "third_party/skia/include/effects/SkMorphologyImageFilter.h"
31 
32 namespace blink {
33 
FEMorphology(Filter * filter,MorphologyOperatorType type,float radius_x,float radius_y)34 FEMorphology::FEMorphology(Filter* filter,
35                            MorphologyOperatorType type,
36                            float radius_x,
37                            float radius_y)
38     : FilterEffect(filter),
39       type_(type),
40       radius_x_(std::max(0.0f, radius_x)),
41       radius_y_(std::max(0.0f, radius_y)) {}
42 
MorphologyOperator() const43 MorphologyOperatorType FEMorphology::MorphologyOperator() const {
44   return type_;
45 }
46 
SetMorphologyOperator(MorphologyOperatorType type)47 bool FEMorphology::SetMorphologyOperator(MorphologyOperatorType type) {
48   if (type_ == type)
49     return false;
50   type_ = type;
51   return true;
52 }
53 
RadiusX() const54 float FEMorphology::RadiusX() const {
55   return radius_x_;
56 }
57 
SetRadiusX(float radius_x)58 bool FEMorphology::SetRadiusX(float radius_x) {
59   radius_x = std::max(0.0f, radius_x);
60   if (radius_x_ == radius_x)
61     return false;
62   radius_x_ = radius_x;
63   return true;
64 }
65 
RadiusY() const66 float FEMorphology::RadiusY() const {
67   return radius_y_;
68 }
69 
SetRadiusY(float radius_y)70 bool FEMorphology::SetRadiusY(float radius_y) {
71   radius_y = std::max(0.0f, radius_y);
72   if (radius_y_ == radius_y)
73     return false;
74   radius_y_ = radius_y;
75   return true;
76 }
77 
MapEffect(const FloatRect & rect) const78 FloatRect FEMorphology::MapEffect(const FloatRect& rect) const {
79   FloatRect result = rect;
80   result.InflateX(GetFilter()->ApplyHorizontalScale(radius_x_));
81   result.InflateY(GetFilter()->ApplyVerticalScale(radius_y_));
82   return result;
83 }
84 
CreateImageFilter()85 sk_sp<PaintFilter> FEMorphology::CreateImageFilter() {
86   sk_sp<PaintFilter> input(paint_filter_builder::Build(
87       InputEffect(0), OperatingInterpolationSpace()));
88   int radius_x = clampTo<int>(GetFilter()->ApplyHorizontalScale(radius_x_));
89   int radius_y = clampTo<int>(GetFilter()->ApplyVerticalScale(radius_y_));
90   PaintFilter::CropRect rect = GetCropRect();
91   MorphologyPaintFilter::MorphType morph_type =
92       type_ == FEMORPHOLOGY_OPERATOR_DILATE
93           ? MorphologyPaintFilter::MorphType::kDilate
94           : MorphologyPaintFilter::MorphType::kErode;
95   return sk_make_sp<MorphologyPaintFilter>(morph_type, radius_x, radius_y,
96                                            std::move(input), &rect);
97 }
98 
operator <<(WTF::TextStream & ts,const MorphologyOperatorType & type)99 static WTF::TextStream& operator<<(WTF::TextStream& ts,
100                                    const MorphologyOperatorType& type) {
101   switch (type) {
102     case FEMORPHOLOGY_OPERATOR_UNKNOWN:
103       ts << "UNKNOWN";
104       break;
105     case FEMORPHOLOGY_OPERATOR_ERODE:
106       ts << "ERODE";
107       break;
108     case FEMORPHOLOGY_OPERATOR_DILATE:
109       ts << "DILATE";
110       break;
111   }
112   return ts;
113 }
114 
ExternalRepresentation(WTF::TextStream & ts,int indent) const115 WTF::TextStream& FEMorphology::ExternalRepresentation(WTF::TextStream& ts,
116                                                       int indent) const {
117   WriteIndent(ts, indent);
118   ts << "[feMorphology";
119   FilterEffect::ExternalRepresentation(ts);
120   ts << " operator=\"" << MorphologyOperator() << "\" "
121      << "radius=\"" << RadiusX() << ", " << RadiusY() << "\"]\n";
122   InputEffect(0)->ExternalRepresentation(ts, indent + 1);
123   return ts;
124 }
125 
126 }  // namespace blink
127