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