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