File indexing completed on 2024-05-12 15:56:40
0001 /* This file is part of the KDE project 0002 * SPDX-FileCopyrightText: 2009-2010 Jan Hambrecht <jaham@gmx.net> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.1-or-later 0005 */ 0006 0007 #include "KoFilterEffectStack.h" 0008 #include "KoFilterEffect.h" 0009 #include "KoXmlWriter.h" 0010 0011 #include <QRectF> 0012 #include <QAtomicInt> 0013 #include <QSet> 0014 #include <QDebug> 0015 0016 class Q_DECL_HIDDEN KoFilterEffectStack::Private 0017 { 0018 public: 0019 Private() 0020 : clipRect(-0.1, -0.1, 1.2, 1.2) // initialize as per svg spec 0021 { 0022 } 0023 0024 ~Private() 0025 { 0026 qDeleteAll(filterEffects); 0027 } 0028 0029 QList<KoFilterEffect*> filterEffects; 0030 QRectF clipRect; 0031 QAtomicInt refCount; 0032 }; 0033 0034 KoFilterEffectStack::KoFilterEffectStack() 0035 : d(new Private()) 0036 { 0037 } 0038 0039 KoFilterEffectStack::~KoFilterEffectStack() 0040 { 0041 delete d; 0042 } 0043 0044 QList<KoFilterEffect*> KoFilterEffectStack::filterEffects() const 0045 { 0046 return d->filterEffects; 0047 } 0048 0049 bool KoFilterEffectStack::isEmpty() const 0050 { 0051 return d->filterEffects.isEmpty(); 0052 } 0053 0054 void KoFilterEffectStack::insertFilterEffect(int index, KoFilterEffect * filter) 0055 { 0056 if (filter) 0057 d->filterEffects.insert(index, filter); 0058 } 0059 0060 void KoFilterEffectStack::appendFilterEffect(KoFilterEffect *filter) 0061 { 0062 if (filter) 0063 d->filterEffects.append(filter); 0064 } 0065 0066 void KoFilterEffectStack::removeFilterEffect(int index) 0067 { 0068 KoFilterEffect * filter = takeFilterEffect(index); 0069 delete filter; 0070 } 0071 0072 KoFilterEffect* KoFilterEffectStack::takeFilterEffect(int index) 0073 { 0074 if (index >= d->filterEffects.size()) 0075 return 0; 0076 return d->filterEffects.takeAt(index); 0077 } 0078 0079 void KoFilterEffectStack::setClipRect(const QRectF &clipRect) 0080 { 0081 d->clipRect = clipRect; 0082 } 0083 0084 QRectF KoFilterEffectStack::clipRect() const 0085 { 0086 return d->clipRect; 0087 } 0088 0089 QRectF KoFilterEffectStack::clipRectForBoundingRect(const QRectF &boundingRect) const 0090 { 0091 qreal x = boundingRect.x() + d->clipRect.x() * boundingRect.width(); 0092 qreal y = boundingRect.y() + d->clipRect.y() * boundingRect.height(); 0093 qreal w = d->clipRect.width() * boundingRect.width(); 0094 qreal h = d->clipRect.height() * boundingRect.height(); 0095 return QRectF(x, y, w, h); 0096 } 0097 0098 bool KoFilterEffectStack::ref() 0099 { 0100 return d->refCount.ref(); 0101 } 0102 0103 bool KoFilterEffectStack::deref() 0104 { 0105 return d->refCount.deref(); 0106 } 0107 0108 int KoFilterEffectStack::useCount() const 0109 { 0110 return d->refCount; 0111 } 0112 0113 void KoFilterEffectStack::save(KoXmlWriter &writer, const QString &filterId) 0114 { 0115 writer.startElement("filter"); 0116 writer.addAttribute("id", filterId); 0117 writer.addAttribute("filterUnits", "objectBoundingBox"); 0118 writer.addAttribute("primitiveUnits", "objectBoundingBox"); 0119 writer.addAttribute("x", d->clipRect.x()); 0120 writer.addAttribute("y", d->clipRect.y()); 0121 writer.addAttribute("width", d->clipRect.width()); 0122 writer.addAttribute("height", d->clipRect.height()); 0123 0124 Q_FOREACH (KoFilterEffect *effect, d->filterEffects) { 0125 effect->save(writer); 0126 } 0127 0128 writer.endElement(); 0129 } 0130 0131 QSet<QString> KoFilterEffectStack::requiredStandarsInputs() const 0132 { 0133 static QSet<QString> stdInputs = QSet<QString>() 0134 << "SourceGraphic" 0135 << "SourceAlpha" 0136 << "BackgroundImage" 0137 << "BackgroundAlpha" 0138 << "FillPaint" 0139 << "StrokePaint"; 0140 0141 QSet<QString> requiredInputs; 0142 if (isEmpty()) 0143 return requiredInputs; 0144 0145 if (d->filterEffects.first()->inputs().contains(QString())) 0146 requiredInputs.insert("SourceGraphic"); 0147 0148 Q_FOREACH (KoFilterEffect *effect, d->filterEffects) { 0149 Q_FOREACH (const QString &input, effect->inputs()) { 0150 if (stdInputs.contains(input)) 0151 requiredInputs.insert(input); 0152 } 0153 } 0154 0155 return requiredInputs; 0156 }