1 /*
2 For general Scribus (>=1.3.2) copyright and licensing information please refer
3 to the COPYING file provided with the program. Following this notice may exist
4 a copyright and/or license notice that predates the release of Scribus 1.3.2
5 for which a new license (GPL+exception) is in place.
6 */
7 #ifndef SVGPLUG_H
8 #define SVGPLUG_H
9 
10 #include <QDomElement>
11 #include <QFont>
12 #include <QList>
13 #include <QRectF>
14 #include <QSizeF>
15 #include <QStack>
16 #include "pluginapi.h"
17 #include "loadsaveplugin.h"
18 #include "../../formatidlist.h"
19 #include "vgradient.h"
20 
21 class ScrAction;
22 class ScribusMainWindow;
23 class TransactionSettings;
24 
25 /**
26  * \brief A class providing the plugin interface implementation for this plugin
27  */
28 class PLUGIN_API SVGImportPlugin : public LoadSavePlugin
29 {
30 	Q_OBJECT
31 
32 	public:
33 		// Standard plugin implementation
34 		SVGImportPlugin();
35 		virtual ~SVGImportPlugin();
36 		QString fullTrName() const override;
37 		const AboutData* getAboutData() const override;
38 		void deleteAboutData(const AboutData* about) const override;
39 		void languageChange() override;
40 		bool fileSupported(QIODevice* file, const QString & fileName=QString()) const override;
41 		bool loadFile(const QString & fileName, const FileFormat & fmt, int flags, int index = 0) override;
42 		QImage readThumbnail(const QString& fileName) override;
addToMainWindowMenu(ScribusMainWindow *)43 		void addToMainWindowMenu(ScribusMainWindow *) override {};
44 
45 	public slots:
46 		/*!
47 		\author Franz Schmid
48 		\brief Run the SVG import
49 		\param filename a file name to import
50 		\retval true for success
51 		 */
52 		virtual bool import(QString filename = QString(), int flags = lfUseCurrentPage|lfInteractive);
53 
54 	private:
55 		void registerFormats();
56 		ScrAction* importAction;
57 
58 };
59 
60 extern "C" PLUGIN_API int svgimplugin_getPluginAPIVersion();
61 extern "C" PLUGIN_API ScPlugin* svgimplugin_getPlugin();
62 extern "C" PLUGIN_API void svgimplugin_freePlugin(ScPlugin* plugin);
63 
64 class PageItem;
65 class ScribusDoc;
66 class PrefsManager;
67 class FPointArray;
68 
69 class GradientHelper
70 {
71 public:
GradientHelper()72 	GradientHelper() :
73 		cspace(false),
74 		cspaceValid(true),
75 		gradient(VGradient::linear),
76 		gradientValid(false),
77 		matrix(),
78 		matrixValid(false),
79 		reference(""),
80 		type(1),
81 		typeValid(false),
82 		x1(0),
83 		x1Valid(true),
84 		x2(1),
85 		x2Valid(true),
86 		y1(0),
87 		y1Valid(true),
88 		y2(0),
89 		y2Valid(true),
90 		fx(0),
91 		fxValid(true),
92 		fy(0),
93 		fyValid(true)
94 		{
95 		}
96 	bool cspace;
97 	bool cspaceValid;
98 	VGradient gradient;
99 	bool gradientValid;
100 	QTransform matrix;
101 	bool matrixValid;
102 	QString reference;
103 	int type;
104 	bool typeValid;
105 	double x1;
106 	bool x1Valid;
107 	double x2;
108 	bool x2Valid;
109 	double y1;
110 	bool y1Valid;
111 	double y2;
112 	bool y2Valid;
113 	double fx;
114 	bool fxValid;
115 	double fy;
116 	bool fyValid;
117 	};
118 
119 class SvgStyle
120 {
121 public:
SvgStyle()122 	SvgStyle() :
123 		Display(true),
124 		FillCSpace(false),
125 		StrokeCSpace(false),
126 		CurCol("Black"),
127 		dashOffset(0),
128 		FontFamily(""),
129 		FontStyle("normal"),
130 		FontWeight("normal"),
131 		FontStretch("normal"),
132 		FontSize(12),
133 		FillCol("Black"),
134 		fillRule("nonzero"),
135 		GFillCol1("Black"),
136 		GStrokeCol1("Black"),
137 		FillGradient(VGradient::linear),
138 		StrokeGradient(VGradient::linear),
139 		FillGradientType(0),
140 		StrokeGradientType(0),
141 		GradFillX1(0),
142 		GradFillX2(0),
143 		GradFillY1(0),
144 		GradFillY2(0),
145 		GradFillFX(0),
146 		GradFillFY(0),
147 		GradStrokeX1(0),
148 		GradStrokeX2(0),
149 		GradStrokeY1(0),
150 		GradStrokeY2(0),
151 		GradStrokeFX(0),
152 		GradStrokeFY(0),
153 		InherCol(false),
154 		LWidth(1.0),
155 		matrix(),
156 		matrixgf(),
157 		matrixgs(),
158 		PLineArt(Qt::SolidLine),
159 		PLineEnd(Qt::FlatCap),
160 		PLineJoin(Qt::MiterJoin),
161 		StrokeCol("None"),
162 		Opacity(1.0),
163 		FillOpacity(1.0),
164 		StrokeOpacity(1.0),
165 		textAnchor("start"),
166 		clipPath(),
167 		endMarker(""),
168 		startMarker("")
169 		{
170 		}
171 	bool Display;
172 	bool FillCSpace;
173 	bool StrokeCSpace;
174 	QString CurCol;
175 	QVector<double> dashArray;
176 	double dashOffset;
177 	QString FontFamily;
178 	QString FontStyle;
179 	QString FontWeight;
180 	QString FontStretch;
181 	double  FontSize;
182 	QString FillCol;
183 	QString fillRule;
184 	QString GFillCol1;
185 	QString GStrokeCol1;
186 	VGradient FillGradient;
187 	VGradient StrokeGradient;
188 	int    FillGradientType;
189 	int    StrokeGradientType;
190 	double GradFillX1;
191 	double GradFillX2;
192 	double GradFillY1;
193 	double GradFillY2;
194 	double GradFillFX;
195 	double GradFillFY;
196 	double GradStrokeX1;
197 	double GradStrokeX2;
198 	double GradStrokeY1;
199 	double GradStrokeY2;
200 	double GradStrokeFX;
201 	double GradStrokeFY;
202 	bool InherCol;
203 	double LWidth;
204 	QTransform matrix;
205 	QTransform matrixgf;
206 	QTransform matrixgs;
207 	Qt::PenStyle PLineArt;
208 	Qt::PenCapStyle PLineEnd;
209 	Qt::PenJoinStyle PLineJoin;
210 	QString StrokeCol;
211 	double Opacity;
212 	double FillOpacity;
213 	double StrokeOpacity;
214 	QString textAnchor;
215 	QString textDecoration;
216 	FPointArray clipPath;
217 	QString filter;
218 	QString endMarker;
219 	QString startMarker;
220 };
221 
222 class SVGPlug : public QObject
223 {
224 	Q_OBJECT
225 
226 public:
227 	/*!
228 	\author Franz Schmid
229 	\brief Create the SVG importer window
230 	\param fName QString
231 	\param isInteractive flag to use GUI
232 	 */
233 	SVGPlug(ScribusDoc* doc, int flags);
234 	~SVGPlug();
235 	bool import(const QString& fname, const TransactionSettings& trSettings, int flags);
236 	QImage readThumbnail(const QString& fn);
237 	bool loadData(const QString& fname);
238 	void convert(const TransactionSettings& trSettings, int flags);
239 	void addGraphicContext();
240 	void setupNode( const QDomElement &e );
241 	void setupTransform( const QDomElement &e );
242 	PageItem* finishNode( const QDomNode &e, PageItem* item);
243 	bool isIgnorableNode( const QDomElement &e );
244 	bool isIgnorableNodeName( const QString &n );
245 	FPoint parseTextPosition(const QDomElement &e, const FPoint* pos = nullptr);
246 	QSizeF  parseWidthHeight(const QDomElement &e);
247 	QRectF  parseViewBox(const QDomElement &e);
248 	void parseDefs(const QDomElement &e);
249 	void parseClipPath(const QDomElement &e);
250 	void parseClipPathAttr(const QDomElement &e, FPointArray& clipPath);
251 	void parseFilterAttr(const QDomElement &e, PageItem* item);
252 	QList<PageItem*> parseA(const QDomElement &e);
253 	QList<PageItem*> parseGroup(const QDomElement &e);
254 	QList<PageItem*> parseDoc(const QDomElement &e);
255 	QList<PageItem*> parseElement(const QDomElement &e);
256 	QList<PageItem*> parseCircle(const QDomElement &e);
257 	QList<PageItem*> parseEllipse(const QDomElement &e);
258 	QList<PageItem*> parseImage(const QDomElement &e);
259 	QList<PageItem*> parseLine(const QDomElement &e);
260 	QList<PageItem*> parsePath(const QDomElement &e);
261 	QList<PageItem*> parsePolyline(const QDomElement &e);
262 	QList<PageItem*> parseRect(const QDomElement &e);
263 	QList<PageItem*> parseText(const QDomElement &e);
264 	QList<PageItem*> parseTextSpan(const QDomElement& e, FPoint& currentPos, double chunkW);
265 	QList<PageItem*> parseTextNode(const QDomText& e, FPoint& currentPos, double chunkW);
266 	QList<PageItem*> parseSwitch(const QDomElement &e);
267 	QList<PageItem*> parseSymbol(const QDomElement &e);
268 	QList<PageItem*> parseUse(const QDomElement &e);
269 	const char* getCoord( const char *ptr, double &number );
270 	QFont       getFontFromStyle(SvgStyle& style);
271 	QDomElement getReferencedNode(const QDomElement &e);
272 	bool        getTextChunkWidth(const QDomElement &e, double& width);
273 	double  fromPercentage(const QString &s );
274 	double  parseFontSize(const QString& fsize);
275 	double  parseUnit(const QString &unit);
276 	QTransform parseTransform(const QString &transform);
277 	QString parseColor( const QString &s );
278 	QString parseIccColor( const QString &s );
279 	QString parseTagName( const QDomElement &e );
280 	void parsePA( SvgStyle *obj, const QString &command, const QString &params );
281 	void parseStyle( SvgStyle *obj, const QDomElement &e );
282 	void parseColorStops(GradientHelper *gradient, const QDomElement &e);
283 	void parseFilter(const QDomElement &b);
284 	void parseMarker(const QDomElement &b);
285 	void parsePattern(const QDomElement &b);
286 	void parseGradient( const QDomElement &e );
287 	FPoint GetMaxClipO(FPointArray Clip);
288 	FPoint GetMinClipO(FPointArray Clip);
289 	QDomDocument inpdoc;
290 	QString docDesc;
291 	QString docTitle;
292 	int groupLevel;
293 	QStack<SvgStyle*>	m_gc;
294 	QMap<QString, GradientHelper>	m_gradients;
295 	QMap<QString, QDomElement>		m_nodeMap;
296 	QMap<QString, FPointArray>		m_clipPaths;
297 	QMap<QString, QString>			m_unsupportedFeatures;
298 	bool PathClosed;
299 	double viewTransformX;
300 	double viewTransformY;
301 	double viewScaleX;
302 	double viewScaleY;
303 	bool interactive;
304 	//! \brief Indicator if there is any unsupported feature in imported svg.
305 	bool unsupported;
306 	bool importFailed;
307 	bool importCanceled;
308 	ScribusDoc* m_Doc;
309 	Selection* tmpSel;
310 	QStringList importedColors;
311 	QStringList importedGradients;
312 	QMap<QString, QString> importedGradTrans;
313 	QStringList importedPatterns;
314 	QMap<QString, QString> importedPattTrans;
315 	double inGroupXOrigin;
316 	double inGroupYOrigin;
317 	int importerFlags;
318 	bool firstLayer;
319 	struct filterSpec
320 	{
321 		int blendMode;
322 	};
323 	struct markerDesc
324 	{
325 		double xref;
326 		double yref;
327 		double wpat;
328 		double hpat;
329 	};
330 	QMap<QString, filterSpec> filters;
331 	QMap<QString, markerDesc> markers;
332 	QList<PageItem*> Elements;
333 
334 protected:
335 	QVector<double> parseNumbersList(const QString& numbersStr);
336 };
337 
338 #endif
339