18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
2dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
3dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
4dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
5dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
6a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * Copyright (C) Research In Motion Limited 2010. All rights reserved.
7dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch *
8dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * This library is free software; you can redistribute it and/or
9dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * modify it under the terms of the GNU Library General Public
10dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * License as published by the Free Software Foundation; either
11dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * version 2 of the License, or (at your option) any later version.
12dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch *
13dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * This library is distributed in the hope that it will be useful,
14dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * but WITHOUT ANY WARRANTY; without even the implied warranty of
15dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * Library General Public License for more details.
17dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch *
18dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * You should have received a copy of the GNU Library General Public License
19dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * along with this library; see the file COPYING.LIB.  If not, write to
20dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * Boston, MA 02110-1301, USA.
22dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch */
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if ENABLE(FILTERS)
27bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#include "FEMorphology.h"
28643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "Filter.h"
3065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "RenderTreeAsText.h"
3165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "TextStream.h"
32643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
33cad810f21b803229eb11403f9209855525a25d57Steve Block#include <wtf/ByteArray.h>
34643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include <wtf/Vector.h>
35643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
36643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockusing std::min;
37643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockusing std::max;
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
414576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) WangFEMorphology::FEMorphology(Filter* filter, MorphologyOperatorType type, float radiusX, float radiusY)
424576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    : FilterEffect(filter)
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_type(type)
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_radiusX(radiusX)
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_radiusY(radiusY)
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
494576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) WangPassRefPtr<FEMorphology> FEMorphology::create(Filter* filter, MorphologyOperatorType type, float radiusX, float radiusY)
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
514576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    return adoptRef(new FEMorphology(filter, type, radiusX, radiusY));
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectMorphologyOperatorType FEMorphology::morphologyOperator() const
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_type;
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochbool FEMorphology::setMorphologyOperator(MorphologyOperatorType type)
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_type == type)
6281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return false;
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_type = type;
6481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return true;
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectfloat FEMorphology::radiusX() const
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_radiusX;
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochbool FEMorphology::setRadiusX(float radiusX)
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_radiusX == radiusX)
7581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return false;
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_radiusX = radiusX;
7781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return true;
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectfloat FEMorphology::radiusY() const
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_radiusY;
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
854576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wangvoid FEMorphology::determineAbsolutePaintRect()
86a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
87a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    FloatRect paintRect = inputEffect(0)->absolutePaintRect();
884576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    Filter* filter = this->filter();
89a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    paintRect.inflateX(filter->applyHorizontalScale(m_radiusX));
90a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    paintRect.inflateY(filter->applyVerticalScale(m_radiusY));
91a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    paintRect.intersect(maxEffectRect());
92a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setAbsolutePaintRect(enclosingIntRect(paintRect));
93a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
94a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
9581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochbool FEMorphology::setRadiusY(float radiusY)
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_radiusY == radiusY)
9881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return false;
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_radiusY = radiusY;
10081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return true;
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1034576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wangvoid FEMorphology::apply()
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
105f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (hasResult())
106f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return;
10768513a70bcd92384395513322f1b801e7bf9c729Steve Block    FilterEffect* in = inputEffect(0);
1084576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    in->apply();
109f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!in->hasResult())
110643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return;
11168513a70bcd92384395513322f1b801e7bf9c729Steve Block
112cad810f21b803229eb11403f9209855525a25d57Steve Block    ByteArray* dstPixelArray = createPremultipliedImageResult();
113cad810f21b803229eb11403f9209855525a25d57Steve Block    if (!dstPixelArray)
114643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return;
115643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
11668513a70bcd92384395513322f1b801e7bf9c729Steve Block    setIsAlphaImage(in->isAlphaImage());
117a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (m_radiusX <= 0 || m_radiusY <= 0)
118643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return;
119643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
1204576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    Filter* filter = this->filter();
121a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int radiusX = static_cast<int>(floorf(filter->applyHorizontalScale(m_radiusX)));
122a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int radiusY = static_cast<int>(floorf(filter->applyVerticalScale(m_radiusY)));
123a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
124a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
125cad810f21b803229eb11403f9209855525a25d57Steve Block    RefPtr<ByteArray> srcPixelArray = in->asPremultipliedImage(effectDrawingRect);
126643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
127643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    int effectWidth = effectDrawingRect.width() * 4;
128643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
129dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Limit the radius size to effect dimensions
130643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    radiusX = min(effectDrawingRect.width() - 1, radiusX);
131dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    radiusY = min(effectDrawingRect.height() - 1, radiusY);
132643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
133643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    Vector<unsigned char> extrema;
134643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    for (int y = 0; y < effectDrawingRect.height(); ++y) {
135643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        int startY = max(0, y - radiusY);
136643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        int endY = min(effectDrawingRect.height() - 1, y + radiusY);
137643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        for (unsigned channel = 0; channel < 4; ++channel) {
138643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            // Fill the kernel
139643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            extrema.clear();
140643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            for (int j = 0; j <= radiusX; ++j) {
141643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                unsigned char columnExtrema = srcPixelArray->get(startY * effectWidth + 4 * j + channel);
142643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                for (int i = startY; i <= endY; ++i) {
143643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                    unsigned char pixel = srcPixelArray->get(i * effectWidth + 4 * j + channel);
144643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                    if ((m_type == FEMORPHOLOGY_OPERATOR_ERODE && pixel <= columnExtrema) ||
145643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                        (m_type == FEMORPHOLOGY_OPERATOR_DILATE && pixel >= columnExtrema))
146643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                        columnExtrema = pixel;
147643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                }
148643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                extrema.append(columnExtrema);
149643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            }
150643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
151643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            // Kernel is filled, get extrema of next column
152643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            for (int x = 0; x < effectDrawingRect.width(); ++x) {
153643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                unsigned endX = min(x + radiusX, effectDrawingRect.width() - 1);
154643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                unsigned char columnExtrema = srcPixelArray->get(startY * effectWidth + endX * 4 + channel);
155643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                for (int i = startY; i <= endY; ++i) {
156643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                    unsigned char pixel = srcPixelArray->get(i * effectWidth + endX * 4 + channel);
157643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                    if ((m_type == FEMORPHOLOGY_OPERATOR_ERODE && pixel <= columnExtrema) ||
158643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                        (m_type == FEMORPHOLOGY_OPERATOR_DILATE && pixel >= columnExtrema))
159643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                        columnExtrema = pixel;
160643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                }
161643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                if (x - radiusX >= 0)
162643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                    extrema.remove(0);
163643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                if (x + radiusX <= effectDrawingRect.width())
164643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                    extrema.append(columnExtrema);
165643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                unsigned char entireExtrema = extrema[0];
166643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                for (unsigned kernelIndex = 0; kernelIndex < extrema.size(); ++kernelIndex) {
167643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                    if ((m_type == FEMORPHOLOGY_OPERATOR_ERODE && extrema[kernelIndex] <= entireExtrema) ||
168643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                        (m_type == FEMORPHOLOGY_OPERATOR_DILATE && extrema[kernelIndex] >= entireExtrema))
169643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                        entireExtrema = extrema[kernelIndex];
170643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                }
171e14391e94c850b8bd03680c23b38978db68687a8John Reck                dstPixelArray->set(y * effectWidth + 4 * x + channel, entireExtrema);
172643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            }
173643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
174643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid FEMorphology::dump()
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1816c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenstatic TextStream& operator<<(TextStream& ts, const MorphologyOperatorType& type)
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1836c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    switch (type) {
1846c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    case FEMORPHOLOGY_OPERATOR_UNKNOWN:
1856c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        ts << "UNKNOWN";
1866c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        break;
1876c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    case FEMORPHOLOGY_OPERATOR_ERODE:
1886c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        ts << "ERODE";
1896c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        break;
1906c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    case FEMORPHOLOGY_OPERATOR_DILATE:
1916c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        ts << "DILATE";
1926c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        break;
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return ts;
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1976c2af9490927c3c5959b5cb07461b646f8b32f6cKristian MonsenTextStream& FEMorphology::externalRepresentation(TextStream& ts, int indent) const
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1996c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    writeIndent(ts, indent);
2006c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    ts << "[feMorphology";
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    FilterEffect::externalRepresentation(ts);
2026c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    ts << " operator=\"" << morphologyOperator() << "\" "
20368513a70bcd92384395513322f1b801e7bf9c729Steve Block       << "radius=\"" << radiusX() << ", " << radiusY() << "\"]\n";
20468513a70bcd92384395513322f1b801e7bf9c729Steve Block    inputEffect(0)->externalRepresentation(ts, indent + 1);
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return ts;
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
210bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#endif // ENABLE(FILTERS)
211