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                           importdrw.cpp  -  description
9                              -------------------
10     begin                : Mon Jan 11 2010
11     copyright            : (C) 2010 by Franz Schmid
12     email                : Franz.Schmid@altmuehlnet.de
13  ***************************************************************************/
14 
15 #include <QByteArray>
16 #include <QCursor>
17 #include <QDrag>
18 #include <QFile>
19 #include <QList>
20 #include <QMimeData>
21 #include <QRegExp>
22 #include <QStack>
23 #include <QDebug>
24 
25 #include <cstdlib>
26 
27 #include "importdrw.h"
28 
29 #include "commonstrings.h"
30 #include "loadsaveplugin.h"
31 #include "pageitem_imageframe.h"
32 #include "pagesize.h"
33 #include "prefscontext.h"
34 #include "prefsfile.h"
35 #include "prefsmanager.h"
36 #include "prefstable.h"
37 #include "rawimage.h"
38 #include "scclocale.h"
39 #include "sccolorengine.h"
40 #include "scconfig.h"
41 #include "scmimedata.h"
42 #include "scpaths.h"
43 #include "scpattern.h"
44 #include "scribusXml.h"
45 #include "scribuscore.h"
46 #include "scribusdoc.h"
47 #include "scribusview.h"
48 #include "sctextstream.h"
49 #include "selection.h"
50 #include "ui/customfdialog.h"
51 #include "ui/missing.h"
52 #include "ui/multiprogressdialog.h"
53 #include "ui/propertiespalette.h"
54 #include "undomanager.h"
55 #include "util.h"
56 #include "util_formats.h"
57 #include "util_math.h"
58 
DrwPlug(ScribusDoc * doc,int flags)59 DrwPlug::DrwPlug(ScribusDoc* doc, int flags)
60 {
61 	tmpSel=new Selection(this, false);
62 	m_Doc=doc;
63 	importerFlags = flags;
64 	interactive = (flags & LoadSavePlugin::lfInteractive);
65 	progressDialog = nullptr;
66 }
67 
readThumbnail(const QString & fName)68 QImage DrwPlug::readThumbnail(const QString& fName)
69 {
70 	QFileInfo fi = QFileInfo(fName);
71 	baseFile = QDir::cleanPath(QDir::toNativeSeparators(fi.absolutePath()+"/"));
72 	double b = PrefsManager::instance().appPrefs.docSetupPrefs.pageWidth;
73 	double h = PrefsManager::instance().appPrefs.docSetupPrefs.pageHeight;
74 	docWidth = b;
75 	docHeight = h;
76 	progressDialog = nullptr;
77 	m_Doc = new ScribusDoc();
78 	m_Doc->setup(0, 1, 1, 1, 1, "Custom", "Custom");
79 	m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false);
80 	m_Doc->addPage(0);
81 	m_Doc->setGUI(false, ScCore->primaryMainWindow(), nullptr);
82 	baseX = m_Doc->currentPage()->xOffset();
83 	baseY = m_Doc->currentPage()->yOffset();
84 	Elements.clear();
85 	m_Doc->setLoading(true);
86 	m_Doc->DoDrawing = false;
87 	m_Doc->scMW()->setScriptRunning(true);
88 	QString CurDirP = QDir::currentPath();
89 	QDir::setCurrent(fi.path());
90 	if (convert(fName))
91 	{
92 		if (!thumbRead)
93 		{
94 			tmpSel->clear();
95 			QDir::setCurrent(CurDirP);
96 			if (Elements.count() > 1)
97 				m_Doc->groupObjectsList(Elements);
98 		}
99 		m_Doc->DoDrawing = true;
100 		m_Doc->m_Selection->delaySignalsOn();
101 		QImage tmpImage;
102 		if (thumbRead)
103 		{
104 			tmpImage = thumbnailImage;
105 			tmpImage.setText("XSize", QString("%1").arg(docWidth));
106 			tmpImage.setText("YSize", QString("%1").arg(docHeight));
107 		}
108 		else
109 		{
110 			if (Elements.count() > 0)
111 			{
112 				for (int dre=0; dre<Elements.count(); ++dre)
113 				{
114 					tmpSel->addItem(Elements.at(dre), true);
115 				}
116 				tmpSel->setGroupRect();
117 				double xs = tmpSel->width();
118 				double ys = tmpSel->height();
119 				tmpImage = Elements.at(0)->DrawObj_toImage(500);
120 				tmpImage.setText("XSize", QString("%1").arg(xs));
121 				tmpImage.setText("YSize", QString("%1").arg(ys));
122 			}
123 		}
124 		m_Doc->scMW()->setScriptRunning(false);
125 		m_Doc->setLoading(false);
126 		m_Doc->m_Selection->delaySignalsOff();
127 		delete m_Doc;
128 		return tmpImage;
129 	}
130 	QDir::setCurrent(CurDirP);
131 	m_Doc->DoDrawing = true;
132 	m_Doc->scMW()->setScriptRunning(false);
133 	delete m_Doc;
134 	return QImage();
135 }
136 
import(const QString & fNameIn,const TransactionSettings & trSettings,int flags,bool showProgress)137 bool DrwPlug::import(const QString& fNameIn, const TransactionSettings& trSettings, int flags, bool showProgress)
138 {
139 	bool success = false;
140 	interactive = (flags & LoadSavePlugin::lfInteractive);
141 	importerFlags = flags;
142 	cancel = false;
143 	double b, h;
144 	bool ret = false;
145 	QFileInfo fi = QFileInfo(fNameIn);
146 	if ( !ScCore->usingGUI() )
147 	{
148 		interactive = false;
149 		showProgress = false;
150 	}
151 	baseFile = QDir::cleanPath(QDir::toNativeSeparators(fi.absolutePath()+"/"));
152 	if ( showProgress )
153 	{
154 		ScribusMainWindow* mw=(m_Doc==nullptr) ? ScCore->primaryMainWindow() : m_Doc->scMW();
155 		progressDialog = new MultiProgressDialog( tr("Importing: %1").arg(fi.fileName()), CommonStrings::tr_Cancel, mw );
156 		QStringList barNames, barTexts;
157 		barNames << "GI";
158 		barTexts << tr("Analyzing File:");
159 		QList<bool> barsNumeric;
160 		barsNumeric << false;
161 		progressDialog->addExtraProgressBars(barNames, barTexts, barsNumeric);
162 		progressDialog->setOverallTotalSteps(3);
163 		progressDialog->setOverallProgress(0);
164 		progressDialog->setProgress("GI", 0);
165 		progressDialog->show();
166 		connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelRequested()));
167 		qApp->processEvents();
168 	}
169 	else
170 		progressDialog = nullptr;
171 /* Set default Page to size defined in Preferences */
172 	b = 0.0;
173 	h = 0.0;
174 	if (progressDialog)
175 	{
176 		progressDialog->setOverallProgress(1);
177 		qApp->processEvents();
178 	}
179 	b = PrefsManager::instance().appPrefs.docSetupPrefs.pageWidth;
180 	h = PrefsManager::instance().appPrefs.docSetupPrefs.pageHeight;
181 	docWidth = b;
182 	docHeight = h;
183 	baseX = 0;
184 	baseY = 0;
185 	if (!interactive || (flags & LoadSavePlugin::lfInsertPage))
186 	{
187 		m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false);
188 		m_Doc->addPage(0);
189 		m_Doc->view()->addPage(0, true);
190 		baseX = 0;
191 		baseY = 0;
192 		baseX = m_Doc->currentPage()->xOffset();
193 		baseY = m_Doc->currentPage()->yOffset();
194 	}
195 	else
196 	{
197 		if (!m_Doc || (flags & LoadSavePlugin::lfCreateDoc))
198 		{
199 			m_Doc=ScCore->primaryMainWindow()->doFileNew(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false, 0, false, 0, 1, "Custom", true);
200 			ScCore->primaryMainWindow()->HaveNewDoc();
201 			ret = true;
202 			baseX = 0;
203 			baseY = 0;
204 			baseX = m_Doc->currentPage()->xOffset();
205 			baseY = m_Doc->currentPage()->yOffset();
206 		}
207 	}
208 	if ((!ret) && (interactive))
209 	{
210 		baseX = m_Doc->currentPage()->xOffset();
211 		baseY = m_Doc->currentPage()->yOffset();
212 	}
213 	if ((ret) || (!interactive))
214 	{
215 		if (docWidth > docHeight)
216 			m_Doc->setPageOrientation(1);
217 		else
218 			m_Doc->setPageOrientation(0);
219 		m_Doc->setPageSize("Custom");
220 	}
221 	if ((!(flags & LoadSavePlugin::lfLoadAsPattern)) && (m_Doc->view() != nullptr))
222 		m_Doc->view()->deselectItems();
223 	Elements.clear();
224 	m_Doc->setLoading(true);
225 	m_Doc->DoDrawing = false;
226 	if ((!(flags & LoadSavePlugin::lfLoadAsPattern)) && (m_Doc->view() != nullptr))
227 		m_Doc->view()->updatesOn(false);
228 	m_Doc->scMW()->setScriptRunning(true);
229 	qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
230 	QString CurDirP = QDir::currentPath();
231 	QDir::setCurrent(fi.path());
232 	if (convert(fNameIn))
233 	{
234 		tmpSel->clear();
235 		QDir::setCurrent(CurDirP);
236 		if ((Elements.count() > 1) && (!(importerFlags & LoadSavePlugin::lfCreateDoc)))
237 			m_Doc->groupObjectsList(Elements);
238 		m_Doc->DoDrawing = true;
239 		m_Doc->scMW()->setScriptRunning(false);
240 		m_Doc->setLoading(false);
241 		qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
242 		if ((Elements.count() > 0) && (!ret) && (interactive))
243 		{
244 			if (flags & LoadSavePlugin::lfScripted)
245 			{
246 				bool loadF = m_Doc->isLoading();
247 				m_Doc->setLoading(false);
248 				m_Doc->changed();
249 				m_Doc->setLoading(loadF);
250 				if (!(flags & LoadSavePlugin::lfLoadAsPattern))
251 				{
252 					m_Doc->m_Selection->delaySignalsOn();
253 					for (int dre=0; dre<Elements.count(); ++dre)
254 					{
255 						m_Doc->m_Selection->addItem(Elements.at(dre), true);
256 					}
257 					m_Doc->m_Selection->delaySignalsOff();
258 					m_Doc->m_Selection->setGroupRect();
259 					if (m_Doc->view() != nullptr)
260 						m_Doc->view()->updatesOn(true);
261 				}
262 			}
263 			else
264 			{
265 				m_Doc->DragP = true;
266 				m_Doc->DraggedElem = nullptr;
267 				m_Doc->DragElements.clear();
268 				m_Doc->m_Selection->delaySignalsOn();
269 				for (int dre=0; dre<Elements.count(); ++dre)
270 				{
271 					tmpSel->addItem(Elements.at(dre), true);
272 				}
273 				tmpSel->setGroupRect();
274 				ScElemMimeData* md = ScriXmlDoc::writeToMimeData(m_Doc, tmpSel);
275 				m_Doc->itemSelection_DeleteItem(tmpSel);
276 				m_Doc->view()->updatesOn(true);
277 				if (importedColors.count() != 0)
278 				{
279 					for (int cd = 0; cd < importedColors.count(); cd++)
280 					{
281 						m_Doc->PageColors.remove(importedColors[cd]);
282 					}
283 				}
284 				if (importedPatterns.count() != 0)
285 				{
286 					for (int cd = 0; cd < importedPatterns.count(); cd++)
287 					{
288 						m_Doc->docPatterns.remove(importedPatterns[cd]);
289 					}
290 				}
291 				m_Doc->m_Selection->delaySignalsOff();
292 				// We must copy the TransationSettings object as it is owned
293 				// by handleObjectImport method afterwards
294 				TransactionSettings* transacSettings = new TransactionSettings(trSettings);
295 				m_Doc->view()->handleObjectImport(md, transacSettings);
296 				m_Doc->DragP = false;
297 				m_Doc->DraggedElem = nullptr;
298 				m_Doc->DragElements.clear();
299 			}
300 		}
301 		else
302 		{
303 			m_Doc->changed();
304 			m_Doc->reformPages();
305 			if (!(flags & LoadSavePlugin::lfLoadAsPattern))
306 				m_Doc->view()->updatesOn(true);
307 		}
308 		success = true;
309 	}
310 	else
311 	{
312 		QDir::setCurrent(CurDirP);
313 		m_Doc->DoDrawing = true;
314 		m_Doc->scMW()->setScriptRunning(false);
315 		m_Doc->view()->updatesOn(true);
316 		qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
317 	}
318 	if (interactive)
319 		m_Doc->setLoading(false);
320 	//CB If we have a gui we must refresh it if we have used the progressbar
321 	if (!(flags & LoadSavePlugin::lfLoadAsPattern))
322 	{
323 		if ((showProgress) && (!interactive))
324 			m_Doc->view()->DrawNew();
325 	}
326 	qApp->restoreOverrideCursor();
327 	return success;
328 }
329 
~DrwPlug()330 DrwPlug::~DrwPlug()
331 {
332 	delete progressDialog;
333 	delete tmpSel;
334 }
335 
convert(const QString & fn)336 bool DrwPlug::convert(const QString& fn)
337 {
338 	Coords.resize(0);
339 	Coords.svgInit();
340 	importedColors.clear();
341 	importedPatterns.clear();
342 	DRWGroup gElements;
343 	gElements.xoffset = 0.0;
344 	gElements.yoffset = 0.0;
345 	gElements.nrOfItems = -1;
346 	gElements.counter = -1;
347 	groupStack.push(gElements);
348 	DRWObjectList gList;
349 	gList.groupX = 0.0;
350 	gList.groupY = 0.0;
351 	listStack.push(gList);
352 	scaleFactor = 0.15;
353 	lineWidth = 1.0;
354 	lineColor = "Black";
355 	fillColor = "Black";
356 	createObjCode = 0;
357 	nrOfPoints = 0;
358 	symbolCount = 0;
359 	recordCount = 0;
360 	imageValid = false;
361 	thumbRead = false;
362 	currentItem = nullptr;
363 	if (progressDialog)
364 	{
365 		progressDialog->setOverallProgress(2);
366 		progressDialog->setLabel("GI", tr("Generating Items"));
367 		qApp->processEvents();
368 	}
369 	QFile f(fn);
370 	if (f.open(QIODevice::ReadOnly))
371 	{
372 		QDataStream ts(&f);
373 		ts.setByteOrder(QDataStream::LittleEndian);
374 		while (!ts.atEnd())
375 		{
376 			quint8 dataS, cmd;
377 			quint16 dataL;
378 			uint dataLen;
379 			int pos = ts.device()->pos();
380 			ts >> dataS;
381 			if (dataS == 0xFF)
382 			{
383 				ts >> dataL;
384 				dataLen = dataL;
385 			}
386 			else
387 				dataLen = dataS;
388 			ts >> cmd;
389 			decodeCmdData(ts, dataLen, cmd);
390 			decodeCmd(cmd, pos);
391 			if (progressDialog)
392 			{
393 				progressDialog->setProgress("GI", ts.device()->pos());
394 				qApp->processEvents();
395 			}
396 			if (cmd == 254)
397 				break;
398 			if ((importerFlags & LoadSavePlugin::lfCreateThumbnail) && (cmd == 11))
399 				thumbRead = true;
400 			if ((importerFlags & LoadSavePlugin::lfCreateThumbnail) && (cmd == 27) && (thumbRead))
401 				break;
402 		}
403 		if (Elements.count() == 0)
404 		{
405 			if (importedColors.count() != 0)
406 			{
407 				for (int cd = 0; cd < importedColors.count(); cd++)
408 				{
409 					m_Doc->PageColors.remove(importedColors[cd]);
410 				}
411 			}
412 			if (importedPatterns.count() != 0)
413 			{
414 				for (int cd = 0; cd < importedPatterns.count(); cd++)
415 				{
416 					m_Doc->docPatterns.remove(importedPatterns[cd]);
417 				}
418 			}
419 		}
420 		f.close();
421 	}
422 	if (progressDialog)
423 		progressDialog->close();
424 	return true;
425 }
426 
decodeCmdData(QDataStream & ts,uint dataLen,quint8 cmd)427 void DrwPlug::decodeCmdData(QDataStream &ts, uint dataLen, quint8 cmd)
428 {
429 	cmdData.resize(0);
430 	uint count = 0;
431 	while (count < dataLen)
432 	{
433 		quint8 d;
434 		ts >> d;
435 		if ((cmd < 96) || (cmd > 160))
436 		{
437 			if (d == 0xFF)
438 			{
439 				quint8 val, dd;
440 				ts >> dd >> val;
441 				for (uint cc = 0; cc < dd; cc++)
442 				{
443 					cmdData.append(val);
444 					count++;
445 				}
446 			}
447 			else
448 			{
449 				cmdData.append(d);
450 				count++;
451 			}
452 		}
453 		else
454 		{
455 			cmdData.append(d);
456 			count++;
457 		}
458 	}
459 }
460 
decodeCmd(quint8 cmd,int pos)461 void DrwPlug::decodeCmd(quint8 cmd, int pos)
462 {
463 	recordCount++;
464 //	bool printMSG = false;
465 /*	if ((recordCount > 29) && (recordCount < 33))
466 	{
467 		QFile f(QString("/home/franz/cmddatas%1.bin").arg(recordCount));
468 		f.open(QIODevice::WriteOnly);
469 		f.write(cmdData);
470 		f.close();
471 	} */
472 	QDataStream ds(cmdData);
473 	DRWGradient gradient;
474 	QByteArray pattern;
475 	quint8 data8, chData;
476 	quint16 data16;
477 	int index;
478 	QString textFont;
479 	ds.setByteOrder(QDataStream::LittleEndian);
480 	QString cmdText = QString("Record %1 Type: ").arg(recordCount);
481 	switch (cmd)
482 	{
483 		case 1:
484 			cmdText += QString("DRW Background Color %1").arg(getColor(ds));
485 			break;
486 		case 2:
487 			cmdText += "DRW Facename";
488 			break;
489 		case 3:
490 			cmdText += QString("DRW Version Data %1").arg(QString(cmdData.toHex().left(64)));
491 			break;
492 		case 4:
493 			cmdText += QString("DRW ID Data %1").arg(QString(cmdData).left(20));
494 			if (listStack.count() > 0)
495 				listStack.top().itemGroupName = QString(cmdData);
496 			break;
497 		case 5:
498 			cmdText += QString("DRW Overlay Data %1").arg(QString(cmdData.toHex().left(20)));
499 			break;
500 		case 6:
501 			cmdText += "DRW Polygon";
502 			if ((createObjCode == 1) || (createObjCode == 3))
503 			{
504 				bool first = true;
505 				bool first2 = true;
506 				QPointF startP;
507 				QPainterPath path;
508 				for (int a = 0; a < nrOfPoints; a++)
509 				{
510 					QPointF coor = getCoordinate(ds);
511 					if (first)
512 					{
513 						path.moveTo(coor);
514 						if (first2)
515 							startP = coor;
516 						first = false;
517 						first2 = false;
518 					}
519 					else
520 					{
521 						if (coor == startP)
522 						{
523 							first = true;
524 							path.closeSubpath();
525 						}
526 						else
527 							path.lineTo(coor);
528 					}
529 				}
530 				if (currentItem != nullptr)
531 				{
532 					currentItem->PoLine.fromQPainterPath(path);
533 					QRectF bBoxO = path.boundingRect();
534 					if (bBoxO.x() < 0)
535 						currentItem->PoLine.translate(-bBoxO.x(), 0);
536 					if (bBoxO.y() < 0)
537 						currentItem->PoLine.translate(0, -bBoxO.y());
538 					finishItem(currentItem);
539 					if (currentItem != nullptr)
540 					{
541 						handleLineStyle(currentItem, flags, lineColor);
542 						handleGradient(currentItem, patternIndex, fillColor, backColor, bBox);
543 					}
544 				}
545 				createObjCode = 0;
546 				currentItem = nullptr;
547 			}
548 			else if (createObjCode == 2)
549 			{
550 				bool first = true;
551 				QPointF startP;
552 				QPainterPath path;
553 				int a = 0;
554 				while (a < nrOfPoints)
555 				{
556 					if (first)
557 					{
558 						QPointF coor = getCoordinate(ds);
559 						a++;
560 						path.moveTo(coor);
561 						startP = coor;
562 						first = false;
563 					}
564 					QPointF p1 = getCoordinate(ds);
565 					QPointF p2 = getCoordinate(ds);
566 					QPointF p3 = getCoordinate(ds);
567 					a += 3;
568 					path.cubicTo(p1, p2, p3);
569 				}
570 				if (currentItem != nullptr)
571 				{
572 					currentItem->PoLine.fromQPainterPath(path);
573 					QRectF bBoxO = path.boundingRect();
574 					if (bBoxO.x() < 0)
575 						currentItem->PoLine.translate(-bBoxO.x(), 0);
576 					if (bBoxO.y() < 0)
577 						currentItem->PoLine.translate(0, -bBoxO.y());
578 					finishItem(currentItem);
579 					if (currentItem != nullptr)
580 					{
581 						handleLineStyle(currentItem, flags, lineColor);
582 						handleGradient(currentItem, patternIndex, fillColor, backColor, bBox);
583 					}
584 				}
585 				createObjCode = 0;
586 				currentItem = nullptr;
587 			}
588 			else if (createObjCode == 4)
589 			{
590 				bool first = true;
591 				QPointF startP;
592 				int a = 0;
593 				QPainterPath path;
594 				while (a < nrOfPoints-1)
595 				{
596 					if (first)
597 					{
598 						QPointF coor = getCoordinate(ds);
599 						a++;
600 						path.moveTo(coor);
601 						startP = coor;
602 						first = false;
603 					}
604 					QPointF p1 = getCoordinate(ds);
605 					a++;
606 					QPointF p2 = getCoordinate(ds);
607 					a++;
608 					path.quadTo(p1, p2);
609 				}
610 				if (currentItem != nullptr)
611 				{
612 					currentItem->PoLine.fromQPainterPath(path);
613 					QRectF bBoxO = path.boundingRect();
614 					if (bBoxO.x() < 0)
615 						currentItem->PoLine.translate(-bBoxO.x(), 0);
616 					if (bBoxO.y() < 0)
617 						currentItem->PoLine.translate(0, -bBoxO.y());
618 					finishItem(currentItem);
619 					if (currentItem != nullptr)
620 					{
621 						handleLineStyle(currentItem, flags, lineColor);
622 						handleGradient(currentItem, patternIndex, fillColor, backColor, bBox);
623 					}
624 				}
625 				createObjCode = 0;
626 				currentItem = nullptr;
627 			}
628 			break;
629 		case 7:
630 			cmdText = "";
631 			decodeSymbol(ds);
632 //			printMSG = false;
633 			break;
634 		case 8:
635 			cmdText += "DRW Text";
636 			if (createObjCode == 5)
637 			{
638 				QString tx = QString(cmdData.left(nrOfChars));
639 				QStringList parList = tx.split(QChar(13));
640 				double yp = 0;
641 				QPainterPath path;
642 				QString fontN = "Arial";
643 				if (fontMap.contains(fontID))
644 					fontN = fontMap[fontID];
645 				QFont textFont = QFont(fontN, fontSize * 0.8);
646 				QFontMetrics fm(textFont);
647 				for (int a = 0; a < parList.size(); a++)
648 				{
649 					path.addText( 0, yp, textFont, parList[a].trimmed());
650 					yp += fm.lineSpacing();
651 				}
652 				QTransform txS;
653 				QRectF bbox = path.boundingRect();
654 				txS = QTransform();
655 				txS.scale(scaleFactor, scaleFactor);
656 				path = txS.map(path);
657 				txS = QTransform();
658 				bbox = path.boundingRect();
659 				txS.translate(-bbox.x(), -bbox.y());
660 				txS.translate(0, fm.leading() * scaleFactor);
661 				path = txS.map(path);
662 				if (currentItem != nullptr)
663 				{
664 					currentItem->PoLine.fromQPainterPath(path);
665 					currentItem->setWidth(bbox.width());
666 					finishItem(currentItem, false);
667 				}
668 				createObjCode = 0;
669 				currentItem = nullptr;
670 			}
671 			break;
672 		case 9:
673 			cmdText += "DRW Color";
674 			break;
675 		case 10:
676 			cmdText += "DRW Color Flag";
677 			break;
678 		case 11:
679 			cmdText += "DRW Preview Bitmap";
680 			handlePreviewBitmap(ds);
681 			break;
682 		case 14:
683 			cmdText += "DRW View";
684 			break;
685 		case 15:
686 			cmdText += "DRW Old Grid";
687 			break;
688 		case 16:
689 			cmdText += QString("DRW Curr Overlay Data %1").arg(QString(cmdData.toHex().left(20)));
690 			break;
691 		case 17:
692 			cmdText += QString("DRW Visible Data %1").arg(QString(cmdData.toHex().left(20)));
693 			break;
694 		case 18:
695 			cmdText += QString("DRW Comment Data %1").arg(QString(cmdData.toHex().left(20)));
696 			break;
697 		case 19:
698 			cmdText += QString("DRW Info Data %1").arg(QString(cmdData).left(20));
699 			break;
700 		case 20:
701 			cmdText += "DRW Bitmap";
702 			break;
703 		case 21:
704 			ds >> fontID;
705 			ds.device()->seek(0x13);
706 			fontName = "";
707 			ds >> chData;
708 			while (chData != 0)
709 			{
710 				fontName += QChar(chData);
711 				ds >> chData;
712 			}
713 			fontName = fontName.trimmed();
714 			fontName.replace( QRegExp( "'" ) , QChar( ' ' ) );
715 			{
716 				textFont = m_Doc->itemToolPrefs().textFont;
717 				bool found = false;
718 				SCFontsIterator it(PrefsManager::instance().appPrefs.fontPrefs.AvailFonts);
719 				for ( ; it.hasNext(); it.next())
720 				{
721 					QString fn = it.current().scName();
722 					if (fn == fontName)
723 					{
724 						found = true;
725 						break;
726 					}
727 				}
728 				if (!found)
729 				{
730 					if (importerFlags & LoadSavePlugin::lfCreateThumbnail)
731 						fontName = PrefsManager::instance().appPrefs.itemToolPrefs.textFont;
732 					else
733 					{
734 						if (!PrefsManager::instance().appPrefs.fontPrefs.GFontSub.contains(fontName))
735 						{
736 							qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
737 							MissingFont *dia = new MissingFont(nullptr, fontName, m_Doc);
738 							dia->exec();
739 							textFont = dia->getReplacementFont();
740 							delete dia;
741 							qApp->changeOverrideCursor(QCursor(Qt::WaitCursor));
742 							PrefsManager::instance().appPrefs.fontPrefs.GFontSub[fontName] = textFont;
743 							fontName = textFont;
744 						}
745 						else
746 							fontName = PrefsManager::instance().appPrefs.fontPrefs.GFontSub[fontName];
747 					}
748 				}
749 			}
750 			fontMap.insert(fontID, fontName);
751 			cmdText += QString("DRW Font %1").arg(fontName);
752 			break;
753 		case 22:
754 			cmdText += "DRW Grid";
755 			break;
756 		case 23:
757 			cmdText += QString("DRW Overlay Name Data %1").arg(QString(cmdData).left(20));
758 //			printMSG = true;
759 			break;
760 		case 24:
761 			cmdText += "DRW Dimensions";
762 			break;
763 		case 25:
764 			ds >> data16;
765 			scaleFactor = (1.0 / static_cast<double>(data16)) * 72.0;
766 			cmdText += QString("DRW Resolution %1").arg(data16);
767 			break;
768 		case 26:
769 			cmdText += "DRW Ruler";
770 			break;
771 		case 27:
772 			cmdText += "DRW Page";
773 			docWidth = getValue(ds);
774 			docHeight = getValue(ds);
775 			if (importerFlags & LoadSavePlugin::lfCreateDoc)
776 			{
777 				m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false);
778 				if (docWidth > docHeight)
779 					m_Doc->setPageOrientation(1);
780 				else
781 					m_Doc->setPageOrientation(0);
782 				m_Doc->setPageSize("Custom");
783 				m_Doc->changePageProperties(0, 0, 0, 0, docHeight, docWidth, docHeight, docWidth, m_Doc->pageOrientation(), m_Doc->pageSize(), m_Doc->currentPage()->pageNr(), false);
784 				cmdText = QString("DRW Page  Width %1  Height %2").arg(docWidth).arg(docHeight);
785 			}
786 			break;
787 		case 28:
788 			cmdText += "DRW Pattern";
789 			ds >> data8;
790 			pattern.resize(16);
791 			ds.readRawData(pattern.data(), 16);
792 			patternDataMap.insert(data8, pattern);
793 //			printMSG = true;
794 			break;
795 		case 29:
796 			cmdText += "DRW Locked";
797 			break;
798 		case 30:
799 			ds >> data8;
800 			index = data8;
801 			ds >> data8;
802 			gradient.type = data8;
803 			ds >> data8;
804 			gradient.xOffset = data8 / 100.0;
805 			ds >> data8;
806 			gradient.yOffset = data8 / 100.0;
807 			ds >> data16;
808 			gradient.angle = data16 / 10.0;
809 			gradientMap.insert(index, gradient);
810 			cmdText += QString("DRW Gradient  Index: %1 Type: %2 Offsets: %3 %4 Angle: %5").arg(index).arg(gradient.type).arg(gradient.xOffset).arg(gradient.yOffset).arg(gradient.angle);
811 //			printMSG = true;
812 			break;
813 		case 31:
814 			cmdText += "DRW Text Hdr";
815 			ds >> data8;					// Version
816 			ds >> data8;					// vertical alignment
817 			cmdText += QString(" VAlign %1").arg(data8);
818 			ds >> data16;					// MemFlags ????
819 			ds >> data16;					// Textrotation
820 			ds >> fontID;					// Font Nr
821 			cmdText += QString(" Font %1").arg(fontID);
822 			ds >> fontStyle;				// Style
823 			ds >> fontWidth;				// Width
824 			ds >> fontSize;					// Height
825 			cmdText += QString(" Size %1").arg(fontSize);
826 			ds >> nrOfParagraphs;			// Nr of paragraph records
827 			paragraphCounter = 0;
828 			cmdText += QString(" NoPara %1").arg(nrOfParagraphs);
829 			paragraphList.clear();
830 			for (quint16 a = 0; a < nrOfParagraphs; a++)
831 			{
832 				DRWParagraph para;
833 				ds >> data16;
834 				ds >> data16;
835 				ds >> data16;
836 				ds >> para.paragraphAlignment;
837 				ds.skipRawData(18);
838 				ds >> para.paragraphLen;
839 				para.paragraphLen -= 17;
840 				ds.skipRawData(4);
841 				paragraphList.append(para);
842 			}
843 			break;
844 		case 32:
845 			cmdText += "DRW Band";
846 /* For this record the documentation is completly wrong
847 
848 	offs	meaning
849 	0		X-Offset
850 	2		Y-Offset
851 	4		bytes per row
852 	6		number of rows stored in this record
853 	8+		Image Data as raw uncompressed values, rows are aligned to even bytes
854 */
855 			if (imageValid)
856 			{
857 				quint16 xoff, yoff, len, count;
858 				ds >> xoff >> yoff >> len >> count;
859 				if (bitsPerPixel == 24)
860 				{
861 					for (quint16 y = 0; y < count; y++)
862 					{
863 						QRgb *q = (QRgb*)(tmpImage.scanLine(yoff + y));
864 						for (quint16 x = 0; x < imageWidth; x++)
865 						{
866 							quint8 r, g, b;
867 							ds >> r >> g >> b;
868 							*q = qRgba(r, g, b, 255);
869 							q++;
870 						}
871 						scanLinesRead++;
872 					}
873 				}
874 				else if (bitsPerPixel == 8)
875 				{
876 					for (quint16 y = 0; y < count; y++)
877 					{
878 						QRgb *q = (QRgb*)(tmpImage.scanLine(yoff + y));
879 						int pos = ds.device()->pos();
880 						for (quint16 x = 0; x < imageWidth; x++)
881 						{
882 							quint8 r;
883 							ds >> r;
884 							*q = qRgba(r, r, r, 255);
885 							q++;
886 						}
887 						QByteArray data;
888 						data.resize(imageWidth);
889 						ds.device()->seek(pos);
890 						ds.readRawData(data.data(), imageWidth);
891 						ds.device()->seek(pos + len);
892 						memcpy(tmpImage2.scanLine(yoff + y), data.data(), imageWidth);
893 						scanLinesRead++;
894 					}
895 				}
896 				if (scanLinesRead >= imageHeight)
897 				{
898 					if (currentItem != nullptr)
899 					{
900 						QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_drw_XXXXXX.png");
901 						tempFile->setAutoRemove(false);
902 						tempFile->open();
903 						QString fileName = getLongPathName(tempFile->fileName());
904 						tempFile->close();
905 						currentItem->isInlineImage = true;
906 						currentItem->isTempFile = true;
907 						tmpImage.save(fileName, "PNG");
908 						m_Doc->loadPict(fileName, currentItem);
909 						delete tempFile;
910 						currentItem->setImageScalingMode(false, false);
911 					}
912 					imageValid = false;
913 					tmpImage = QImage();
914 				}
915 			}
916 			break;
917 		case 33:
918 			ds >> data16;
919 			cmdText += QString("DRW Symbolversion %1").arg(data16);
920 			break;
921 		case 34:
922 			cmdText += "DRW Text Para";
923 			ds.device()->seek(0x11);
924 			if (createObjCode == 6)
925 			{
926 				if (currentItem != nullptr)
927 				{
928 					DRWParagraph para = paragraphList.at(paragraphCounter);
929 					paragraphCounter++;
930 					ParagraphStyle newStyle;
931 					newStyle.setLineSpacingMode(ParagraphStyle::AutomaticLineSpacing);
932 					newStyle.setAlignment(static_cast<ParagraphStyle::AlignmentType>(para.paragraphAlignment));
933 					newStyle.charStyle().setFontSize(fontSize * scaleFactor * 10.0 * 0.8);
934 					QString fontN(m_Doc->itemToolPrefs().textFont);
935 					if (fontMap.contains(fontID))
936 						fontN = fontMap[fontID];
937 					newStyle.charStyle().setFont((*m_Doc->AllFonts)[fontN]);
938 					newStyle.charStyle().setFillColor(fontColor);
939 					newStyle.setLineSpacing(newStyle.charStyle().font().height(fontSize * scaleFactor * 10.0 * 0.8));
940 					if (para.paragraphLen > 0)
941 					{
942 						int pos = currentItem->itemText.length();
943 						QByteArray data;
944 						data.resize(para.paragraphLen);
945 						ds.readRawData(data.data(), para.paragraphLen);
946 						QString chars = QString(data);
947 						if (!chars.isEmpty())
948 						{
949 							currentItem->itemText.insertChars( -1, chars);
950 							currentItem->itemText.applyStyle(pos, newStyle);
951 						}
952 						if (nrOfParagraphs > 0)
953 							currentItem->itemText.insertChars(-1, SpecialChars::PARSEP);
954 					}
955 				}
956 			}
957 			break;
958 		case 35:
959 			cmdText += "DRW Colortable";
960 			if (currentItem != nullptr)
961 			{
962 				if (currentItem->isImageFrame())
963 				{
964 					QString fileName = currentItem->Pfile;
965 					if (!fileName.isEmpty())
966 					{
967 						QVector<QRgb> colors;
968 						for (quint16 cc = 0; cc < 255; cc++)	// now reading ColorTable, exactly 1024 bytes
969 						{
970 							quint8 r, g, b, a;
971 							ds >> r >> g >> b >> a;				// values are stored in RGB order
972 							if ((r == rTrans) && (g == gTrans) && (b == bTrans))
973 								colors.append(qRgba(r, g, b, 0));
974 							else
975 								colors.append(qRgb(r, g, b));
976 						}
977 						tmpImage2.setColorTable(colors);
978 						tmpImage2 = tmpImage2.convertToFormat(QImage::Format_ARGB32);
979 						tmpImage2.save(fileName, "PNG");
980 						m_Doc->loadPict(fileName, currentItem, true);
981 					}
982 				}
983 			}
984 			break;
985 		case 36:
986 			cmdText += "DRW Text Extra";
987 			break;
988 		case 37:
989 			cmdText += "DRW Max Link ID";
990 			break;
991 		case 44:
992 			cmdText += "Skip Symbols";
993 			break;
994 		case 254:
995 			cmdText += "DRW EOF";
996 			decodeSymbol(ds, true);
997 //			printMSG = true;
998 			break;
999 		case 255:
1000 			cmdText += QString("DRW Start File");
1001 			//printMSG = true;
1002 			break;
1003 		default:
1004 			cmdText += QString("Unknown Cmd-Nr %1  Data %2 Size %3").arg(cmd).arg(QString(cmdData.toHex().left(64))).arg(cmdData.size());
1005 			break;
1006 	}
1007 //	printMSG = false;
1008 //	if (printMSG)
1009 //	{
1010 //		qDebug() << cmdText; // << QString("at %1").arg(pos, 8, 16);
1011 //		qDebug() << "\tData:" << cmdData.toHex().left(32);
1012 //	}
1013 }
1014 
decodeSymbol(QDataStream & ds,bool last)1015 void DrwPlug::decodeSymbol(QDataStream &ds, bool last)
1016 {
1017 	symbolCount++;
1018 	QString cmdText = QString("Record %1 Symbol %2 Type:").arg(recordCount).arg(symbolCount);
1019 	//bool printMSG = false;
1020 	double bX = 0.0;
1021 	double bY = 0.0;
1022 	double groupX = 0.0;
1023 	double groupY = 0.0;
1024 	DRWObjectList gList;
1025 	DRWGroup gElements;
1026 	DRWGroup cElements;
1027 	if (groupStack.count() > 0)
1028 	{
1029 		cElements = groupStack.top();
1030 		bX = cElements.xoffset;
1031 		bY = cElements.yoffset;
1032 		if (cElements.nrOfItems != -1)
1033 		{
1034 			while (groupStack.count() > 1)
1035 			{
1036 				if (cElements.nrOfItems == cElements.counter)
1037 				{
1038 					listStack.pop();
1039 					DRWGroup popped = groupStack.pop();
1040 					cElements = groupStack.top();
1041 					tmpSel->clear();
1042 					for (int dre = 0;  dre < popped.GElements.count(); ++dre)
1043 					{
1044 						tmpSel->addItem(popped.GElements.at(dre), true);
1045 					}
1046 					bX = cElements.xoffset;
1047 					bY = cElements.yoffset;
1048 					uint selectedItemCount = tmpSel->count();
1049 					if (selectedItemCount > 0)
1050 					{
1051 						double scx = 1.0;
1052 						double scy = 1.0;
1053 						QPainterPath gesPa;
1054 						bool firstP = true;
1055 						for (uint i = 0; i < selectedItemCount; ++i)
1056 						{
1057 							QPainterPath pa;
1058 							PageItem *item = tmpSel->itemAt(i);
1059 							item->PoLine.translate(item->xPos(), item->yPos());
1060 							pa = item->PoLine.toQPainterPath(false);
1061 							if (!pa.isEmpty())
1062 							{
1063 								const QPainterPath::Element &elm = pa.elementAt(0);
1064 								QPointF lastP = pa.currentPosition();
1065 								bool conn = false;
1066 								bool conn2 = false;
1067 								if ((fabs(lastP.x() - elm.x) < 1) && (fabs(lastP.y() - elm.y) < 1))
1068 								{
1069 									pa.closeSubpath();
1070 									conn = true;
1071 								}
1072 								if (!gesPa.isEmpty())
1073 								{
1074 									const QPainterPath::Element &elm2 = gesPa.elementAt(0);
1075 									QPointF lastP2 = gesPa.currentPosition();
1076 									if ((fabs(lastP2.x() - elm2.x) < 1) && (fabs(lastP2.y() - elm2.y) < 1))
1077 									{
1078 										gesPa.closeSubpath();
1079 										conn2 = true;
1080 									}
1081 								}
1082 								if ((firstP) || (conn) || (conn2))
1083 								{
1084 									gesPa.addPath(pa);
1085 									firstP = false;
1086 								}
1087 								else
1088 									gesPa.connectPath(pa);
1089 							}
1090 						}
1091 						if (!gesPa.isEmpty())
1092 						{
1093 							QRectF bb = gesPa.controlPointRect();
1094 							if (popped.rotationAngle != 0)
1095 							{
1096 								QTransform mt;
1097 								mt.translate(-bb.x(), -bb.y());
1098 								gesPa = mt.map(gesPa);
1099 								QTransform ma;
1100 								ma.translate(popped.posPivot.x(), popped.posPivot.y());
1101 								ma.rotate(-popped.rotationAngle / 10.0);
1102 								gesPa = ma.map(gesPa);
1103 							}
1104 							bb = gesPa.controlPointRect();
1105 							QTransform mt;
1106 							mt.translate(-bb.x(), -bb.y());
1107 							gesPa = mt.map(gesPa);
1108 							if ((bb.width() != 0) && (bb.height() != 0) && (popped.width != 0) && (popped.height != 0))
1109 							{
1110 								if (bb.width() != popped.width)
1111 									scx = popped.width / bb.width();
1112 								if (bb.height() != popped.height)
1113 									scy = popped.height / bb.height();
1114 								QTransform ms;
1115 								ms.scale(scx, scy);
1116 								gesPa = ms.map(gesPa);
1117 							}
1118 							if (popped.filled)
1119 								gesPa.closeSubpath();
1120 							FPointArray res;
1121 							res.fromQPainterPath(gesPa);
1122 							PageItem *ite = tmpSel->takeItem(0);
1123 							ite->setXYPos(popped.xoffset + baseX, popped.yoffset + baseY);
1124 							ite->PoLine = res.copy();
1125 							FPoint wh = getMaxClipF(&ite->PoLine);
1126 							ite->setWidthHeight(wh.x(),wh.y());
1127 							ite->OldB2 = ite->width();
1128 							ite->OldH2 = ite->height();
1129 							if (popped.filled)
1130 								ite->setFillColor(popped.fillColor);
1131 							else
1132 								ite->setFillColor(CommonStrings::None);
1133 							ite->setLineWidth(popped.lineWidth);
1134 							ite->setLineWidth(ite->lineWidth() / qMin(scx, scy));
1135 							handleLineStyle(ite, popped.flags, popped.lineColor);
1136 							if (popped.filled)
1137 								handleGradient(ite, popped.patternIndex, popped.fillColor, popped.backColor, QRectF(0, 0, ite->width(), ite->height()));
1138 							groupStack.top().GElements.append(ite);
1139 							listStack.top().GElements.append(ite);
1140 						}
1141 						selectedItemCount = tmpSel->count();
1142 						for (uint i = 0; i < selectedItemCount; ++i)
1143 						{
1144 							Elements.removeAll(tmpSel->itemAt(i));
1145 							listStack.top().GElements.removeAll(tmpSel->itemAt(i));
1146 						}
1147 						m_Doc->itemSelection_DeleteItem(tmpSel);
1148 					}
1149 					tmpSel->clear();
1150 				}
1151 				else
1152 					break;
1153 			}
1154 			groupStack.top().counter++;
1155 		}
1156 	}
1157 	if (listStack.count() > 1)
1158 	{
1159 		while (listStack.count() > 1)
1160 		{
1161 			if (listStack.top().nrOfItems == listStack.top().counter)
1162 			{
1163 				DRWObjectList popped = listStack.pop();
1164 				tmpSel->clear();
1165 				for (int dre = 0;  dre < popped.GElements.count(); ++dre)
1166 				{
1167 					tmpSel->addItem(popped.GElements.at(dre), true);
1168 				}
1169 				uint selectedItemCount = tmpSel->count();
1170 				if (selectedItemCount > 0)
1171 				{
1172 					if (popped.rotationAngle != 0)
1173 					{
1174 						PageItem* currItem;
1175 						QTransform ma;
1176 						ma.translate(popped.posPivot.x(), popped.posPivot.y());
1177 						ma.rotate(-popped.rotationAngle / 10.0);
1178 						FPoint n;
1179 						for (int a = 0; a < tmpSel->count(); ++a)
1180 						{
1181 							currItem = tmpSel->itemAt(a);
1182 							n = FPoint(currItem->xPos(), currItem->yPos());
1183 							currItem->setXYPos(ma.m11() * n.x() + ma.m21() * n.y() + ma.dx(), ma.m22() * n.y() + ma.m12() * n.x() + ma.dy());
1184 							currItem->rotateBy(-popped.rotationAngle / 10.0);
1185 						}
1186 					}
1187 					tmpSel->setGroupRect();
1188 					QRectF gr = tmpSel->getGroupRect();
1189 					double dx = popped.groupItem->xPos() - gr.x();
1190 					double dy = popped.groupItem->yPos() - gr.y();
1191 					for (int a = 0; a < tmpSel->count(); ++a)
1192 					{
1193 						tmpSel->itemAt(a)->moveBy(dx, dy);
1194 					}
1195 					tmpSel->setGroupRect();
1196 					if ((popped.scaleX != 0) || (popped.scaleY != 0))
1197 					{
1198 						if ((tmpSel->width() != 0) && (tmpSel->height() != 0) && (popped.width != 0) && (popped.height != 0))
1199 						{
1200 							double scx = 1.0;
1201 							if (tmpSel->width() != popped.width)
1202 								scx = popped.width / tmpSel->width();
1203 							double scy = 1.0;
1204 							if (tmpSel->height() != popped.height)
1205 								scy = popped.height / tmpSel->height();
1206 							m_Doc->scaleGroup(scx, scy, true, tmpSel);
1207 						}
1208 					}
1209 					listStack.top().GElements.append(popped.groupItem);
1210 					for (uint i = 0; i < selectedItemCount; ++i)
1211 					{
1212 						PageItem *item = tmpSel->itemAt(i);
1213 						popped.groupItem->groupItemList.append(item);
1214 						item->gXpos = item->xPos() - popped.groupItem->xPos();
1215 						item->gYpos = item->yPos() - popped.groupItem->yPos();
1216 						item->Parent = popped.groupItem;
1217 						if (groupStack.count() > 0)
1218 							groupStack.top().GElements.removeAll(tmpSel->itemAt(i));
1219 						Elements.removeAll(tmpSel->itemAt(i));
1220 						m_Doc->Items->removeAll(tmpSel->itemAt(i));
1221 					}
1222 					if (popped.itemGroupName.isEmpty())
1223 						popped.groupItem->setItemName( tr("Group%1").arg(m_Doc->GroupCounter));
1224 					else
1225 						popped.groupItem->setItemName(popped.itemGroupName);
1226 					popped.groupItem->AutoName = false;
1227 					popped.groupItem->groupWidth = tmpSel->width();
1228 					popped.groupItem->groupHeight = tmpSel->height();
1229 				}
1230 				m_Doc->GroupCounter++;
1231 				tmpSel->clear();
1232 			}
1233 			else
1234 				break;
1235 		}
1236 		listStack.top().counter++;
1237 		groupX = listStack.top().groupX;
1238 		groupY = listStack.top().groupY;
1239 	}
1240 	if (last)
1241 		return;
1242 /*	if ((symbolCount > 31) && (symbolCount < 33))
1243 	{
1244 		QFile f(QString("/home/franz/cmddatas%1.bin").arg(symbolCount));
1245 		f.open(QIODevice::WriteOnly);
1246 		f.write(cmdData);
1247 		f.close();
1248 	} */
1249 	int z;
1250 	quint8 data8, appFlags;
1251 	quint16 dummy, nPoints, nItems;
1252 	double boundingBoxXO, boundingBoxYO, boundingBoxWO, boundingBoxHO, cornerRadius;
1253 	QRectF bBoxO;
1254 	QString fillC = CommonStrings::None;
1255 	createObjCode = 0;
1256 	currentItem = nullptr;
1257 	ds >> data8;							// reading Symbol Type
1258 // now reading common values
1259 	ds >> flags;
1260 	QPainterPath path;
1261 	QPointF posEnd, posMid, posStart;
1262 	QLineF sLin, eLin;
1263 	getCoordinate(ds);						// don't remove dummy parameters
1264 	double boundingBoxX = getValue(ds);
1265 	double boundingBoxY = getValue(ds);
1266 	double boundingBoxW = getValue(ds);
1267 	double boundingBoxH = getValue(ds);
1268 	bBox = QRectF(QPointF(boundingBoxX, boundingBoxY), QPointF(boundingBoxW, boundingBoxH)).normalized();
1269 	rotationAngle = getRawValue(ds);
1270 	scaleX = getRawValue(ds);
1271 	scaleY = getRawValue(ds);
1272 	double rotS, rotE;
1273 	double posX = baseX + bBox.x() + bX + groupX;
1274 	double posY = baseY + bBox.y() + bY + groupY;
1275 	lineColor = getColor(ds);
1276 	ds >> dummy;		// handle
1277 	ds >> dummy;		// next
1278 	ds >> dummy;
1279 	ds >> dummy;		// prev
1280 	ds >> dummy;
1281 	switch (data8)			// Symbol type is in the first data byte
1282 	{
1283 		case 0:
1284 			cmdText += "elliptical Arc";
1285 			ds >> patternIndex;
1286 			fillColor = getColor(ds);
1287 			if (patternIndex != 0)
1288 				fillC = fillColor;
1289 			posStart = getCoordinate(ds);
1290 			posEnd = getCoordinate(ds);
1291 			if (posStart == posEnd)
1292 				break;
1293 			boundingBoxXO = getValue(ds);
1294 			boundingBoxYO = getValue(ds);
1295 			boundingBoxWO = getValue(ds);
1296 			boundingBoxHO = getValue(ds);
1297 			getCommonData(ds);
1298 			bBoxO = QRectF(QPointF(boundingBoxXO, boundingBoxYO), QPointF(boundingBoxWO, boundingBoxHO)).normalized();
1299 			sLin = QLineF(bBoxO.center(), posStart);
1300 			eLin = QLineF(bBoxO.center(), posEnd);
1301 			rotS = sLin.angle();
1302 			rotE = eLin.angle();
1303 			if (rotS > rotE)
1304 				rotS = rotS - 360;
1305 			rotE = rotE - rotS;
1306 			path = QPainterPath();
1307 			path.arcMoveTo(bBoxO, rotS);
1308 			path.arcTo(bBoxO, rotS, rotE);
1309 			scaleX = 1;
1310 			scaleY = 1;
1311 			z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, posX, posY, bBox.width(), bBox.height(), lineWidth, fillC, lineColor);
1312 			currentItem = m_Doc->Items->at(z);
1313 			currentItem->PoLine.fromQPainterPath(path);
1314 			bBoxO = path.controlPointRect();
1315 			currentItem->PoLine.translate(-bBoxO.x(), -bBoxO.y());
1316 			handleLineStyle(currentItem, flags, lineColor);
1317 			finishItem(currentItem);
1318 			break;
1319 		case 1:
1320 			cmdText += "filled Polygon";
1321 			ds >> patternIndex;
1322 			fillColor = getColor(ds);
1323 			if (patternIndex != 0)
1324 				fillC = fillColor;
1325 			ds >> dummy;
1326 			ds >> nPoints;
1327 			ds >> appFlags;
1328 			getCommonData(ds);
1329 			nrOfPoints = nPoints;
1330 			createObjCode = 1;
1331 			z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, posX, posY, bBox.width(), bBox.height(), lineWidth, fillC, lineColor);
1332 			currentItem = m_Doc->Items->at(z);
1333 			handleLineStyle(currentItem, flags, lineColor);
1334 			handleGradient(currentItem, patternIndex, fillColor, backColor, bBox);
1335 			break;
1336 		case 2:
1337 			getCommonData(ds);
1338 			ds.device()->seek(0x26);
1339 			ds >> dummy;
1340 			if (dummy > 0)
1341 			{
1342 				z = m_Doc->itemAdd(PageItem::Group, PageItem::Rectangle, posX, posY, bBox.width(), bBox.height(), 0, fillC, fillC);
1343 				gList.groupItem = m_Doc->Items->at(z);
1344 				gList.groupX = groupX + bBox.x();
1345 				gList.groupY = groupY + bBox.y();
1346 				gList.width = bBox.width();
1347 				gList.height = bBox.height();
1348 				gList.scaleX = scaleX;
1349 				gList.scaleY = scaleY;
1350 				gList.rotationAngle = rotationAngle;
1351 				gList.nrOfItems = dummy;
1352 				gList.counter = 0;
1353 				gList.posPivot = posPivot;
1354 				gList.itemGroupName = "";
1355 				gList.GElements.clear();
1356 				listStack.push(gList);
1357 				gList.groupItem->ClipEdited = true;
1358 				gList.groupItem->FrameType = 3;
1359 				gList.groupItem->setTextFlowMode(PageItem::TextFlowDisabled);
1360 				gList.groupItem->OldB2 = gList.groupItem->width();
1361 				gList.groupItem->OldH2 = gList.groupItem->height();
1362 				gList.groupItem->updateClip();
1363 				Elements.append(gList.groupItem);
1364 			}
1365 			cmdText += QString("Group  Count %1").arg(dummy);
1366 			break;
1367 		case 3:
1368 			cmdText += "Ellipse";
1369 			ds >> patternIndex;
1370 			fillColor = getColor(ds);
1371 			if (patternIndex != 0)
1372 				fillC = fillColor;
1373 			boundingBoxXO = getValue(ds);
1374 			boundingBoxYO = getValue(ds);
1375 			boundingBoxWO = getValue(ds);
1376 			boundingBoxHO = getValue(ds);
1377 			bBoxO = QRectF(QPointF(boundingBoxXO, boundingBoxYO), QPointF(boundingBoxWO, boundingBoxHO));
1378 			cornerRadius = getValue(ds);
1379 			ds >> appFlags;
1380 			getCommonData(ds);
1381 			z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, posX, posY, bBox.width(), bBox.height(), lineWidth, fillC, lineColor);
1382 			currentItem = m_Doc->Items->at(z);
1383 			finishItem(currentItem);
1384 			if (currentItem != nullptr)
1385 			{
1386 				handleLineStyle(currentItem, flags, lineColor);
1387 				handleGradient(currentItem, patternIndex, fillColor, backColor, bBox);
1388 			}
1389 			break;
1390 		case 5:
1391 			cmdText += "Text";
1392 			ds >> dummy;
1393 			ds >> fontID;
1394 			ds >> nrOfChars;
1395 			ds >> fontSize;
1396 			fontColor = lineColor;
1397 			createObjCode = 5;
1398 			z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, posX, posY, bBox.width(), bBox.height(), 0, lineColor, CommonStrings::None);
1399 			currentItem = m_Doc->Items->at(z);
1400 			scaleX = 0;
1401 			break;
1402 		case 6:
1403 			cmdText += "Line";
1404 			posEnd = getCoordinate(ds);
1405 			posStart = getCoordinate(ds);
1406 			if (posStart == posEnd)
1407 				break;
1408 			ds >> patternIndex;
1409 			getCommonData(ds);
1410 			lineWidth = patternIndex * scaleFactor;
1411 			path = QPainterPath();
1412 			path.moveTo(posStart);
1413 			path.lineTo(posEnd);
1414 			z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, posX, posY, bBox.width(), bBox.height(), lineWidth, fillC, lineColor);
1415 			currentItem = m_Doc->Items->at(z);
1416 			currentItem->PoLine.fromQPainterPath(path);
1417 			bBoxO = path.boundingRect();
1418 			currentItem->PoLine.translate(-bBoxO.x(), -bBoxO.y());
1419 			handleLineStyle(currentItem, flags, lineColor);
1420 			finishItem(currentItem);
1421 			break;
1422 		case 8:
1423 			cmdText += "Polyline";
1424 			ds >> patternIndex;
1425 			fillColor = getColor(ds);
1426 			if (patternIndex != 0)
1427 				fillC = fillColor;
1428 			ds >> dummy;
1429 			ds >> nPoints;
1430 			ds >> appFlags;
1431 			getCommonData(ds);
1432 			nrOfPoints = nPoints;
1433 			createObjCode = 3;
1434 			z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, posX, posY, bBox.width(), bBox.height(), lineWidth, fillC, lineColor);
1435 			currentItem = m_Doc->Items->at(z);
1436 			handleLineStyle(currentItem, flags, lineColor);
1437 			break;
1438 		case 9:
1439 			cmdText += "Pie Wedge";
1440 			//printMSG = true;
1441 			break;
1442 		case 10:
1443 		case 11:
1444 			if (data8 == 10)
1445 				cmdText += "Rectangle";
1446 			else
1447 				cmdText += "Rounded Rectangle";
1448 			ds >> patternIndex;
1449 			fillColor = getColor(ds);
1450 			if (patternIndex != 0)
1451 				fillC = fillColor;
1452 			boundingBoxXO = getValue(ds);
1453 			boundingBoxYO = getValue(ds);
1454 			boundingBoxWO = getValue(ds);
1455 			boundingBoxHO = getValue(ds);
1456 			cornerRadius = getValue(ds);
1457 			bBoxO = QRectF(QPointF(boundingBoxXO, boundingBoxYO), QPointF(boundingBoxWO, boundingBoxHO));
1458 			ds >> appFlags;
1459 			getCommonData(ds);
1460 			z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, posX, posY, bBox.width(), bBox.height(), lineWidth, fillC, lineColor);
1461 			currentItem = m_Doc->Items->at(z);
1462 			handleLineStyle(currentItem, flags, lineColor);
1463 			finishItem(currentItem);
1464 			if (currentItem != nullptr)
1465 			{
1466 				if (data8 == 11)
1467 					currentItem->setCornerRadius(cornerRadius);
1468 				handleGradient(currentItem, patternIndex, fillColor, backColor, bBox);
1469 			}
1470 			break;
1471 		case 13:
1472 			cmdText += "filled Ellipse";
1473 			ds >> patternIndex;
1474 			fillColor = getColor(ds);
1475 			if (patternIndex != 0)
1476 				fillC = fillColor;
1477 			boundingBoxXO = getValue(ds);
1478 			boundingBoxYO = getValue(ds);
1479 			boundingBoxWO = getValue(ds);
1480 			boundingBoxHO = getValue(ds);
1481 			bBoxO = QRectF(QPointF(boundingBoxXO, boundingBoxYO), QPointF(boundingBoxWO, boundingBoxHO));
1482 			cornerRadius = getValue(ds);
1483 			ds >> appFlags;
1484 			getCommonData(ds);
1485 			z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, posX, posY, bBox.width(), bBox.height(), lineWidth, fillC, lineColor);
1486 			currentItem = m_Doc->Items->at(z);
1487 			handleLineStyle(currentItem, flags, lineColor);
1488 			finishItem(currentItem);
1489 			if (currentItem != nullptr)
1490 				handleGradient(currentItem, patternIndex, fillColor, backColor, bBox);
1491 			break;
1492 		case 14:
1493 			cmdText += "elliptical Arc, clockwise";
1494 			ds >> patternIndex;
1495 			fillColor = getColor(ds);
1496 			if (patternIndex != 0)
1497 				fillC = fillColor;
1498 			posStart = getCoordinate(ds);
1499 			posEnd = getCoordinate(ds);
1500 			if (posStart == posEnd)
1501 				break;
1502 			boundingBoxXO = getValue(ds);
1503 			boundingBoxYO = getValue(ds);
1504 			boundingBoxWO = getValue(ds);
1505 			boundingBoxHO = getValue(ds);
1506 			getCommonData(ds);
1507 			bBoxO = QRectF(QPointF(boundingBoxXO, boundingBoxYO), QPointF(boundingBoxWO, boundingBoxHO)).normalized();
1508 			sLin = QLineF(bBoxO.center(), posStart);
1509 			eLin = QLineF(bBoxO.center(), posEnd);
1510 			rotS = sLin.angle();
1511 			rotE = eLin.angle();
1512 			if (rotS < rotE)
1513 				rotS = rotS + 360;
1514 			rotE = rotS - rotE;
1515 			path = QPainterPath();
1516 			path.arcMoveTo(bBoxO, rotS);
1517 			path.arcTo(bBoxO, rotS, -rotE);
1518 			scaleX = 1;
1519 			scaleY = 1;
1520 			z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, posX, posY, bBox.width(), bBox.height(), lineWidth, fillC, lineColor);
1521 			currentItem = m_Doc->Items->at(z);
1522 			currentItem->PoLine.fromQPainterPath(path);
1523 			bBoxO = path.controlPointRect();
1524 			currentItem->PoLine.translate(-bBoxO.x(), -bBoxO.y());
1525 			handleLineStyle(currentItem, flags, lineColor);
1526 			finishItem(currentItem);
1527 			break;
1528 		case 15:
1529 			cmdText += "filled parabolic Arc";
1530 			ds >> patternIndex;
1531 			fillColor = getColor(ds);
1532 			if (patternIndex != 0)
1533 				fillC = fillColor;
1534 			posStart = getCoordinate(ds);
1535 			posMid = getCoordinate(ds);
1536 			posEnd = getCoordinate(ds);
1537 			if (posStart == posEnd)
1538 				break;
1539 			getCommonData(ds);
1540 			path = QPainterPath();
1541 			path.moveTo(posStart);
1542 			path.cubicTo(posMid, posMid, posEnd);
1543 			z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, posX, posY, bBox.width(), bBox.height(), lineWidth, fillC, lineColor);
1544 			currentItem = m_Doc->Items->at(z);
1545 			currentItem->PoLine.fromQPainterPath(path);
1546 			bBoxO = path.controlPointRect();
1547 			currentItem->PoLine.translate(-bBoxO.x(), -bBoxO.y());
1548 			finishItem(currentItem);
1549 			if (currentItem != nullptr)
1550 			{
1551 				handleLineStyle(currentItem, flags, lineColor);
1552 				handleGradient(currentItem, patternIndex, fillColor, backColor, bBox);
1553 			}
1554 			break;
1555 		case 16:
1556 			cmdText += "filled quadratic Spline";
1557 			ds >> patternIndex;
1558 			fillColor = getColor(ds);
1559 			if (patternIndex != 0)
1560 				fillC = fillColor;
1561 			ds >> dummy;
1562 			ds >> nPoints;
1563 			ds >> appFlags;
1564 			getCommonData(ds);
1565 			nrOfPoints = nPoints;
1566 			createObjCode = 4;
1567 			z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, posX, posY, bBox.width(), bBox.height(), lineWidth, fillC, lineColor);
1568 			currentItem = m_Doc->Items->at(z);
1569 			handleLineStyle(currentItem, flags, lineColor);
1570 			handleGradient(currentItem, patternIndex, fillColor, backColor, bBox);
1571 			break;
1572 		case 17:
1573 		case 20:
1574 			ds >> patternIndex;
1575 			fillColor = getColor(ds);
1576 			ds.device()->seek(0x2B);
1577 			ds >> nItems;
1578 			ds >> dummy;
1579 			ds >> appFlags;
1580 			getCommonData(ds);
1581 			gElements.xoffset = bX + bBox.x() + groupX;
1582 			gElements.yoffset = bY + bBox.y() + groupY;
1583 			gElements.width = bBox.width();
1584 			gElements.height = bBox.height();
1585 			gElements.lineWidth = lineWidth;
1586 			gElements.scaleX = scaleX;
1587 			gElements.scaleY = scaleY;
1588 			gElements.rotationAngle = rotationAngle;
1589 			gElements.posPivot = posPivot;
1590 			gElements.filled = (data8 == 17);
1591 			gElements.nrOfItems = nItems;
1592 			gElements.counter = 0;
1593 			gElements.patternIndex = patternIndex;
1594 			gElements.flags = flags;
1595 			gElements.fillColor = fillColor;
1596 			gElements.lineColor = lineColor;
1597 			gElements.backColor = backColor;
1598 			groupStack.push(gElements);
1599 			gList.groupX = groupX;
1600 			gList.groupY = groupY;
1601 			gList.width = bBox.width();
1602 			gList.height = bBox.height();
1603 			gList.nrOfItems = 0xFFFF;
1604 			gList.counter = 0;
1605 			listStack.push(gList);
1606 			cmdText += QString("filled complex Object Count %1  Scale %2 %3 LW %4").arg(nItems).arg(scaleX).arg(scaleY).arg(lineWidth);
1607 			break;
1608 		case 18:
1609 			cmdText += "parabolic Arc";
1610 			ds >> patternIndex;
1611 			fillColor = getColor(ds);
1612 			if (patternIndex != 0)
1613 				fillC = fillColor;
1614 			posStart = getCoordinate(ds);
1615 			posMid = getCoordinate(ds);
1616 			posEnd = getCoordinate(ds);
1617 			if (posStart == posEnd)
1618 				break;
1619 			getCommonData(ds);
1620 			path = QPainterPath();
1621 			path.moveTo(posStart);
1622 			path.cubicTo(posMid, posMid, posEnd);
1623 			z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, posX, posY, bBox.width(), bBox.height(), lineWidth, fillC, lineColor);
1624 			currentItem = m_Doc->Items->at(z);
1625 			currentItem->PoLine.fromQPainterPath(path);
1626 			bBoxO = path.controlPointRect();
1627 			currentItem->PoLine.translate(-bBoxO.x(), -bBoxO.y());
1628 			handleLineStyle(currentItem, flags, lineColor);
1629 			finishItem(currentItem);
1630 			break;
1631 		case 19:
1632 			cmdText += "quadratic Spline";
1633 			ds >> patternIndex;
1634 			fillColor = getColor(ds);
1635 			if (patternIndex != 0)
1636 				fillC = fillColor;
1637 			ds >> dummy;
1638 			ds >> nPoints;
1639 			ds >> appFlags;
1640 			getCommonData(ds);
1641 			nrOfPoints = nPoints;
1642 			createObjCode = 4;
1643 			z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, posX, posY, bBox.width(), bBox.height(), lineWidth, fillC, lineColor);
1644 			currentItem = m_Doc->Items->at(z);
1645 			handleLineStyle(currentItem, flags, lineColor);
1646 			break;
1647 		case 22:
1648 			cmdText += "Bitmap monochrome";
1649 			ds >> dummy;
1650 			boundingBoxXO = getValue(ds);
1651 			boundingBoxYO = getValue(ds);
1652 			boundingBoxWO = getValue(ds);
1653 			boundingBoxHO = getValue(ds);
1654 			ds >> bitsPerPixel;
1655 			ds >> bytesScanline;
1656 			ds >> planes;
1657 			ds >> imageHeight;
1658 			ds >> imageWidth;
1659 			ds >> dummy;
1660 			ds >> rTrans;
1661 			ds >> gTrans;
1662 			ds >> bTrans;
1663 			getCommonData(ds);
1664 			if ((bitsPerPixel == 24) || (bitsPerPixel == 8))
1665 			{
1666 				z = m_Doc->itemAdd(PageItem::ImageFrame, PageItem::Rectangle, posX, posY, bBox.width(), bBox.height(), lineWidth, CommonStrings::None, CommonStrings::None);
1667 				currentItem = m_Doc->Items->at(z);
1668 				finishItem(currentItem);
1669 				scanLinesRead = 0;
1670 				tmpImage = QImage(imageWidth, imageHeight, QImage::Format_ARGB32);
1671 				if (bitsPerPixel == 8)
1672 					tmpImage2 = QImage(imageWidth, imageHeight, QImage::Format_Indexed8);
1673 				imageValid = true;
1674 			}
1675 			break;
1676 		case 23:
1677 			cmdText += "Bezier line";
1678 			ds >> patternIndex;
1679 			fillColor = getColor(ds);
1680 			if (patternIndex != 0)
1681 				fillC = fillColor;
1682 			ds >> dummy;
1683 			ds >> nPoints;
1684 			ds >> appFlags;
1685 			getCommonData(ds);
1686 			nrOfPoints = nPoints;
1687 			createObjCode = 2;
1688 			z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, posX, posY, bBox.width(), bBox.height(), lineWidth, fillC, lineColor);
1689 			currentItem = m_Doc->Items->at(z);
1690 			handleLineStyle(currentItem, flags, lineColor);
1691 			break;
1692 		case 24:
1693 			cmdText += "filled Bezier line";
1694 			ds >> patternIndex;
1695 			fillColor = getColor(ds);
1696 			if (patternIndex != 0)
1697 				fillC = fillColor;
1698 			ds >> dummy;
1699 			ds >> nPoints;
1700 			ds >> appFlags;
1701 			getCommonData(ds);
1702 			nrOfPoints = nPoints;
1703 			createObjCode = 2;
1704 			z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, posX, posY, bBox.width(), bBox.height(), lineWidth, fillC, lineColor);
1705 			currentItem = m_Doc->Items->at(z);
1706 			handleLineStyle(currentItem, flags, lineColor);
1707 			handleGradient(currentItem, patternIndex, fillColor, backColor, bBox);
1708 			break;
1709 		case 25:
1710 			cmdText += "Rich Text";
1711 			fontColor = lineColor;
1712 			getCommonData(ds);
1713 			createObjCode = 6;
1714 			z = m_Doc->itemAdd(PageItem::TextFrame, PageItem::Rectangle, posX, posY, bBox.width(), bBox.height(), 0, CommonStrings::None, CommonStrings::None);
1715 			currentItem = m_Doc->Items->at(z);
1716 			currentItem->setTextToFrameDist(0.0, 0.0, 0.0, 0.0);
1717 			finishItem(currentItem);
1718 			break;
1719 		case 26:
1720 			cmdText += "virtual Bitmap";
1721 			//printMSG = true;
1722 			break;
1723 		case 27:
1724 			cmdText += "simple Clip Path";
1725 			//printMSG = true;
1726 			break;
1727 		case 28:
1728 			cmdText += "tiled Clip Path";
1729 			//printMSG = true;
1730 			break;
1731 		case 29:
1732 			cmdText += "Path Text";
1733 			//printMSG = true;
1734 			break;
1735 		default:
1736 			cmdText += "Unknown";
1737 			break;
1738 	}
1739 	//printMSG = false;
1740 //	if (printMSG)
1741 //	{
1742 //		if (currentItem != nullptr)
1743 //			qDebug() << cmdText << " " << currentItem->itemName();
1744 //		else
1745 //			qDebug() << cmdText;
1746 //		if (imageValid)
1747 //			qDebug() << "Bits/Pixel" << bitsPerPixel << "Bytes" << bytesScanline << "Planes" << planes << "Height" << imageHeight << "Width" << imageWidth;
1748 //		qDebug() << "Pos" << rotS << " --> " << rotE << " Box " << boundingBoxWO << boundingBoxHO;
1749 //		qDebug() << "Rot" << rotationAngle << "Bounding Box" << bBoxO;
1750 //		qDebug() << "Line" << lineColor << "LWidth" << lineWidth << "Fill" << fillColor;
1751 //		qDebug() << "Scale" << scaleX << " " << scaleY;
1752 //		qDebug() << QString("Flags %1").arg(flags, 8, 2, QChar('0')) << QString("Pattern %1").arg(patternIndex, 2, 16, QChar('0'));
1753 //		if (createObjCode == 4)
1754 //		{
1755 //			qDebug() << "Expecting" << nrOfPoints;
1756 //		}
1757 //	}
1758 }
1759 
handleLineStyle(PageItem * currentItem,quint8 flags,const QString & lineColor)1760 void DrwPlug::handleLineStyle(PageItem* currentItem, quint8 flags, const QString& lineColor)
1761 {
1762 	if ((flags & 0x0F) == 5)
1763 		currentItem->setLineColor(CommonStrings::None);
1764 	else
1765 		currentItem->setLineColor(lineColor);
1766 	if ((flags & 0x0F) == 0)
1767 		currentItem->setLineStyle(Qt::SolidLine);
1768 	else if ((flags & 0x0F) == 1)
1769 		currentItem->setLineStyle(Qt::DashLine);
1770 	else if ((flags & 0x0F) == 2)
1771 		currentItem->setLineStyle(Qt::DotLine);
1772 	else if ((flags & 0x0F) == 3)
1773 		currentItem->setLineStyle(Qt::DashDotLine);
1774 	else
1775 		currentItem->setLineStyle(Qt::SolidLine);
1776 }
1777 
handleGradient(PageItem * currentItem,quint8 patternIndex,const QString & fillColor,const QString & backColor,QRectF bBox)1778 void DrwPlug::handleGradient(PageItem* currentItem, quint8 patternIndex, const QString& fillColor, const QString& backColor, QRectF bBox)
1779 {
1780 	if ((fillColor == CommonStrings::None) || (backColor == CommonStrings::None))
1781 		return;
1782 	if ((patternIndex > 0x40) && (patternIndex < 0x80))
1783 	{
1784 		quint8 ind = patternIndex - 0x40;
1785 		DRWGradient grad;
1786 		if (gradientMap.contains(ind))
1787 		{
1788 			grad = gradientMap[ind];
1789 			if (grad.xOffset > 1)
1790 				grad.xOffset -= 1;
1791 			if (grad.yOffset > 1)
1792 				grad.yOffset -= 1;
1793 			double xoff = bBox.width() * grad.xOffset;
1794 			double yoff = bBox.height() * grad.yOffset;
1795 			VGradient FillGradient = VGradient(VGradient::linear);
1796 			FillGradient.clearStops();
1797 			const ScColor& gradC1 = m_Doc->PageColors[fillColor];
1798 			FillGradient.addStop( ScColorEngine::getRGBColor(gradC1, m_Doc), 0.0, 0.5, 1.0, fillColor, 100 );
1799 			const ScColor& gradC2 = m_Doc->PageColors[backColor];
1800 			if (grad.type == 1)
1801 			{
1802 				FillGradient.addStop( ScColorEngine::getRGBColor(gradC2, m_Doc), qMin(grad.yOffset, 0.99), 0.5, 1.0, backColor, 100 );
1803 				FillGradient.addStop( ScColorEngine::getRGBColor(gradC1, m_Doc), 1.0, 0.5, 1.0, fillColor, 100 );
1804 				currentItem->GrType = Gradient_Linear;
1805 				currentItem->fill_gradient = FillGradient;
1806 				currentItem->setGradientVector(bBox.width() / 2.0, 0, bBox.width() / 2.0, bBox.height(), 0, 0, 1, 0);
1807 			}
1808 			else
1809 			{
1810 				FillGradient.addStop( ScColorEngine::getRGBColor(gradC2, m_Doc), 1.0, 0.5, 1.0, backColor, 100 );
1811 				currentItem->GrType = Gradient_Radial;
1812 				currentItem->fill_gradient = FillGradient;
1813 				currentItem->setGradientVector(xoff, yoff, qMax(bBox.width(), bBox.height()), qMax(bBox.width(), bBox.height()), xoff, yoff, 1, 0);
1814 			}
1815 		}
1816 	}
1817 	else if (((patternIndex > 0x80) && (patternIndex < 0xC0)) || (patternIndex > 0xC0))
1818 	{
1819 		int ind;
1820 		if (patternIndex > 0xC0)
1821 			ind = patternIndex - 0xC0;
1822 		else
1823 			ind = patternIndex - 0x80;
1824 		if (patternDataMap.contains(ind))
1825 		{
1826 			QColor back = ScColorEngine::getRGBColor(m_Doc->PageColors[fillColor], m_Doc);
1827 			QColor fore = ScColorEngine::getRGBColor(m_Doc->PageColors[backColor], m_Doc);
1828 			QString patNa = QString("%1%2%3").arg(back.name(), fore.name()).arg(ind);
1829 			QString patternName;
1830 			if (!patternMap.contains(patNa))
1831 			{
1832 				uint oldNum = m_Doc->TotalItems;
1833 				QByteArray data = patternDataMap[ind];
1834 				QVector<QRgb> colors;
1835 				int offs = 0;
1836 				QImage image;
1837 				if (patternIndex > 0xC0)
1838 				{
1839 					colors.append(qRgb(255,255,255));
1840 					colors.append(back.rgb());
1841 					image = QImage(16, 8, QImage::Format_Mono);
1842 					image.setColorTable(colors);
1843 					for (int rr = 0; rr < 8; rr++)
1844 					{
1845 						uchar *q = (uchar*)(image.scanLine(rr));
1846 						*q++ = data[offs++];
1847 						*q++ = data[offs++];
1848 					}
1849 					image = image.scaled(96, 48);
1850 				}
1851 				else
1852 				{
1853 					colors.append(back.rgb());
1854 					colors.append(fore.rgb());
1855 					image = QImage(8, 8, QImage::Format_Mono);
1856 					image.setColorTable(colors);
1857 					for (int rr = 0; rr < 8; rr++)
1858 					{
1859 						uchar *q = (uchar*)(image.scanLine(rr));
1860 						*q++ = data[offs++];
1861 						offs++;
1862 					}
1863 					image = image.scaled(48, 48);
1864 				}
1865 				image = image.convertToFormat(QImage::Format_ARGB32);
1866 				ScPattern pat = ScPattern();
1867 				pat.setDoc(m_Doc);
1868 				PageItem* newItem = new PageItem_ImageFrame(m_Doc, 0, 0, 1, 1, 0, CommonStrings::None, CommonStrings::None);
1869 				QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_drw_XXXXXX.png");
1870 				tempFile->setAutoRemove(false);
1871 				tempFile->open();
1872 				QString fileName = getLongPathName(tempFile->fileName());
1873 				tempFile->close();
1874 				delete tempFile;
1875 				newItem->isInlineImage = true;
1876 				newItem->isTempFile = true;
1877 				image.setDotsPerMeterY(2834);
1878 				image.setDotsPerMeterX(2834);
1879 				image.save(fileName, "PNG");
1880 				if (newItem->loadImage(fileName, false, 72, false))
1881 				{
1882 					pat.width = image.width();
1883 					pat.height = image.height();
1884 					pat.scaleX = (72.0 / newItem->pixm.imgInfo.xres) * newItem->pixm.imgInfo.lowResScale;
1885 					pat.scaleY = (72.0 / newItem->pixm.imgInfo.xres) * newItem->pixm.imgInfo.lowResScale;
1886 					pat.pattern = newItem->pixm.qImage().copy();
1887 					newItem->setWidth(pat.pattern.width());
1888 					newItem->setHeight(pat.pattern.height());
1889 					newItem->SetRectFrame();
1890 					newItem->gXpos = 0.0;
1891 					newItem->gYpos = 0.0;
1892 					newItem->gWidth = pat.pattern.width();
1893 					newItem->gHeight = pat.pattern.height();
1894 					pat.items.append(newItem);
1895 				}
1896 				patternName = "Pattern_"+newItem->itemName();
1897 				patternName = patternName.trimmed().simplified().replace(" ", "_");
1898 				m_Doc->addPattern(patternName, pat);
1899 				patternMap.insert(patNa, patternName);
1900 				m_Doc->TotalItems = oldNum;
1901 			}
1902 			else
1903 				patternName = patternMap[patNa];
1904 			importedPatterns.append(patternName);
1905 			currentItem->setPattern(patternName);
1906 			currentItem->setPatternTransform(16.6666, 16.6666, 0, 0, 0, 0, 0);
1907 			currentItem->GrType = Gradient_Pattern;
1908 		}
1909 	}
1910 }
1911 
handlePreviewBitmap(QDataStream & ds)1912 void DrwPlug::handlePreviewBitmap(QDataStream &ds)
1913 {
1914 	/* create a fake BMP header section */
1915 	QByteArray header;
1916 	header.resize(14);
1917 	header.fill(0);
1918 	QDataStream hs(&header, QIODevice::ReadWrite);
1919 	hs.setByteOrder(QDataStream::LittleEndian);
1920 	quint16 size;
1921 	size = 0x4D42;
1922 	hs << size;
1923 	size = cmdData.size() + 14;
1924 	hs << size;
1925 	header.append(cmdData);
1926 	thumbnailImage.loadFromData(header, "BMP");
1927 }
1928 
handleColor(ScColor & color,const QString & proposedName)1929 QString DrwPlug::handleColor(ScColor &color, const QString& proposedName)
1930 {
1931 	QString tmpName = m_Doc->PageColors.tryAddColor(proposedName, color);
1932 	if (tmpName == proposedName)
1933 		importedColors.append(tmpName);
1934 	return tmpName;
1935 }
1936 
1937 
getCommonData(QDataStream & ds)1938 void DrwPlug::getCommonData(QDataStream &ds)
1939 {
1940 	quint16 dummy;
1941 	ds.device()->seek(0x38);
1942 	backColor = getColor(ds);
1943 	lineWidth = getValue(ds);
1944 	ds >> dummy;
1945 	posPivot = getCoordinate(ds);
1946 }
1947 
getColor(QDataStream & ds)1948 QString DrwPlug::getColor(QDataStream &ds)
1949 {
1950 	quint8 r;
1951 	quint8 g;
1952 	quint8 b;
1953 	quint8 a;
1954 	ds >> r >> g >> b >> a;
1955 	ScColor color = ScColor(r, g, b);
1956 	return handleColor(color, "FromDRW"+color.name());
1957 }
1958 
finishItem(PageItem * ite,bool scale)1959 void DrwPlug::finishItem(PageItem* ite, bool scale)
1960 {
1961 	if (ite->PoLine.size() < 4)
1962 	{
1963 		tmpSel->clear();
1964 		tmpSel->addItem(ite, true);
1965 		m_Doc->itemSelection_DeleteItem(tmpSel);
1966 		currentItem = nullptr;
1967 		createObjCode = 0;
1968 		tmpSel->clear();
1969 		return;
1970 	}
1971 	ite->ClipEdited = true;
1972 	ite->FrameType = 3;
1973 	ite->setTextFlowMode(PageItem::TextFlowDisabled);
1974 	if (rotationAngle != 0)
1975 	{
1976 		QTransform ma;
1977 		ma.translate(posPivot.x(), posPivot.y());
1978 		ma.rotate(-rotationAngle / 10.0);
1979 		ite->PoLine.map(ma);
1980 		FPoint tp2(getMinClipF(&ite->PoLine));
1981 		ite->PoLine.translate(-tp2.x(), -tp2.y());
1982 	}
1983 	if (scale)
1984 	{
1985 		if ((scaleX != 0) || (scaleY != 0))
1986 		{
1987 			QPainterPath pa = ite->PoLine.toQPainterPath(true);
1988 			QRectF bb = pa.controlPointRect();
1989 			double scx = 1.0;
1990 			double scy = 1.0;
1991 			if ((bb.width() != 0.0) && (ite->width() != 0.0))
1992 				scx = ite->width() / bb.width();
1993 			else
1994 				scx = 1.0;
1995 			if ((bb.height() != 0.0) && (ite->height() != 0.0))
1996 				scy = ite->height() / bb.height();
1997 			else
1998 				scy = 1.0;
1999 			ite->PoLine.scale(scx, scy);
2000 			ite->setLineWidth(ite->lineWidth() / qMin(scx, scy));
2001 		}
2002 	}
2003 	FPoint wh = getMaxClipF(&ite->PoLine);
2004 	ite->setWidthHeight(wh.x(),wh.y());
2005 	m_Doc->adjustItemSize(ite);
2006 	ite->OldB2 = ite->width();
2007 	ite->OldH2 = ite->height();
2008 	ite->updateClip();
2009 	Elements.append(ite);
2010 	if (groupStack.count() > 1)
2011 		groupStack.top().GElements.append(ite);
2012 	if (listStack.count() > 1)
2013 		listStack.top().GElements.append(ite);
2014 	Coords.resize(0);
2015 	Coords.svgInit();
2016 }
2017 
getValue(QDataStream & ds)2018 double DrwPlug::getValue(QDataStream &ds)
2019 {
2020 	qint16 data16;
2021 	ds >> data16;
2022 	return data16 * scaleFactor;
2023 }
2024 
getRawValue(QDataStream & ds)2025 double DrwPlug::getRawValue(QDataStream &ds)
2026 {
2027 	qint16 data16;
2028 	ds >> data16;
2029 	return static_cast<double>(data16);
2030 }
2031 
getCoordinate(QDataStream & ds)2032 QPointF DrwPlug::getCoordinate(QDataStream &ds)
2033 {
2034 	qint16 x, y;
2035 	ds >> x >> y;
2036 	return QPointF(x * scaleFactor, y * scaleFactor);
2037 }
2038