1 /*
2 For general Scribus (>=1.3.2) copyright and licensing information please refer
3 to the COPYING file provided with the program. Following this notice may exist
4 a copyright and/or license notice that predates the release of Scribus 1.3.2
5 for which a new license (GPL+exception) is in place.
6 */
7
8 #include <QByteArray>
9 #include <QCursor>
10 #include <QDrag>
11 #include <QFile>
12 #include <QList>
13 #include <QMimeData>
14 #include <QRegExp>
15 #include <QTextCodec>
16 #include <QStack>
17 #include <QDebug>
18
19 #include <cstdlib>
20
21 #include "importpct.h"
22
23 #include "commonstrings.h"
24 #include "loadsaveplugin.h"
25 #include "pageitem_imageframe.h"
26 #include "pagesize.h"
27 #include "prefscontext.h"
28 #include "prefsfile.h"
29 #include "prefsmanager.h"
30 #include "prefstable.h"
31 #include "rawimage.h"
32 #include "scclocale.h"
33 #include "sccolorengine.h"
34 #include "scconfig.h"
35 #include "scmimedata.h"
36 #include "scpaths.h"
37 #include "scpattern.h"
38 #include "scribusXml.h"
39 #include "scribuscore.h"
40 #include "scribusdoc.h"
41 #include "scribusview.h"
42 #include "sctextstream.h"
43 #include "selection.h"
44 #include "ui/customfdialog.h"
45 #include "ui/missing.h"
46 #include "ui/multiprogressdialog.h"
47 #include "ui/propertiespalette.h"
48 #include "undomanager.h"
49 #include "util.h"
50 #include "util_formats.h"
51 #include "util_math.h"
52
PctPlug(ScribusDoc * doc,int flags)53 PctPlug::PctPlug(ScribusDoc* doc, int flags)
54 {
55 tmpSel=new Selection(this, false);
56 m_Doc=doc;
57 importerFlags = flags;
58 interactive = (flags & LoadSavePlugin::lfInteractive);
59 progressDialog = nullptr;
60 }
61
readThumbnail(const QString & fName)62 QImage PctPlug::readThumbnail(const QString& fName)
63 {
64 QFileInfo fi = QFileInfo(fName);
65 baseFile = QDir::cleanPath(QDir::toNativeSeparators(fi.absolutePath()+"/"));
66 double b {0.0};
67 double h {0.0};
68 double x {0.0};
69 double y {0.0};
70 parseHeader(fName, x, y, b, h);
71 if (b == 0.0)
72 b = PrefsManager::instance().appPrefs.docSetupPrefs.pageWidth;
73 if (h == 0.0)
74 h = PrefsManager::instance().appPrefs.docSetupPrefs.pageHeight;
75 docWidth = b;
76 docHeight = h;
77 progressDialog = nullptr;
78 m_Doc = new ScribusDoc();
79 m_Doc->setup(0, 1, 1, 1, 1, "Custom", "Custom");
80 m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false);
81 m_Doc->addPage(0);
82 m_Doc->setGUI(false, ScCore->primaryMainWindow(), nullptr);
83 baseX = m_Doc->currentPage()->xOffset() - x;
84 baseY = m_Doc->currentPage()->yOffset() - y;
85 Elements.clear();
86 m_Doc->setLoading(true);
87 m_Doc->DoDrawing = false;
88 m_Doc->scMW()->setScriptRunning(true);
89 QString CurDirP = QDir::currentPath();
90 QDir::setCurrent(fi.path());
91 if (convert(fName))
92 {
93 tmpSel->clear();
94 QDir::setCurrent(CurDirP);
95 if (Elements.count() > 1)
96 m_Doc->groupObjectsList(Elements);
97 m_Doc->DoDrawing = true;
98 m_Doc->m_Selection->delaySignalsOn();
99 QImage tmpImage;
100 if (Elements.count() > 0)
101 {
102 for (int dre=0; dre<Elements.count(); ++dre)
103 {
104 tmpSel->addItem(Elements.at(dre), true);
105 }
106 tmpSel->setGroupRect();
107 double xs = tmpSel->width();
108 double ys = tmpSel->height();
109 tmpImage = Elements.at(0)->DrawObj_toImage(500);
110 tmpImage.setText("XSize", QString("%1").arg(xs));
111 tmpImage.setText("YSize", QString("%1").arg(ys));
112 }
113 m_Doc->scMW()->setScriptRunning(false);
114 m_Doc->setLoading(false);
115 m_Doc->m_Selection->delaySignalsOff();
116 delete m_Doc;
117 return tmpImage;
118 }
119 QDir::setCurrent(CurDirP);
120 m_Doc->DoDrawing = true;
121 m_Doc->scMW()->setScriptRunning(false);
122 delete m_Doc;
123 return QImage();
124 }
125
import(const QString & fNameIn,const TransactionSettings & trSettings,int flags,bool showProgress)126 bool PctPlug::import(const QString& fNameIn, const TransactionSettings& trSettings, int flags, bool showProgress)
127 {
128 bool success = false;
129 interactive = (flags & LoadSavePlugin::lfInteractive);
130 importerFlags = flags;
131 cancel = false;
132 bool ret = false;
133 CustColors.clear();
134 QFileInfo fi = QFileInfo(fNameIn);
135 if ( !ScCore->usingGUI() )
136 {
137 interactive = false;
138 showProgress = false;
139 }
140 baseFile = QDir::cleanPath(QDir::toNativeSeparators(fi.absolutePath()+"/"));
141 if ( showProgress )
142 {
143 ScribusMainWindow* mw=(m_Doc==nullptr) ? ScCore->primaryMainWindow() : m_Doc->scMW();
144 progressDialog = new MultiProgressDialog( tr("Importing: %1").arg(fi.fileName()), CommonStrings::tr_Cancel, mw );
145 QStringList barNames, barTexts;
146 barNames << "GI";
147 barTexts << tr("Analyzing File:");
148 QList<bool> barsNumeric;
149 barsNumeric << false;
150 progressDialog->addExtraProgressBars(barNames, barTexts, barsNumeric);
151 progressDialog->setOverallTotalSteps(3);
152 progressDialog->setOverallProgress(0);
153 progressDialog->setProgress("GI", 0);
154 progressDialog->show();
155 connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelRequested()));
156 qApp->processEvents();
157 }
158 else
159 progressDialog = nullptr;
160 /* Set default Page to size defined in Preferences */
161 double x = 0.0;
162 double y = 0.0;
163 double b = 0.0;
164 double h = 0.0;
165 if (progressDialog)
166 {
167 progressDialog->setOverallProgress(1);
168 qApp->processEvents();
169 }
170 parseHeader(fNameIn, x, y, b, h);
171 if (b == 0.0)
172 b = PrefsManager::instance().appPrefs.docSetupPrefs.pageWidth;
173 if (h == 0.0)
174 h = PrefsManager::instance().appPrefs.docSetupPrefs.pageHeight;
175 docWidth = b;
176 docHeight = h;
177 baseX = 0;
178 baseY = 0;
179 if (!interactive || (flags & LoadSavePlugin::lfInsertPage))
180 {
181 m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false);
182 m_Doc->addPage(0);
183 m_Doc->view()->addPage(0, true);
184 m_Doc->currentPage()->setInitialWidth(docWidth);
185 m_Doc->currentPage()->setInitialHeight(docHeight);
186 m_Doc->currentPage()->setWidth(docWidth);
187 m_Doc->currentPage()->setHeight(docHeight);
188 m_Doc->currentPage()->setMasterPageNameNormal();
189 m_Doc->currentPage()->setSize("Custom");
190 m_Doc->reformPages(true);
191 baseX = m_Doc->currentPage()->xOffset();
192 baseY = m_Doc->currentPage()->yOffset();
193 }
194 else
195 {
196 if (!m_Doc || (flags & LoadSavePlugin::lfCreateDoc))
197 {
198 m_Doc = ScCore->primaryMainWindow()->doFileNew(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false, 0, false, 0, 1, "Custom", true);
199 ScCore->primaryMainWindow()->HaveNewDoc();
200 m_Doc->setPageHeight(docHeight);
201 m_Doc->setPageWidth(docWidth);
202 m_Doc->currentPage()->setInitialWidth(docWidth);
203 m_Doc->currentPage()->setInitialHeight(docHeight);
204 m_Doc->currentPage()->setWidth(docWidth);
205 m_Doc->currentPage()->setHeight(docHeight);
206 ret = true;
207 baseX = m_Doc->currentPage()->xOffset();
208 baseY = m_Doc->currentPage()->yOffset();
209 }
210 }
211 offsetX += m_Doc->currentPage()->xOffset();
212 offsetY += m_Doc->currentPage()->yOffset();
213 offsetX *= -1;
214 offsetY *= -1;
215 if ((!ret) && (interactive))
216 {
217 baseX = m_Doc->currentPage()->xOffset();
218 baseY = m_Doc->currentPage()->yOffset();
219 }
220 if ((ret) || (!interactive))
221 {
222 if (docWidth > docHeight)
223 m_Doc->setPageOrientation(1);
224 else
225 m_Doc->setPageOrientation(0);
226 m_Doc->setPageSize("Custom");
227 }
228 if ((!(flags & LoadSavePlugin::lfLoadAsPattern)) && (m_Doc->view() != nullptr))
229 m_Doc->view()->deselectItems();
230 Elements.clear();
231 m_Doc->setLoading(true);
232 m_Doc->DoDrawing = false;
233 if ((!(flags & LoadSavePlugin::lfLoadAsPattern)) && (m_Doc->view() != nullptr))
234 m_Doc->view()->updatesOn(false);
235 m_Doc->scMW()->setScriptRunning(true);
236 qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
237 QString CurDirP = QDir::currentPath();
238 QDir::setCurrent(fi.path());
239 if (convert(fNameIn))
240 {
241 tmpSel->clear();
242 QDir::setCurrent(CurDirP);
243 if ((Elements.count() > 1) && (!(importerFlags & LoadSavePlugin::lfCreateDoc)))
244 m_Doc->groupObjectsList(Elements);
245 m_Doc->DoDrawing = true;
246 m_Doc->scMW()->setScriptRunning(false);
247 m_Doc->setLoading(false);
248 qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
249 if ((Elements.count() > 0) && (!ret) && (interactive))
250 {
251 if (flags & LoadSavePlugin::lfScripted)
252 {
253 bool loadF = m_Doc->isLoading();
254 m_Doc->setLoading(false);
255 m_Doc->changed();
256 m_Doc->setLoading(loadF);
257 if (!(flags & LoadSavePlugin::lfLoadAsPattern))
258 {
259 m_Doc->m_Selection->delaySignalsOn();
260 for (int dre=0; dre<Elements.count(); ++dre)
261 {
262 m_Doc->m_Selection->addItem(Elements.at(dre), true);
263 }
264 m_Doc->m_Selection->delaySignalsOff();
265 m_Doc->m_Selection->setGroupRect();
266 if (m_Doc->view() != nullptr)
267 m_Doc->view()->updatesOn(true);
268 }
269 }
270 else
271 {
272 m_Doc->DragP = true;
273 m_Doc->DraggedElem = nullptr;
274 m_Doc->DragElements.clear();
275 m_Doc->m_Selection->delaySignalsOn();
276 for (int dre=0; dre<Elements.count(); ++dre)
277 {
278 tmpSel->addItem(Elements.at(dre), true);
279 }
280 tmpSel->setGroupRect();
281 ScElemMimeData* md = ScriXmlDoc::writeToMimeData(m_Doc, tmpSel);
282 m_Doc->itemSelection_DeleteItem(tmpSel);
283 m_Doc->view()->updatesOn(true);
284 if (importedColors.count() != 0)
285 {
286 for (int cd = 0; cd < importedColors.count(); cd++)
287 {
288 m_Doc->PageColors.remove(importedColors[cd]);
289 }
290 }
291 if (importedPatterns.count() != 0)
292 {
293 for (int cd = 0; cd < importedPatterns.count(); cd++)
294 {
295 m_Doc->docPatterns.remove(importedPatterns[cd]);
296 }
297 }
298 m_Doc->m_Selection->delaySignalsOff();
299 // We must copy the TransationSettings object as it is owned
300 // by handleObjectImport method afterwards
301 TransactionSettings* transacSettings = new TransactionSettings(trSettings);
302 m_Doc->view()->handleObjectImport(md, transacSettings);
303 m_Doc->DragP = false;
304 m_Doc->DraggedElem = nullptr;
305 m_Doc->DragElements.clear();
306 }
307 }
308 else
309 {
310 m_Doc->changed();
311 m_Doc->reformPages();
312 if (!(flags & LoadSavePlugin::lfLoadAsPattern))
313 m_Doc->view()->updatesOn(true);
314 }
315 success = true;
316 }
317 else
318 {
319 QDir::setCurrent(CurDirP);
320 m_Doc->DoDrawing = true;
321 m_Doc->scMW()->setScriptRunning(false);
322 m_Doc->view()->updatesOn(true);
323 qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
324 }
325 if (interactive)
326 m_Doc->setLoading(false);
327 //CB If we have a gui we must refresh it if we have used the progressbar
328 if (!(flags & LoadSavePlugin::lfLoadAsPattern))
329 {
330 if ((showProgress) && (!interactive))
331 m_Doc->view()->DrawNew();
332 }
333 qApp->restoreOverrideCursor();
334 return success;
335 }
336
~PctPlug()337 PctPlug::~PctPlug()
338 {
339 delete progressDialog;
340 delete tmpSel;
341 }
342
parseHeader(const QString & fName,double & x,double & y,double & b,double & h)343 void PctPlug::parseHeader(const QString& fName, double &x, double &y, double &b, double &h)
344 {
345 QFile f(fName);
346 if (f.open(QIODevice::ReadOnly))
347 {
348 QDataStream ts(&f);
349 ts.setByteOrder(QDataStream::BigEndian);
350 ts.device()->seek(512);
351 qint16 pgX, pgY, pgW, pgH, dummy;
352 ts >> dummy >> pgX >> pgY >> pgW >> pgH;
353 quint16 vers, vers2, vers3;
354 ts >> vers;
355 if (vers == 0x1101)
356 {
357 pctVersion = 1;
358 h = pgW - pgX;
359 b = pgH - pgY;
360 x = pgY;
361 y = pgX;
362 offsetX = x;
363 offsetY = y;
364 resX = 1.0;
365 resY = 1.0;
366 }
367 else if (vers == 0x0011)
368 {
369 ts >> vers2 >> vers3;
370 if ((vers2 == 0x02FF) && (vers3 == 0x0C00))
371 {
372 pctVersion = 2;
373 qint16 vExt;
374 ts >> vExt;
375 if (vExt == -1)
376 {
377 ts >> dummy;
378 // quint32 xres, yres;
379 // xres = 72;
380 // yres = 72;
381 resX = 1.0;
382 resY = 1.0;
383 qint32 pgX2, pgY2, pgW2, pgH2;
384 ts >> pgX2 >> pgY2 >> pgW2 >> pgH2;
385 ts >> dummy;
386 ts >> dummy;
387 h = pgW - pgX;
388 b = pgH - pgY;
389 x = pgY;
390 y = pgX;
391 offsetX = x;
392 offsetY = y;
393 }
394 else if (vExt == -2)
395 {
396 ts >> dummy;
397 quint16 xres, yres;
398 ts >> xres >> dummy >> yres >> dummy;
399 ts >> pgX >> pgY >> pgW >> pgH;
400 ts >> dummy;
401 resX = 72.0 / static_cast<double>(xres);
402 resY = 72.0 / static_cast<double>(yres);
403 h = (pgW - pgX) * resX;
404 b = (pgH - pgY) * resY;
405 x = pgY * resX;
406 y = pgX * resY;
407 offsetX = x;
408 offsetY = y;
409 }
410 }
411 }
412 f.close();
413 // qDebug() << "W" << b << "H" << h;
414 }
415 }
416
convert(const QString & fn)417 bool PctPlug::convert(const QString& fn)
418 {
419 CurrColorFill = "White";
420 CurrFillShade = 100.0;
421 CurrColorStroke = "Black";
422 CurrStrokeShade = 100.0;
423 patternMode = false;
424 patternData.resize(0);
425 backColor = Qt::white;
426 foreColor = Qt::black;
427 Coords.resize(0);
428 Coords.svgInit();
429 LineW = 1.0;
430 currentPoint = QPoint(0, 0);
431 currentPointT = QPoint(0, 0);
432 ovalSize = QPoint(0, 0);
433 fontMap.clear();
434 currentTextSize = 12;
435 currentFontID = 0;
436 currentFontStyle = 0;
437 imageData.resize(0);
438 lineMode = false;
439 skipOpcode = false;
440 postscriptMode = false;
441 textIsPostScript = false;
442 importedColors.clear();
443 importedPatterns.clear();
444 QList<PageItem*> gElements;
445 groupStack.push(gElements);
446 currentItemNr = 0;
447 if (progressDialog)
448 {
449 progressDialog->setOverallProgress(2);
450 progressDialog->setLabel("GI", tr("Generating Items"));
451 qApp->processEvents();
452 }
453 QFile f(fn);
454 if (f.open(QIODevice::ReadOnly))
455 {
456 int fSize = (int) f.size();
457 if (progressDialog)
458 {
459 progressDialog->setTotalSteps("GI", fSize);
460 qApp->processEvents();
461 }
462 QDataStream ts(&f);
463 ts.setByteOrder(QDataStream::BigEndian);
464 ts.device()->seek(522);
465 quint16 vers = 0;
466 ts >> vers;
467 while (vers == 0)
468 {
469 ts >> vers;
470 if (vers == 0x00FF)
471 {
472 if (progressDialog)
473 progressDialog->close();
474 f.close();
475 return false;
476 }
477 }
478 if (vers == 0x1101)
479 {
480 pctVersion = 1; // Pict Version 1
481 parsePict(ts);
482 }
483 else
484 {
485 ts.skipRawData(4); // skip the next 4 Bytes
486 ts >> vers; // read the version info
487 // if (vers == 0x0FFFE)
488 pctVersion = 2; // Pict Extended Version 2
489 // else if (vers == 0x0FFFF)
490 // pctVersion = 3; // Pict Version 2
491 // else
492 // {
493 // if (progressDialog)
494 // progressDialog->close();
495 // f.close();
496 // return false; // bail out, no Mac Pict
497 // }
498 ts.skipRawData(22);
499 parsePict(ts);
500 }
501 if (Elements.count() == 0)
502 {
503 if (importedColors.count() != 0)
504 {
505 for (int cd = 0; cd < importedColors.count(); cd++)
506 {
507 m_Doc->PageColors.remove(importedColors[cd]);
508 }
509 }
510 if (importedPatterns.count() != 0)
511 {
512 for (int cd = 0; cd < importedPatterns.count(); cd++)
513 {
514 m_Doc->docPatterns.remove(importedPatterns[cd]);
515 }
516 }
517 }
518 f.close();
519 }
520 if (progressDialog)
521 progressDialog->close();
522 return true;
523 }
524
parsePict(QDataStream & ts)525 void PctPlug::parsePict(QDataStream &ts)
526 {
527 while (!ts.atEnd())
528 {
529 quint16 opCode, dataLen;
530 quint8 dataLenByte;
531 quint32 dataLenLong;
532 if (pctVersion == 1)
533 {
534 ts >> dataLenByte;
535 opCode = dataLenByte;
536 }
537 else
538 ts >> opCode;
539 if (((opCode >= 0x0092) && (opCode <= 0x0097)) || ((opCode >= 0x009C) && (opCode <= 0x009F)) || ((opCode >= 0x00A2) && (opCode <= 0x00AF)))
540 {
541 // Reserved by Apple
542 // qDebug() << "Reserved by Apple";
543 ts >> dataLen;
544 alignStreamToWord(ts, dataLen);
545 }
546 else if (((opCode >= 0x00B0) && (opCode <= 0x00CF)) || ((opCode >= 0x8000) && (opCode <= 0x80FF)))
547 {
548 // Reserved by Apple
549 // qDebug() << "Reserved by Apple";
550 }
551 else if (((opCode >= 0x00D0) && (opCode <= 0x00FE)) || ((opCode >= 0x8100) && (opCode <= 0x81FF)))
552 {
553 // Reserved by Apple
554 // qDebug() << "Reserved by Apple";
555 ts >> dataLenLong;
556 alignStreamToWord(ts, dataLenLong);
557 }
558 else if (((opCode >= 0x0100) && (opCode <= 0x01FF)) || ((opCode >= 0x02FF) && (opCode <= 0x0BFE)))
559 {
560 // Reserved by Apple
561 // qDebug() << "Reserved by Apple";
562 alignStreamToWord(ts, 2);
563 }
564 else if ((opCode >= 0x0C00) && (opCode <= 0x7EFF))
565 {
566 // Reserved by Apple
567 // qDebug() << "Reserved by Apple";
568 alignStreamToWord(ts, 24);
569 }
570 else if ((opCode >= 0x7F00) && (opCode <= 0x7FFF))
571 {
572 // Reserved by Apple
573 // qDebug() << "Reserved by Apple";
574 alignStreamToWord(ts, 254);
575 }
576 else
577 {
578 switch (opCode)
579 {
580 case 0x0000: // NOP
581 // qDebug() << "NOP";
582 break;
583 case 0x0001: // Clipping Region
584 // qDebug() << "Clipping Region";
585 ts >> dataLen;
586 alignStreamToWord(ts, dataLen-2);
587 break;
588 case 0x0002: // Background Pattern
589 handleLineModeEnd();
590 // qDebug() << "Background Pattern";
591 alignStreamToWord(ts, 8);
592 break;
593 case 0x0003: // Text Font
594 handleTextFont(ts);
595 break;
596 case 0x0004: // Text Style
597 handleTextStyle(ts);
598 break;
599 case 0x0005: // Text Mode
600 handleLineModeEnd();
601 ts >> dataLen;
602 // qDebug() << "Text Mode" << dataLen;
603 // alignStreamToWord(ts, 2);
604 break;
605 case 0x0006: // Extra Space
606 // qDebug() << "Extra Space";
607 alignStreamToWord(ts, 4);
608 break;
609 case 0x0007: // Pen Size
610 handlePenSize(ts);
611 break;
612 case 0x0008: // Pen Mode
613 handleLineModeEnd();
614 ts >> dataLen;
615 // qDebug() << "Pen Mode" << dataLen;
616 // alignStreamToWord(ts, 2);
617 break;
618 case 0x0009: // Pen Pattern
619 handlePenPattern(ts);
620 break;
621 case 0x000A: // Fill Pattern
622 handleLineModeEnd();
623 // qDebug() << "Fill Pattern";
624 alignStreamToWord(ts, 8);
625 break;
626 case 0x000B: // Oval Size
627 handleOvalSize(ts);
628 break;
629 case 0x000C: // Origin
630 // qDebug() << "Origin";
631 alignStreamToWord(ts, 4);
632 break;
633 case 0x000D: // Text Size
634 handleTextSize(ts);
635 break;
636 case 0x000E: // Foreground Color
637 handleColor(ts, false);
638 break;
639 case 0x000F: // Background Color
640 handleColor(ts, true);
641 break;
642 case 0x0010: // Text Ratio
643 handleLineModeEnd();
644 // qDebug() << "Text Ratio";
645 alignStreamToWord(ts, 8);
646 break;
647 case 0x0011: // Version
648 // qDebug() << "Version";
649 alignStreamToWord(ts, 1);
650 break;
651 case 0x0015: // Fractional pen position
652 handleLineModeEnd();
653 // qDebug() << "Fractional pen position at" << ts.device()->pos();
654 alignStreamToWord(ts, 2);
655 break;
656 case 0x0016: // Extra char space
657 // qDebug() << "Extra char space";
658 alignStreamToWord(ts, 2);
659 break;
660 case 0x0017:
661 case 0x0018:
662 case 0x0019:
663 // qDebug() << "Reserved by Apple";
664 break;
665 case 0x001A: // Foreground color RGB
666 handleColorRGB(ts, false);
667 break;
668 case 0x001B: // Background color RGB
669 handleColorRGB(ts, true);
670 break;
671 case 0x001C: // Highlight mode
672 // qDebug() << "Highlight mode";
673 break;
674 case 0x001D: // Highlight color RGB
675 // qDebug() << "Highlight color RGB";
676 alignStreamToWord(ts, 6);
677 break;
678 case 0x001E: // Use default highlight color
679 // qDebug() << "Use default highlight color";
680 break;
681 case 0x0020: // Line
682 handleLine(ts);
683 break;
684 case 0x0021: // Line To
685 handleLineFrom(ts);
686 break;
687 case 0x0022: // Short Line
688 handleShortLine(ts);
689 break;
690 case 0x0023: // Short Line To
691 handleShortLineFrom(ts);
692 break;
693 case 0x0024:
694 case 0x0025:
695 case 0x0026:
696 case 0x0027: // Reserved by Apple
697 // qDebug() << "Reserved by Apple";
698 ts >> dataLen;
699 alignStreamToWord(ts, dataLen);
700 break;
701 case 0x0028: // Long Text
702 handleLongText(ts);
703 break;
704 case 0x0029: // Text DH
705 handleDHText(ts);
706 break;
707 case 0x002A: // Text DV
708 handleDVText(ts);
709 break;
710 case 0x002B: // Text DHV
711 handleDHVText(ts);
712 break;
713 case 0x002C: // Font Name
714 handleFontName(ts);
715 break;
716 case 0x002D: // Line justify
717 handleLineModeEnd();
718 // qDebug() << "Line justify";
719 alignStreamToWord(ts, 10);
720 break;
721 case 0x002E: // Glyph state
722 handleLineModeEnd();
723 // qDebug() << "Glyph state";
724 ts >> dataLen;
725 alignStreamToWord(ts, dataLen);
726 break;
727 case 0x002F: // Reserved by Apple
728 // qDebug() << "Reserved by Apple";
729 ts >> dataLen;
730 alignStreamToWord(ts, dataLen);
731 break;
732 case 0x0030: // Frame rect
733 case 0x0031: // Paint rect
734 case 0x0032: // Erase rect
735 case 0x0033: // Invert rect
736 case 0x0034: // Fill rect
737 handleShape(ts, opCode);
738 break;
739 case 0x0035:
740 case 0x0036:
741 case 0x0037: // Reserved by Apple
742 // qDebug() << "Reserved by Apple";
743 alignStreamToWord(ts, 8);
744 break;
745 case 0x0038: // Frame same rect
746 case 0x0039: // Paint same rect
747 case 0x003A: // Erase same rect
748 case 0x003B: // Invert same rect
749 case 0x003C: // Fill same rect
750 handleSameShape(ts, opCode);
751 break;
752 case 0x003D:
753 case 0x003E:
754 case 0x003F: // Reserved by Apple
755 // qDebug() << "Reserved by Apple";
756 break;
757 case 0x0040: // Frame round rect
758 case 0x0041: // Paint round rect
759 case 0x0042: // Erase round rect
760 case 0x0043: // Invert round rect
761 case 0x0044: // Fill round rect
762 handleShape(ts, opCode);
763 break;
764 case 0x0045:
765 case 0x0046:
766 case 0x0047: // Reserved by Apple
767 // qDebug() << "Reserved by Apple";
768 alignStreamToWord(ts, 8);
769 break;
770 case 0x0048: // Frame same round rect
771 case 0x0049: // Paint same round rect
772 case 0x004A: // Erase same round rect
773 case 0x004B: // Invert same round rect
774 case 0x004C: // Fill same round rect
775 handleSameShape(ts, opCode);
776 break;
777 case 0x004D:
778 case 0x004E:
779 case 0x004F: // Reserved by Apple
780 // qDebug() << "Reserved by Apple";
781 break;
782 case 0x0050: // Frame oval
783 case 0x0051: // Paint oval
784 case 0x0052: // Erase oval
785 case 0x0053: // Invert oval
786 case 0x0054: // Fill oval
787 handleShape(ts, opCode);
788 break;
789 case 0x0055:
790 case 0x0056:
791 case 0x0057: // Reserved by Apple
792 // qDebug() << "Reserved by Apple";
793 alignStreamToWord(ts, 8);
794 break;
795 case 0x0058: // Frame same oval
796 case 0x0059: // Paint same oval
797 case 0x005A: // Erase same oval
798 case 0x005B: // Invert same oval
799 case 0x005C: // Fill same oval
800 handleSameShape(ts, opCode);
801 break;
802 case 0x005D:
803 case 0x005E:
804 case 0x005F: // Reserved by Apple
805 // qDebug() << "Reserved by Apple";
806 break;
807 case 0x0060: // Frame arc
808 handleLineModeEnd();
809 // qDebug() << "Frame arc";
810 alignStreamToWord(ts, 12);
811 break;
812 case 0x0061: // Paint arc
813 handleLineModeEnd();
814 // qDebug() << "Paint arc";
815 alignStreamToWord(ts, 12);
816 break;
817 case 0x0062: // Erase arc
818 handleLineModeEnd();
819 // qDebug() << "Erase arc";
820 alignStreamToWord(ts, 12);
821 break;
822 case 0x0063: // Invert arc
823 handleLineModeEnd();
824 // qDebug() << "Invert arc";
825 alignStreamToWord(ts, 12);
826 break;
827 case 0x0064: // Fill arc
828 handleLineModeEnd();
829 // qDebug() << "Fill arc";
830 alignStreamToWord(ts, 12);
831 break;
832 case 0x0065:
833 case 0x0066:
834 case 0x0067: // Reserved by Apple
835 // qDebug() << "Reserved by Apple";
836 alignStreamToWord(ts, 12);
837 break;
838 case 0x0068: // Frame same arc
839 handleLineModeEnd();
840 // qDebug() << "Frame same arc";
841 alignStreamToWord(ts, 4);
842 break;
843 case 0x0069: // Paint same arc
844 handleLineModeEnd();
845 // qDebug() << "Paint same arc";
846 alignStreamToWord(ts, 4);
847 break;
848 case 0x006A: // Erase same arc
849 handleLineModeEnd();
850 // qDebug() << "Erase same arc";
851 alignStreamToWord(ts, 4);
852 break;
853 case 0x006B: // Invert same arc
854 handleLineModeEnd();
855 // qDebug() << "Invert same arc";
856 alignStreamToWord(ts, 4);
857 break;
858 case 0x006C: // Fill same arc
859 handleLineModeEnd();
860 // qDebug() << "Fill same arc";
861 alignStreamToWord(ts, 4);
862 break;
863 case 0x006D:
864 case 0x006E:
865 case 0x006F: // Reserved by Apple
866 // qDebug() << "Reserved by Apple";
867 alignStreamToWord(ts, 4);
868 break;
869 case 0x0070: // Frame poly
870 case 0x0071: // Paint poly
871 case 0x0072: // Erase poly
872 case 0x0073: // Invert poly
873 case 0x0074: // Fill poly
874 handlePolygon(ts, opCode);
875 break;
876 case 0x0075:
877 case 0x0076:
878 case 0x0077: // Reserved by Apple
879 // qDebug() << "Reserved by Apple";
880 ts >> dataLen;
881 alignStreamToWord(ts, dataLen-2);
882 break;
883 case 0x0078: // Frame same poly
884 handleLineModeEnd();
885 // qDebug() << "Frame same poly";
886 break;
887 case 0x0079: // Paint same poly
888 handleLineModeEnd();
889 // qDebug() << "Paint same poly";
890 break;
891 case 0x007A: // Erase same poly
892 handleLineModeEnd();
893 // qDebug() << "Erase same poly";
894 break;
895 case 0x007B: // Invert same poly
896 handleLineModeEnd();
897 // qDebug() << "Invert same poly";
898 break;
899 case 0x007C: // Fill same poly
900 handleLineModeEnd();
901 // qDebug() << "Fill same poly";
902 break;
903 case 0x007D:
904 case 0x007E:
905 case 0x007F: // Reserved by Apple
906 // qDebug() << "Reserved by Apple";
907 break;
908 case 0x0080: // Frame region
909 // qDebug() << "Frame region";
910 ts >> dataLen;
911 alignStreamToWord(ts, dataLen-2);
912 break;
913 case 0x0081: // Paint region
914 handleLineModeEnd();
915 // qDebug() << "Paint region";
916 ts >> dataLen;
917 alignStreamToWord(ts, dataLen-2);
918 break;
919 case 0x0082: // Erase region
920 handleLineModeEnd();
921 // qDebug() << "Erase region";
922 ts >> dataLen;
923 alignStreamToWord(ts, dataLen-2);
924 break;
925 case 0x0083: // Invert region
926 handleLineModeEnd();
927 // qDebug() << "Invert region";
928 ts >> dataLen;
929 alignStreamToWord(ts, dataLen-2);
930 break;
931 case 0x0084: // Fill region
932 handleLineModeEnd();
933 // qDebug() << "Fill region";
934 ts >> dataLen;
935 alignStreamToWord(ts, dataLen-2);
936 break;
937 case 0x0085:
938 case 0x0086:
939 case 0x0087: // Reserved by Apple
940 // qDebug() << "Reserved by Apple";
941 ts >> dataLen;
942 alignStreamToWord(ts, dataLen-2);
943 break;
944 case 0x0088: // Frame same region
945 handleLineModeEnd();
946 // qDebug() << "Frame same region";
947 break;
948 case 0x0089: // Paint same region
949 handleLineModeEnd();
950 // qDebug() << "Paint same region";
951 break;
952 case 0x008A: // Erase same region
953 handleLineModeEnd();
954 // qDebug() << "Erase same region";
955 break;
956 case 0x008B: // Invert same region
957 handleLineModeEnd();
958 // qDebug() << "Invert same region";
959 break;
960 case 0x008C: // Fill same region
961 handleLineModeEnd();
962 // qDebug() << "Fill same region";
963 break;
964 case 0x008D:
965 case 0x008E:
966 case 0x008F: // Reserved by Apple
967 // qDebug() << "Reserved by Apple";
968 break;
969 case 0x0090: // Bits Rect
970 // qDebug() << "Bits Rect";
971 handlePixmap(ts, opCode);
972 break;
973 case 0x0091: // Bits Region
974 // qDebug() << "Bits Region";
975 handlePixmap(ts, opCode);
976 break;
977 case 0x0098: // Pack Bits Rect
978 // qDebug() << "Pack Bits Rect";
979 handlePixmap(ts, opCode);
980 break;
981 case 0x0099: // Pack Bits Region
982 // qDebug() << "Pack Bits Region";
983 handlePixmap(ts, opCode);
984 break;
985 case 0x009A: // Direct Bits Rect
986 // qDebug() << "Direct Bits Rect";
987 handlePixmap(ts, opCode);
988 break;
989 case 0x009B: // Direct Bits Region
990 // qDebug() << "Direct Bits Region";
991 handlePixmap(ts, opCode);
992 break;
993 case 0x00A0: // Short Comment
994 handleComment(ts, false);
995 break;
996 case 0x00A1: // Long Comment
997 handleComment(ts, true);
998 break;
999 case 0x00FF: // End of Pict
1000 handleLineModeEnd();
1001 if (imageData.size() > 0)
1002 {
1003 QImage image;
1004 image.loadFromData(imageData);
1005 image = image.convertToFormat(QImage::Format_ARGB32);
1006 int z = m_Doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, baseX, baseY, image.width() * resX, image.height() * resY, 0, m_Doc->itemToolPrefs().imageFillColor, CommonStrings::None);
1007 PageItem *ite = m_Doc->Items->at(z);
1008 QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_pct_XXXXXX.png");
1009 tempFile->setAutoRemove(false);
1010 tempFile->open();
1011 QString fileName = getLongPathName(tempFile->fileName());
1012 tempFile->close();
1013 ite->isInlineImage = true;
1014 ite->isTempFile = true;
1015 image.save(fileName, "PNG");
1016 ite->moveBy(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
1017 ite->moveBy(offsetX, offsetY);
1018 finishItem(ite);
1019 m_Doc->loadPict(fileName, ite);
1020 ite->setImageScalingMode(false, false);
1021 delete tempFile;
1022 }
1023 // qDebug() << "End of Pict";
1024 return;
1025 break;
1026 case 0x0200: // Reserved by Apple
1027 // qDebug() << "Reserved by Apple";
1028 alignStreamToWord(ts, 4);
1029 break;
1030 case 0x8200: // Compressed QuickTime
1031 case 0x8201: // Uncompressed QuickTime
1032 handleQuickTime(ts, opCode);
1033 break;
1034 case 0xFFFF: // Reserved by Apple
1035 // qDebug() << "Reserved by Apple";
1036 ts >> dataLenLong;
1037 alignStreamToWord(ts, dataLenLong);
1038 break;
1039 default:
1040 // qDebug() << QString("Not implemented OpCode: 0x%1 at %2").arg(opCode, 4, 16, QLatin1Char('0')).arg(ts.device()->pos()-2);
1041 return;
1042 break;
1043 }
1044 }
1045 if (progressDialog)
1046 {
1047 progressDialog->setProgress("GI", ts.device()->pos());
1048 qApp->processEvents();
1049 }
1050 }
1051 }
1052
alignStreamToWord(QDataStream & ts,uint len)1053 void PctPlug::alignStreamToWord(QDataStream &ts, uint len)
1054 {
1055 ts.skipRawData(len);
1056 if (pctVersion == 1)
1057 return;
1058 uint adj = ts.device()->pos() % 2;
1059 if (adj != 0)
1060 ts.skipRawData(1);
1061 }
1062
handleColor(QDataStream & ts,bool back)1063 void PctPlug::handleColor(QDataStream &ts, bool back)
1064 {
1065
1066 handleLineModeEnd();
1067 QString tmpName = CommonStrings::None;
1068 ScColor tmp;
1069 quint16 Rc, Gc, Bc;
1070 quint32 colVal;
1071 ts >> colVal;
1072 // qDebug() << "Color" << colVal << back;
1073 switch (colVal)
1074 {
1075 case 30:
1076 Rc = 0xFFFF;
1077 Gc = 0xFFFF;
1078 Bc = 0xFFFF;
1079 break;
1080 case 33:
1081 Rc = 0x0000;
1082 Gc = 0x0000;
1083 Bc = 0x0000;
1084 break;
1085 case 69:
1086 Rc = 0xFC00;
1087 Gc = 0xF37D;
1088 Bc = 0x052F;
1089 break;
1090 case 137:
1091 Rc = 0xF2D7;
1092 Gc = 0x0856;
1093 Bc = 0x84EC;
1094 break;
1095 case 205:
1096 Rc = 0xDD6B;
1097 Gc = 0x08C2;
1098 Bc = 0x06A2;
1099 break;
1100 case 273:
1101 Rc = 0x0241;
1102 Gc = 0xAB54;
1103 Bc = 0xEAFF;
1104 break;
1105 case 341:
1106 Rc = 0x0000;
1107 Gc = 0x64AF;
1108 Bc = 0x11B0;
1109 break;
1110 case 409:
1111 Rc = 0x0000;
1112 Gc = 0x0000;
1113 Bc = 0xD400;
1114 break;
1115 default:
1116 Rc = 0x0000;
1117 Gc = 0x0000;
1118 Bc = 0x0000;
1119 break;
1120 }
1121 int redC, greenC, blueC;
1122 redC = qRound((Rc / 65535.0) * 255.0);
1123 greenC = qRound((Gc / 65535.0) * 255.0);
1124 blueC = qRound((Bc / 65535.0) * 255.0);
1125 QColor c = QColor(redC, greenC, blueC);
1126 tmp.setRgbColor(redC, greenC, blueC);
1127 tmp.setSpotColor(false);
1128 tmp.setRegistrationColor(false);
1129 tmpName = "FromPict"+c.name();
1130 QString fNam = m_Doc->PageColors.tryAddColor(tmpName, tmp);
1131 if (fNam == tmpName)
1132 importedColors.append(tmpName);
1133 tmpName = fNam;
1134 if (back)
1135 {
1136 CurrColorFill = tmpName;
1137 backColor = c;
1138 }
1139 else
1140 {
1141 CurrColorStroke = tmpName;
1142 foreColor = c;
1143 }
1144 }
1145
handleColorRGB(QDataStream & ts,bool back)1146 void PctPlug::handleColorRGB(QDataStream &ts, bool back)
1147 {
1148 handleLineModeEnd();
1149 QString tmpName = CommonStrings::None;
1150 ScColor tmp;
1151 ColorList::Iterator it;
1152 quint16 Rc, Gc, Bc;
1153 int redC, greenC, blueC;
1154 ts >> Rc >> Gc >> Bc;
1155 redC = qRound((Rc / 65535.0) * 255.0);
1156 greenC = qRound((Gc / 65535.0) * 255.0);
1157 blueC = qRound((Bc / 65535.0) * 255.0);
1158 QColor c = QColor(redC, greenC, blueC);
1159 tmp.setRgbColor(redC, greenC, blueC);
1160 tmp.setSpotColor(false);
1161 tmp.setRegistrationColor(false);
1162 tmpName = "FromPict"+c.name();
1163 QString fNam = m_Doc->PageColors.tryAddColor(tmpName, tmp);
1164 if (fNam == tmpName)
1165 importedColors.append(tmpName);
1166 tmpName = fNam;
1167 if (back)
1168 {
1169 CurrColorFill = tmpName;
1170 backColor = c;
1171 }
1172 else
1173 {
1174 CurrColorStroke = tmpName;
1175 foreColor = c;
1176 }
1177 }
1178
handlePenPattern(QDataStream & ts)1179 void PctPlug::handlePenPattern(QDataStream &ts)
1180 {
1181 handleLineModeEnd();
1182 patternData.resize(8);
1183 ts.readRawData(patternData.data(), 8);
1184 patternMode = false;
1185 for (int a = 0; a < patternData.size(); a++)
1186 {
1187 uchar d = patternData[a];
1188 if ((d != 0x00) && (d != 0xFF))
1189 {
1190 patternMode = true;
1191 break;
1192 }
1193 }
1194 }
1195
handlePolygon(QDataStream & ts,quint16 opCode)1196 void PctPlug::handlePolygon(QDataStream &ts, quint16 opCode)
1197 {
1198 // qDebug() << "Handle Polygon";
1199 handleLineModeEnd();
1200 quint16 polySize;
1201 ts >> polySize; // read polygon size
1202 ts.skipRawData(8); // skip bounding rect;
1203 polySize -= 14; // subtract size count, bounding rect and first point from size
1204 qint16 x, y;
1205 ts >> y >> x;
1206 Coords.resize(0);
1207 Coords.svgInit();
1208 PageItem *ite;
1209 Coords.svgMoveTo(x * resX, y * resY);
1210 for (unsigned i = 0; i < polySize; i += 4)
1211 {
1212 ts >> y >> x;
1213 Coords.svgLineTo(x * resX, y * resX);
1214 }
1215 if (!Coords.empty())
1216 {
1217 int z;
1218 if (opCode == 0x0070)
1219 z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CommonStrings::None, CurrColorStroke);
1220 else if (opCode == 0x0071)
1221 z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColorStroke, CommonStrings::None);
1222 // else if (opCode == 0x0072)
1223 // z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColorFill, CommonStrings::None);
1224 else if (opCode == 0x0074)
1225 z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColorStroke, CommonStrings::None);
1226 else
1227 {
1228 // qDebug() << QString("Not implemented OpCode: 0x%1").arg(opCode, 4, 16, QLatin1Char('0'));
1229 return;
1230 }
1231 ite = m_Doc->Items->at(z);
1232 ite->PoLine = Coords.copy();
1233 ite->PoLine.translate(baseX, baseY);
1234 ite->PoLine.translate(offsetX, offsetY);
1235 finishItem(ite);
1236 if ((patternMode) && (opCode != 0x0070))
1237 setFillPattern(ite);
1238 }
1239 }
1240
handleShape(QDataStream & ts,quint16 opCode)1241 void PctPlug::handleShape(QDataStream &ts, quint16 opCode)
1242 {
1243 handleLineModeEnd();
1244 QRect bounds = readRect(ts);
1245 // qDebug() << QString("Handle Rect/Oval 0x%1").arg(opCode, 4, 16, QLatin1Char('0'));
1246 int z;
1247 double xp = baseX + (bounds.x() * resX);
1248 double yp = baseX + (bounds.y() * resY);
1249 double wv = (bounds.width() - 1) * resX;
1250 double hv = (bounds.height() - 1) * resY;
1251 PageItem *ite;
1252 if (opCode == 0x0030)
1253 z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, xp, yp, wv, hv, LineW, CommonStrings::None, CurrColorStroke);
1254 else if (opCode == 0x0031)
1255 z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, xp, yp, wv, hv, 0, CurrColorStroke, CommonStrings::None);
1256 // else if (opCode == 0x0032)
1257 // z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, baseX + bounds.x(), baseY + bounds.y(), bounds.width() - 1, bounds.height() - 1, 0, CurrColorFill, CommonStrings::None);
1258 else if (opCode == 0x0034)
1259 z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, xp, yp, wv, hv, 0, CurrColorStroke, CommonStrings::None);
1260 else if (opCode == 0x0040)
1261 {
1262 z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, xp, yp, wv, hv, LineW, CommonStrings::None, CurrColorStroke);
1263 ite = m_Doc->Items->at(z);
1264 ite->setCornerRadius(qMax(ovalSize.x(), ovalSize.y()));
1265 ite->SetFrameRound();
1266 m_Doc->setRedrawBounding(ite);
1267 }
1268 else if (opCode == 0x0041)
1269 {
1270 z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, xp, yp, wv, hv, 0, CurrColorStroke, CommonStrings::None);
1271 ite = m_Doc->Items->at(z);
1272 ite->setCornerRadius(qMax(ovalSize.x(), ovalSize.y()));
1273 ite->SetFrameRound();
1274 m_Doc->setRedrawBounding(ite);
1275 }
1276 // else if (opCode == 0x0042)
1277 // {
1278 // z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, baseX + bounds.x(), baseY + bounds.y(), bounds.width() - 1, bounds.height() - 1, 0, CurrColorFill, CommonStrings::None);
1279 // ite = m_Doc->Items->at(z);
1280 // ite->setCornerRadius(qMax(ovalSize.x(), ovalSize.y()));
1281 // ite->SetFrameRound();
1282 // m_Doc->setRedrawBounding(ite);
1283 // }
1284 else if (opCode == 0x0044)
1285 {
1286 z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, xp, yp, wv, hv, 0, CurrColorStroke, CommonStrings::None);
1287 ite = m_Doc->Items->at(z);
1288 ite->setCornerRadius(qMax(ovalSize.x(), ovalSize.y()));
1289 ite->SetFrameRound();
1290 m_Doc->setRedrawBounding(ite);
1291 }
1292 else if (opCode == 0x0050)
1293 z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, xp, yp, wv, hv, LineW, CommonStrings::None, CurrColorStroke);
1294 else if (opCode == 0x0051)
1295 z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, xp, yp, wv, hv, 0, CurrColorStroke, CommonStrings::None);
1296 // else if (opCode == 0x0052)
1297 // z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, baseX + bounds.x(), baseY + bounds.y(), bounds.width() - 1, bounds.height() - 1, 0, CurrColorFill, CommonStrings::None);
1298 else if (opCode == 0x0054)
1299 z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, xp, yp, wv, hv, 0, CurrColorStroke, CommonStrings::None);
1300 else
1301 {
1302 // qDebug() << QString("Not implemented OpCode: 0x%1").arg(opCode, 4, 16, QLatin1Char('0'));
1303 return;
1304 }
1305 ite = m_Doc->Items->at(z);
1306 ite->PoLine.translate(offsetX, offsetY);
1307 currRect = QRect(bounds.x() * resX, bounds.y() * resY, bounds.width() * resX, bounds.height() * resY);
1308 currRectItemNr = z;
1309 currRectType = 0;
1310 if (opCode > 0x0044)
1311 currRectType = 1;
1312 finishItem(ite);
1313 if ((patternMode) && (opCode != 0x0030) && (opCode != 0x0040) && (opCode != 0x0050))
1314 setFillPattern(ite);
1315 }
1316
handleSameShape(QDataStream & ts,quint16 opCode)1317 void PctPlug::handleSameShape(QDataStream &ts, quint16 opCode)
1318 {
1319 // qDebug() << QString("Handle Same Rect/Oval 0x%1").arg(opCode, 4, 16, QLatin1Char('0'));
1320 int rectType = 0;
1321 if (opCode > 0x0050)
1322 rectType = 1;
1323 handleLineModeEnd();
1324 int z;
1325 PageItem *ite;
1326 if (currRectType == rectType)
1327 {
1328 ite = m_Doc->Items->at(currRectItemNr);
1329 if ((opCode == 0x0038) || (opCode == 0x0048) || (opCode == 0x0058))
1330 {
1331 ite->setLineColor(CurrColorStroke);
1332 ite->setLineWidth(LineW);
1333 }
1334 // else if ((opCode == 0x003A) || (opCode == 0x004A) || (opCode == 0x005A))
1335 // ite->setFillColor(CurrColorFill);
1336 else
1337 ite->setFillColor(CurrColorStroke);
1338 }
1339 else
1340 {
1341 if (opCode == 0x0038)
1342 z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, baseX + currRect.x(), baseY + currRect.y(), currRect.width() - 1, currRect.height() - 1, LineW, CommonStrings::None, CurrColorStroke);
1343 else if (opCode == 0x0039)
1344 z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, baseX + currRect.x(), baseY + currRect.y(), currRect.width() - 1, currRect.height() - 1, 0, CurrColorStroke, CommonStrings::None);
1345 // else if (opCode == 0x003A)
1346 // z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, baseX + currRect.x(), baseY + currRect.y(), currRect.width() - 1, currRect.height() - 1, 0, CurrColorFill, CommonStrings::None);
1347 else if (opCode == 0x003C)
1348 z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, baseX + currRect.x(), baseY + currRect.y(), currRect.width() - 1, currRect.height() - 1, 0, CurrColorStroke, CommonStrings::None);
1349 else if (opCode == 0x0048)
1350 {
1351 z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, baseX + currRect.x(), baseY + currRect.y(), currRect.width() - 1, currRect.height() - 1, 0, CommonStrings::None, CurrColorStroke);
1352 ite = m_Doc->Items->at(z);
1353 ite->setCornerRadius(qMax(ovalSize.x(), ovalSize.y()));
1354 ite->SetFrameRound();
1355 m_Doc->setRedrawBounding(ite);
1356 }
1357 else if (opCode == 0x0049)
1358 {
1359 z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, baseX + currRect.x(), baseY + currRect.y(), currRect.width() - 1, currRect.height() - 1, 0, CurrColorStroke, CommonStrings::None);
1360 ite = m_Doc->Items->at(z);
1361 ite->setCornerRadius(qMax(ovalSize.x(), ovalSize.y()));
1362 ite->SetFrameRound();
1363 m_Doc->setRedrawBounding(ite);
1364 }
1365 // else if (opCode == 0x004A)
1366 // {
1367 // z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, baseX + currRect.x(), baseY + currRect.y(), currRect.width() - 1, currRect.height() - 1, 0, CurrColorFill, CommonStrings::None);
1368 // ite = m_Doc->Items->at(z);
1369 // ite->setCornerRadius(qMax(ovalSize.x(), ovalSize.y()));
1370 // ite->SetFrameRound();
1371 // m_Doc->setRedrawBounding(ite);
1372 // }
1373 else if (opCode == 0x004C)
1374 {
1375 z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, baseX + currRect.x(), baseY + currRect.y(), currRect.width() - 1, currRect.height() - 1, 0, CurrColorStroke, CommonStrings::None);
1376 ite = m_Doc->Items->at(z);
1377 ite->setCornerRadius(qMax(ovalSize.x(), ovalSize.y()));
1378 ite->SetFrameRound();
1379 m_Doc->setRedrawBounding(ite);
1380 }
1381 else if (opCode == 0x0058)
1382 z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, baseX + currRect.x(), baseY + currRect.y(), currRect.width() - 1, currRect.height() - 1, LineW, CommonStrings::None, CurrColorStroke);
1383 else if (opCode == 0x0059)
1384 z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, baseX + currRect.x(), baseY + currRect.y(), currRect.width() - 1, currRect.height() - 1, 0, CurrColorStroke, CommonStrings::None);
1385 // else if (opCode == 0x005A)
1386 // z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, baseX + currRect.x(), baseY + currRect.y(), currRect.width() - 1, currRect.height() - 1, 0, CurrColorFill, CommonStrings::None);
1387 else if (opCode == 0x005C)
1388 z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, baseX + currRect.x(), baseY + currRect.y(), currRect.width() - 1, currRect.height() - 1, 0, CurrColorStroke, CommonStrings::None);
1389 else
1390 {
1391 // qDebug() << QString("Not implemented OpCode: 0x%1").arg(opCode, 4, 16, QLatin1Char('0'));
1392 return;
1393 }
1394 ite = m_Doc->Items->at(z);
1395 ite->PoLine.translate(offsetX, offsetY);
1396 finishItem(ite);
1397 }
1398 if ((patternMode) && (opCode != 0x0038) && (opCode != 0x0048) && (opCode != 0x0058))
1399 setFillPattern(ite);
1400 }
1401
handleFontName(QDataStream & ts)1402 void PctPlug::handleFontName(QDataStream &ts)
1403 {
1404 handleLineModeEnd();
1405 quint16 dataLen, fontID;
1406 quint8 nameLen;
1407 ts >> dataLen >> fontID;
1408 ts >> nameLen;
1409 QByteArray fontRawName;
1410 fontRawName.resize(nameLen);
1411 ts.readRawData(fontRawName.data(), nameLen);
1412 QString fontName = fontRawName;
1413 fontName = fontName.simplified();
1414 SCFonts fonts = PrefsManager::instance().appPrefs.fontPrefs.AvailFonts;
1415 SCFontsIterator it(fonts);
1416 for ( ; it.hasNext() ; it.next())
1417 {
1418
1419 if (fonts[it.currentKey()].scName().simplified() == fontName)
1420 {
1421 fontName = fonts[it.currentKey()].family();
1422 break;
1423 }
1424 }
1425 fontMap.insert(fontID, fontName);
1426 alignStreamToWord(ts, 0);
1427 // qDebug() << "Handle FontName" << fontName << "ID" << fontID;
1428 }
1429
handleTextSize(QDataStream & ts)1430 void PctPlug::handleTextSize(QDataStream &ts)
1431 {
1432 handleLineModeEnd();
1433 quint16 fontSize;
1434 ts >> fontSize;
1435 currentTextSize = fontSize * resY;
1436 // qDebug() << "Handle Text Size" << fontSize;
1437 }
1438
handleTextFont(QDataStream & ts)1439 void PctPlug::handleTextFont(QDataStream &ts)
1440 {
1441 handleLineModeEnd();
1442 quint16 fontID;
1443 ts >> fontID;
1444 currentFontID = fontID;
1445 // qDebug() << "Handle Text Font" << fontID;
1446 }
1447
handleTextStyle(QDataStream & ts)1448 void PctPlug::handleTextStyle(QDataStream &ts)
1449 {
1450 handleLineModeEnd();
1451 quint8 style;
1452 ts >> style;
1453 alignStreamToWord(ts, 0);
1454 currentFontStyle = style;
1455 // qDebug() << "Text Style" << style;
1456 }
1457
handleLongText(QDataStream & ts)1458 void PctPlug::handleLongText(QDataStream &ts)
1459 {
1460 handleLineModeEnd();
1461 quint8 textLen;
1462 qint16 x, y;
1463 ts >> y >> x;
1464 ts >> textLen;
1465 QByteArray text;
1466 text.resize(textLen);
1467 ts.readRawData(text.data(), textLen);
1468 if (!textIsPostScript)
1469 {
1470 currentPointT = QPoint(x * resX, y * resY);
1471 createTextPath(text);
1472 // qDebug() << "Handle Long Text at" << x << y << text;
1473 }
1474 alignStreamToWord(ts, 0);
1475 }
1476
handleDHText(QDataStream & ts)1477 void PctPlug::handleDHText(QDataStream &ts)
1478 {
1479 handleLineModeEnd();
1480 quint8 textLen, dh;
1481 ts >> dh >> textLen;
1482 QByteArray text;
1483 text.resize(textLen);
1484 ts.readRawData(text.data(), textLen);
1485 if (!textIsPostScript)
1486 {
1487 QPoint s = currentPointT;
1488 currentPointT = QPoint(s.x()+dh * resX, s.y());
1489 createTextPath(text);
1490 // qDebug() << "Handle DH Text at" << currentPointT << text;
1491 }
1492 alignStreamToWord(ts, 0);
1493 }
1494
handleDVText(QDataStream & ts)1495 void PctPlug::handleDVText(QDataStream &ts)
1496 {
1497 handleLineModeEnd();
1498 quint8 textLen, dv;
1499 ts >> dv >> textLen;
1500 QByteArray text;
1501 text.resize(textLen);
1502 ts.readRawData(text.data(), textLen);
1503 if (!textIsPostScript)
1504 {
1505 QPoint s = currentPointT;
1506 currentPointT = QPoint(s.x(), s.y()+dv * resY);
1507 createTextPath(text);
1508 // qDebug() << "Handle DV Text at" << currentPointT << text;
1509 }
1510 alignStreamToWord(ts, 0);
1511 }
1512
handleDHVText(QDataStream & ts)1513 void PctPlug::handleDHVText(QDataStream &ts)
1514 {
1515 handleLineModeEnd();
1516 quint8 textLen, dv, dh;
1517 ts >> dh >> dv >> textLen;
1518 QByteArray text;
1519 text.resize(textLen);
1520 ts.readRawData(text.data(), textLen);
1521 if (!textIsPostScript)
1522 {
1523 QPoint s = currentPointT;
1524 currentPointT = QPoint(s.x()+dh * resX, s.y()+dv * resY);
1525 createTextPath(text);
1526 // qDebug() << "Handle DHV Text" << dh << dv << "->" << currentPointT << text;
1527 }
1528 alignStreamToWord(ts, 0);
1529 }
1530
createTextPath(const QByteArray & textString)1531 void PctPlug::createTextPath(const QByteArray& textString)
1532 {
1533 QTextCodec *codec = QTextCodec::codecForName("Apple Roman");
1534 if (!codec)
1535 {
1536 codec = QTextCodec::codecForName("macroman");
1537 if (!codec)
1538 return;
1539 }
1540 QString string(codec->toUnicode(textString));
1541 QFont textFont;
1542 if (!fontMap.contains(currentFontID))
1543 textFont = QFont();
1544 else
1545 textFont = QFont(fontMap[currentFontID], currentTextSize);
1546 textFont.setPixelSize(currentTextSize);
1547 if (currentFontStyle & 1)
1548 textFont.setBold(true);
1549 if (currentFontStyle & 2)
1550 textFont.setItalic(true);
1551 if (currentFontStyle & 4)
1552 textFont.setUnderline(true);
1553 FPointArray textPath;
1554 QPainterPath painterPath;
1555 painterPath.addText( currentPointT.x(), currentPointT.y(), textFont, string);
1556 textPath.fromQPainterPath(painterPath);
1557 if (!textPath.empty())
1558 {
1559 int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, CurrColorStroke, CommonStrings::None);
1560 PageItem* ite = m_Doc->Items->at(z);
1561 ite->PoLine = textPath;
1562 ite->PoLine.translate(baseX, baseY);
1563 ite->PoLine.translate(offsetX, offsetY);
1564 finishItem(ite);
1565 if (patternMode)
1566 setFillPattern(ite);
1567 }
1568 }
1569
handlePenSize(QDataStream & ts)1570 void PctPlug::handlePenSize(QDataStream &ts)
1571 {
1572 // qDebug() << "Handle Pen Size";
1573 handleLineModeEnd();
1574 quint16 x, y;
1575 ts >> y >> x;
1576 LineW = qMax(x, y) * resX;
1577 }
1578
handleOvalSize(QDataStream & ts)1579 void PctPlug::handleOvalSize(QDataStream &ts)
1580 {
1581 // qDebug() << "Handle Oval Size";
1582 handleLineModeEnd();
1583 quint16 x, y;
1584 ts >> y >> x;
1585 ovalSize = QPoint(x * resX, y * resY);
1586 }
1587
handleShortLine(QDataStream & ts)1588 void PctPlug::handleShortLine(QDataStream &ts)
1589 {
1590 quint16 x, y;
1591 qint8 dh, dv;
1592 ts >> y >> x;
1593 ts >> dh >> dv;
1594 if ((dh == 0) && (dv == 0))
1595 {
1596 handleLineModeEnd();
1597 Coords.svgMoveTo(x * resX, y * resY);
1598 currentPoint = QPoint(x * resX, y * resY);
1599 return;
1600 }
1601 QPoint s = QPoint(x * resX, y * resY);
1602 if (currentPoint != s)
1603 {
1604 handleLineModeEnd();
1605 Coords.svgMoveTo(x * resX, y * resY);
1606 }
1607 Coords.svgLineTo((x+dh) * resX, (y+dv) * resY);
1608 currentPoint = QPoint((x+dh) * resX, (y+dv) * resY);
1609 lineMode = true;
1610 // qDebug() << "Handle Short Line" << x << y << "+" << dh << dv << "->" << currentPoint;
1611 }
1612
handleShortLineFrom(QDataStream & ts)1613 void PctPlug::handleShortLineFrom(QDataStream &ts)
1614 {
1615 qint8 dh, dv;
1616 ts >> dh >> dv;
1617 if ((dh == 0) && (dv == 0))
1618 return;
1619 QPoint s = currentPoint;
1620 if (Coords.empty())
1621 Coords.svgMoveTo(s.x(), s.y());
1622 Coords.svgLineTo(s.x()+dh * resX, s.y()+dv * resY);
1623 currentPoint = QPoint(s.x()+dh * resX, s.y()+dv * resY);
1624 lineMode = true;
1625 // qDebug() << "Handle Short Line from" << dh << dv << "->" << currentPoint;
1626 }
1627
handleLine(QDataStream & ts)1628 void PctPlug::handleLine(QDataStream &ts)
1629 {
1630 qint16 x1, x2, y1, y2;
1631 ts >> y1 >> x1;
1632 ts >> y2 >> x2;
1633 QPoint s = QPoint(x1 * resX, y1 * resY);
1634 if (currentPoint != s)
1635 {
1636 handleLineModeEnd();
1637 Coords.svgMoveTo(x1 * resX, y1 * resY);
1638 }
1639 Coords.svgLineTo(x2 * resX, y2 * resY);
1640 currentPoint = QPoint(x2 * resX, y2 * resY);
1641 lineMode = true;
1642 // qDebug() << "Handle Line" << x1 << y1 << "->" << currentPoint;
1643 }
1644
handleLineFrom(QDataStream & ts)1645 void PctPlug::handleLineFrom(QDataStream &ts)
1646 {
1647 qint16 x, y;
1648 ts >> y >> x;
1649 if ((x == 0) && (y == 0))
1650 return;
1651 QPoint s = currentPoint;
1652 if (Coords.empty())
1653 Coords.svgMoveTo(s.x(), s.y());
1654 Coords.svgLineTo(x * resX, y * resY);
1655 currentPoint = QPoint(x * resX, y * resY);
1656 lineMode = true;
1657 // qDebug() << "Handle Line from" << s << "->" << currentPoint;
1658 }
1659
handlePixmap(QDataStream & ts,quint16 opCode)1660 void PctPlug::handlePixmap(QDataStream &ts, quint16 opCode)
1661 {
1662 handleLineModeEnd();
1663 quint16 bytesPerLine = 0, packType = 0, pixel_type = 0, bits_per_pixel = 0, component_count = 0, component_size = 0;
1664 quint32 packSize = 0, horizontal_resolution = 0, vertical_resolution = 0, color_table = 0, plane_bytes = 0;
1665 if ((opCode == 0x009A) || (opCode == 0x009B))
1666 ts.skipRawData(4);
1667 ts >> bytesPerLine;
1668 QRect bounds = readRect(ts);
1669 bool isPixmap = bytesPerLine & 0x8000;
1670 bytesPerLine &= 0x7FFF;
1671 // qDebug() << "Bytes per Line" << bytesPerLine << "Pixmap" << isPixmap;
1672 // qDebug() << "Bounds" << bounds.right() - bounds.left() << bounds.bottom() - bounds.top();
1673 QVector<QRgb> colors;
1674 if (isPixmap)
1675 {
1676 ts.skipRawData(2); // skip Version info, always 0
1677 ts >> packType;
1678 ts >> packSize;
1679 ts >> horizontal_resolution >> vertical_resolution;
1680 ts >> pixel_type >> bits_per_pixel >> component_count >> component_size;
1681 ts >> plane_bytes >> color_table;
1682 ts.skipRawData(4);
1683 // qDebug() << "Pack Type" << packType;
1684 // qDebug() << "Pack Size" << packSize;
1685 // qDebug() << "Pixel Type" << pixel_type;
1686 // qDebug() << "Bits per Pixel" << bits_per_pixel;
1687 // qDebug() << "Component Count" << component_count << "Size" << component_size;
1688 // now reading color Table
1689 if ((opCode != 0x009A) && (opCode != 0x009B))
1690 {
1691 quint32 ct_seed;
1692 quint16 ct_flags, ct_size;
1693 ts >> ct_seed;
1694 ts >> ct_flags >> ct_size;
1695 // qDebug() << "ColorTable has" << ct_size << "Entries";
1696 colors.reserve(ct_size + 1);
1697 for (quint16 cc = 0; cc < ct_size+1; cc++)
1698 {
1699 quint16 cev, cRed, cGreen, cBlue;
1700 ts >> cev >> cRed >> cGreen >> cBlue;
1701 colors.append(qRgb(cRed, cGreen, cBlue));
1702 }
1703 }
1704 }
1705 // reading scrRect
1706 QRect scrRect = readRect(ts);
1707 Q_UNUSED(scrRect);
1708 // qDebug() << "Src Rect" << scrRect;
1709 // reading dstRect
1710 QRect dstRect = readRect(ts);
1711 // qDebug() << "Dst Rect" << dstRect;
1712 ts.skipRawData(2);
1713 if ((opCode == 0x0091) || (opCode == 0x0099) || (opCode == 0x009B))
1714 {
1715 quint16 dataLen;
1716 ts >> dataLen;
1717 alignStreamToWord(ts, dataLen-2);
1718 }
1719 quint16 pixRows = bounds.bottom() - bounds.top();
1720 quint16 pixCols = bounds.right() - bounds.left();
1721 quint16 imgRows = dstRect.bottom() - dstRect.top();
1722 quint16 imgCols = dstRect.right() - dstRect.left();
1723 QImage image;
1724 if (isPixmap)
1725 {
1726 if (component_count == 1)
1727 {
1728 image = QImage(pixCols, pixRows, QImage::Format_Indexed8);
1729 image.setColorTable(colors);
1730 }
1731 else
1732 image = QImage(pixCols, pixRows, QImage::Format_ARGB32);
1733 }
1734 else
1735 image = QImage(pixCols, pixRows, QImage::Format_Mono);
1736 for (quint16 rr = 0; rr < pixRows; rr++)
1737 {
1738 quint16 pixByteCount;
1739 if (bytesPerLine < 250)
1740 {
1741 quint8 byteCount;
1742 ts >> byteCount;
1743 pixByteCount = byteCount;
1744 }
1745 else
1746 ts >> pixByteCount;
1747 if (!skipOpcode)
1748 {
1749 QByteArray data;
1750 data.resize(pixByteCount);
1751 ts.readRawData(data.data(), pixByteCount);
1752 int twoByte = 1;
1753 if (component_size == 5)
1754 twoByte = 2;
1755 QByteArray img;
1756 if (bytesPerLine < 8)
1757 img = data;
1758 else
1759 img = decodeRLE(data, bytesPerLine, twoByte);
1760 if ((opCode == 0x0098) || (opCode == 0x0099))
1761 {
1762 if (!isPixmap)
1763 {
1764 memcpy(image.scanLine(rr), img.data(), bytesPerLine);
1765 }
1766 else if (component_count == 1)
1767 {
1768 if (component_size == 4)
1769 {
1770 uchar *q = (uchar*)(image.scanLine(rr));
1771 for (int xx = 0; xx < img.size(); xx++)
1772 {
1773 uchar i = (img[xx] >> 4) & 0x0F;
1774 uchar j = img[xx] & 0x0F;
1775 *q++ = i;
1776 *q++ = j;
1777 }
1778 }
1779 else
1780 memcpy(image.scanLine(rr), img.data(), bytesPerLine);
1781 }
1782 }
1783 else if ((opCode == 0x009A) || (opCode == 0x009B))
1784 {
1785 if (component_size == 5)
1786 {
1787 QRgb *q = (QRgb*)(image.scanLine(rr));
1788 int imgDcount = 0;
1789 for (quint16 xx = 0; xx < pixCols; xx++)
1790 {
1791 uchar i = img[imgDcount++];
1792 uchar j = img[imgDcount++];
1793 quint16 r = (i & 0x7c) << 1;
1794 quint16 g = ((i & 0x03) << 6) | ((j & 0xe0) >> 2);
1795 quint16 b = (j & 0x1f) << 3;
1796 *q++ = qRgba(r, g, b, 255);
1797 }
1798 }
1799 else if ((component_size == 8) || (component_size == 24))
1800 {
1801 QRgb *q = (QRgb*)(image.scanLine(rr));
1802 for (uint xx = 0; xx < (uint) pixCols; xx++)
1803 {
1804 uchar r = 0;
1805 uchar g = 0;
1806 uchar b = 0;
1807 uchar a = 255;
1808 if (component_count == 3)
1809 {
1810 r = img[xx];
1811 g = img[xx + pixCols];
1812 b = img[xx + 2 * pixCols];
1813 }
1814 else if (component_count == 4)
1815 {
1816 a = 255 - img[xx];
1817 r = img[xx + pixCols];
1818 g = img[xx + 2 * pixCols];
1819 b = img[xx + 3 * pixCols];
1820 }
1821 *q++ = qRgba(r, g, b, a);
1822 }
1823 }
1824 }
1825 }
1826 else
1827 {
1828 ts.skipRawData(pixByteCount);
1829 }
1830 }
1831 if (skipOpcode)
1832 {
1833 image.loadFromData(imageData);
1834 isPixmap = true;
1835 imageData.resize(0);
1836 }
1837 if ((component_size == 24) || (component_size == 8) || (component_size == 1) || (component_size == 5) || (component_size == 4) || (!isPixmap) || (skipOpcode))
1838 {
1839 image = image.convertToFormat(QImage::Format_ARGB32);
1840 if (!isPixmap)
1841 image.invertPixels();
1842 int z = m_Doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, baseX + dstRect.left() * resX, baseY + dstRect.top() * resY, imgCols * resY, imgRows * resY, 0, m_Doc->itemToolPrefs().imageFillColor, m_Doc->itemToolPrefs().imageStrokeColor);
1843 PageItem *ite = m_Doc->Items->at(z);
1844 QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_pct_XXXXXX.png");
1845 tempFile->setAutoRemove(false);
1846 tempFile->open();
1847 QString fileName = getLongPathName(tempFile->fileName());
1848 tempFile->close();
1849 delete tempFile;
1850 ite->isInlineImage = true;
1851 ite->isTempFile = true;
1852 image.save(fileName, "PNG");
1853 ite->moveBy(baseX, baseY);
1854 ite->moveBy(offsetX, offsetY);
1855 finishItem(ite);
1856 m_Doc->loadPict(fileName, ite);
1857 ite->setImageScalingMode(false, false);
1858 skipOpcode = false;
1859 }
1860 alignStreamToWord(ts, 0);
1861 }
1862
handleQuickTime(QDataStream & ts,quint16 opCode)1863 void PctPlug::handleQuickTime(QDataStream &ts, quint16 opCode)
1864 {
1865 // qDebug() << "Handle QuickTime Data";
1866 quint32 dataLenLong, matteSize, maskSize, dataLen;
1867 quint16 mode;
1868 ts >> dataLenLong;
1869 uint pos = ts.device()->pos();
1870 handleLineModeEnd();
1871 alignStreamToWord(ts, 38); // Skip version and Matrix information
1872 ts >> matteSize;
1873 /*QRect matteRect =*/ readRect(ts);
1874 if (opCode == 0x8200)
1875 {
1876 ts >> mode;
1877 /*QRect srcRect =*/ readRect(ts);
1878 alignStreamToWord(ts, 4);
1879 ts >> maskSize;
1880 if (matteSize != 0)
1881 {
1882 ts >> dataLen;
1883 alignStreamToWord(ts, dataLen);
1884 alignStreamToWord(ts, matteSize);
1885 }
1886 if (maskSize != 0)
1887 {
1888 ts >> dataLen;
1889 alignStreamToWord(ts, dataLen);
1890 alignStreamToWord(ts, maskSize);
1891 }
1892 quint32 cType, vendor, dummyLong, imgDataSize;
1893 quint16 width, height, dummyShort;
1894 ts >> dataLen;
1895 ts >> cType;
1896 if (cType == 0x6A706567)
1897 {
1898 ts >> dummyLong;
1899 ts >> dummyShort;
1900 ts >> dummyShort;
1901 ts >> dummyShort;
1902 ts >> dummyShort;
1903 ts >> vendor;
1904 ts >> dummyLong;
1905 ts >> dummyLong;
1906 ts >> width;
1907 ts >> height;
1908 ts >> dummyLong;
1909 ts >> dummyLong;
1910 ts >> imgDataSize;
1911 alignStreamToWord(ts, 38);
1912 imageData.resize(imgDataSize);
1913 ts.readRawData(imageData.data(), imgDataSize);
1914 skipOpcode = true;
1915 }
1916 }
1917 else
1918 {
1919 if (matteSize != 0)
1920 {
1921 ts >> dataLen;
1922 alignStreamToWord(ts, dataLen);
1923 alignStreamToWord(ts, matteSize);
1924 }
1925 ts >> mode;
1926 handlePixmap(ts, mode);
1927 skipOpcode = true;
1928 }
1929 ts.device()->seek(pos + dataLenLong);
1930 // qDebug() << "File Pos" << ts.device()->pos();
1931 }
1932
handleComment(QDataStream & ts,bool longComment)1933 void PctPlug::handleComment(QDataStream &ts, bool longComment)
1934 {
1935 quint16 commentCode;
1936 handleLineModeEnd();
1937 ts >> commentCode;
1938 switch (commentCode)
1939 {
1940 case 100: // picAppComment
1941 // qDebug() << "Comment type: picAppComment";
1942 break;
1943 case 130: // picDwgBeg
1944 // qDebug() << "Comment type: picDwgBeg";
1945 break;
1946 case 131: // picDwgEnd
1947 // qDebug() << "Comment type: picDwgEnd";
1948 break;
1949 case 140: // picGrpBeg
1950 // qDebug() << "Comment type: picGrpBeg";
1951 break;
1952 case 141: // picGrpEnd
1953 // qDebug() << "Comment type: picGrpEnd";
1954 break;
1955 case 142: // picBitBeg
1956 // qDebug() << "Comment type: picBitBeg";
1957 break;
1958 case 143: // picBitEnd
1959 // qDebug() << "Comment type: picBitEnd";
1960 break;
1961 case 150: // TextBegin
1962 // qDebug() << "Comment type: TextBegin";
1963 break;
1964 case 151: // TextEnd
1965 // qDebug() << "Comment type: TextEnd";
1966 break;
1967 case 152: // StringBegin
1968 // qDebug() << "Comment type: StringBegin";
1969 break;
1970 case 153: // StringEnd
1971 // qDebug() << "Comment type: StringEnd";
1972 break;
1973 case 154: // TextCenter
1974 // qDebug() << "Comment type: TextCenter";
1975 break;
1976 case 155: // LineLayoutOff
1977 // qDebug() << "Comment type: LineLayoutOff";
1978 break;
1979 case 156: // LineLayoutOn
1980 // qDebug() << "Comment type: LineLayoutOn";
1981 break;
1982 case 157: // ClientLineLayout
1983 // qDebug() << "Comment type: ClientLineLayout";
1984 break;
1985 case 160: // PolyBegin
1986 // qDebug() << "Comment type: PolyBegin";
1987 break;
1988 case 161: // PolyEnd
1989 // qDebug() << "Comment type: PolyEnd";
1990 break;
1991 case 163: // PolyIgnore
1992 // qDebug() << "Comment type: PolyIgnore";
1993 break;
1994 case 164: // PolySmooth
1995 // qDebug() << "Comment type: PolySmooth";
1996 break;
1997 case 165: // PolyClose
1998 // qDebug() << "Comment type: PolyClose";
1999 break;
2000 case 170: // picArrw1 Arrowhead on 2nd point of line
2001 // qDebug() << "Comment type: picArrw1";
2002 break;
2003 case 171: // picArrw2 Arrowhead on 1nd point of line
2004 // qDebug() << "Comment type: picArrw2";
2005 break;
2006 case 172: // picArrw3 Arrowhead on both endpoints
2007 // qDebug() << "Comment type: picArrw3";
2008 break;
2009 case 173: // picArrwEnd End of arrowhead comment
2010 // qDebug() << "Comment type: picArrwEnd";
2011 break;
2012 case 180: // DashedLine
2013 // qDebug() << "Comment type: DashedLine";
2014 break;
2015 case 181: // DashedStop
2016 // qDebug() << "Comment type: DashedStop";
2017 break;
2018 case 182: // SetLineWidth
2019 // qDebug() << "Comment type: SetLineWidth";
2020 break;
2021 case 190: // PostScriptBegin
2022 postscriptMode = true;
2023 // qDebug() << "Comment type: PostScriptBegin";
2024 break;
2025 case 191: // PostScriptEnd
2026 postscriptMode = false;
2027 textIsPostScript = false;
2028 // qDebug() << "Comment type: PostScriptEnd";
2029 break;
2030 case 192: // PostScriptHandle
2031 // qDebug() << "Comment type: PostScriptHandle";
2032 break;
2033 case 193: // PostScriptFile
2034 // qDebug() << "Comment type: PostScriptFile";
2035 break;
2036 case 194: // TextIsPostScript
2037 textIsPostScript = true;
2038 // qDebug() << "Comment type: TextIsPostScript";
2039 break;
2040 case 195: // ResourcePS
2041 // qDebug() << "Comment type: ResourcePS";
2042 break;
2043 case 196: // PSBeginNoSave
2044 // qDebug() << "Comment type: PSBeginNoSave";
2045 break;
2046 case 200: // RotateBegin
2047 // qDebug() << "Comment type: RotateBegin";
2048 break;
2049 case 201: // RotateEnd
2050 // qDebug() << "Comment type: RotateEnd";
2051 break;
2052 case 210: // FormsPrinting
2053 // qDebug() << "Comment type: FormsPrinting";
2054 break;
2055 case 211: // EndFormsPrinting
2056 // qDebug() << "Comment type: EndFormsPrinting";
2057 break;
2058 case 220: // CMBeginProfile
2059 // qDebug() << "Comment type: CMBeginProfile";
2060 break;
2061 case 221: // CMEndProfile
2062 // qDebug() << "Comment type: CMEndProfile";
2063 break;
2064 case 222: // CMEnableMatching
2065 // qDebug() << "Comment type: CMEnableMatching";
2066 break;
2067 case 223: // CMDisableMatching
2068 // qDebug() << "Comment type: CMDisableMatching";
2069 break;
2070 default:
2071 // qDebug() << "Unknown Pict-Comment" << commentCode;
2072 break;
2073 }
2074 if (longComment)
2075 {
2076 quint16 dataLen;
2077 ts >> dataLen;
2078 alignStreamToWord(ts, dataLen);
2079 }
2080 }
2081
readRect(QDataStream & ts)2082 QRect PctPlug::readRect(QDataStream &ts)
2083 {
2084 qint16 RectX, RectY, RectW, RectH;
2085 ts >> RectX >> RectY >> RectW >> RectH;
2086 return QRect(QPoint(RectY, RectX), QPoint(RectH, RectW));
2087 }
2088
decodeRLE(QByteArray & in,quint16 bytesPerLine,int twoByte)2089 QByteArray PctPlug::decodeRLE(QByteArray &in, quint16 bytesPerLine, int twoByte)
2090 {
2091 QByteArray ret = QByteArray(bytesPerLine, ' ');
2092 uchar *ptrOut, *ptrIn;
2093 ptrOut = (uchar*)ret.data();
2094 ptrIn = (uchar*)in.data();
2095 quint16 count = 0;
2096 uchar c, c2;
2097 quint16 len;
2098 while (count < in.size())
2099 {
2100 c = *ptrIn++;
2101 count++;
2102 len = c;
2103 if (len < 128)
2104 {
2105 // Copy next len+1 bytes literally.
2106 len++;
2107 len *= twoByte;
2108 while (len != 0)
2109 {
2110 *ptrOut++ = *ptrIn++;
2111 len--;
2112 count++;
2113 if (twoByte == 2)
2114 {
2115 *ptrOut++ = *ptrIn++;
2116 len--;
2117 count++;
2118 }
2119 }
2120 }
2121 else if (len > 128)
2122 {
2123 // Next -len+1 bytes in the dest are replicated from next source byte.
2124 // (Interpret len as a negative 8-bit int.)
2125 len ^= 0xFF;
2126 len += 2;
2127 len *= twoByte;
2128 if (twoByte == 2)
2129 {
2130 c = *ptrIn++;
2131 count++;
2132 c2 = *ptrIn++;
2133 count++;
2134 while (len != 0)
2135 {
2136 *ptrOut++ = c;
2137 *ptrOut++ = c2;
2138 len--;
2139 len--;
2140 }
2141 }
2142 else
2143 {
2144 c = *ptrIn++;
2145 count++;
2146 while (len != 0)
2147 {
2148 *ptrOut++ = c;
2149 len--;
2150 }
2151 }
2152 }
2153 else if (len == 128)
2154 {
2155 // No-op.
2156 }
2157 }
2158 return ret;
2159 }
2160
setFillPattern(PageItem * ite)2161 void PctPlug::setFillPattern(PageItem* ite)
2162 {
2163 uint oldNum = m_Doc->TotalItems;
2164 QString patternName;
2165 quint32 patDat1, patDat2;
2166 QDataStream bu(&patternData, QIODevice::ReadOnly);
2167 bu >> patDat1 >> patDat2;
2168 QString patNa = QString("%1%2%3%4").arg(backColor.name(), foreColor.name()).arg(patDat1, 8, 16, QLatin1Char('0')).arg(patDat2, 8, 16, QLatin1Char('0'));
2169 if (!patternMap.contains(patNa))
2170 {
2171 QImage image = QImage(8, 8, QImage::Format_Mono);
2172 QVector<QRgb> colors;
2173 colors.append(backColor.rgb());
2174 colors.append(foreColor.rgb());
2175 image.setColorTable(colors);
2176 for (int rr = 0; rr < 8; rr++)
2177 {
2178 uchar *q = (uchar*)(image.scanLine(rr));
2179 *q = patternData[rr];
2180 }
2181 image = image.convertToFormat(QImage::Format_ARGB32);
2182 ScPattern pat = ScPattern();
2183 pat.setDoc(m_Doc);
2184 PageItem* newItem = new PageItem_ImageFrame(m_Doc, 0, 0, 1, 1, 0, CommonStrings::None, CommonStrings::None);
2185 QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_pct_XXXXXX.png");
2186 tempFile->setAutoRemove(false);
2187 tempFile->open();
2188 QString fileName = getLongPathName(tempFile->fileName());
2189 tempFile->close();
2190 delete tempFile;
2191 newItem->isInlineImage = true;
2192 newItem->isTempFile = true;
2193 image.setDotsPerMeterY(2834);
2194 image.setDotsPerMeterX(2834);
2195 image.save(fileName, "PNG");
2196 if (newItem->loadImage(fileName, false, 72, false))
2197 {
2198 pat.width = image.width();
2199 pat.height = image.height();
2200 pat.scaleX = (72.0 / newItem->pixm.imgInfo.xres) * newItem->pixm.imgInfo.lowResScale;
2201 pat.scaleY = (72.0 / newItem->pixm.imgInfo.xres) * newItem->pixm.imgInfo.lowResScale;
2202 pat.pattern = newItem->pixm.qImage().copy();
2203 newItem->setWidth(pat.pattern.width());
2204 newItem->setHeight(pat.pattern.height());
2205 newItem->SetRectFrame();
2206 newItem->gXpos = 0.0;
2207 newItem->gYpos = 0.0;
2208 newItem->gWidth = pat.pattern.width();
2209 newItem->gHeight = pat.pattern.height();
2210 pat.items.append(newItem);
2211 }
2212 patternName = "Pattern_"+newItem->itemName();
2213 patternName = patternName.trimmed().simplified().replace(" ", "_");
2214 m_Doc->addPattern(patternName, pat);
2215 importedPatterns.append(patternName);
2216 patternMap.insert(patNa, patternName);
2217 }
2218 else
2219 patternName = patternMap[patNa];
2220 ite->setPattern(patternName);
2221 ite->GrType = Gradient_Pattern;
2222 m_Doc->TotalItems = oldNum;
2223 // qDebug() << "Using Pattern" << patternName << "internal Name" << patNa;
2224 }
2225
handleLineModeEnd()2226 void PctPlug::handleLineModeEnd()
2227 {
2228 if ((Coords.size() > 3) && lineMode)
2229 {
2230 int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CommonStrings::None, CurrColorStroke);
2231 PageItem *ite = m_Doc->Items->at(z);
2232 ite->PoLine = Coords.copy();
2233 ite->PoLine.translate(offsetX, offsetY);
2234 finishItem(ite);
2235 }
2236 Coords.resize(0);
2237 Coords.svgInit();
2238 lineMode = false;
2239 }
2240
finishItem(PageItem * ite)2241 void PctPlug::finishItem(PageItem* ite)
2242 {
2243 ite->ClipEdited = true;
2244 ite->FrameType = 3;
2245 ite->setFillShade(CurrFillShade);
2246 ite->setLineShade(CurrStrokeShade);
2247 FPoint wh = getMaxClipF(&ite->PoLine);
2248 ite->setWidthHeight(wh.x(),wh.y());
2249 ite->setTextFlowMode(PageItem::TextFlowDisabled);
2250 m_Doc->adjustItemSize(ite);
2251 ite->OldB2 = ite->width();
2252 ite->OldH2 = ite->height();
2253 ite->updateClip();
2254 Elements.append(ite);
2255 lastCoords = Coords;
2256 Coords.resize(0);
2257 Coords.svgInit();
2258 }
2259