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 
8 #include <QByteArray>
9 #include <QCursor>
10 #include <QDrag>
11 #include <QFile>
12 #include <QList>
13 #include <QMimeData>
14 #include <QRegExp>
15 #include <QStack>
16 #include <QDebug>
17 
18 #include <cstdlib>
19 
20 #include "importsml.h"
21 
22 
23 #include "commonstrings.h"
24 #include "loadsaveplugin.h"
25 #include "pagesize.h"
26 #include "prefscontext.h"
27 #include "prefsfile.h"
28 #include "prefsmanager.h"
29 #include "prefstable.h"
30 #include "rawimage.h"
31 #include "scclocale.h"
32 #include "sccolorengine.h"
33 #include "scconfig.h"
34 #include "scmimedata.h"
35 #include "scpaths.h"
36 #include "scribusXml.h"
37 #include "scribuscore.h"
38 #include "scribusdoc.h"
39 #include "scribusview.h"
40 #include "sctextstream.h"
41 #include "selection.h"
42 #include "ui/customfdialog.h"
43 #include "ui/missing.h"
44 #include "ui/multiprogressdialog.h"
45 #include "ui/propertiespalette.h"
46 #include "undomanager.h"
47 #include "util.h"
48 #include "util_formats.h"
49 #include "util_math.h"
50 
SmlPlug(ScribusDoc * doc,int flags)51 SmlPlug::SmlPlug(ScribusDoc* doc, int flags)
52 {
53 	tmpSel=new Selection(this, false);
54 	m_Doc=doc;
55 	importerFlags = flags;
56 	interactive = (flags & LoadSavePlugin::lfInteractive);
57 	progressDialog = nullptr;
58 }
59 
readThumbnail(const QString & fName)60 QImage SmlPlug::readThumbnail(const QString& fName)
61 {
62 	QFileInfo fi = QFileInfo(fName);
63 	baseFile = QDir::cleanPath(QDir::toNativeSeparators(fi.absolutePath()+"/"));
64 	double b, h;
65 	parseHeader(fName, b, h);
66 	if (b == 0.0)
67 		b = PrefsManager::instance().appPrefs.docSetupPrefs.pageWidth;
68 	if (h == 0.0)
69 		h = PrefsManager::instance().appPrefs.docSetupPrefs.pageHeight;
70 	docWidth = b;
71 	docHeight = h;
72 	progressDialog = nullptr;
73 	m_Doc = new ScribusDoc();
74 	m_Doc->setup(0, 1, 1, 1, 1, "Custom", "Custom");
75 	m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false);
76 	m_Doc->addPage(0);
77 	m_Doc->setGUI(false, ScCore->primaryMainWindow(), nullptr);
78 	baseX = m_Doc->currentPage()->xOffset();
79 	baseY = m_Doc->currentPage()->yOffset();
80 	Elements.clear();
81 	m_Doc->setLoading(true);
82 	m_Doc->DoDrawing = false;
83 	m_Doc->scMW()->setScriptRunning(true);
84 	QString CurDirP = QDir::currentPath();
85 	QDir::setCurrent(fi.path());
86 	if (convert(fName))
87 	{
88 		tmpSel->clear();
89 		QDir::setCurrent(CurDirP);
90 		if (Elements.count() > 1)
91 			m_Doc->groupObjectsList(Elements);
92 		m_Doc->DoDrawing = true;
93 		m_Doc->m_Selection->delaySignalsOn();
94 		QImage tmpImage;
95 		if (Elements.count() > 0)
96 		{
97 			for (int dre=0; dre<Elements.count(); ++dre)
98 			{
99 				tmpSel->addItem(Elements.at(dre), true);
100 			}
101 			tmpSel->setGroupRect();
102 			double xs = tmpSel->width();
103 			double ys = tmpSel->height();
104 			tmpImage = Elements.at(0)->DrawObj_toImage(500);
105 			tmpImage.setText("XSize", QString("%1").arg(xs));
106 			tmpImage.setText("YSize", QString("%1").arg(ys));
107 		}
108 		m_Doc->scMW()->setScriptRunning(false);
109 		m_Doc->setLoading(false);
110 		m_Doc->m_Selection->delaySignalsOff();
111 		delete m_Doc;
112 		return tmpImage;
113 	}
114 	QDir::setCurrent(CurDirP);
115 	m_Doc->DoDrawing = true;
116 	m_Doc->scMW()->setScriptRunning(false);
117 	delete m_Doc;
118 	return QImage();
119 }
120 
import(const QString & fNameIn,const TransactionSettings & trSettings,int flags,bool showProgress)121 bool SmlPlug::import(const QString& fNameIn, const TransactionSettings& trSettings, int flags, bool showProgress)
122 {
123 	bool success = false;
124 	interactive = (flags & LoadSavePlugin::lfInteractive);
125 	importerFlags = flags;
126 	cancel = false;
127 	double b, h;
128 	bool ret = false;
129 	QFileInfo fi = QFileInfo(fNameIn);
130 	if ( !ScCore->usingGUI() )
131 	{
132 		interactive = false;
133 		showProgress = false;
134 	}
135 	baseFile = QDir::cleanPath(QDir::toNativeSeparators(fi.absolutePath()+"/"));
136 	if ( showProgress )
137 	{
138 		ScribusMainWindow* mw=(m_Doc==nullptr) ? ScCore->primaryMainWindow() : m_Doc->scMW();
139 		progressDialog = new MultiProgressDialog( tr("Importing: %1").arg(fi.fileName()), CommonStrings::tr_Cancel, mw );
140 		QStringList barNames, barTexts;
141 		barNames << "GI";
142 		barTexts << tr("Analyzing File:");
143 		QList<bool> barsNumeric;
144 		barsNumeric << false;
145 		progressDialog->addExtraProgressBars(barNames, barTexts, barsNumeric);
146 		progressDialog->setOverallTotalSteps(3);
147 		progressDialog->setOverallProgress(0);
148 		progressDialog->setProgress("GI", 0);
149 		progressDialog->show();
150 		connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelRequested()));
151 		qApp->processEvents();
152 	}
153 	else
154 		progressDialog = nullptr;
155 /* Set default Page to size defined in Preferences */
156 	b = 0.0;
157 	h = 0.0;
158 	if (progressDialog)
159 	{
160 		progressDialog->setOverallProgress(1);
161 		qApp->processEvents();
162 	}
163 	parseHeader(fNameIn, b, h);
164 	if (b == 0.0)
165 		b = PrefsManager::instance().appPrefs.docSetupPrefs.pageWidth;
166 	if (h == 0.0)
167 		h = PrefsManager::instance().appPrefs.docSetupPrefs.pageHeight;
168 	docWidth = b;
169 	docHeight = h;
170 	baseX = 0;
171 	baseY = 0;
172 	if (!interactive || (flags & LoadSavePlugin::lfInsertPage))
173 	{
174 		m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false);
175 		m_Doc->addPage(0);
176 		m_Doc->view()->addPage(0, true);
177 		baseX = 0;
178 		baseY = 0;
179 	}
180 	else
181 	{
182 		if (!m_Doc || (flags & LoadSavePlugin::lfCreateDoc))
183 		{
184 			m_Doc=ScCore->primaryMainWindow()->doFileNew(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false, 0, false, 0, 1, "Custom", true);
185 			ScCore->primaryMainWindow()->HaveNewDoc();
186 			ret = true;
187 			baseX = 0;
188 			baseY = 0;
189 			baseX = m_Doc->currentPage()->xOffset();
190 			baseY = m_Doc->currentPage()->yOffset();
191 		}
192 	}
193 	if ((!ret) && (interactive))
194 	{
195 		baseX = m_Doc->currentPage()->xOffset();
196 		baseY = m_Doc->currentPage()->yOffset();
197 	}
198 	if ((ret) || (!interactive))
199 	{
200 		if (docWidth > docHeight)
201 			m_Doc->setPageOrientation(1);
202 		else
203 			m_Doc->setPageOrientation(0);
204 		m_Doc->setPageSize("Custom");
205 	}
206 	if ((!(flags & LoadSavePlugin::lfLoadAsPattern)) && (m_Doc->view() != nullptr))
207 		m_Doc->view()->deselectItems();
208 	Elements.clear();
209 	m_Doc->setLoading(true);
210 	m_Doc->DoDrawing = false;
211 	if ((!(flags & LoadSavePlugin::lfLoadAsPattern)) && (m_Doc->view() != nullptr))
212 		m_Doc->view()->updatesOn(false);
213 	m_Doc->scMW()->setScriptRunning(true);
214 	qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
215 	QString CurDirP = QDir::currentPath();
216 	QDir::setCurrent(fi.path());
217 	if (convert(fNameIn))
218 	{
219 		tmpSel->clear();
220 		QDir::setCurrent(CurDirP);
221 		if ((Elements.count() > 1) && (!(importerFlags & LoadSavePlugin::lfCreateDoc)))
222 			m_Doc->groupObjectsList(Elements);
223 		m_Doc->DoDrawing = true;
224 		m_Doc->scMW()->setScriptRunning(false);
225 		m_Doc->setLoading(false);
226 		qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
227 		if ((Elements.count() > 0) && (!ret) && (interactive))
228 		{
229 			if (flags & LoadSavePlugin::lfScripted)
230 			{
231 				bool loadF = m_Doc->isLoading();
232 				m_Doc->setLoading(false);
233 				m_Doc->changed();
234 				m_Doc->setLoading(loadF);
235 				if (!(flags & LoadSavePlugin::lfLoadAsPattern))
236 				{
237 					m_Doc->m_Selection->delaySignalsOn();
238 					for (int dre=0; dre<Elements.count(); ++dre)
239 					{
240 						m_Doc->m_Selection->addItem(Elements.at(dre), true);
241 					}
242 					m_Doc->m_Selection->delaySignalsOff();
243 					m_Doc->m_Selection->setGroupRect();
244 					if (m_Doc->view() != nullptr)
245 						m_Doc->view()->updatesOn(true);
246 				}
247 			}
248 			else
249 			{
250 				m_Doc->DragP = true;
251 				m_Doc->DraggedElem = nullptr;
252 				m_Doc->DragElements.clear();
253 				m_Doc->m_Selection->delaySignalsOn();
254 				for (int dre=0; dre<Elements.count(); ++dre)
255 				{
256 					tmpSel->addItem(Elements.at(dre), true);
257 				}
258 				tmpSel->setGroupRect();
259 				ScElemMimeData* md = ScriXmlDoc::writeToMimeData(m_Doc, tmpSel);
260 				m_Doc->itemSelection_DeleteItem(tmpSel);
261 				m_Doc->view()->updatesOn(true);
262 				m_Doc->m_Selection->delaySignalsOff();
263 				// We must copy the TransationSettings object as it is owned
264 				// by handleObjectImport method afterwards
265 				TransactionSettings* transacSettings = new TransactionSettings(trSettings);
266 				m_Doc->view()->handleObjectImport(md, transacSettings);
267 				m_Doc->DragP = false;
268 				m_Doc->DraggedElem = nullptr;
269 				m_Doc->DragElements.clear();
270 			}
271 		}
272 		else
273 		{
274 			m_Doc->changed();
275 			m_Doc->reformPages();
276 			if (!(flags & LoadSavePlugin::lfLoadAsPattern))
277 				m_Doc->view()->updatesOn(true);
278 		}
279 		success = true;
280 	}
281 	else
282 	{
283 		QDir::setCurrent(CurDirP);
284 		m_Doc->DoDrawing = true;
285 		m_Doc->scMW()->setScriptRunning(false);
286 		if (!(flags & LoadSavePlugin::lfLoadAsPattern))
287 			m_Doc->view()->updatesOn(true);
288 		qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
289 	}
290 	if (interactive)
291 		m_Doc->setLoading(false);
292 	//CB If we have a gui we must refresh it if we have used the progressbar
293 	if (!(flags & LoadSavePlugin::lfLoadAsPattern))
294 	{
295 		if ((showProgress) && (!interactive))
296 			m_Doc->view()->DrawNew();
297 	}
298 	qApp->restoreOverrideCursor();
299 	return success;
300 }
301 
~SmlPlug()302 SmlPlug::~SmlPlug()
303 {
304 	delete progressDialog;
305 	delete tmpSel;
306 }
307 
parseHeader(const QString & fName,double & b,double & h)308 void SmlPlug::parseHeader(const QString& fName, double &b, double &h)
309 {
310 	QFile f(fName);
311 	if (f.open(QIODevice::ReadOnly))
312 	{
313 		QDomDocument docu("scridoc");
314 		docu.setContent(&f);
315 		QDomElement elem = docu.documentElement();
316 		QDomNode node = elem.firstChild();
317 		while (!node.isNull())
318 		{
319 			QDomElement pg = node.toElement();
320 			if (pg.tagName() == "Dimensions")
321 			{
322 				b = ScCLocale::toDoubleC(pg.attribute("w"), 50.0);
323 				h = ScCLocale::toDoubleC(pg.attribute("h"), 50.0);
324 				break;
325 			}
326 			node = node.nextSibling();
327 		}
328 		f.close();
329 	}
330 }
331 
convert(const QString & fn)332 bool SmlPlug::convert(const QString& fn)
333 {
334 	CurrColorFill = "White";
335 	CurrFillShade = 100.0;
336 	CurrColorStroke = "Black";
337 	CurrStrokeShade = 100.0;
338 	LineW = 1.0;
339 	Dash = Qt::SolidLine;
340 	LineEnd = Qt::FlatCap;
341 	LineJoin = Qt::MiterJoin;
342 	fillStyle = 1;
343 	Coords.resize(0);
344 	Coords.svgInit();
345 	importedColors.clear();
346 	QList<PageItem*> gElements;
347 	groupStack.push(gElements);
348 	currentItemNr = 0;
349 	if (progressDialog)
350 	{
351 		progressDialog->setOverallProgress(2);
352 		progressDialog->setLabel("GI", tr("Generating Items"));
353 		qApp->processEvents();
354 	}
355 	QFile f(fn);
356 	if (f.open(QIODevice::ReadOnly))
357 	{
358 		QDomDocument docu("scridoc");
359 		docu.setContent(&f);
360 		QDomElement elem = docu.documentElement();
361 		if (elem.tagName() != "KivioShapeStencil")
362 			return false;
363 		QDomNode node = elem.firstChild();
364 		while (!node.isNull())
365 		{
366 			QDomElement pg = node.toElement();
367 			if (pg.tagName() == "KivioShape")
368 				processShapeNode(pg);
369 			node = node.nextSibling();
370 		}
371 		if (Elements.count() == 0)
372 		{
373 			if (importedColors.count() != 0)
374 			{
375 				for (int cd = 0; cd < importedColors.count(); cd++)
376 				{
377 					m_Doc->PageColors.remove(importedColors[cd]);
378 				}
379 			}
380 		}
381 		f.close();
382 	}
383 	if (progressDialog)
384 		progressDialog->close();
385 	return true;
386 }
387 
finishItem(QDomElement & e,PageItem * ite)388 void SmlPlug::finishItem(QDomElement &e, PageItem* ite)
389 {
390 	ite->ClipEdited = true;
391 	ite->FrameType = 3;
392 	ite->setFillShade(CurrFillShade);
393 	ite->setLineShade(CurrStrokeShade);
394 	ite->setLineJoin(LineJoin);
395 	ite->setLineEnd(LineEnd);
396 	ite->setTextFlowMode(PageItem::TextFlowDisabled);
397 	ite->PoLine.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
398 	m_Doc->adjustItemSize(ite);
399 	ite->OldB2 = ite->width();
400 	ite->OldH2 = ite->height();
401 	ite->updateClip();
402 	ite->setItemName(e.attribute("name"));
403 	ite->AutoName = false;
404 	Elements.append(ite);
405 	Coords.resize(0);
406 	Coords.svgInit();
407 }
408 
processShapeNode(QDomElement & elem)409 void SmlPlug::processShapeNode(QDomElement &elem)
410 {
411 	Coords.resize(0);
412 	Coords.svgInit();
413 	currx = 0.0;
414 	curry = 0.0;
415 	startx = 0.0;
416 	starty = 0.0;
417 	count = 0;
418 	first = true;
419 	if (elem.hasChildNodes())
420 	{
421 		QDomNode node = elem.firstChild();
422 		while (!node.isNull())
423 		{
424 			QDomElement pg = node.toElement();
425 			if (pg.tagName() == "KivioLineStyle")
426 				processStrokeNode(pg);
427 			else if (pg.tagName() == "KivioFillStyle")
428 				processFillNode(pg);
429 			else if (pg.tagName() == "KivioPoint")
430 				processPointNode(pg);
431 			else if (pg.tagName() == "Line")
432 				processLineNode(pg);
433 			node = node.nextSibling();
434 		}
435 	}
436 	QString typ = elem.attribute("type");
437 	if (typ == "Rectangle")
438 	{
439 		double x = ScCLocale::toDoubleC(elem.attribute("x"));
440 		double y = ScCLocale::toDoubleC(elem.attribute("y"));
441 		double w = ScCLocale::toDoubleC(elem.attribute("w"));
442 		double h = ScCLocale::toDoubleC(elem.attribute("h"));
443 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, baseX + x, baseY + y, w, h, LineW, CurrColorFill, CurrColorStroke);
444 		finishItem(elem, m_Doc->Items->at(z));
445 	}
446 	else if (typ == "RoundRectangle")
447 	{
448 		double x = ScCLocale::toDoubleC(elem.attribute("x"));
449 		double y = ScCLocale::toDoubleC(elem.attribute("y"));
450 		double w = ScCLocale::toDoubleC(elem.attribute("w"));
451 		double h = ScCLocale::toDoubleC(elem.attribute("h"));
452 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, baseX + x, baseY + y, w, h, LineW, CurrColorFill, CurrColorStroke);
453 		m_Doc->Items->at(z)->setCornerRadius(qMax(ScCLocale::toDoubleC(elem.attribute("r1")), ScCLocale::toDoubleC(elem.attribute("r2"))));
454 		m_Doc->Items->at(z)->SetFrameRound();
455 		finishItem(elem, m_Doc->Items->at(z));
456 	}
457 	else if (typ == "Ellipse")
458 	{
459 		double x = ScCLocale::toDoubleC(elem.attribute("x"));
460 		double y = ScCLocale::toDoubleC(elem.attribute("y"));
461 		double w = ScCLocale::toDoubleC(elem.attribute("w"));
462 		double h = ScCLocale::toDoubleC(elem.attribute("h"));
463 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, baseX + x, baseY + y, w, h, LineW, CurrColorFill, CurrColorStroke);
464 		finishItem(elem, m_Doc->Items->at(z));
465 	}
466 	else if ((typ == "Polygon") || (typ == "ClosedPath"))
467 	{
468 		int z;
469 		FPoint s = Coords.point(0);
470 		FPoint e = Coords.point(Coords.count() - 1);
471 		if (s == e)
472 			z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColorFill, CurrColorStroke);
473 		else
474 			z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColorFill, CurrColorStroke);
475 		m_Doc->Items->at(z)->PoLine = Coords.copy();
476 		finishItem(elem, m_Doc->Items->at(z));
477 	}
478 	else if ((typ == "Bezier") || (typ == "OpenPath") || (typ == "LineArray") || (typ == "Polyline"))
479 	{
480 		int	z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColorFill, CurrColorStroke);
481 		m_Doc->Items->at(z)->PoLine = Coords.copy();
482 		finishItem(elem, m_Doc->Items->at(z));
483 	}
484 	if (typ == "TextBox")
485 	{
486 		double x = ScCLocale::toDoubleC(elem.attribute("x"));
487 		double y = ScCLocale::toDoubleC(elem.attribute("y"));
488 		double w = ScCLocale::toDoubleC(elem.attribute("w"));
489 		double h = ScCLocale::toDoubleC(elem.attribute("h"));
490 		int z = m_Doc->itemAdd(PageItem::TextFrame, PageItem::Rectangle, baseX + x, baseY + y, w, h, 0, CommonStrings::None, CommonStrings::None);
491 		finishItem(elem, m_Doc->Items->at(z));
492 	}
493 	else if (typ == "Line")
494 	{
495 		double x = ScCLocale::toDoubleC(elem.attribute("x1"));
496 		double y = ScCLocale::toDoubleC(elem.attribute("y1"));
497 		double x1 = ScCLocale::toDoubleC(elem.attribute("x2"));
498 		double y1 = ScCLocale::toDoubleC(elem.attribute("y2"));
499 		Coords.addPoint(x, y);
500 		Coords.addPoint(x, y);
501 		Coords.addPoint(x1, y1);
502 		Coords.addPoint(x1, y1);
503 		int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CommonStrings::None, CurrColorStroke);
504 		m_Doc->Items->at(z)->PoLine = Coords.copy();
505 		finishItem(elem, m_Doc->Items->at(z));
506 	}
507 }
508 
processColor(QDomElement & elem)509 QString SmlPlug::processColor(QDomElement &elem)
510 {
511 	QString colnam = elem.attribute("color","#ffffff");
512 	QColor stroke;
513 	stroke.setNamedColor("#"+colnam.right(6));
514 	ScColor tmp;
515 	tmp.fromQColor(stroke);
516 	tmp.setSpotColor(false);
517 	tmp.setRegistrationColor(false);
518 	QString newColorName = "FromSML"+tmp.name();
519 	QString fNam = m_Doc->PageColors.tryAddColor(newColorName, tmp);
520 	if (fNam == newColorName)
521 		importedColors.append(newColorName);
522 	return fNam;
523 }
524 
processStrokeNode(QDomElement & elem)525 void SmlPlug::processStrokeNode(QDomElement &elem)
526 {
527 	CurrColorStroke = processColor(elem);
528 	LineW = ScCLocale::toDoubleC(elem.attribute("width"), 1.0);
529 	LineJoin = Qt::PenJoinStyle(elem.attribute("joinStyle", "0").toInt());
530 	Dash = Qt::PenStyle(elem.attribute("pattern", "1").toInt());
531 	LineEnd = Qt::PenCapStyle(elem.attribute("capStyle", "0").toInt());
532 }
533 
processFillNode(QDomElement & elem)534 void SmlPlug::processFillNode(QDomElement &elem)
535 {
536 	fillStyle = elem.attribute("colorStyle","1").toInt();
537 	if (fillStyle == 0)
538 		CurrColorFill = CommonStrings::None;
539 	else
540 		CurrColorFill = processColor(elem);
541 }
542 
processLineNode(QDomElement & elem)543 void SmlPlug::processLineNode(QDomElement &elem)
544 {
545 	double x = ScCLocale::toDoubleC(elem.attribute("x1"));
546 	double y = ScCLocale::toDoubleC(elem.attribute("y1"));
547 	double x1 = ScCLocale::toDoubleC(elem.attribute("x2"));
548 	double y1 = ScCLocale::toDoubleC(elem.attribute("y2"));
549 	if (!first)
550 		Coords.setMarker();
551 	Coords.addPoint(x, y);
552 	Coords.addPoint(x, y);
553 	Coords.addPoint(x1, y1);
554 	Coords.addPoint(x1, y1);
555 	first = false;
556 }
557 
processPointNode(QDomElement & elem)558 void SmlPlug::processPointNode(QDomElement &elem)
559 {
560 	double x = ScCLocale::toDoubleC(elem.attribute("x"));
561 	double y = ScCLocale::toDoubleC(elem.attribute("y"));
562 	if (first)
563 	{
564 		currx = x;
565 		curry = y;
566 		startx = x;
567 		starty = y;
568 		first = false;
569 		if (elem.attribute("type") == "bezier")
570 			count = 0;
571 		else
572 			count = -1;
573 	}
574 	else
575 	{
576 		if (elem.attribute("type") != "bezier")
577 		{
578 			Coords.addPoint(currx, curry);
579 			Coords.addPoint(currx, curry);
580 			Coords.addPoint(x, y);
581 			Coords.addPoint(x, y);
582 			currx = x;
583 			curry = y;
584 		}
585 		else
586 		{
587 			if (count == -1)
588 			{
589 				if (FPoint(currx, curry) != FPoint(x, y))
590 				{
591 					Coords.addPoint(currx, curry);
592 					Coords.addPoint(currx, curry);
593 					Coords.addPoint(x, y);
594 					Coords.addPoint(x, y);
595 				}
596 				currx = x;
597 				curry = y;
598 				count++;
599 			}
600 			else if (count == 0)
601 			{
602 				Coords.addPoint(currx, curry);
603 				Coords.addPoint(x, y);
604 				count++;
605 			}
606 			else if (count == 1)
607 			{
608 				currx = x;
609 				curry = y;
610 				count++;
611 			}
612 			else if (count == 2)
613 			{
614 				Coords.addPoint(x, y);
615 				Coords.addPoint(currx, curry);
616 				currx = x;
617 				curry = y;
618 				count = -1;
619 			}
620 		}
621 	}
622 }
623