File indexing completed on 2025-03-09 04:03:45
0001 /* This file is part of the KDE project 0002 * SPDX-FileCopyrightText: 2002-2003, 2005 Rob Buis <buis@kde.org> 0003 * SPDX-FileCopyrightText: 2005-2006 Tim Beaulen <tbscope@gmail.com> 0004 * SPDX-FileCopyrightText: 2005, 2007-2009 Jan Hambrecht <jaham@gmx.net> 0005 * 0006 * SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #ifndef SVGPARSER_H 0010 #define SVGPARSER_H 0011 0012 #include <QMap> 0013 #include <QSizeF> 0014 #include <QRectF> 0015 #include <QSharedPointer> 0016 #include <QExplicitlySharedDataPointer> 0017 0018 #include "kritaflake_export.h" 0019 #include "SvgGradientHelper.h" 0020 #include "SvgFilterHelper.h" 0021 #include "SvgClipPathHelper.h" 0022 #include "SvgLoadingContext.h" 0023 #include "SvgStyleParser.h" 0024 #include "KoClipMask.h" 0025 #include <resources/KoSvgSymbolCollectionResource.h> 0026 #include <KoID.h> 0027 0028 class KoShape; 0029 class KoShapeGroup; 0030 class KoShapeContainer; 0031 class KoDocumentResourceManager; 0032 class KoVectorPatternBackground; 0033 class KoMarker; 0034 class KoPathShape; 0035 class KoSvgTextShape; 0036 class KoSvgTextLoader; 0037 0038 class KRITAFLAKE_EXPORT SvgParser 0039 { 0040 struct DeferredUseStore; 0041 0042 public: 0043 explicit SvgParser(KoDocumentResourceManager *documentResourceManager); 0044 virtual ~SvgParser(); 0045 0046 static QDomDocument createDocumentFromSvg(QIODevice *device, QString *errorMsg = 0, int *errorLine = 0, int *errorColumn = 0); 0047 static QDomDocument createDocumentFromSvg(const QByteArray &data, QString *errorMsg = 0, int *errorLine = 0, int *errorColumn = 0); 0048 static QDomDocument createDocumentFromSvg(const QString &data, QString *errorMsg = 0, int *errorLine = 0, int *errorColumn = 0); 0049 static QDomDocument createDocumentFromSvg(QXmlInputSource *source, QString *errorMsg = 0, int *errorLine = 0, int *errorColumn = 0); 0050 0051 /// Parses a svg fragment, returning the list of top level child shapes 0052 QList<KoShape*> parseSvg(const QDomElement &e, QSizeF * fragmentSize = 0); 0053 0054 /// Sets the initial xml base directory (the directory form where the file is read) 0055 void setXmlBaseDir(const QString &baseDir); 0056 0057 void setResolution(const QRectF boundsInPixels, qreal pixelsPerInch); 0058 void setDefaultKraTextVersion(int version); 0059 0060 /// Returns the list of all shapes of the svg document 0061 QList<KoShape*> shapes() const; 0062 0063 /// Takes the collection of symbols contained in the svg document. The parser will 0064 /// no longer know about the symbols. 0065 QVector<KoSvgSymbol*> takeSymbols(); 0066 0067 QString documentTitle() const; 0068 QString documentDescription() const; 0069 0070 0071 typedef std::function<QByteArray(const QString&)> FileFetcherFunc; 0072 void setFileFetcher(FileFetcherFunc func); 0073 0074 QList<QExplicitlySharedDataPointer<KoMarker>> knownMarkers() const; 0075 0076 void parseDefsElement(const QDomElement &e); 0077 KoShape* parseTextElement(const QDomElement &e, KoSvgTextShape *mergeIntoShape = 0); 0078 0079 QStringList warnings() const; 0080 0081 protected: 0082 0083 /// Parses a group-like element element, saving all its topmost properties 0084 KoShape* parseGroup(const QDomElement &e, const QDomElement &overrideChildrenFrom = QDomElement(), bool createContext = true); 0085 0086 /// Get the path for the gives textPath element. 0087 KoShape* getTextPath(const QDomElement &e); 0088 0089 /// parse children of a <text /> element into the root shape. 0090 void parseTextChildren(const QDomElement &e, KoSvgTextLoader &textLoader); 0091 0092 /// Parses a container element, returning a list of child shapes 0093 QList<KoShape*> parseContainer(const QDomElement &, bool parseTextNodes = false); 0094 0095 /// XXX 0096 QList<KoShape*> parseSingleElement(const QDomElement &b, DeferredUseStore* deferredUseStore = 0); 0097 0098 /// Parses a use element, returning a list of child shapes 0099 KoShape* parseUse(const QDomElement &, DeferredUseStore* deferredUseStore); 0100 0101 KoShape* resolveUse(const QDomElement &e, const QString& key); 0102 0103 /// Parses a gradient element 0104 SvgGradientHelper *parseGradient(const QDomElement &); 0105 0106 /// Parses mesh gradient element 0107 SvgGradientHelper* parseMeshGradient(const QDomElement&); 0108 0109 /// Parses a single meshpatch and returns the pointer 0110 QList<QPair<QString, QColor>> parseMeshPatch(const QDomNode& meshpatch); 0111 0112 /// Parses a pattern element 0113 QSharedPointer<KoVectorPatternBackground> parsePattern(const QDomElement &e, const KoShape *__shape); 0114 0115 /// Parses a filter element 0116 bool parseFilter(const QDomElement &, const QDomElement &referencedBy = QDomElement()); 0117 0118 /// Parses a clip path element 0119 bool parseClipPath(const QDomElement &); 0120 bool parseClipMask(const QDomElement &e); 0121 0122 bool parseMarker(const QDomElement &e); 0123 0124 bool parseSymbol(const QDomElement &e); 0125 0126 /// parses a length attribute 0127 qreal parseUnit(const QString &, bool horiz = false, bool vert = false, const QRectF &bbox = QRectF()); 0128 0129 /// parses a length attribute in x-direction 0130 qreal parseUnitX(const QString &unit); 0131 0132 /// parses a length attribute in y-direction 0133 qreal parseUnitY(const QString &unit); 0134 0135 /// parses a length attribute in xy-direction 0136 qreal parseUnitXY(const QString &unit); 0137 0138 /// parses a angular attribute values, result in radians 0139 qreal parseAngular(const QString &unit); 0140 0141 KoShape *createObjectDirect(const QDomElement &b); 0142 0143 /// Creates an object from the given xml element 0144 KoShape * createObject(const QDomElement &, const SvgStyles &style = SvgStyles()); 0145 0146 /// Create path object from the given xml element 0147 KoShape * createPath(const QDomElement &); 0148 0149 /// find gradient with given id in gradient map 0150 SvgGradientHelper* findGradient(const QString &id); 0151 0152 /// find pattern with given id in pattern map 0153 QSharedPointer<KoVectorPatternBackground> findPattern(const QString &id, const KoShape *shape); 0154 0155 /// find filter with given id in filter map 0156 SvgFilterHelper* findFilter(const QString &id, const QString &href = QString()); 0157 0158 /// find clip path with given id in clip path map 0159 SvgClipPathHelper* findClipPath(const QString &id); 0160 0161 /// Adds list of shapes to the given group shape 0162 void addToGroup(QList<KoShape*> shapes, KoShapeContainer *group); 0163 0164 /// creates a shape from the given shape id 0165 KoShape * createShape(const QString &shapeID); 0166 0167 /// Creates shape from specified svg element 0168 KoShape * createShapeFromElement(const QDomElement &element, SvgLoadingContext &context); 0169 0170 /// Creates a shape from a CSS shapes definition. 0171 KoShape * createShapeFromCSS(const QDomElement e, const QString value, SvgLoadingContext &context); 0172 0173 /// Create a list of shapes from a CSS shapes definition with potentially multiple shapes. 0174 QList<KoShape*> createListOfShapesFromCSS(const QDomElement e, const QString value, SvgLoadingContext &context); 0175 0176 /// Builds the document from the given shapes list 0177 void buildDocument(QList<KoShape*> shapes); 0178 0179 void uploadStyleToContext(const QDomElement &e); 0180 void applyCurrentStyle(KoShape *shape, const QPointF &shapeToOriginalUserCoordinates); 0181 void applyCurrentBasicStyle(KoShape *shape); 0182 0183 /// Applies styles to the given shape 0184 void applyStyle(KoShape *, const QDomElement &, const QPointF &shapeToOriginalUserCoordinates); 0185 0186 /// Applies styles to the given shape 0187 void applyStyle(KoShape *, const SvgStyles &, const QPointF &shapeToOriginalUserCoordinates); 0188 0189 /// Applies the current fill style to the object 0190 void applyFillStyle(KoShape * shape); 0191 0192 /// Applies the current stroke style to the object 0193 void applyStrokeStyle(KoShape * shape); 0194 0195 /// Applies the current filter to the object 0196 void applyFilter(KoShape * shape); 0197 0198 /// Applies the current clip path to the object 0199 void applyClipping(KoShape *shape, const QPointF &shapeToOriginalUserCoordinates); 0200 void applyMaskClipping(KoShape *shape, const QPointF &shapeToOriginalUserCoordinates); 0201 void applyMarkers(KoPathShape *shape); 0202 0203 void applyPaintOrder(KoShape *shape); 0204 0205 /// Applies id to specified shape 0206 void applyId(const QString &id, KoShape *shape); 0207 0208 /// Applies viewBox transformation to the current graphical context 0209 /// NOTE: after applying the function currentBoundingBox can become null! 0210 void applyViewBoxTransform(const QDomElement &element); 0211 0212 private: 0213 SvgLoadingContext m_context; 0214 QMap<QString, SvgGradientHelper> m_gradients; 0215 QMap<QString, SvgFilterHelper> m_filters; 0216 QMap<QString, SvgClipPathHelper> m_clipPaths; 0217 QMap<QString, QSharedPointer<KoClipMask>> m_clipMasks; 0218 QMap<QString, QExplicitlySharedDataPointer<KoMarker>> m_markers; 0219 KoDocumentResourceManager *m_documentResourceManager; 0220 QList<KoShape*> m_shapes; 0221 QMap<QString, KoSvgSymbol*> m_symbols; 0222 QList<KoShape*> m_defsShapes; 0223 bool m_isInsideTextSubtree = false; 0224 QString m_documentTitle; 0225 QString m_documentDescription; 0226 QVector<KoID> m_warnings; 0227 QMap<KoShape *, QTransform> m_shapeParentTransform; 0228 }; 0229 0230 #endif