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 <QDataStream>
11 #include <QDrag>
12 #include <QFile>
13 #include <QList>
14 #include <QMimeData>
15 #include <QRegExp>
16 #include <QStack>
17 #include <QTemporaryFile>
18 #include <QDebug>
19
20 #include <cstdlib>
21 #include <tiffio.h>
22 #include <zlib.h>
23
24 #include "importai.h"
25
26 #include "commonstrings.h"
27 #include "loadsaveplugin.h"
28 #include "prefscontext.h"
29 #include "prefsfile.h"
30 #include "prefsmanager.h"
31 #include "prefstable.h"
32 #include "qtiocompressor.h"
33 #include "rawimage.h"
34 #include "scclocale.h"
35 #include "sccolorengine.h"
36 #include "scconfig.h"
37 #include "scmimedata.h"
38 #include "scpaths.h"
39 #include "scpattern.h"
40 #include "scribusXml.h"
41 #include "scribuscore.h"
42 #include "scribusdoc.h"
43 #include "scribusview.h"
44 #include "sctextstream.h"
45 #include "selection.h"
46 #include "text/specialchars.h"
47 #include "ui/customfdialog.h"
48 #include "ui/missing.h"
49 #include "ui/multiprogressdialog.h"
50 #include "ui/propertiespalette.h"
51 #include "undomanager.h"
52 #include "util.h"
53 #include "util_color.h"
54 #include "util_file.h"
55 #include "util_formats.h"
56 #include "util_ghostscript.h"
57 #include "util_math.h"
58
59 #include <cairo.h>
60
61 #ifdef HAVE_PODOFO
62 #include <podofo/podofo.h>
63 #endif
64
AIPlug(ScribusDoc * doc,int flags)65 AIPlug::AIPlug(ScribusDoc* doc, int flags)
66 {
67 tmpSel = new Selection(this, false);
68 m_Doc = doc;
69 importerFlags = flags;
70 interactive = (flags & LoadSavePlugin::lfInteractive);
71 }
72
readThumbnail(const QString & fNameIn)73 QImage AIPlug::readThumbnail(const QString& fNameIn)
74 {
75 QString fName = fNameIn;
76 double x, y, b, h;
77 CustColors.clear();
78 importedColors.clear();
79 importedGradients.clear();
80 importedPatterns.clear();
81 QFileInfo fi = QFileInfo(fName);
82 /* Check if the file is an old style AI or one of the newer PDF wrapped ones */
83 QFile fT(fName);
84 if (fT.open(QIODevice::ReadOnly))
85 {
86 QByteArray tempBuf(9, ' ');
87 fT.read(tempBuf.data(), 8);
88 fT.close();
89 if (tempBuf.startsWith("%PDF"))
90 {
91 QString tmp;
92 QString pdfFile = QDir::toNativeSeparators(fName);
93 QString tmpFile = QDir::toNativeSeparators(ScPaths::tempFileDir() + "sc.png");
94 int ret = -1;
95 tmp.setNum(1);
96 QStringList args;
97 args.append("-r72");
98 args.append("-sOutputFile="+tmpFile);
99 args.append("-dFirstPage="+tmp);
100 args.append("-dLastPage="+tmp);
101 args.append(pdfFile);
102 ret = callGS(args);
103 if (ret == 0)
104 {
105 QImage image;
106 image.load(tmpFile);
107 QFile::remove(tmpFile);
108 image.setText("XSize", QString("%1").arg(image.width()));
109 image.setText("YSize", QString("%1").arg(image.height()));
110 return image;
111 }
112 return QImage();
113 }
114 }
115 QFile fT2(fName);
116 if (fT2.open(QIODevice::ReadOnly))
117 {
118 QByteArray tempBuf(25, ' ');
119 fT2.read(tempBuf.data(), 20);
120 fT2.close();
121 /* Illustrator CS files might be compressed
122 the compressed Data starts right after the "%AI12_CompressedData" comment
123 Compression is a simple zlib compression */
124 if (tempBuf.startsWith("%AI12_CompressedData"))
125 decompressAIData(fName);
126 }
127 progressDialog = nullptr;
128 /* Set default Page to size defined in Preferences */
129 x = 0.0;
130 y = 0.0;
131 b = PrefsManager::instance().appPrefs.docSetupPrefs.pageWidth;
132 h = PrefsManager::instance().appPrefs.docSetupPrefs.pageHeight;
133 parseHeader(fName, x, y, b, h);
134 if (b == 0)
135 b = PrefsManager::instance().appPrefs.docSetupPrefs.pageWidth;
136 if (h == 0)
137 h = PrefsManager::instance().appPrefs.docSetupPrefs.pageHeight;
138 docX = x;
139 docY = y;
140 docWidth = b - x;
141 docHeight = h - y;
142 baseX = 0;
143 baseY = 0;
144 m_Doc = new ScribusDoc();
145 m_Doc->setup(0, 1, 1, 1, 1, "Custom", "Custom");
146 m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false);
147 m_Doc->addPage(0);
148 m_Doc->setGUI(false, ScCore->primaryMainWindow(), nullptr);
149 baseX = m_Doc->currentPage()->xOffset();
150 baseY = m_Doc->currentPage()->yOffset();
151 ColorList::Iterator it;
152 for (it = CustColors.begin(); it != CustColors.end(); ++it)
153 {
154 if (!m_Doc->PageColors.contains(it.key()))
155 {
156 m_Doc->PageColors.insert(it.key(), it.value());
157 importedColors.append(it.key());
158 }
159 }
160 Elements.clear();
161 m_Doc->setLoading(true);
162 m_Doc->DoDrawing = false;
163 m_Doc->scMW()->setScriptRunning(true);
164 QString CurDirP = QDir::currentPath();
165 QDir::setCurrent(fi.path());
166 QImage tmpImage;
167 if (convert(fName))
168 {
169 tmpSel->clear();
170 QDir::setCurrent(CurDirP);
171 if (Elements.count() > 1)
172 m_Doc->groupObjectsList(Elements);
173 m_Doc->DoDrawing = true;
174 m_Doc->m_Selection->delaySignalsOn();
175 for (int dre=0; dre<Elements.count(); ++dre)
176 {
177 tmpSel->addItem(Elements.at(dre), true);
178 }
179 tmpSel->setGroupRect();
180 double xs = tmpSel->width();
181 double ys = tmpSel->height();
182 if (Elements.count() > 0)
183 tmpImage = Elements.at(0)->DrawObj_toImage(500);
184 tmpImage.setText("XSize", QString("%1").arg(xs));
185 tmpImage.setText("YSize", QString("%1").arg(ys));
186 m_Doc->m_Selection->delaySignalsOff();
187 }
188 else
189 tmpImage = QImage();
190 m_Doc->scMW()->setScriptRunning(false);
191 m_Doc->setLoading(false);
192 delete m_Doc;
193 QDir::setCurrent(CurDirP);
194 return tmpImage;
195 }
196
readColors(const QString & fileName,ColorList & colors)197 bool AIPlug::readColors(const QString& fileName, ColorList & colors)
198 {
199 QString fName(fileName);
200 bool success = false;
201 cancel = false;
202 double x, y, b, h;
203 convertedPDF = false;
204 CustColors.clear();
205 importedColors.clear();
206 importedGradients.clear();
207 importedPatterns.clear();
208 QFileInfo fi = QFileInfo(fName);
209 /* Check if the file is an old style AI or one of the newer PDF wrapped ones */
210 QFile fT(fName);
211 if (fT.open(QIODevice::ReadOnly))
212 {
213 QByteArray tempBuf(9, ' ');
214 fT.read(tempBuf.data(), 8);
215 fT.close();
216 if (tempBuf.startsWith("%PDF"))
217 {
218 QFileInfo bF2(fName);
219 QString tmpFile = ScPaths::tempFileDir()+ "/"+bF2.baseName()+"_tmp.ai";
220 if (!extractFromPDF(fName, tmpFile))
221 return false;
222 convertedPDF = true;
223 fName = tmpFile;
224 }
225 }
226 QFile fT2(fName);
227 if (fT2.open(QIODevice::ReadOnly))
228 {
229 QByteArray tempBuf(25, ' ');
230 fT2.read(tempBuf.data(), 20);
231 fT2.close();
232 /* Illustrator CS files might be compressed
233 the compressed Data starts right after the "%AI12_CompressedData" comment
234 Compression is a simple zlib compression */
235 if (tempBuf.startsWith("%AI12_CompressedData"))
236 decompressAIData(fName);
237 }
238 progressDialog = nullptr;
239 /* Set default Page to size defined in Preferences */
240 x = 0.0;
241 y = 0.0;
242 b = PrefsManager::instance().appPrefs.docSetupPrefs.pageWidth;
243 h = PrefsManager::instance().appPrefs.docSetupPrefs.pageHeight;
244 parseHeader(fName, x, y, b, h);
245 docX = x;
246 docY = y;
247 docWidth = b - x;
248 docHeight = h - y;
249 m_Doc = new ScribusDoc();
250 m_Doc->setup(0, 1, 1, 1, 1, "Custom", "Custom");
251 m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false);
252 m_Doc->addPage(0);
253 m_Doc->setGUI(false, ScCore->primaryMainWindow(), nullptr);
254 baseX = m_Doc->currentPage()->xOffset();
255 baseY = m_Doc->currentPage()->yOffset();
256 ColorList::Iterator it;
257 for (it = CustColors.begin(); it != CustColors.end(); ++it)
258 {
259 if (!m_Doc->PageColors.contains(it.key()))
260 {
261 m_Doc->PageColors.insert(it.key(), it.value());
262 importedColors.append(it.key());
263 }
264 }
265 Elements.clear();
266 m_Doc->setLoading(true);
267 m_Doc->DoDrawing = false;
268 m_Doc->scMW()->setScriptRunning(true);
269 QString CurDirP = QDir::currentPath();
270 QDir::setCurrent(fi.path());
271 convert(fName);
272 if (importedColors.count() != 0)
273 {
274 colors = m_Doc->PageColors;
275 success = true;
276 }
277 m_Doc->scMW()->setScriptRunning(false);
278 m_Doc->setLoading(false);
279 delete m_Doc;
280 QDir::setCurrent(CurDirP);
281 if (convertedPDF)
282 QFile::remove(fName);
283 return success;
284 }
285
import(const QString & fNameIn,const TransactionSettings & trSettings,int flags,bool showProgress)286 bool AIPlug::import(const QString& fNameIn, const TransactionSettings& trSettings, int flags, bool showProgress)
287 {
288 QString fName = fNameIn;
289 bool success = false;
290 interactive = (flags & LoadSavePlugin::lfInteractive);
291 importerFlags = flags;
292 cancel = false;
293 double x, y, b, h;
294 bool ret = false;
295 convertedPDF = false;
296 CustColors.clear();
297 importedColors.clear();
298 importedGradients.clear();
299 importedPatterns.clear();
300 QFileInfo fi = QFileInfo(fName);
301 // QString ext = fi.suffix().toLower();
302 if ( !ScCore->usingGUI() )
303 {
304 interactive = false;
305 showProgress = false;
306 }
307
308 /* Check if the file is an old style AI or one of the newer PDF wrapped ones */
309 QFile fT(fName);
310 if (fT.open(QIODevice::ReadOnly))
311 {
312 QByteArray tempBuf(9, ' ');
313 fT.read(tempBuf.data(), 8);
314 fT.close();
315 if (tempBuf.startsWith("%PDF"))
316 {
317 QFileInfo bF2(fName);
318 QString tmpFile = ScPaths::tempFileDir()+ "/"+bF2.baseName()+"_tmp.ai";
319 if (!extractFromPDF(fName, tmpFile))
320 return false;
321 convertedPDF = true;
322 fName = tmpFile;
323 }
324 }
325 QFile fT2(fName);
326 if (fT2.open(QIODevice::ReadOnly))
327 {
328 QByteArray tempBuf(25, ' ');
329 fT2.read(tempBuf.data(), 20);
330 fT2.close();
331 /* Illustrator CS files might be compressed
332 the compressed Data starts right after the "%AI12_CompressedData" comment
333 Compression is a simple zlib compression */
334 if (tempBuf.startsWith("%AI12_CompressedData"))
335 decompressAIData(fName);
336 }
337 if ( showProgress )
338 {
339 ScribusMainWindow* mw=(m_Doc==nullptr) ? ScCore->primaryMainWindow() : m_Doc->scMW();
340 progressDialog = new MultiProgressDialog( tr("Importing: %1").arg(fi.fileName()), CommonStrings::tr_Cancel, mw );
341 QStringList barNames, barTexts;
342 barNames << "GI";
343 barTexts << tr("Analyzing File:");
344 QList<bool> barsNumeric;
345 barsNumeric << false;
346 progressDialog->addExtraProgressBars(barNames, barTexts, barsNumeric);
347 progressDialog->setOverallTotalSteps(3);
348 progressDialog->setOverallProgress(0);
349 progressDialog->setProgress("GI", 0);
350 progressDialog->show();
351 connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelRequested()));
352 qApp->processEvents();
353 }
354 else
355 progressDialog = nullptr;
356 /* Set default Page to size defined in Preferences */
357 x = 0.0;
358 y = 0.0;
359 b = PrefsManager::instance().appPrefs.docSetupPrefs.pageWidth;
360 h = PrefsManager::instance().appPrefs.docSetupPrefs.pageHeight;
361 if (progressDialog)
362 {
363 progressDialog->setOverallProgress(1);
364 qApp->processEvents();
365 }
366 parseHeader(fName, x, y, b, h);
367 if (b == 0)
368 b = PrefsManager::instance().appPrefs.docSetupPrefs.pageWidth;
369 if (h == 0)
370 h = PrefsManager::instance().appPrefs.docSetupPrefs.pageHeight;
371 docX = x;
372 docY = y;
373 docWidth = b - x;
374 docHeight = h - y;
375 baseX = 0;
376 baseY = 0;
377 if (!interactive || (flags & LoadSavePlugin::lfInsertPage))
378 {
379 m_Doc->setPage(b-x, h-y, 0, 0, 0, 0, 0, 0, false, false);
380 m_Doc->addPage(0);
381 m_Doc->view()->addPage(0, true);
382 baseX = 0;
383 baseY = 0;
384 }
385 else
386 {
387 if (!m_Doc || (flags & LoadSavePlugin::lfCreateDoc))
388 {
389 m_Doc=ScCore->primaryMainWindow()->doFileNew(b-x, h-y, 0, 0, 0, 0, 0, 0, false, false, 0, false, 0, 1, "Custom", true);
390 ScCore->primaryMainWindow()->HaveNewDoc();
391 ret = true;
392 baseX = 0;
393 baseY = 0;
394 }
395 }
396 if (flags & LoadSavePlugin::lfCreateDoc)
397 {
398 m_Doc->documentInfo().setAuthor(docCreator);
399 m_Doc->documentInfo().setPublisher(docOrganisation);
400 m_Doc->documentInfo().setTitle(docTitle);
401 m_Doc->documentInfo().setDate(docDate+" "+docTime);
402 }
403 if ((!ret) && (interactive))
404 {
405 baseX = m_Doc->currentPage()->xOffset();
406 baseY = m_Doc->currentPage()->yOffset();
407 }
408 if ((ret) || (!interactive))
409 {
410 if (b-x > h-y)
411 m_Doc->setPageOrientation(1);
412 else
413 m_Doc->setPageOrientation(0);
414 m_Doc->setPageSize("Custom");
415 }
416 ColorList::Iterator it;
417 for (it = CustColors.begin(); it != CustColors.end(); ++it)
418 {
419 if (!m_Doc->PageColors.contains(it.key()))
420 {
421 m_Doc->PageColors.insert(it.key(), it.value());
422 importedColors.append(it.key());
423 }
424 }
425 if ((!(flags & LoadSavePlugin::lfLoadAsPattern)) && (m_Doc->view() != nullptr))
426 m_Doc->view()->deselectItems();
427 Elements.clear();
428 m_Doc->setLoading(true);
429 m_Doc->DoDrawing = false;
430 if ((!(flags & LoadSavePlugin::lfLoadAsPattern)) && (m_Doc->view() != nullptr))
431 m_Doc->view()->updatesOn(false);
432 m_Doc->scMW()->setScriptRunning(true);
433 qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
434 QString CurDirP = QDir::currentPath();
435 QDir::setCurrent(fi.path());
436 if (convert(fName))
437 {
438 if (Elements.count() == 0)
439 {
440 if ((importedColors.count() != 0) && (!((flags & LoadSavePlugin::lfKeepGradients) || (flags & LoadSavePlugin::lfKeepColors) || (flags & LoadSavePlugin::lfKeepPatterns))))
441 {
442 for (int cd = 0; cd < importedColors.count(); cd++)
443 {
444 m_Doc->PageColors.remove(importedColors[cd]);
445 }
446 }
447 if ((importedGradients.count() != 0) && (!((flags & LoadSavePlugin::lfKeepGradients || (flags & LoadSavePlugin::lfKeepPatterns)))))
448 {
449 for (int cd = 0; cd < importedGradients.count(); cd++)
450 {
451 m_Doc->docGradients.remove(importedGradients[cd]);
452 }
453 }
454 if ((importedPatterns.count() != 0) && (!(flags & LoadSavePlugin::lfKeepPatterns)))
455 {
456 for (int cd = 0; cd < importedPatterns.count(); cd++)
457 {
458 m_Doc->docPatterns.remove(importedPatterns[cd]);
459 }
460 }
461 }
462 tmpSel->clear();
463 QDir::setCurrent(CurDirP);
464 if ((Elements.count() > 1) && (!(importerFlags & LoadSavePlugin::lfCreateDoc)))
465 m_Doc->groupObjectsList(Elements);
466 m_Doc->DoDrawing = true;
467 m_Doc->scMW()->setScriptRunning(false);
468 m_Doc->setLoading(false);
469 qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
470 if ((Elements.count() > 0) && (!ret) && (interactive))
471 {
472 if (flags & LoadSavePlugin::lfScripted)
473 {
474 bool loadF = m_Doc->isLoading();
475 m_Doc->setLoading(false);
476 m_Doc->changed();
477 m_Doc->setLoading(loadF);
478 if (!(flags & LoadSavePlugin::lfLoadAsPattern))
479 {
480 m_Doc->m_Selection->delaySignalsOn();
481 for (int dre=0; dre<Elements.count(); ++dre)
482 {
483 m_Doc->m_Selection->addItem(Elements.at(dre), true);
484 }
485 m_Doc->m_Selection->delaySignalsOff();
486 m_Doc->m_Selection->setGroupRect();
487 if (m_Doc->view() != nullptr)
488 m_Doc->view()->updatesOn(true);
489 }
490 }
491 else
492 {
493 m_Doc->DragP = true;
494 m_Doc->DraggedElem = nullptr;
495 m_Doc->DragElements.clear();
496 m_Doc->m_Selection->delaySignalsOn();
497 for (int dre=0; dre<Elements.count(); ++dre)
498 {
499 tmpSel->addItem(Elements.at(dre), true);
500 }
501 tmpSel->setGroupRect();
502 ScElemMimeData* md = ScriXmlDoc::writeToMimeData(m_Doc, tmpSel);
503 m_Doc->itemSelection_DeleteItem(tmpSel);
504 m_Doc->view()->updatesOn(true);
505 if ((importedColors.count() != 0) && (!((flags & LoadSavePlugin::lfKeepGradients) || (flags & LoadSavePlugin::lfKeepColors) || (flags & LoadSavePlugin::lfKeepPatterns))))
506 {
507 for (int cd = 0; cd < importedColors.count(); cd++)
508 {
509 m_Doc->PageColors.remove(importedColors[cd]);
510 }
511 }
512 if ((importedGradients.count() != 0) && (!((flags & LoadSavePlugin::lfKeepGradients || (flags & LoadSavePlugin::lfKeepPatterns)))))
513 {
514 for (int cd = 0; cd < importedGradients.count(); cd++)
515 {
516 m_Doc->docGradients.remove(importedGradients[cd]);
517 }
518 }
519 if ((importedPatterns.count() != 0) && (!(flags & LoadSavePlugin::lfKeepPatterns)))
520 {
521 for (int cd = 0; cd < importedPatterns.count(); cd++)
522 {
523 m_Doc->docPatterns.remove(importedPatterns[cd]);
524 }
525 }
526 m_Doc->m_Selection->delaySignalsOff();
527 // We must copy the TransationSettings object as it is owned
528 // by handleObjectImport method afterwards
529 TransactionSettings* transacSettings = new TransactionSettings(trSettings);
530 m_Doc->view()->handleObjectImport(md, transacSettings);
531 m_Doc->DragP = false;
532 m_Doc->DraggedElem = nullptr;
533 m_Doc->DragElements.clear();
534 }
535 }
536 else
537 {
538 m_Doc->changed();
539 m_Doc->reformPages();
540 if (!(flags & LoadSavePlugin::lfLoadAsPattern))
541 m_Doc->view()->updatesOn(true);
542 }
543 success = true;
544 }
545 else
546 {
547 QDir::setCurrent(CurDirP);
548 m_Doc->DoDrawing = true;
549 m_Doc->scMW()->setScriptRunning(false);
550 m_Doc->view()->updatesOn(true);
551 qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
552 }
553 if (interactive)
554 m_Doc->setLoading(false);
555 //CB If we have a gui we must refresh it if we have used the progressbar
556 if (!(flags & LoadSavePlugin::lfLoadAsPattern))
557 {
558 if ((showProgress) && (!interactive))
559 m_Doc->view()->DrawNew();
560 }
561 if (convertedPDF)
562 QFile::remove(fName);
563 qApp->restoreOverrideCursor();
564 return success;
565 }
566
~AIPlug()567 AIPlug::~AIPlug()
568 {
569 delete progressDialog;
570 delete tmpSel;
571 }
572
extractFromPDF(const QString & infile,const QString & outfile)573 bool AIPlug::extractFromPDF(const QString& infile, const QString& outfile)
574 {
575 bool ret = false;
576 #ifdef HAVE_PODOFO
577 QFile outf(outfile);
578 if (!outf.open(QIODevice::WriteOnly))
579 {
580 qDebug()<<"Failed to open QFile outf in AIPlug::extractFromPDF";
581 return false;
582 }
583 try
584 {
585 PoDoFo::PdfError::EnableDebug( false );
586 PoDoFo::PdfError::EnableLogging( false );
587 PoDoFo::PdfMemDocument doc( infile.toLocal8Bit().data() );
588 PoDoFo::PdfPage *curPage = doc.GetPage(0);
589 if (curPage != nullptr)
590 {
591 PoDoFo::PdfObject *piece = curPage->GetObject()->GetIndirectKey("PieceInfo");
592 if (piece != nullptr)
593 {
594 PoDoFo::PdfObject *illy = piece->GetIndirectKey("Illustrator");
595 if (illy != nullptr)
596 {
597 PoDoFo::PdfObject *priv = illy->GetIndirectKey("Private");
598 if (priv == nullptr)
599 priv = illy;
600 int num = 0;
601 PoDoFo::PdfObject *numBl = priv->GetIndirectKey("NumBlock");
602 if (numBl != nullptr)
603 num = numBl->GetNumber() + 1;
604 if (num == 0)
605 num = 99999;
606 QString name = "AIPrivateData%1";
607 QString Key = name.arg(1);
608 PoDoFo::PdfObject *data = priv->GetIndirectKey(PoDoFo::PdfName(Key.toUtf8().data()));
609 if (data == nullptr)
610 {
611 name = "AIPDFPrivateData%1";
612 Key = name.arg(1);
613 data = priv->GetIndirectKey(PoDoFo::PdfName(Key.toUtf8().data()));
614 }
615 if (data != nullptr)
616 {
617 if (num == 2)
618 {
619 Key = name.arg(1);
620 data = priv->GetIndirectKey(PoDoFo::PdfName(Key.toUtf8().data()));
621 PoDoFo::PdfStream const *stream = data->GetStream();
622 PoDoFo::PdfMemoryOutputStream oStream(1);
623 stream->GetFilteredCopy(&oStream);
624 oStream.Close();
625 long bLen = oStream.GetLength();
626 char *Buffer = oStream.TakeBuffer();
627 outf.write(Buffer, bLen);
628 free( Buffer );
629 }
630 else
631 {
632 for (int a = 2; a < num; a++)
633 {
634 Key = name.arg(a);
635 data = priv->GetIndirectKey(PoDoFo::PdfName(Key.toUtf8().data()));
636 if (data == nullptr)
637 break;
638 PoDoFo::PdfStream const *stream = data->GetStream();
639 PoDoFo::PdfMemoryOutputStream oStream(1);
640 stream->GetFilteredCopy(&oStream);
641 oStream.Close();
642 long bLen = oStream.GetLength();
643 char *Buffer = oStream.TakeBuffer();
644 outf.write(Buffer, bLen);
645 free( Buffer );
646 }
647 }
648 }
649 ret = true;
650 }
651 }
652 }
653 outf.close();
654 }
655 catch (PoDoFo::PdfError& e)
656 {
657 outf.close();
658 qDebug("Scribus caught and handled the following exception from PoDoFo while processing a PDF format ai file:\n----\n");
659 e.PrintErrorMsg();
660 qDebug("----\nThe ai file could not be imported.\n");
661 QFile::remove(outfile);
662 return false;
663 }
664 #endif
665 return ret;
666 }
667
decompressAIData(QString & fName)668 bool AIPlug::decompressAIData(QString &fName)
669 {
670 QString f2 = fName+"_decom.ai";
671 char buffer[4096];
672
673 QFile source(fName);
674 if (!source.open(QFile::ReadOnly))
675 return false;
676 if (!source.seek(20))
677 {
678 source.close();
679 return false;
680 }
681
682 QtIOCompressor compressor(&source);
683 compressor.setStreamFormat(QtIOCompressor::ZlibFormat);
684 if (!compressor.open(QIODevice::ReadOnly))
685 {
686 source.close();
687 return false;
688 }
689
690 QFile dest(f2);
691 if (!dest.open(QFile::WriteOnly))
692 {
693 source.close();
694 return false;
695 }
696 QDataStream destStream(&dest);
697
698 qint64 bytesRead = -1;
699 qint64 bytesWritten = -1;
700
701 bytesRead = compressor.read(buffer, 4096);
702 while (bytesRead > 0)
703 {
704 bytesWritten = destStream.writeRawData(buffer, (int) bytesRead);
705 if (bytesWritten < 0)
706 break;
707 bytesRead = compressor.read(buffer, 4096);
708 }
709
710 compressor.close();
711 source.close();
712 dest.close();
713
714 if (bytesRead < 0 || bytesWritten < 0)
715 return false;
716
717 if (!convertedPDF)
718 {
719 QFileInfo bF2(fName);
720 QString tmpFile = ScPaths::tempFileDir()+ "/"+bF2.baseName()+"_tmp.ai";
721 moveFile(f2, tmpFile);
722 fName = tmpFile;
723 convertedPDF = true;
724 }
725 else
726 {
727 QFile::remove(fName);
728 fName = f2;
729 }
730 return true;
731 }
732
parseHeader(const QString & fName,double & x,double & y,double & b,double & h)733 bool AIPlug::parseHeader(const QString& fName, double &x, double &y, double &b, double &h)
734 {
735 QString tmp, BBox, FarNam;
736 ScColor cc;
737 double c, m, yc, k;
738 bool found = false;
739 QFile f(fName);
740 if (f.open(QIODevice::ReadOnly))
741 {
742 /* Try to find Bounding Box */
743 bool isAtend = false;
744 QDataStream ts(&f);
745 while (!ts.atEnd())
746 {
747 tmp = readLineFromDataStream(ts);
748 if (tmp.startsWith("%%BoundingBox:"))
749 {
750 found = true;
751 BBox = tmp.remove("%%BoundingBox:");
752 }
753 if (!found)
754 {
755 if (tmp.startsWith("%%BoundingBox"))
756 {
757 found = true;
758 BBox = tmp.remove("%%BoundingBox");
759 }
760 }
761 if (tmp.startsWith("%%HiResBoundingBox:"))
762 {
763 found = true;
764 BBox = tmp.remove("%%HiResBoundingBox:");
765 }
766 // if (tmp.startsWith("%AI3_TileBox:"))
767 // {
768 // found = true;
769 // BBox = tmp.remove("%AI3_TileBox:");
770 // }
771 if (tmp.startsWith("%%For"))
772 {
773 QStringList res = getStrings(tmp);
774 if (res.count() > 1)
775 {
776 docCreator = res[0];
777 docOrganisation = res[1];
778 }
779 }
780 if (tmp.startsWith("%%CreationDate:"))
781 {
782 QStringList res = getStrings(tmp);
783 if (res.count() > 1)
784 {
785 docDate = res[0];
786 docTime = res[1];
787 }
788 else
789 {
790 docDate = tmp.remove("%%CreationDate: ");
791 docTime = "";
792 }
793 }
794 if (tmp.startsWith("%%Title"))
795 {
796 QStringList res = getStrings(tmp);
797 if (res.count() > 0)
798 docTitle = res[0];
799 }
800 if ((tmp.startsWith("%%CMYKCustomColor")) || (tmp.startsWith("%%CMYKProcessColor")))
801 {
802 if (tmp.contains("(atend)"))
803 isAtend = true;
804 else
805 {
806 if (tmp.startsWith("%%CMYKCustomColor"))
807 tmp = tmp.remove(0,18);
808 else if (tmp.startsWith("%%CMYKProcessColor"))
809 tmp = tmp.remove(0,19);
810 ScTextStream ts2(&tmp, QIODevice::ReadOnly);
811 ts2 >> c >> m >> yc >> k;
812 FarNam = ts2.readAll();
813 FarNam = FarNam.trimmed();
814 FarNam = FarNam.remove(0,1);
815 FarNam = FarNam.remove(FarNam.length()-1,1);
816 FarNam = FarNam.simplified();
817 QByteArray farN;
818 for (int a = 0; a < FarNam.length(); a++)
819 {
820 QChar ch = FarNam.at(a);
821 uint chc = ch.unicode();
822 if (chc > 255)
823 farN.append(chc >> 8);
824 farN.append(chc & 0x00FF);
825 }
826 FarNam = QString::fromUtf8(farN.constData());
827 cc = ScColor(qRound(255 * c), qRound(255 * m), qRound(255 * yc), qRound(255 * k));
828 cc.setSpotColor(true);
829 if (!FarNam.isEmpty())
830 CustColors.tryAddColor(FarNam, cc);
831 while (!ts.atEnd())
832 {
833 quint64 oldPos = ts.device()->pos();
834 tmp = readLineFromDataStream(ts);
835 if (!tmp.startsWith("%%+"))
836 {
837 ts.device()->seek(oldPos);
838 break;
839 }
840 tmp = tmp.remove(0,3);
841 ScTextStream ts2(&tmp, QIODevice::ReadOnly);
842 ts2 >> c >> m >> yc >> k;
843 FarNam = ts2.readAll();
844 FarNam = FarNam.trimmed();
845 FarNam = FarNam.remove(0,1);
846 FarNam = FarNam.remove(FarNam.length()-1,1);
847 FarNam = FarNam.simplified();
848 QByteArray farN;
849 for (int a = 0; a < FarNam.length(); a++)
850 {
851 QChar ch = FarNam.at(a);
852 uint chc = ch.unicode();
853 if (chc > 255)
854 farN.append(chc >> 8);
855 farN.append(chc & 0x00FF);
856 }
857 FarNam = QString::fromUtf8(farN.constData());
858 cc = ScColor(qRound(255 * c), qRound(255 * m), qRound(255 * yc), qRound(255 * k));
859 cc.setSpotColor(true);
860 if (!FarNam.isEmpty())
861 CustColors.tryAddColor(FarNam, cc);
862 }
863 }
864 }
865 if ((tmp.startsWith("%%RGBCustomColor")) || (tmp.startsWith("%%RGBProcessColor")))
866 {
867 if (tmp.contains("(atend)"))
868 isAtend = true;
869 else
870 {
871 if (tmp.startsWith("%%RGBCustomColor"))
872 tmp = tmp.remove(0,17);
873 else if (tmp.startsWith("%%RGBProcessColor"))
874 tmp = tmp.remove(0,18);
875 ScTextStream ts2(&tmp, QIODevice::ReadOnly);
876 ts2 >> c >> m >> yc;
877 FarNam = ts2.readAll();
878 FarNam = FarNam.trimmed();
879 FarNam = FarNam.remove(0,1);
880 FarNam = FarNam.remove(FarNam.length()-1,1);
881 FarNam = FarNam.simplified();
882 QByteArray farN;
883 for (int a = 0; a < FarNam.length(); a++)
884 {
885 QChar ch = FarNam.at(a);
886 uint chc = ch.unicode();
887 if (chc > 255)
888 farN.append(chc >> 8);
889 farN.append(chc & 0x00FF);
890 }
891 FarNam = QString::fromUtf8(farN.constData());
892 cc = ScColor(qRound(255 * c), qRound(255 * m), qRound(255 * yc));
893 if (!FarNam.isEmpty())
894 CustColors.tryAddColor(FarNam, cc);
895 while (!ts.atEnd())
896 {
897 quint64 oldPos = ts.device()->pos();
898 tmp = readLineFromDataStream(ts);
899 if (!tmp.startsWith("%%+"))
900 {
901 ts.device()->seek(oldPos);
902 break;
903 }
904 tmp = tmp.remove(0,3);
905 ScTextStream ts2(&tmp, QIODevice::ReadOnly);
906 ts2 >> c >> m >> yc;
907 FarNam = ts2.readAll();
908 FarNam = FarNam.trimmed();
909 FarNam = FarNam.remove(0,1);
910 FarNam = FarNam.remove(FarNam.length()-1,1);
911 FarNam = FarNam.simplified();
912 QByteArray farN;
913 for (int a = 0; a < FarNam.length(); a++)
914 {
915 QChar ch = FarNam.at(a);
916 uint chc = ch.unicode();
917 if (chc > 255)
918 farN.append(chc >> 8);
919 farN.append(chc & 0x00FF);
920 }
921 FarNam = QString::fromUtf8(farN.constData());
922 cc = ScColor(qRound(255 * c), qRound(255 * m), qRound(255 * yc));
923 if (!FarNam.isEmpty())
924 CustColors.tryAddColor(FarNam, cc);
925 }
926 }
927 }
928 if (tmp.startsWith("%%EndComments"))
929 {
930 while (!ts.atEnd())
931 {
932 bool isX = false;
933 tmp = readLineFromDataStream(ts);
934 if ((tmp.endsWith("Xa") || tmp.endsWith(" k") || tmp.endsWith(" x")) && (tmp.length() > 4))
935 {
936 ScTextStream ts2(&tmp, QIODevice::ReadOnly);
937 ts2 >> c >> m >> yc >> k;
938 if (tmp.endsWith(" x"))
939 {
940 isX = true;
941 int an = tmp.indexOf("(");
942 int en = tmp.lastIndexOf(")");
943 FarNam = tmp.mid(an+1, en-an-1);
944 FarNam = FarNam.simplified();
945 QByteArray farN;
946 for (int a = 0; a < FarNam.length(); a++)
947 {
948 QChar ch = FarNam.at(a);
949 uint chc = ch.unicode();
950 if (chc > 255)
951 farN.append(chc >> 8);
952 farN.append(chc & 0x00FF);
953 }
954 FarNam = QString::fromUtf8(farN.constData());
955 }
956 tmp = readLineFromDataStream(ts);
957 if (tmp.endsWith("Pc"))
958 {
959 if (!isX)
960 {
961 tmp = tmp.trimmed();
962 tmp = tmp.remove(0,1);
963 int en = tmp.indexOf(")");
964 FarNam = tmp.mid(0, en);
965 FarNam = FarNam.simplified();
966 QByteArray farN;
967 for (int a = 0; a < FarNam.length(); a++)
968 {
969 QChar ch = FarNam.at(a);
970 uint chc = ch.unicode();
971 if (chc > 255)
972 farN.append(chc >> 8);
973 farN.append(chc & 0x00FF);
974 }
975 FarNam = QString::fromUtf8(farN.constData());
976 }
977 cc = ScColor(qRound(255 * c), qRound(255 * m), qRound(255 * yc), qRound(255 * k));
978 cc.setSpotColor(true);
979 CustColors.tryAddColor(FarNam, cc);
980 }
981 }
982 }
983 if (!isAtend)
984 break;
985 }
986 }
987 f.close();
988 if (found)
989 {
990 QStringList bb = BBox.split(" ", Qt::SkipEmptyParts);
991 if (bb.count() == 4)
992 {
993 x = ScCLocale::toDoubleC(bb[0]);
994 y = ScCLocale::toDoubleC(bb[1]);
995 b = ScCLocale::toDoubleC(bb[2]);
996 h = ScCLocale::toDoubleC(bb[3]);
997 }
998 }
999 }
1000 return found;
1001 }
1002
removeAIPrefix(QString comment)1003 QString AIPlug::removeAIPrefix(QString comment)
1004 {
1005 QString tmp;
1006 if (comment.startsWith("%AI"))
1007 {
1008 int an = comment.indexOf("_");
1009 tmp = comment.remove(0, an+1);
1010 }
1011 else
1012 tmp = comment;
1013 return tmp;
1014 }
1015
parseColor(QString data)1016 QString AIPlug::parseColor(QString data)
1017 {
1018 QString ret = CommonStrings::None;
1019 if (data.isEmpty())
1020 return ret;
1021 double c, m, y, k;
1022 ScColor tmp;
1023 ScTextStream Code(&data, QIODevice::ReadOnly);
1024 Code >> c;
1025 Code >> m;
1026 Code >> y;
1027 Code >> k;
1028 tmp.setColorF(c, m, y, k);
1029 tmp.setSpotColor(false);
1030 tmp.setRegistrationColor(false);
1031 QString namPrefix = "FromAI";
1032 QString fNam = m_Doc->PageColors.tryAddColor(namPrefix+tmp.name(), tmp);
1033 if (fNam == namPrefix+tmp.name())
1034 importedColors.append(fNam);
1035 ret = fNam;
1036 meshColorMode = 0;
1037 return ret;
1038 }
1039
parseColorGray(QString data)1040 QString AIPlug::parseColorGray(QString data)
1041 {
1042 QString ret = CommonStrings::None;
1043 if (data.isEmpty())
1044 return ret;
1045 double k;
1046 ScColor tmp;
1047 ColorList::Iterator it;
1048 ScTextStream Code(&data, QIODevice::ReadOnly);
1049 Code >> k;
1050 tmp.setColorF(0, 0, 0, 1.0 - k);
1051 tmp.setSpotColor(false);
1052 tmp.setRegistrationColor(false);
1053 QString namPrefix = "FromAI";
1054 QString fNam = m_Doc->PageColors.tryAddColor(namPrefix+tmp.name(), tmp);
1055 if (fNam == namPrefix+tmp.name())
1056 importedColors.append(fNam);
1057 ret = fNam;
1058 meshColorMode = 2;
1059 return ret;
1060 }
1061
parseColorRGB(QString data)1062 QString AIPlug::parseColorRGB(QString data)
1063 {
1064 QString ret = CommonStrings::None;
1065 if (data.isEmpty())
1066 return ret;
1067 double r, g, b;
1068 ScColor tmp;
1069 ScTextStream Code(&data, QIODevice::ReadOnly);
1070 Code >> r;
1071 Code >> g;
1072 Code >> b;
1073 tmp.setRgbColorF(r, g, b);
1074 tmp.setSpotColor(false);
1075 tmp.setRegistrationColor(false);
1076 QString namPrefix = "FromAI";
1077 QString fNam = m_Doc->PageColors.tryAddColor(namPrefix+tmp.name(), tmp);
1078 if (fNam == namPrefix+tmp.name())
1079 importedColors.append(fNam);
1080 ret = fNam;
1081 meshColorMode = 1;
1082 return ret;
1083 }
1084
parseCustomColor(QString data,double & shade)1085 QString AIPlug::parseCustomColor(QString data, double &shade)
1086 {
1087 QString ret = CommonStrings::None;
1088 if (data.isEmpty())
1089 return ret;
1090 double c, m, y, k, sh;
1091 ScColor tmp;
1092 ScTextStream Code(&data, QIODevice::ReadOnly);
1093 Code >> c;
1094 Code >> m;
1095 Code >> y;
1096 Code >> k;
1097 int an = data.indexOf("(");
1098 int en = data.lastIndexOf(")");
1099 QString FarNam = data.mid(an+1, en-an-1);
1100 FarNam.remove("\\");
1101 QString FarSha = data.mid(en+1, data.size() - en);
1102 ScTextStream Val(&FarSha, QIODevice::ReadOnly);
1103 Val >> sh;
1104 shade = (1.0 - sh) * 100.0;
1105 tmp.setColorF(c, m, y, k);
1106 tmp.setSpotColor(true);
1107 tmp.setRegistrationColor(false);
1108 QString fNam = m_Doc->PageColors.tryAddColor(FarNam, tmp);
1109 if (fNam == FarNam)
1110 importedColors.append(FarNam);
1111 ret = fNam;
1112 meshColorMode = 0;
1113 return ret;
1114 }
1115
parseCustomColorX(QString data,double & shade,const QString & type)1116 QString AIPlug::parseCustomColorX(QString data, double &shade, const QString& type)
1117 {
1118 QString ret = CommonStrings::None;
1119 if (data.isEmpty())
1120 return ret;
1121 double c, m, y, k, sh, r, g, b;
1122 ScColor tmp;
1123 ScTextStream Code(&data, QIODevice::ReadOnly);
1124 if (type == "1")
1125 {
1126 Code >> r;
1127 Code >> g;
1128 Code >> b;
1129 tmp.setRgbColorF(r, g, b);
1130 meshColorMode = 1;
1131 }
1132 else
1133 {
1134 Code >> c;
1135 Code >> m;
1136 Code >> y;
1137 Code >> k;
1138 tmp.setColorF(c, m, y, k);
1139 meshColorMode = 0;
1140 }
1141 int an = data.indexOf("(");
1142 int en = data.lastIndexOf(")");
1143 QString FarNam = data.mid(an+1, en-an-1);
1144 FarNam.remove("\\");
1145 QString FarSha = data.mid(en+1, data.size() - en);
1146 ScTextStream Val(&FarSha, QIODevice::ReadOnly);
1147 Val >> sh;
1148 shade = (1.0 - sh) * 100.0;
1149 if (type == "0")
1150 tmp.setSpotColor(true);
1151 tmp.setRegistrationColor(false);
1152 QString fNam = m_Doc->PageColors.tryAddColor(FarNam, tmp);
1153 if (fNam == FarNam)
1154 importedColors.append(FarNam);
1155 ret = fNam;
1156 return ret;
1157 }
1158
getStrings(const QString & data)1159 QStringList AIPlug::getStrings(const QString& data)
1160 {
1161 QStringList result;
1162 result.clear();
1163 QChar tmp;
1164 QString tmp2;
1165 QString tmp3;
1166 bool paran = false;
1167 bool skip = false;
1168 int digitCount = 0;
1169 for (int i = 0; i < data.count(); i++)
1170 {
1171 tmp = data[i];
1172 if (skip)
1173 {
1174 if (paran)
1175 {
1176 if (tmp.isDigit())
1177 {
1178 tmp3 += tmp;
1179 digitCount++;
1180 if (digitCount == 3)
1181 {
1182 bool ok = false;
1183 int code = tmp3.toInt(&ok, 8);
1184 if (ok)
1185 tmp2 += QChar(code);
1186 digitCount = 0;
1187 tmp3 = "";
1188 skip = false;
1189 }
1190 }
1191 else
1192 {
1193 if (tmp == 'r')
1194 tmp = SpecialChars::PARSEP;
1195 tmp2 += tmp;
1196 skip = false;
1197 }
1198 }
1199 continue;
1200 }
1201 if (tmp == '(')
1202 {
1203 paran = true;
1204 continue;
1205 }
1206 if (tmp == ')')
1207 {
1208 paran = false;
1209 result.append(tmp2);
1210 tmp2 = "";
1211 continue;
1212 }
1213 if (tmp == '\\')
1214 {
1215 skip = true;
1216 continue;
1217 }
1218 if (paran)
1219 tmp2 += tmp;
1220 }
1221 return result;
1222 }
1223
getCommands(const QString & data,QStringList & commands)1224 void AIPlug::getCommands(const QString& data, QStringList &commands)
1225 {
1226 QString tmp;
1227 QString tmp2;
1228 QString tmp3;
1229 bool paran = false;
1230 //bool arra = false;
1231 bool skip = false;
1232 for (int a = 0; a < data.count(); a++)
1233 {
1234 tmp = data[a];
1235 if (skip)
1236 {
1237 tmp2 += tmp;
1238 skip = false;
1239 continue;
1240 }
1241 if (tmp == "(")
1242 {
1243 paran = true;
1244 tmp2 += tmp;
1245 continue;
1246 }
1247 if (tmp == ")")
1248 {
1249 paran = false;
1250 tmp2 += tmp;
1251 continue;
1252 }
1253 if (tmp == "[")
1254 {
1255 // arra = true;
1256 tmp2 += tmp;
1257 continue;
1258 }
1259 if (tmp == "]")
1260 {
1261 // arra = false;
1262 tmp2 += tmp;
1263 continue;
1264 }
1265 // if (tmp == "\\")
1266 // {
1267 // skip = true;
1268 // continue;
1269 // }
1270 if (!paran)
1271 {
1272 if (tmp == " ")
1273 {
1274 tmp3 += " " + tmp2;
1275 if (commandList.contains(tmp2))
1276 {
1277 commands.append(tmp3);
1278 tmp3 = "";
1279 }
1280 tmp2 = "";
1281 continue;
1282 }
1283 }
1284 tmp2 += tmp;
1285 }
1286 if (!tmp2.isEmpty())
1287 {
1288 tmp3 += " " + tmp2;
1289 commands.append(tmp3);
1290 }
1291 }
1292
decodeA85(QByteArray & psdata,const QString & tmp)1293 void AIPlug::decodeA85(QByteArray &psdata, const QString& tmp)
1294 {
1295 uchar byte;
1296 ushort data;
1297 unsigned long sum = 0;
1298 int quintet = 0;
1299 for (int c = 0; c < tmp.length(); c++)
1300 {
1301 byte = QChar(tmp.at(c)).cell();
1302 if (byte >= '!' && byte <= 'u')
1303 {
1304 sum = sum * 85 + ((unsigned long)byte - '!');
1305 quintet++;
1306 if (quintet == 5)
1307 {
1308 psdata.resize(psdata.size()+4);
1309 data = (sum >> 24) & 0xFF;
1310 psdata[psdata.size()-4] = data;
1311 data = (sum >> 16) & 0xFF;
1312 psdata[psdata.size()-3] = data;
1313 data = (sum >> 8) & 0xFF;
1314 psdata[psdata.size()-2] = data;
1315 data = sum & 0xFF;
1316 psdata[psdata.size()-1] = data;
1317 quintet = 0;
1318 sum = 0;
1319 }
1320 }
1321 else if (byte == 'z')
1322 {
1323 psdata.resize(psdata.size()+4);
1324 psdata[psdata.size()-4] = 0;
1325 psdata[psdata.size()-3] = 0;
1326 psdata[psdata.size()-2] = 0;
1327 psdata[psdata.size()-1] = 0;
1328 }
1329 else if (byte == '~')
1330 {
1331 if (quintet)
1332 {
1333 int i;
1334 for (i = 0; i < 5 - quintet; i++)
1335 sum *= 85;
1336 if (quintet > 1)
1337 sum += (0xFFFFFF >> ((quintet - 2) * 8));
1338 for (i = 0; i < quintet - 1; i++)
1339 {
1340 data = (sum >> (24 - 8 * i)) & 0xFF;
1341 psdata.resize(psdata.size()+1);
1342 psdata[psdata.size()-1] = data;
1343 }
1344 quintet = 0;
1345 }
1346 break;
1347 }
1348 }
1349 }
1350
processData(const QString & data)1351 void AIPlug::processData(const QString& data)
1352 {
1353 double x, y, x1, y1, x2, y2;
1354 int z, tmpInt;
1355 PageItem *ite;
1356 QString command = "";
1357 QString Cdata = "";
1358 QStringList da;
1359 if (dataMode && fObjectMode)
1360 {
1361 if (data.contains("~>"))
1362 {
1363 dataString += data.midRef(1);
1364 dataMode = false;
1365 QByteArray fData;
1366 decodeA85(fData, dataString);
1367 dataString = "";
1368 if (fObjectMode)
1369 {
1370 FPoint wh = currentSpecialPath.widthHeight();
1371 if ((currentSpecialPath.size() > 3) && (wh.x() != 0.0) && (wh.y() != 0.0))
1372 {
1373 z = m_Doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, baseX, baseY, 10, 10, 0, CommonStrings::None, CommonStrings::None);
1374 ite = m_Doc->Items->at(z);
1375 ite->PoLine = currentSpecialPath.copy();
1376 ite->PoLine.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
1377 ite->ClipEdited = true;
1378 ite->FrameType = 3;
1379 ite->setFillShade(CurrFillShade);
1380 ite->setLineShade(CurrStrokeShade);
1381 ite->setFillEvenOdd(fillRule);
1382 ite->setFillTransparency(1.0 - Opacity);
1383 ite->setLineTransparency(1.0 - Opacity);
1384 ite->setFillBlendmode(blendMode);
1385 ite->setLineBlendmode(blendMode);
1386 ite->setLineEnd(CapStyle);
1387 ite->setLineJoin(JoinStyle);
1388 wh = getMaxClipF(&ite->PoLine);
1389 ite->setWidthHeight(wh.x(),wh.y());
1390 ite->setTextFlowMode(PageItem::TextFlowDisabled);
1391 m_Doc->adjustItemSize(ite);
1392 QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_ai_XXXXXX.pdf");
1393 tempFile->setAutoRemove(false);
1394 tempFile->open();
1395 tempFile->write(fData);
1396 QString imgName = getLongPathName(tempFile->fileName());
1397 tempFile->close();
1398 ite->isInlineImage = true;
1399 ite->isTempFile = true;
1400 m_Doc->loadPict(imgName, ite);
1401 delete tempFile;
1402 if (ite->imageIsAvailable)
1403 ite->setImageXYScale(ite->width() / ite->pixm.width(), ite->height() / ite->pixm.height());
1404 ite->setImageFlippedV(true);
1405 ite->Clip = flattenPath(ite->PoLine, ite->Segments);
1406 ite->setRedrawBounding();
1407 if (importerFlags & LoadSavePlugin::lfCreateDoc)
1408 ite->setLocked(itemLocked);
1409 if (patternMode)
1410 PatternElements.append(ite);
1411 else
1412 Elements.append(ite);
1413 if (groupStack.count() != 0)
1414 groupStack.top().append(ite);
1415 }
1416 }
1417 fObjectMode = false;
1418 currentSpecialPath.resize(0);
1419 currentSpecialPath.svgInit();
1420 }
1421 else
1422 {
1423 dataString += data.midRef(1);
1424 }
1425 return;
1426 }
1427 getCommands(data, da);
1428 for (int a = 0; a < da.count(); a++)
1429 {
1430 Cdata = da[a];
1431 if (((Cdata.startsWith("%")) || (Cdata.startsWith(" %"))) && (!meshMode))
1432 continue;
1433 if (Cdata.contains("SymbolInstance"))
1434 {
1435 symbolMode = true;
1436 return;
1437 }
1438 if (symbolMode)
1439 {
1440 if (Cdata.contains("SymbolRef"))
1441 {
1442 int an = Cdata.indexOf("(");
1443 int en = Cdata.lastIndexOf(")");
1444 if ((an != -1) && (en != -1))
1445 {
1446 currentSymbolName = Cdata.mid(an+1, en-an-1);
1447 currentSymbolName.remove("\\");
1448 currentSymbolName = "S_"+currentSymbolName.trimmed().simplified().replace(" ", "_");
1449 }
1450 }
1451 else if (Cdata.contains("TransformMatrix"))
1452 {
1453 ScTextStream ts2(&Cdata, QIODevice::ReadOnly);
1454 ts2 >> x >> y >> x1 >> y1 >> x2 >> y2;
1455 QTransform symTrans = QTransform(x, y, x1, y1, x2, y2);
1456 double rotation = getRotationFromMatrix(symTrans, 0.0);
1457 QTransform symT;
1458 symT.translate(x2, y2);
1459 QPointF pos1 = importedSymbols[currentSymbolName];
1460 pos1 = symT.map(pos1);
1461 double xp = pos1.x();
1462 double yp = pos1.y();
1463 // xp += m_Doc->currentPage()->xOffset();
1464 // yp += m_Doc->currentPage()->yOffset();
1465 int z = m_Doc->itemAdd(PageItem::Symbol, PageItem::Unspecified, baseX + xp, baseY + yp, 1, 1, 0, CommonStrings::None, CommonStrings::None);
1466 PageItem *b = m_Doc->Items->at(z);
1467 b->m_layerID = m_Doc->activeLayer();
1468 ScPattern pat = m_Doc->docPatterns[currentSymbolName];
1469 b->setWidth(pat.width * symTrans.m11());
1470 b->setHeight(pat.height * symTrans.m22());
1471 b->OldB2 = b->width();
1472 b->OldH2 = b->height();
1473 b->setPattern(currentSymbolName);
1474 double xoffset = 0.0, yoffset = 0.0;
1475 // if (rotation != 0.0)
1476 // {
1477 // double temp = -b->height();
1478 // xoffset = sin(-rotation) * temp;
1479 // yoffset = cos(-rotation) * temp;
1480 // }
1481 b->setXPos(xp + xoffset);
1482 b->setYPos(yp + yoffset);
1483 m_Doc->setRotationMode(3);
1484 m_Doc->rotateItem(rotation * 180 / M_PI, b);
1485 m_Doc->setRotationMode(0);
1486 // b->setRotation(rotation * 180 / M_PI);
1487 b->setTextFlowMode(PageItem::TextFlowDisabled);
1488 b->setFillTransparency(1.0 - Opacity);
1489 b->setLineTransparency(1.0 - Opacity);
1490 b->setFillBlendmode(blendMode);
1491 b->setLineBlendmode(blendMode);
1492 b->updateClip();
1493 if (patternMode)
1494 PatternElements.append(b);
1495 else
1496 Elements.append(b);
1497 if (groupStack.count() != 0)
1498 groupStack.top().append(b);
1499 symbolMode = false;
1500 }
1501 }
1502 QStringList da2 = Cdata.split(" ", Qt::SkipEmptyParts);
1503 if (da2.count() == 0)
1504 return;
1505 command = da2.last();
1506 /* Start Path construction commands */
1507 if (command == "m")
1508 {
1509 ScTextStream ts2(&Cdata, QIODevice::ReadOnly);
1510 ts2 >> x >> y;
1511 Coords.svgMoveTo(x - docX, docHeight - (y - docY));
1512 currentPoint = FPoint(x - docX, docHeight - (y - docY));
1513 }
1514 else if ((command == "L") || (command == "l"))
1515 {
1516 ScTextStream ts2(&Cdata, QIODevice::ReadOnly);
1517 ts2 >> x >> y;
1518 Coords.svgLineTo(x - docX, docHeight - (y - docY));
1519 currentPoint = FPoint(x - docX, docHeight - (y - docY));
1520 }
1521 else if ((command == "C") || (command == "c"))
1522 {
1523 ScTextStream ts2(&Cdata, QIODevice::ReadOnly);
1524 ts2 >> x >> y >> x1 >> y1 >> x2 >> y2;
1525 Coords.svgCurveToCubic(x - docX, docHeight - (y - docY),
1526 x1 - docX, docHeight - (y1 - docY),
1527 x2 - docX, docHeight - (y2 - docY));
1528 currentPoint = FPoint(x2 - docX, docHeight - (y2 - docY));
1529 }
1530 else if ((command == "Y") || (command == "y"))
1531 {
1532 ScTextStream ts2(&Cdata, QIODevice::ReadOnly);
1533 ts2 >> x1 >> y1 >> x2 >> y2;
1534 Coords.svgCurveToCubic(x1 - docX, docHeight - (y1 - docY), x2 - docX, docHeight - (y2 - docY), x2 - docX, docHeight - (y2 - docY));
1535 currentPoint = FPoint(x2 - docX, docHeight - (y2 - docY));
1536 }
1537 else if ((command == "V") || (command == "v"))
1538 {
1539 ScTextStream ts2(&Cdata, QIODevice::ReadOnly);
1540 ts2 >> x >> y >> x2 >> y2;
1541 Coords.svgCurveToCubic(currentPoint.x(), currentPoint.y(), x - docX, docHeight - (y - docY), x2 - docX, docHeight - (y2 - docY));
1542 currentPoint = FPoint(x2 - docX, docHeight - (y2 - docY));
1543 }
1544 /* End Path construction commands */
1545 /* Start Object creation commands */
1546 else if ((command == "b") || (command == "B") || (command == "f") || (command == "F") || (command == "s") || (command == "S"))
1547 {
1548 FPoint wh = Coords.widthHeight();
1549 if ((Coords.size() > 3) && (wh.x() != 0.0) && (wh.y() != 0.0))
1550 {
1551 if ((!WasU) || ((WasU) && (FirstU)))
1552 {
1553 if ((command == "B") || (command == "F") || (command == "S"))
1554 {
1555 if (command == "F")
1556 z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColorFill, CommonStrings::None);
1557 else if (command == "B")
1558 z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColorFill, CurrColorStroke);
1559 else
1560 z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CommonStrings::None, CurrColorStroke);
1561 }
1562 else
1563 {
1564 if (command == "f")
1565 z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColorFill, CommonStrings::None);
1566 else if (command == "b")
1567 z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColorFill, CurrColorStroke);
1568 else
1569 z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CommonStrings::None, CurrColorStroke);
1570 }
1571 ite = m_Doc->Items->at(z);
1572 ite->PoLine = Coords.copy();
1573 ite->PoLine.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
1574 ite->ClipEdited = true;
1575 ite->FrameType = 3;
1576 ite->setFillShade(CurrFillShade);
1577 ite->setLineShade(CurrStrokeShade);
1578 ite->setFillEvenOdd(fillRule);
1579 ite->setFillTransparency(1.0 - Opacity);
1580 ite->setLineTransparency(1.0 - Opacity);
1581 ite->setFillBlendmode(blendMode);
1582 ite->setLineBlendmode(blendMode);
1583 if (!currentPatternName.isEmpty())
1584 {
1585 ite->setPattern(currentPatternName);
1586 ite->setPatternTransform(currentPatternXScale * 100, currentPatternYScale * 100, currentPatternX, currentPatternY, currentPatternRotation, 0.0, 0.0);
1587 ite->GrType = Gradient_Pattern;
1588 currentPatternName.clear();
1589 }
1590 if (!currentStrokePatternName.isEmpty())
1591 {
1592 ite->setStrokePattern(currentStrokePatternName);
1593 ite->setStrokePatternTransform(currentStrokePatternXScale * 100, currentStrokePatternYScale * 100, currentStrokePatternX, currentStrokePatternY, currentStrokePatternRotation, 0.0, 0.0, 1.0);
1594 currentStrokePatternName.clear();
1595 }
1596 ite->setLineEnd(CapStyle);
1597 ite->setLineJoin(JoinStyle);
1598 if (!WasU)
1599 {
1600 FPoint wh = getMaxClipF(&ite->PoLine);
1601 ite->setWidthHeight(wh.x(),wh.y());
1602 ite->setTextFlowMode(PageItem::TextFlowDisabled);
1603 m_Doc->adjustItemSize(ite);
1604 }
1605 if (patternMode)
1606 PatternElements.append(ite);
1607 else
1608 Elements.append(ite);
1609 if (groupStack.count() != 0)
1610 groupStack.top().append(ite);
1611 if (importerFlags & LoadSavePlugin::lfCreateDoc)
1612 ite->setLocked(itemLocked);
1613
1614 }
1615 else if (m_Doc->Items->count() > 0)
1616 {
1617 ite = m_Doc->Items->last();
1618 ite->PoLine.setMarker();
1619 Coords.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
1620 ite->PoLine.putPoints(ite->PoLine.size(), Coords.size(), Coords);
1621 }
1622 FirstU = false;
1623 itemRendered = true;
1624 CurrFillShade = 100.0;
1625 CurrStrokeShade = 100.0;
1626 }
1627 Coords.resize(0);
1628 Coords.svgInit();
1629 }
1630 else if (command == "*u")
1631 {
1632 FirstU = true;
1633 WasU = true;
1634 }
1635 else if (command == "*U")
1636 {
1637 if (m_Doc->Items->count() > 0)
1638 {
1639 WasU = false;
1640 ite = m_Doc->Items->last();
1641 FPoint wh = getMaxClipF(&ite->PoLine);
1642 ite->setWidthHeight(wh.x(),wh.y());
1643 m_Doc->adjustItemSize(ite);
1644 }
1645 }
1646 else if ((command == "u") || (command == "q"))
1647 {
1648 QList<PageItem*> gElements;
1649 groupStack.push(gElements);
1650 clipStack.push(clipCoords);
1651 }
1652 else if ((command == "U") || (command == "Q"))
1653 {
1654 if (groupStack.count() != 0)
1655 {
1656 QList<PageItem*> gElements = groupStack.pop();
1657 clipCoords = clipStack.pop();
1658 tmpSel->clear();
1659 if (gElements.count() > 0)
1660 {
1661 for (int dre = 0; dre < gElements.count(); ++dre)
1662 {
1663 tmpSel->addItem(gElements.at(dre), true);
1664 if (patternMode)
1665 PatternElements.removeAll(gElements.at(dre));
1666 else
1667 Elements.removeAll(gElements.at(dre));
1668 }
1669 ite = m_Doc->groupObjectsSelection(tmpSel);
1670 if ((clipCoords.size() > 4) && (command == "Q"))
1671 {
1672 clipCoords.translate(m_Doc->currentPage()->xOffset()-ite->xPos(), m_Doc->currentPage()->yOffset()-ite->yPos());
1673 ite->PoLine = clipCoords.copy();
1674 ite->PoLine.translate(baseX, baseY);
1675 }
1676 for (int as = 0; as < tmpSel->count(); ++as)
1677 {
1678 if (patternMode)
1679 PatternElements.append(tmpSel->itemAt(as));
1680 else
1681 Elements.append(tmpSel->itemAt(as));
1682 }
1683 }
1684 if (groupStack.count() != 0)
1685 {
1686 for (int as = 0; as < tmpSel->count(); ++as)
1687 {
1688 groupStack.top().append(tmpSel->itemAt(as));
1689 }
1690 }
1691 tmpSel->clear();
1692 }
1693 if (command == "Q")
1694 {
1695 clipCoords.resize(0);
1696 clipCoords.svgInit();
1697 }
1698 }
1699 else if (command == "W")
1700 {
1701 if (clipStack.count() != 0)
1702 {
1703 if (clipStack.top().size() > 3)
1704 {
1705 clipStack.top().setMarker();
1706 clipStack.top().putPoints(clipStack.top().size(), Coords.size(), Coords);
1707 }
1708 else
1709 clipStack.top() = Coords.copy();
1710 }
1711 }
1712 else if ((command == "N") || (command == "n"))
1713 {
1714 if (command == "n")
1715 Coords.svgClosePath();
1716 currentSpecialPath = Coords.copy();
1717 Coords.resize(0);
1718 Coords.svgInit();
1719 }
1720 /* End Object construction commands */
1721 /* Start Graphics state commands */
1722 else if (command == "A")
1723 {
1724 ScTextStream ts2(&Cdata, QIODevice::ReadOnly);
1725 ts2 >> tmpInt;
1726 if (tmpInt == 1)
1727 itemLocked = true;
1728 else
1729 itemLocked = false;
1730 }
1731 else if (command == "w")
1732 {
1733 ScTextStream ts2(&Cdata, QIODevice::ReadOnly);
1734 ts2 >> LineW;
1735 }
1736 else if (command == "j")
1737 {
1738 ScTextStream ts2(&Cdata, QIODevice::ReadOnly);
1739 ts2 >> tmpInt;
1740 if (tmpInt == 0)
1741 JoinStyle = Qt::MiterJoin;
1742 else if (tmpInt == 1)
1743 JoinStyle = Qt::RoundJoin;
1744 else if (tmpInt == 2)
1745 JoinStyle = Qt::BevelJoin;
1746 }
1747 else if (command == "J")
1748 {
1749 ScTextStream ts2(&Cdata, QIODevice::ReadOnly);
1750 ts2 >> tmpInt;
1751 if (tmpInt == 0)
1752 CapStyle = Qt::FlatCap;
1753 else if (tmpInt == 1)
1754 CapStyle = Qt::RoundCap;
1755 else if (tmpInt == 2)
1756 CapStyle = Qt::SquareCap;
1757 }
1758 /* undocumented Command Xy
1759 - has up to 5 Parameters
1760 - first Parameter might be the Blendmode
1761 - second Parameter is the Opacity
1762 */
1763 else if (command == "Xy")
1764 {
1765 ScTextStream ts2(&Cdata, QIODevice::ReadOnly);
1766 int mode = 0;
1767 ts2 >> mode >> Opacity;
1768 // Adjusting blendmodes, taken from the PDF importer
1769 switch (mode)
1770 {
1771 default:
1772 case 0:
1773 blendMode = 0;
1774 break;
1775 case 4:
1776 blendMode = 1;
1777 break;
1778 case 5:
1779 blendMode = 2;
1780 break;
1781 case 1:
1782 blendMode = 3;
1783 break;
1784 case 2:
1785 blendMode = 4;
1786 break;
1787 case 3:
1788 blendMode = 5;
1789 break;
1790 case 8:
1791 blendMode = 6;
1792 break;
1793 case 9:
1794 blendMode = 7;
1795 break;
1796 case 10:
1797 blendMode = 8;
1798 break;
1799 case 11:
1800 blendMode = 9;
1801 break;
1802 case 6:
1803 blendMode = 10;
1804 break;
1805 case 7:
1806 blendMode = 11;
1807 break;
1808 case 12:
1809 blendMode = 12;
1810 break;
1811 case 13:
1812 blendMode = 13;
1813 break;
1814 case 14:
1815 blendMode = 14;
1816 break;
1817 case 15:
1818 blendMode = 15;
1819 break;
1820 }
1821 }
1822 else if (command == "XR")
1823 {
1824 ScTextStream ts2(&Cdata, QIODevice::ReadOnly);
1825 ts2 >> tmpInt;
1826 if (tmpInt == 1)
1827 fillRule = true;
1828 else
1829 fillRule = false;
1830 }
1831 else if (command == "Bb")
1832 {
1833 gradientMode = true;
1834 wasBC = false;
1835 itemRendered = false;
1836 startMatrix = QTransform();
1837 endMatrix = QTransform();
1838 }
1839 else if (command == "Xm")
1840 {
1841 ScTextStream gVals(&Cdata, QIODevice::ReadOnly);
1842 double m1, m2, m3, m4, m5, m6;
1843 gVals >> m1 >> m2 >> m3 >> m4 >> m5 >> m6;
1844 startMatrix.translate(m5, -m6);
1845 endMatrix.scale(m1, m4);
1846 wasBC = true;
1847 }
1848 else if (command == "Bm")
1849 {
1850 if (m_gradients[currentGradientName].type() == 1)
1851 {
1852 ScTextStream gVals(&Cdata, QIODevice::ReadOnly);
1853 double m1, m2, m3, m4, m5, m6;
1854 gVals >> m1 >> m2 >> m3 >> m4 >> m5 >> m6;
1855 startMatrix.translate(m5, -m6);
1856 // endMatrix.scale(m1, m4);
1857 endMatrix *= QTransform(m1, m2, m3, m4, 0, 0);
1858 // endMatrix = QTransform(m1, m2, m3, m4, m5, m6);
1859 wasBC = true;
1860 }
1861 }
1862 else if (command == "BB")
1863 {
1864 if (itemRendered)
1865 {
1866 gradientMode = false;
1867 ite = m_Doc->Items->last();
1868 ite->fill_gradient = m_gradients[currentGradientName];
1869 ite->setGradient(currentGradientName);
1870 if (ite->fill_gradient.type() == 0)
1871 ite->GrType = Gradient_Linear;
1872 else
1873 ite->GrType = Gradient_Radial;
1874 QTransform m1;
1875 m1.translate(currentGradientOrigin.x() - ite->xPos(), currentGradientOrigin.y() - ite->yPos());
1876 m1.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
1877 m1.rotate(-currentGradientAngle);
1878 ite->GrStartX = currentGradientOrigin.x() - ite->xPos() + m_Doc->currentPage()->xOffset();
1879 ite->GrStartY = currentGradientOrigin.y() - ite->yPos() + m_Doc->currentPage()->yOffset();
1880 QPointF target = m1.map(QPointF(currentGradientLength, 0.0));
1881 ite->GrEndX = target.x();
1882 ite->GrEndY = target.y();
1883 if (wasBC)
1884 {
1885 QPointF newS = startMatrix.map(QPointF(ite->GrStartX, ite->GrStartY));
1886 ite->GrStartX = newS.x();
1887 ite->GrStartY = newS.y();
1888 QTransform m2;
1889 m2.rotate(-currentGradientAngle);
1890 m2 *= endMatrix;
1891 QPointF target = m2.map(QPointF(currentGradientLength, 0.0));
1892 ite->GrEndX = target.x();
1893 ite->GrEndY = target.y();
1894 }
1895 }
1896 wasBC = false;
1897 currentGradientMatrix = QTransform();
1898 currentGradientOrigin = QPointF(0.0, 0.0);
1899 currentGradientAngle = 0.0;
1900 currentGradientLength = 1.0;
1901 itemRendered = false;
1902 }
1903 else if (command == "Bg")
1904 {
1905 int an = Cdata.indexOf("(");
1906 int en = Cdata.lastIndexOf(")");
1907 currentGradientName = Cdata.mid(an+1, en-an-1);
1908 currentGradientName.remove("\\");
1909 QString tmpS = Cdata.mid(en+1, Cdata.size() - en);
1910 ScTextStream gVals(&tmpS, QIODevice::ReadOnly);
1911 double xOrig, yOrig, m1, m2, m3, m4, m5, m6;
1912 gVals >> xOrig >> yOrig >> currentGradientAngle >> currentGradientLength >> m1 >> m2 >> m3 >> m4 >> m5 >> m6;
1913 currentGradientOrigin = QPointF(xOrig - docX, docHeight - (yOrig - docY));
1914 currentGradientMatrix = QTransform(m1, m2, m3, m4, m5, m6);
1915 }
1916 /* End Graphics state commands */
1917 /* Start Color commands */
1918 else if ((command == "G") || (command == "g"))
1919 {
1920 if (command == "G")
1921 CurrColorStroke = parseColorGray(Cdata);
1922 else
1923 CurrColorFill = parseColorGray(Cdata);
1924 meshColorMode = 2;
1925 }
1926 else if ((command == "K") || (command == "k"))
1927 {
1928 if (command == "K")
1929 CurrColorStroke = parseColor(Cdata);
1930 else
1931 CurrColorFill = parseColor(Cdata);
1932 }
1933 else if ((command == "XA") || (command == "Xa"))
1934 {
1935 QString Xdata = da2[da2.count()-4] + " " + da2[da2.count()-3] + " " + da2[da2.count()-2];
1936 if (command == "XA")
1937 CurrColorStroke = parseColorRGB(Xdata);
1938 else
1939 CurrColorFill = parseColorRGB(Xdata);
1940 meshColorMode = 1;
1941 }
1942 else if ((command == "XX") || (command == "Xx") || (command == "Xk"))
1943 {
1944 if (command == "XX")
1945 CurrColorStroke = parseCustomColorX(Cdata, CurrStrokeShade, da2[da2.count()-2]);
1946 else
1947 CurrColorFill = parseCustomColorX(Cdata, CurrFillShade, da2[da2.count()-2]);
1948 }
1949 else if ((command == "X") || (command == "x"))
1950 {
1951 if (command == "X")
1952 CurrColorStroke = parseCustomColor(Cdata, CurrStrokeShade);
1953 else
1954 CurrColorFill = parseCustomColor(Cdata, CurrFillShade);
1955 }
1956 else if (command == "p")
1957 {
1958 int an = Cdata.indexOf("(");
1959 int en = Cdata.lastIndexOf(")");
1960 currentPatternName = Cdata.mid(an+1, en-an-1);
1961 currentPatternName.remove("\\");
1962 currentPatternName = currentPatternName.trimmed().simplified().replace(" ", "_");
1963 QString tmpS = Cdata.mid(en+1, Cdata.size() - en);
1964 ScTextStream gVals(&tmpS, QIODevice::ReadOnly);
1965 gVals >> currentPatternX >> currentPatternY >> currentPatternXScale >> currentPatternYScale >> currentPatternRotation;
1966 }
1967 else if (command == "P")
1968 {
1969 int an = Cdata.indexOf("(");
1970 int en = Cdata.lastIndexOf(")");
1971 currentStrokePatternName = Cdata.mid(an+1, en-an-1);
1972 currentStrokePatternName.remove("\\");
1973 currentStrokePatternName = currentPatternName.trimmed().simplified().replace(" ", "_");
1974 QString tmpS = Cdata.mid(en+1, Cdata.size() - en);
1975 ScTextStream gVals(&tmpS, QIODevice::ReadOnly);
1976 gVals >> currentStrokePatternX >> currentStrokePatternY >> currentStrokePatternXScale >> currentStrokePatternYScale >> currentStrokePatternRotation;
1977 }
1978 else if (command == "X!")
1979 {
1980 if (Cdata.contains("/Mesh"))
1981 {
1982 meshMode = true;
1983 meshNodeCounter = 0;
1984 // meshColorMode = 0;
1985 meshGradientArray.clear();
1986 }
1987 if (Cdata.contains("/End"))
1988 {
1989 meshMode = false;
1990 if (meshGradientArray.count() != 0)
1991 {
1992 z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, CommonStrings::None, CommonStrings::None);
1993 ite = m_Doc->Items->at(z);
1994 for (int x = 0; x < meshGradientArray.count(); x++)
1995 {
1996 for (int y = 0; y < meshGradientArray[x].count(); y++)
1997 {
1998 meshGradientArray[x][y].moveRel(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
1999 }
2000 }
2001 ite->meshGradientArray = meshGradientArray;
2002 ite->GrType = Gradient_Mesh;
2003 ite->meshToShape();
2004 for (int grow = 0; grow < ite->meshGradientArray.count(); grow++)
2005 {
2006 for (int gcol = 0; gcol < ite->meshGradientArray[grow].count(); gcol++)
2007 {
2008 MeshPoint mp = ite->meshGradientArray[grow][gcol];
2009 ite->setMeshPointColor(grow, gcol, mp.colorName, mp.shade, mp.transparency);
2010 }
2011 }
2012 ite->setFillShade(CurrFillShade);
2013 ite->setLineShade(CurrFillShade);
2014 ite->setFillEvenOdd(fillRule);
2015 ite->setFillTransparency(1.0 - Opacity);
2016 ite->setLineTransparency(1.0 - Opacity);
2017 ite->setFillBlendmode(blendMode);
2018 ite->setLineBlendmode(blendMode);
2019 ite->setLineEnd(CapStyle);
2020 ite->setLineJoin(JoinStyle);
2021 if (importerFlags & LoadSavePlugin::lfCreateDoc)
2022 ite->setLocked(itemLocked);
2023 if (patternMode)
2024 PatternElements.append(ite);
2025 else
2026 Elements.append(ite);
2027 if (groupStack.count() != 0)
2028 groupStack.top().append(ite);
2029 }
2030 }
2031 }
2032 else if (command == "X#")
2033 {
2034 int an = Cdata.indexOf("_");
2035 QString cmdLine = Cdata.remove(0, an+1);
2036 an = cmdLine.lastIndexOf("/");
2037 QString tmpS = cmdLine.mid(an+1, Cdata.size());
2038 ScTextStream mVals(&tmpS, QIODevice::ReadOnly);
2039 QString mKey;
2040 mVals >> mKey;
2041 if (mKey == "Size")
2042 {
2043 meshGradientArray.clear();
2044 int ans = cmdLine.indexOf("[");
2045 int ens = cmdLine.lastIndexOf("]");
2046 QString sizeVals = cmdLine.mid(ans+1, ens-ans-1);
2047 ScTextStream mVals2(&sizeVals, QIODevice::ReadOnly);
2048 mVals2 >> meshXSize >> meshYSize;
2049 for (int mgr = 0; mgr < meshYSize+1; mgr++)
2050 {
2051 QList<MeshPoint> ml;
2052 for (int mgc = 0; mgc < meshXSize+1; mgc++)
2053 {
2054 MeshPoint mp;
2055 ml.append(mp);
2056 }
2057 meshGradientArray.append(ml);
2058 }
2059 }
2060 if (mKey == "P")
2061 {
2062 int ans = cmdLine.indexOf("[");
2063 int ens = cmdLine.lastIndexOf("]");
2064 QString posVals = cmdLine.mid(ans+1, ens-ans-1);
2065 ScTextStream mVals3(&posVals, QIODevice::ReadOnly);
2066 mVals3 >> currentMeshXPos >> currentMeshYPos;
2067 }
2068 if (mKey == "CS")
2069 {
2070 if (Cdata.contains("CMYK"))
2071 meshColorMode = 0;
2072 else if (Cdata.contains("RGB"))
2073 meshColorMode = 1;
2074 else if (Cdata.contains("Gray"))
2075 meshColorMode = 2;
2076 }
2077 if (mKey == "E")
2078 {
2079 int indY = meshYSize - currentMeshYPos - 1;
2080 int indX = currentMeshXPos;
2081 meshGradientArray[indY+1][indX+1].gridPoint = FPoint(meshNode2PointX, meshNode2PointY);
2082 meshGradientArray[indY+1][indX+1].controlTop = FPoint(meshNode2Control2X, meshNode2Control2Y);
2083 meshGradientArray[indY+1][indX+1].controlLeft = FPoint(meshNode2Control1X, meshNode2Control1Y);
2084 meshGradientArray[indY+1][indX+1].colorName = meshColor2;
2085 meshGradientArray[indY+1][indX+1].shade = 100;
2086 meshGradientArray[indY+1][indX+1].transparency = 1.0;
2087 meshGradientArray[indY+1][indX].gridPoint = FPoint(meshNode1PointX, meshNode1PointY);
2088 meshGradientArray[indY+1][indX].controlRight = FPoint(meshNode1Control2X, meshNode1Control2Y);
2089 meshGradientArray[indY+1][indX].controlTop = FPoint(meshNode1Control1X, meshNode1Control1Y);
2090 meshGradientArray[indY+1][indX].colorName = meshColor1;
2091 meshGradientArray[indY+1][indX].shade = 100;
2092 meshGradientArray[indY+1][indX].transparency = 1.0;
2093 meshGradientArray[indY][indX].gridPoint = FPoint(meshNode4PointX, meshNode4PointY);
2094 meshGradientArray[indY][indX].controlBottom = FPoint(meshNode4Control2X, meshNode4Control2Y);
2095 meshGradientArray[indY][indX].controlRight = FPoint(meshNode4Control1X, meshNode4Control1Y);
2096 meshGradientArray[indY][indX].colorName = meshColor4;
2097 meshGradientArray[indY][indX].shade = 100;
2098 meshGradientArray[indY][indX].transparency = 1.0;
2099 meshGradientArray[indY][indX+1].gridPoint = FPoint(meshNode3PointX, meshNode3PointY);
2100 meshGradientArray[indY][indX+1].controlLeft = FPoint(meshNode3Control2X, meshNode3Control2Y);
2101 meshGradientArray[indY][indX+1].controlBottom = FPoint(meshNode3Control1X, meshNode3Control1Y);
2102 meshGradientArray[indY][indX+1].colorName = meshColor3;
2103 meshGradientArray[indY][indX+1].shade = 100;
2104 meshGradientArray[indY][indX+1].transparency = 1.0;
2105 meshNodeCounter = 0;
2106 }
2107 if (mKey == "N")
2108 {
2109 double cVal {0.0}, mVal {0.0}, yVal {0.0}, kVal {0.0}, coorX1 {0.0}, coorY1 {0.0}, coorX2 {0.0}, coorY2 {0.0}, coorX3 {0.0}, coorY3 {0.0};
2110 int dummy {0};
2111 meshNodeCounter++;
2112 int ans = cmdLine.indexOf("[");
2113 int ens = cmdLine.lastIndexOf("]");
2114 QString nodeVals = cmdLine.mid(ans+1, ens-ans-1);
2115 ScTextStream mVals4(&nodeVals, QIODevice::ReadOnly);
2116 cVal = 0.0;
2117 mVal = 0.0;
2118 yVal = 0.0;
2119 kVal = 0.0;
2120 if (meshColorMode == 0)
2121 mVals4 >> cVal >> mVal >> yVal >> kVal >> coorX1 >> coorY1 >> coorX2 >> coorY2 >> dummy >> coorX3 >> coorY3;
2122 else if (meshColorMode == 1)
2123 mVals4 >> cVal >> mVal >> yVal >> coorX1 >> coorY1 >> coorX2 >> coorY2 >> dummy >> coorX3 >> coorY3;
2124 else if (meshColorMode == 2)
2125 mVals4 >> cVal >> coorX1 >> coorY1 >> coorX2 >> coorY2 >> dummy >> coorX3 >> coorY3;
2126 QString nodeColor;
2127 ScColor tmpColor;
2128 ColorList::Iterator it;
2129 int Cc = qRound(cVal * 255);
2130 int Mc = qRound(mVal * 255);
2131 int Yc = qRound(yVal * 255);
2132 int Kc = qRound(kVal * 255);
2133 int hC, hM, hY, hK;
2134 bool found = false;
2135 if (meshColorMode == 0)
2136 {
2137 tmpColor.setColor(Cc, Mc, Yc, Kc);
2138 for (it = m_Doc->PageColors.begin(); it != m_Doc->PageColors.end(); ++it)
2139 {
2140 if (it.value().getColorModel() == colorModelCMYK)
2141 {
2142 it.value().getCMYK(&hC, &hM, &hY, &hK);
2143 if ((Cc == hC) && (Mc == hM) && (Yc == hY) && (Kc == hK))
2144 {
2145 nodeColor = it.key();
2146 found = true;
2147 break;
2148 }
2149 }
2150 }
2151 }
2152 else if (meshColorMode == 1)
2153 {
2154 tmpColor.setRgbColor(Cc, Mc, Yc);
2155 for (it = m_Doc->PageColors.begin(); it != m_Doc->PageColors.end(); ++it)
2156 {
2157 if (it.value().getColorModel() == colorModelRGB)
2158 {
2159 it.value().getRGB(&hC, &hM, &hY);
2160 if ((Cc == hC) && (Mc == hM) && (Yc == hY))
2161 {
2162 nodeColor = it.key();
2163 found = true;
2164 break;
2165 }
2166 }
2167 }
2168 }
2169 else if (meshColorMode == 2)
2170 {
2171 tmpColor.setColor(0, 0, 0, Cc);
2172 for (it = m_Doc->PageColors.begin(); it != m_Doc->PageColors.end(); ++it)
2173 {
2174 if (it.value().getColorModel() == colorModelCMYK)
2175 {
2176 it.value().getCMYK(&hC, &hM, &hY, &hK);
2177 if ((Cc == hC) && (Mc == hM) && (Yc == hY) && (Kc == hK))
2178 {
2179 nodeColor = it.key();
2180 found = true;
2181 break;
2182 }
2183 }
2184 }
2185 }
2186 if (!found)
2187 {
2188 tmpColor.setSpotColor(false);
2189 tmpColor.setRegistrationColor(false);
2190 QString namPrefix = "FromAI";
2191 m_Doc->PageColors.insert(namPrefix+tmpColor.name(), tmpColor);
2192 nodeColor = namPrefix+tmpColor.name();
2193 }
2194 if (meshNodeCounter == 1)
2195 {
2196 meshNode1PointX = coorX1 - docX;
2197 meshNode1PointY = docHeight - (coorY1 - docY);
2198 meshNode1Control2X = coorX2 - docX;
2199 meshNode1Control2Y = docHeight - (coorY2 - docY);
2200 meshNode1Control1X = coorX3 - docX;
2201 meshNode1Control1Y = docHeight - (coorY3 - docY);
2202 meshColor1 = nodeColor;
2203 }
2204 if (meshNodeCounter == 2)
2205 {
2206 meshNode2PointX = coorX1 - docX;
2207 meshNode2PointY = docHeight - (coorY1 - docY);
2208 meshNode2Control2X = coorX2 - docX;
2209 meshNode2Control2Y = docHeight - (coorY2 - docY);
2210 meshNode2Control1X = coorX3 - docX;
2211 meshNode2Control1Y = docHeight - (coorY3 - docY);
2212 meshColor2 = nodeColor;
2213 }
2214 if (meshNodeCounter == 3)
2215 {
2216 meshNode3PointX = coorX1 - docX;
2217 meshNode3PointY = docHeight - (coorY1 - docY);
2218 meshNode3Control2X = coorX2 - docX;
2219 meshNode3Control2Y = docHeight - (coorY2 - docY);
2220 meshNode3Control1X = coorX3 - docX;
2221 meshNode3Control1Y = docHeight - (coorY3 - docY);
2222 meshColor3 = nodeColor;
2223 }
2224 if (meshNodeCounter == 4)
2225 {
2226 meshNode4PointX = coorX1 - docX;
2227 meshNode4PointY = docHeight - (coorY1 - docY);
2228 meshNode4Control2X = coorX2 - docX;
2229 meshNode4Control2Y = docHeight - (coorY2 - docY);
2230 meshNode4Control1X = coorX3 - docX;
2231 meshNode4Control1Y = docHeight - (coorY3 - docY);
2232 meshColor4 = nodeColor;
2233 }
2234 }
2235 }
2236 /* End Color commands */
2237 /* Start Layer commands */
2238 else if (command == "Lb")
2239 {
2240 if (importerFlags & LoadSavePlugin::lfCreateDoc)
2241 {
2242 int visible, preview, enabled, printing, dummy, rc, gc, bc;
2243 ScTextStream ts2(&Cdata, QIODevice::ReadOnly);
2244 ts2 >> visible >> preview >> enabled >> printing >> dummy >> dummy >> dummy >> rc >> gc >> bc;
2245 if (!firstLayer)
2246 currentLayer = m_Doc->addLayer("Layer", true);
2247 m_Doc->setLayerVisible(currentLayer, static_cast<bool>(visible));
2248 m_Doc->setLayerOutline(currentLayer, static_cast<bool>(!preview));
2249 m_Doc->setLayerLocked(currentLayer, static_cast<bool>(!enabled));
2250 m_Doc->setLayerPrintable(currentLayer, static_cast<bool>(printing));
2251 m_Doc->setLayerMarker(currentLayer, QColor(rc, gc, bc));
2252 QList<PageItem*> gElements;
2253 groupStack.push(gElements);
2254 clipStack.push(clipCoords);
2255 firstLayer = false;
2256 }
2257 Coords.resize(0);
2258 Coords.svgInit();
2259 }
2260 else if (command == "LB")
2261 {
2262 if (importerFlags & LoadSavePlugin::lfCreateDoc)
2263 {
2264 if (groupStack.count() != 0)
2265 {
2266 QList<PageItem*> gElements = groupStack.pop();
2267 clipStack.pop();
2268 tmpSel->clear();
2269 if (gElements.count() > 0)
2270 {
2271 for (int dre = 0; dre < gElements.count(); ++dre)
2272 {
2273 tmpSel->addItem(gElements.at(dre), true);
2274 if (patternMode)
2275 PatternElements.removeAll(gElements.at(dre));
2276 else
2277 Elements.removeAll(gElements.at(dre));
2278 }
2279 m_Doc->groupObjectsSelection(tmpSel);
2280 ite = tmpSel->itemAt(0);
2281 if (Coords.size() > 3)
2282 {
2283 Coords.translate(m_Doc->currentPage()->xOffset()-ite->xPos(), m_Doc->currentPage()->yOffset()-ite->yPos());
2284 ite->PoLine = Coords.copy();
2285 ite->PoLine.translate(baseX, baseY);
2286 }
2287 for (int as = 0; as < tmpSel->count(); ++as)
2288 {
2289 if (patternMode)
2290 PatternElements.append(tmpSel->itemAt(as));
2291 else
2292 Elements.append(tmpSel->itemAt(as));
2293 }
2294 ite->setItemName( tr("Group%1").arg(m_Doc->layerName(currentLayer)));
2295 }
2296 if (groupStack.count() != 0)
2297 {
2298 for (int as = 0; as < tmpSel->count(); ++as)
2299 {
2300 groupStack.top().append(tmpSel->itemAt(as));
2301 }
2302 }
2303 tmpSel->clear();
2304 }
2305 }
2306 Coords.resize(0);
2307 Coords.svgInit();
2308 }
2309 else if (command == "Ln")
2310 {
2311 if (importerFlags & LoadSavePlugin::lfCreateDoc)
2312 {
2313 int an = Cdata.indexOf("(");
2314 int en = Cdata.lastIndexOf(")");
2315 QString LayerNam = Cdata.mid(an+1, en-an-1);
2316 LayerNam.remove("\\");
2317 m_Doc->changeLayerName(currentLayer, LayerNam);
2318 }
2319 }
2320 /* End Layer commands */
2321 /* Start Text commands */
2322 else if (command == "To")
2323 {
2324 ScTextStream ts2(&Cdata, QIODevice::ReadOnly);
2325 ts2 >> textMode;
2326 textData.clear();
2327 textMatrix = QTransform();
2328 maxWidth = 0;
2329 tempW = 0;
2330 maxHeight = 0;
2331 textKern = 0;
2332 startCurrentTextRange = 0;
2333 endCurrentTextRange = 0;
2334 textScaleH = 1000;
2335 textScaleV = 1000;
2336 }
2337 else if (command == "Tp")
2338 {
2339 ScTextStream gVals(&Cdata, QIODevice::ReadOnly);
2340 double m1, m2, m3, m4, m5, m6;
2341 gVals >> m1 >> m2 >> m3 >> m4 >> m5 >> m6;
2342 textMatrix = QTransform(m1, m2, m3, m4, m5, m6);
2343 }
2344 else if (command == "Tx") // || (command == "TX"))
2345 {
2346 QStringList res = getStrings(Cdata);
2347 if (res.count() > 0)
2348 {
2349 QString tex = res[0];
2350 double tempH = 0;
2351 startCurrentTextRange = textData.length();
2352 for (int tt = 0; tt < tex.length(); ++tt)
2353 {
2354 CharStyle nstyle;
2355 QString ch = tex.mid(tt,1);
2356 nstyle.setFont((*m_Doc->AllFonts)[textFont]);
2357 nstyle.setFontSize(textSize);
2358 nstyle.setFillColor(CurrColorFill);
2359 nstyle.setTracking(textKern);
2360 nstyle.setFillShade(100);
2361 nstyle.setStrokeColor(CurrColorStroke);
2362 nstyle.setStrokeShade(100);
2363 nstyle.setScaleH(textScaleH);
2364 nstyle.setScaleV(textScaleV);
2365 nstyle.setBaselineOffset(0);
2366 nstyle.setShadowXOffset(50);
2367 nstyle.setShadowYOffset(-50);
2368 nstyle.setOutlineWidth(10);
2369 nstyle.setUnderlineOffset(-1);
2370 nstyle.setUnderlineWidth(-1);
2371 nstyle.setStrikethruOffset(-1);
2372 nstyle.setStrikethruWidth(-1);
2373 nstyle.setFeatures(StyleFlag(ScStyle_Default).featureList());
2374 int pot = textData.length();
2375 textData.insertChars(pot, ch);
2376 textData.applyCharStyle(pot, 1, nstyle);
2377 // FIXME HOST: This code does not handle CTL!
2378 ScFace::gid_type gid = nstyle.font().char2CMap(ch.toUcs4()[0]);
2379 tempW += nstyle.font().glyphBBox(gid, nstyle.fontSize() / 10.0).width + 1;
2380 tempH = qMax(tempH, nstyle.font().height(nstyle.fontSize() / 10.0) + 2.0);
2381 maxWidth = qMax(tempW, maxWidth);
2382 maxHeight = qMax(tempH, maxHeight);
2383 if ((ch == SpecialChars::PARSEP) || (ch == SpecialChars::LINEBREAK))
2384 {
2385 maxHeight += nstyle.font().height(nstyle.fontSize() / 10.0);
2386 tempW = 0;
2387 }
2388 endCurrentTextRange = pot;
2389 }
2390 }
2391 }
2392 else if (command == "Tk")
2393 {
2394 int flag;
2395 double val;
2396 ScTextStream gVals(&Cdata, QIODevice::ReadOnly);
2397 gVals >> flag >> val;
2398 if (flag == 1)
2399 val = 0;
2400 double oldval = textData.charStyle(startCurrentTextRange).tracking();
2401 CharStyle nstyle = textData.charStyle(startCurrentTextRange);
2402 nstyle.setTracking(oldval + val);
2403 textData.applyCharStyle(startCurrentTextRange, 1, nstyle);
2404 }
2405 else if (command == "Tc")
2406 {
2407 ScTextStream gVals(&Cdata, QIODevice::ReadOnly);
2408 gVals >> textKern;
2409 textKern *= 100.0;
2410 }
2411 else if (command == "Tz")
2412 {
2413 ScTextStream gVals(&Cdata, QIODevice::ReadOnly);
2414 gVals >> textScaleH >> textScaleV;
2415 textScaleH *= 10.0;
2416 textScaleV *= 10.0;
2417 }
2418 else if (command == "T*")
2419 {
2420 CharStyle nstyle;
2421 QString ch = SpecialChars::LINEBREAK;
2422 nstyle.setFont((*m_Doc->AllFonts)[textFont]);
2423 nstyle.setFontSize(textSize);
2424 nstyle.setFillColor(CurrColorFill);
2425 nstyle.setTracking(textKern);
2426 nstyle.setFillShade(100);
2427 nstyle.setStrokeColor(CurrColorStroke);
2428 nstyle.setStrokeShade(100);
2429 nstyle.setScaleH(textScaleH);
2430 nstyle.setScaleV(textScaleV);
2431 nstyle.setBaselineOffset(0);
2432 nstyle.setShadowXOffset(50);
2433 nstyle.setShadowYOffset(-50);
2434 nstyle.setOutlineWidth(10);
2435 nstyle.setUnderlineOffset(-1);
2436 nstyle.setUnderlineWidth(-1);
2437 nstyle.setStrikethruOffset(-1);
2438 nstyle.setStrikethruWidth(-1);
2439 nstyle.setFeatures(StyleFlag(ScStyle_Default).featureList());
2440 int pot = textData.length();
2441 textData.insertChars(pot, ch);
2442 textData.applyCharStyle(pot, 1, nstyle);
2443 maxHeight += nstyle.font().height(nstyle.fontSize() / 10.0) + 2.0;
2444 tempW = 0;
2445 }
2446 else if (command == "Tf")
2447 {
2448 ScTextStream gVals(&Cdata, QIODevice::ReadOnly);
2449 gVals >> textFont >> textSize;
2450 textFont.remove(0, 2);
2451 QString family = textFont;
2452 QString ret = "";
2453 family.replace( QRegExp( "'" ) , QChar( ' ' ) );
2454 textFont = m_Doc->itemToolPrefs().textFont;
2455 bool found = false;
2456 SCFontsIterator it(PrefsManager::instance().appPrefs.fontPrefs.AvailFonts);
2457 for ( ; it.hasNext(); it.next())
2458 {
2459 QString fam;
2460 QString fn = it.current().scName();
2461 int pos = fn.indexOf(" ");
2462 fam = fn.left(pos);
2463 if (fam == family)
2464 {
2465 found = true;
2466 ret = fn;
2467 }
2468 }
2469 if (found)
2470 textFont = family;
2471 else
2472 {
2473 if (importerFlags & LoadSavePlugin::lfCreateThumbnail)
2474 textFont = PrefsManager::instance().appPrefs.itemToolPrefs.textFont;
2475 else
2476 {
2477 if (!PrefsManager::instance().appPrefs.fontPrefs.GFontSub.contains(family))
2478 {
2479 qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
2480 MissingFont *dia = new MissingFont(nullptr, family, m_Doc);
2481 dia->exec();
2482 QString tmpf = dia->getReplacementFont();
2483 delete dia;
2484 qApp->changeOverrideCursor(QCursor(Qt::WaitCursor));
2485 PrefsManager::instance().appPrefs.fontPrefs.GFontSub[family] = tmpf;
2486 }
2487 else
2488 textFont = PrefsManager::instance().appPrefs.fontPrefs.GFontSub[family];
2489 }
2490 }
2491 textSize *= 10.0;
2492 }
2493 else if (command == "TO")
2494 {
2495 if (textData.length() > 0)
2496 {
2497 if (!((textData.length() == 1) && (textData.text(0) == SpecialChars::PARSEP)))
2498 {
2499 QPointF pos = QPointF(textMatrix.dx(), textMatrix.dy());
2500 pos += QPointF(m_Doc->currentPage()->xOffset(), -m_Doc->currentPage()->yOffset());
2501 pos += QPointF(0.0, textSize / 10.0 + 2.0);
2502 z = m_Doc->itemAdd(PageItem::TextFrame, PageItem::Unspecified, pos.x() - docX, docHeight - (pos.y() - docY), 10, 10, 0, CommonStrings::None, CommonStrings::None);
2503 ite = m_Doc->Items->at(z);
2504 ite->setTextToFrameDist(0.0, 0.0, 0.0, 0.0);
2505 ite->itemText.append(textData);
2506 ite->itemText.trim();
2507 double xpos = ite->xPos();
2508 double ypos = ite->yPos();
2509 ite->setWidthHeight(qMax(ite->width(), maxWidth), qMax(ite->height(), maxHeight));
2510 double xoffset = 0.0, yoffset = 0.0;
2511 double rotation = getRotationFromMatrix(textMatrix, 0.0);
2512 if (rotation != 0.0)
2513 {
2514 double temp = textSize / 10.0 + 2.0;
2515 xoffset = sin(rotation) * temp;
2516 yoffset = cos(rotation) * temp;
2517 }
2518 ite->setXPos(xpos + xoffset);
2519 ite->setYPos(ypos + yoffset);
2520 ite->setRotation(rotation * 180 / M_PI);
2521 ite->SetRectFrame();
2522 m_Doc->setRedrawBounding(ite);
2523 ite->Clip = flattenPath(ite->PoLine, ite->Segments);
2524 ite->setTextFlowMode(PageItem::TextFlowDisabled);
2525 ite->setFillShade(CurrFillShade);
2526 ite->setLineShade(CurrStrokeShade);
2527 ite->setFillEvenOdd(fillRule);
2528 ite->setFillTransparency(1.0 - Opacity);
2529 ite->setLineTransparency(1.0 - Opacity);
2530 ite->setLineEnd(CapStyle);
2531 ite->setLineJoin(JoinStyle);
2532 if (importerFlags & LoadSavePlugin::lfCreateDoc)
2533 ite->setLocked(itemLocked);
2534 if (patternMode)
2535 PatternElements.append(ite);
2536 else
2537 Elements.append(ite);
2538 if (groupStack.count() != 0)
2539 groupStack.top().append(ite);
2540 }
2541 }
2542 }
2543 /* End Text commands */
2544 /* Start special Commands */
2545 else if (command == "*")
2546 {
2547 Coords.resize(0);
2548 Coords.svgInit();
2549 }
2550 else if (command == "[")
2551 {
2552 Coords.resize(0);
2553 Coords.svgInit();
2554 int an = Cdata.indexOf("(");
2555 int en = Cdata.lastIndexOf(")");
2556 if ((an != -1) && (en != -1))
2557 {
2558 patternMode = true;
2559 currentPatternDefName = Cdata.mid(an+1, en-an-1);
2560 currentPatternDefName.remove("\\");
2561 currentPatternDefName = currentPatternDefName.trimmed().simplified().replace(" ", "_");
2562 QString tmpS = Cdata.mid(en+1, Cdata.size() - en);
2563 ScTextStream gVals(&tmpS, QIODevice::ReadOnly);
2564 gVals >> patternX1 >> patternY1 >> patternX2 >> patternY2;
2565 }
2566 }
2567 else if (command == ",")
2568 {
2569 if (Cdata.contains("/Data"))
2570 {
2571 dataMode = true;
2572 dataString = "";
2573 }
2574 }
2575 else if (command == ":")
2576 {
2577 fObjectMode = true;
2578 }
2579 /* End special Commands */
2580 /* Skip everything else */
2581 // else
2582 // qDebug() << command;
2583 }
2584 }
2585
processGradientData(const QString & data)2586 void AIPlug::processGradientData(const QString& data)
2587 {
2588 QString command;
2589 QString Cdata;
2590 QStringList da;
2591 getCommands(data, da);
2592 for (int a = 0; a < da.count(); a++)
2593 {
2594 Cdata = da[a];
2595 QStringList da2 = Cdata.split(" ", Qt::SkipEmptyParts);
2596 command = da2.last();
2597 if (command == "Bd")
2598 {
2599 int an = Cdata.indexOf("(");
2600 int en = Cdata.lastIndexOf(")");
2601 currentGradientName = Cdata.mid(an+1, en-an-1);
2602 currentGradientName.remove("\\");
2603 if (da2[da2.count()-3] == "0")
2604 currentGradient = VGradient(VGradient::linear);
2605 else
2606 currentGradient = VGradient(VGradient::radial);
2607 currentGradient.clearStops();
2608 }
2609 else if ((command == "%_Bs") || (command == "%_BS"))
2610 {
2611 QString stopName = "";
2612 double stop = ScCLocale::toDoubleC(da2[da2.count()-2]) / 100.0;
2613 double colorShade = 100.0;
2614 int colortype = da2[da2.count()-4].toInt();
2615 if (colortype == 0)
2616 {
2617 stopName = parseColorGray(Cdata);
2618 const ScColor& gradC = m_Doc->PageColors[stopName];
2619 currentGradient.addStop( ScColorEngine::getRGBColor(gradC, m_Doc), stop, 0.5, 1.0, stopName, 100 );
2620 }
2621 else if (colortype == 1)
2622 {
2623 stopName = parseColor(Cdata);
2624 const ScColor& gradC = m_Doc->PageColors[stopName];
2625 currentGradient.addStop( ScColorEngine::getRGBColor(gradC, m_Doc), stop, 0.5, 1.0, stopName, 100 );
2626 }
2627 else if (colortype == 2)
2628 {
2629 stopName = parseColor(Cdata);
2630 const ScColor& gradC = m_Doc->PageColors[stopName];
2631 currentGradient.addStop( ScColorEngine::getRGBColor(gradC, m_Doc), stop, 0.5, 1.0, stopName, 100 );
2632 }
2633 else if (colortype == 3)
2634 {
2635 stopName = parseCustomColor(Cdata, colorShade);
2636 int stopShade = qRound(colorShade);
2637 const ScColor& gradC = m_Doc->PageColors[stopName];
2638 currentGradient.addStop( ScColorEngine::getShadeColor(gradC, m_Doc, stopShade), stop, 0.5, 1.0, stopName, stopShade);
2639 }
2640 else if (colortype == 4)
2641 {
2642 stopName = parseCustomColorX(Cdata, colorShade, "0");
2643 int stopShade = qRound(colorShade);
2644 const ScColor& gradC = m_Doc->PageColors[stopName];
2645 currentGradient.addStop( ScColorEngine::getShadeColor(gradC, m_Doc, stopShade), stop, 0.5, 1.0, stopName, stopShade);
2646 }
2647 else if (colortype == 6)
2648 {
2649 stopName = parseColor(Cdata);
2650 const ScColor& gradC = m_Doc->PageColors[stopName];
2651 currentGradient.addStop( ScColorEngine::getRGBColor(gradC, m_Doc), stop, 0.5, 1.0, stopName, 100 );
2652 }
2653 }
2654 else if (command == "BD")
2655 {
2656 m_gradients.insert(currentGradientName, currentGradient);
2657 if (m_Doc->addGradient(currentGradientName, currentGradient))
2658 importedGradients.append(currentGradientName);
2659 currentGradient = VGradient(VGradient::linear);
2660 currentGradient.clearStops();
2661 currentGradient.setRepeatMethod( VGradient::none );
2662 currentGradientName = "";
2663 }
2664 }
2665 }
2666
processPattern(QDataStream & ts)2667 void AIPlug::processPattern(QDataStream &ts)
2668 {
2669 QString tmp = "";
2670 QString tmpData = "";
2671 while (!ts.atEnd())
2672 {
2673 tmp = removeAIPrefix(readLineFromDataStream(ts));
2674 if (importerFlags & LoadSavePlugin::lfKeepPatterns)
2675 {
2676 if (tmp.startsWith("%_"))
2677 tmp.remove(0, 2);
2678 }
2679 if (patternMode)
2680 {
2681 if (tmp == "EndPattern")
2682 {
2683 tmpSel->clear();
2684 if (PatternElements.count() > 0)
2685 {
2686 for (int dre = 0; dre < PatternElements.count(); ++dre)
2687 {
2688 tmpSel->addItem(PatternElements.at(dre), true);
2689 if (groupStack.count() != 0)
2690 groupStack.top().removeAll(PatternElements.at(dre));
2691 }
2692 if (PatternElements.count() > 1)
2693 m_Doc->itemSelection_GroupObjects(false, false, tmpSel);
2694 if ((tmpSel->width() > 1) && (tmpSel->height() > 1))
2695 {
2696 ScPattern pat = ScPattern();
2697 pat.setDoc(m_Doc);
2698 PageItem* currItem = tmpSel->itemAt(0);
2699 currItem->setItemName(currentPatternDefName);
2700 m_Doc->DoDrawing = true;
2701 QImage tmpImg = currItem->DrawObj_toImage(qMin(qMax(qRound(patternX2 - patternX1), qRound(patternY2 - patternY1)), 500));
2702 if (!tmpImg.isNull())
2703 {
2704 QImage retImg = QImage(qRound(patternX2 - patternX1), qRound(patternY2 - patternY1), QImage::Format_ARGB32_Premultiplied);
2705 retImg.fill( qRgba(255, 255, 255, 0) );
2706 QPainter p;
2707 p.begin(&retImg);
2708 if (PatternElements.count() > 1)
2709 p.drawImage(qRound(-patternX1), qRound(-patternY1), tmpImg);
2710 else
2711 p.drawImage(0, 0, tmpImg);
2712 p.end();
2713 pat.pattern = retImg;
2714 m_Doc->DoDrawing = false;
2715 pat.width = patternX2 - patternX1;
2716 pat.height = patternY2 - patternY1;
2717 pat.xoffset = -patternX1;
2718 pat.yoffset = -patternY1;
2719 for (int as = 0; as < tmpSel->count(); ++as)
2720 {
2721 PageItem* Neu = tmpSel->itemAt(as);
2722 Neu->moveBy(-patternX1, -patternY1, true);
2723 Neu->gXpos -= patternX1;
2724 Neu->gYpos -= patternY1;
2725 pat.items.append(Neu);
2726 }
2727 m_Doc->addPattern(currentPatternDefName, pat);
2728 importedPatterns.append(currentPatternDefName);
2729 /* double minx = std::numeric_limits<double>::max();
2730 double miny = std::numeric_limits<double>::max();
2731 double maxx = -std::numeric_limits<double>::max();
2732 double maxy = -std::numeric_limits<double>::max();
2733 double x1, x2, y1, y2;
2734 currItem->getVisualBoundingRect(&x1, &y1, &x2, &y2);
2735 minx = qMin(minx, x1);
2736 miny = qMin(miny, y1);
2737 maxx = qMax(maxx, x2);
2738 maxy = qMax(maxy, y2);
2739 currItem->gXpos = currItem->xPos() - minx;
2740 currItem->gYpos = currItem->yPos() - miny;
2741 currItem->setXYPos(currItem->gXpos, currItem->gYpos, true);
2742 m_Doc->docPatterns[currentPatternDefName].width = maxx - minx;
2743 m_Doc->docPatterns[currentPatternDefName].height = maxy - miny;*/
2744 }
2745 }
2746 m_Doc->itemSelection_DeleteItem(tmpSel);
2747 }
2748 PatternElements.clear();
2749 currentPatternDefName = "";
2750 break;
2751 }
2752 if (tmp.startsWith("Tile"))
2753 continue;
2754 if (tmp.contains(") @"))
2755 {
2756 tmpData += tmp;
2757 tmpData.remove(") @");
2758 processData(tmpData);
2759 tmpData = "";
2760 }
2761 else if (tmp.contains(") &"))
2762 {
2763 tmpData += tmp;
2764 tmpData.remove(") &");
2765 processData(tmpData);
2766 tmpData = "";
2767 }
2768 else if (tmp.startsWith("("))
2769 {
2770 if (tmp.startsWith("("))
2771 tmp.remove(0, 1);
2772 tmpData += " "+tmp;
2773 }
2774 else
2775 processData(tmp);
2776 }
2777 else if (tmp == "EndPattern")
2778 {
2779 PatternElements.clear();
2780 currentPatternDefName = "";
2781 break;
2782 }
2783 else if (tmp.contains("BeginRaster") && (tmp.startsWith("%")))
2784 {
2785 while (!ts.atEnd())
2786 {
2787 tmp = readLineFromDataStream(ts);
2788 if (tmp.contains("EndRaster"))
2789 break;
2790 if (progressDialog)
2791 {
2792 progressDialog->setProgress("GI", ts.device()->pos());
2793 qApp->processEvents();
2794 }
2795 }
2796 }
2797 else
2798 {
2799 Coords.resize(0);
2800 Coords.svgInit();
2801 int an = tmp.indexOf("(");
2802 int en = tmp.lastIndexOf(")");
2803 if ((an != -1) && (en != -1))
2804 {
2805 patternMode = true;
2806 currentPatternDefName = tmp.mid(an+1, en-an-1);
2807 currentPatternDefName.remove("\\");
2808 currentPatternDefName = currentPatternDefName.trimmed().simplified().replace(" ", "_");
2809 QString tmpS = tmp.mid(en+1, tmp.size() - en);
2810 ScTextStream gVals(&tmpS, QIODevice::ReadOnly);
2811 gVals >> patternX1 >> patternY1 >> patternX2 >> patternY2;
2812 }
2813 }
2814 // processData(tmp);
2815 }
2816 patternMode = false;
2817 }
2818
processSymbol(QDataStream & ts,bool sym)2819 void AIPlug::processSymbol(QDataStream &ts, bool sym)
2820 {
2821 QString tmp;
2822 while (!ts.atEnd())
2823 {
2824 tmp = removeAIPrefix(readLineFromDataStream(ts));
2825 if (!patternMode)
2826 {
2827 int an = tmp.indexOf("(");
2828 int en = tmp.lastIndexOf(")");
2829 if ((an != -1) && (en != -1))
2830 {
2831 patternMode = true;
2832 currentPatternDefName = tmp.mid(an+1, en-an-1);
2833 currentPatternDefName.remove("\\");
2834 if (sym)
2835 currentPatternDefName = "S_"+currentPatternDefName.trimmed().simplified().replace(" ", "_");
2836 else
2837 currentPatternDefName = currentPatternDefName.trimmed().simplified().replace(" ", "_");
2838 }
2839 }
2840 else if ((tmp == "EndSymbol") || (tmp == "EndBrushPattern"))
2841 {
2842 tmpSel->clear();
2843 if (PatternElements.count() > 0)
2844 {
2845 for (int dre = 0; dre < PatternElements.count(); ++dre)
2846 {
2847 tmpSel->addItem(PatternElements.at(dre), true);
2848 groupStack.top().removeAll(PatternElements.at(dre));
2849 }
2850 if (PatternElements.count() > 1)
2851 m_Doc->itemSelection_GroupObjects(false, false, tmpSel);
2852 if ((tmpSel->width() > 1) && (tmpSel->height() > 1))
2853 {
2854 ScPattern pat = ScPattern();
2855 pat.setDoc(m_Doc);
2856 PageItem* currItem = tmpSel->itemAt(0);
2857 currItem->setItemName(currentPatternDefName);
2858 m_Doc->DoDrawing = true;
2859 pat.pattern = currItem->DrawObj_toImage(qMin(qMax(tmpSel->width(), tmpSel->height()), 500.0));
2860 if (!pat.pattern.isNull())
2861 {
2862 pat.width = tmpSel->width();
2863 pat.height = tmpSel->height();
2864 m_Doc->DoDrawing = false;
2865 for (int as = 0; as < tmpSel->count(); ++as)
2866 {
2867 PageItem* Neu = tmpSel->itemAt(as);
2868 pat.items.append(Neu);
2869 }
2870 importedPatterns.append(currentPatternDefName);
2871 importedSymbols.insert(currentPatternDefName, QPointF(currItem->xPos(), currItem->yPos()));
2872 m_Doc->addPattern(currentPatternDefName, pat);
2873 }
2874 }
2875 m_Doc->itemSelection_DeleteItem(tmpSel);
2876 }
2877 PatternElements.clear();
2878 currentPatternDefName = "";
2879 break;
2880 }
2881 else if (tmp.contains("BeginRaster") && (tmp.startsWith("%")))
2882 {
2883 while (!ts.atEnd())
2884 {
2885 tmp = readLineFromDataStream(ts);
2886 if (tmp.contains("EndRaster"))
2887 break;
2888 if (progressDialog)
2889 {
2890 progressDialog->setProgress("GI", ts.device()->pos());
2891 qApp->processEvents();
2892 }
2893 }
2894 }
2895 else
2896 {
2897 processData(tmp);
2898 }
2899 }
2900 patternMode = false;
2901 }
2902
processRaster(QDataStream & ts)2903 void AIPlug::processRaster(QDataStream &ts)
2904 {
2905 double m1, m2, m3, m4, m5, m6, x1, y1, x2, y2, dummy;
2906 int w, h, type, alpha, bin, bits;
2907 QString tmp = "";
2908 QString cumulated = "";
2909 while (!ts.atEnd())
2910 {
2911 tmp = readLineFromDataStream(ts);
2912 if (tmp.startsWith("%"))
2913 break;
2914 tmp.remove("[");
2915 tmp.remove("]");
2916 if (!tmp.isEmpty())
2917 cumulated += " " + tmp;
2918 }
2919 QString Cdata = "";
2920 QStringList da;
2921 getCommands(cumulated, da);
2922 Cdata = da.last();
2923 ScTextStream gVals(&Cdata, QIODevice::ReadOnly);
2924 gVals >> m1 >> m2 >> m3 >> m4 >> m5 >> m6 >> x1 >> y1 >> x2 >> y2 >> w >> h >> bits >> type >> alpha >> dummy >> bin;
2925 // qDebug() << QString("Matrix: %1 %2 %3 %4 %5 %6").arg(m1).arg(m2).arg(m3).arg(m4).arg(m5).arg(m6);
2926 // qDebug() << QString("Bounds: %1 %2 %3 %4").arg(x1).arg(y1).arg(x2).arg(y2);
2927 // qDebug() << QString("Size: %1 %2").arg(w).arg(h);
2928 // qDebug() << QString("Bits: %1").arg(bits);
2929 // qDebug() << QString("Typ: %1").arg(type);
2930 // qDebug() << QString("Alpha-Channels: %1").arg(alpha);
2931 // qDebug() << QString("Encoding: %1").arg(bin);
2932 uint dataSize = w * h * (type + alpha);
2933 uint alphaData = w * h * type;
2934 // bool cmyk = false;
2935 // if (type == 4)
2936 // cmyk = true;
2937 if (tmp.startsWith("%%BeginData"))
2938 {
2939 ScTextStream gVals2(&tmp, QIODevice::ReadOnly);
2940 tmp = readLineFromDataStream(ts);
2941 }
2942 QByteArray psdata;
2943 psdata.resize(dataSize);
2944 RawImage m_image;
2945 if (type == 4)
2946 {
2947 if (alpha > 0)
2948 m_image.create(w, 1, 5);
2949 else
2950 m_image.create(w, 1, 4);
2951 }
2952 else
2953 {
2954 if (alpha > 0)
2955 m_image.create(w, 1, 4);
2956 else
2957 m_image.create(w, 1, 3);
2958 }
2959 bool first = false;
2960 if (bin == 0) // 0 = ASCII encoded data
2961 {
2962 uint dataPointer = 0;
2963 while (!ts.atEnd())
2964 {
2965 if (first)
2966 tmp = readLineFromDataStream(ts);
2967 first = true;
2968 if (tmp.startsWith("%AI5_EndRaster"))
2969 break;
2970 for (int a = 1; a < tmp.length(); a += 2)
2971 {
2972 bool ok;
2973 ushort data = tmp.midRef(a, 2).toUShort(&ok, 16);
2974 psdata[dataPointer++] = data;
2975 }
2976 }
2977 }
2978 else
2979 {
2980 psdata.resize(dataSize);
2981 ts.readRawData(psdata.data(), dataSize);
2982 }
2983 QTransform imgMatrix = QTransform(m1, m2, m3, m4, m5, m6);
2984 QPointF pos = QPointF(imgMatrix.dx(), imgMatrix.dy());
2985 pos += QPointF(m_Doc->currentPage()->xOffset(), -m_Doc->currentPage()->yOffset());
2986 pos += QPointF(baseX, -baseY);
2987 int z = m_Doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, pos.x() - docX, docHeight - (pos.y() - docY), 10, 10, 0, CurrColorFill, CurrColorStroke);
2988 PageItem* ite = m_Doc->Items->at(z);
2989 ite->setWidthHeight(fabs(w * m1), fabs(h * m4));
2990 double rotation = getRotationFromMatrix(imgMatrix, 0.0);
2991 ite->setRotation(rotation * 180 / M_PI);
2992 ite->SetRectFrame();
2993 m_Doc->setRedrawBounding(ite);
2994 ite->Clip = flattenPath(ite->PoLine, ite->Segments);
2995 ite->setTextFlowMode(PageItem::TextFlowDisabled);
2996 ite->setFillShade(CurrFillShade);
2997 ite->setLineShade(CurrStrokeShade);
2998 ite->setFillEvenOdd(fillRule);
2999 ite->setFillTransparency(1.0 - Opacity);
3000 ite->setLineTransparency(1.0 - Opacity);
3001 ite->setFillBlendmode(blendMode);
3002 ite->setLineBlendmode(blendMode);
3003 ite->setLineEnd(CapStyle);
3004 ite->setLineJoin(JoinStyle);
3005 uchar *p;
3006 uint yCount = 0;
3007 quint16 eTag = EXTRASAMPLE_UNASSALPHA;
3008 QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_ai_XXXXXX.tif");
3009 tempFile->setAutoRemove(false);
3010 tempFile->open();
3011 QString imgName = getLongPathName(tempFile->fileName());
3012 tempFile->close();
3013 ite->isInlineImage = true;
3014 ite->isTempFile = true;
3015 delete tempFile;
3016 TIFF* tif = TIFFOpen(imgName.toLocal8Bit().data(), "w");
3017 if (tif)
3018 {
3019 TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, w);
3020 TIFFSetField(tif, TIFFTAG_IMAGELENGTH, h);
3021 TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
3022 TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, m_image.channels());
3023 if (alpha == 1)
3024 TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, 1, &eTag);
3025 TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
3026 if (type == 4)
3027 TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_SEPARATED);
3028 else
3029 TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
3030 TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
3031 for (int y = 0; y < h; ++y)
3032 {
3033 p = m_image.scanLine( 0 );
3034 for (int xh = 0; xh < m_image.width(); ++xh )
3035 {
3036 p[0] = psdata[yCount++];
3037 if (type > 1)
3038 {
3039 p[1] = psdata[yCount++];
3040 p[2] = psdata[yCount++];
3041 if (type == 4)
3042 p[3] = psdata[yCount++];
3043 }
3044 else
3045 {
3046 p[1] = p[0];
3047 p[2] = p[0];
3048 }
3049 if (alpha == 1)
3050 {
3051 if (type == 4)
3052 p[4] = psdata[alphaData++];
3053 else
3054 p[3] = psdata[alphaData++];
3055 }
3056 p += m_image.channels();
3057 }
3058 TIFFWriteScanline(tif, m_image.scanLine(0), y);
3059 }
3060 TIFFClose(tif);
3061 }
3062 m_Doc->loadPict(imgName, ite);
3063 if (ite->imageIsAvailable)
3064 ite->setImageXYScale(ite->width() / ite->pixm.width(), ite->height() / ite->pixm.height());
3065 if (importerFlags & LoadSavePlugin::lfCreateDoc)
3066 ite->setLocked(itemLocked);
3067 if (patternMode)
3068 PatternElements.append(ite);
3069 else
3070 Elements.append(ite);
3071 if (groupStack.count() != 0)
3072 groupStack.top().append(ite);
3073 }
3074
processComment(QDataStream & ts,const QString & comment)3075 void AIPlug::processComment(QDataStream &ts, const QString& comment)
3076 {
3077 QString tmp = removeAIPrefix(comment);
3078 if (tmp.startsWith("Begin_NonPrinting"))
3079 {
3080 while (!ts.atEnd())
3081 {
3082 tmp = removeAIPrefix(readLineFromDataStream(ts));
3083 if (tmp.startsWith("BeginGradient"))
3084 {
3085 while (!ts.atEnd())
3086 {
3087 tmp = removeAIPrefix(readLineFromDataStream(ts));
3088 if (tmp.startsWith("EndGradient"))
3089 break;
3090 processGradientData(tmp);
3091 }
3092 }
3093 if (tmp.startsWith("BeginPattern:"))
3094 processPattern(ts);
3095 if (tmp == "BeginSymbol")
3096 processSymbol(ts, true);
3097 if (tmp == "BeginBrushPattern")
3098 processSymbol(ts, false);
3099 if (tmp.startsWith("End_NonPrinting"))
3100 break;
3101 if (progressDialog)
3102 {
3103 progressDialog->setProgress("GI", ts.device()->pos());
3104 qApp->processEvents();
3105 }
3106 }
3107 }
3108 else if (tmp.startsWith("BeginPattern:"))
3109 processPattern(ts);
3110 else if (tmp.startsWith("BeginGradient"))
3111 {
3112 while (!ts.atEnd())
3113 {
3114 tmp = removeAIPrefix(readLineFromDataStream(ts));
3115 if (tmp.startsWith("EndGradient"))
3116 break;
3117 processGradientData(tmp);
3118 if (progressDialog)
3119 {
3120 progressDialog->setProgress("GI", ts.device()->pos());
3121 qApp->processEvents();
3122 }
3123 }
3124 }
3125 else if (tmp.startsWith("BeginPalette"))
3126 {
3127 while (!ts.atEnd())
3128 {
3129 tmp = removeAIPrefix(readLineFromDataStream(ts));
3130 if (tmp.startsWith("EndPalette"))
3131 break;
3132 if (progressDialog)
3133 {
3134 progressDialog->setProgress("GI", ts.device()->pos());
3135 qApp->processEvents();
3136 }
3137 }
3138 }
3139 else if (tmp == "BeginSymbol")
3140 processSymbol(ts, true);
3141 else if (tmp == "BeginBrushPattern")
3142 processSymbol(ts, false);
3143 /* {
3144 while (!ts.atEnd())
3145 {
3146 processSymbol(ts);
3147 tmp = removeAIPrefix(readLineFromDataStream(ts));
3148 if (tmp.startsWith("EndSymbol"))
3149 break;
3150 if (progressDialog)
3151 {
3152 progressDialog->setProgress("GI", ts.device()->pos());
3153 qApp->processEvents();
3154 }
3155 }
3156 } */
3157 else if (tmp.startsWith("BeginDocumentData"))
3158 {
3159 while (!ts.atEnd())
3160 {
3161 tmp = removeAIPrefix(readLineFromDataStream(ts));
3162 if (tmp.startsWith("EndDocumentData"))
3163 break;
3164 if (progressDialog)
3165 {
3166 progressDialog->setProgress("GI", ts.device()->pos());
3167 qApp->processEvents();
3168 }
3169 }
3170 }
3171 else if (tmp.startsWith("BeginTextDocument"))
3172 {
3173 tmp = removeAIPrefix(readLineFromDataStream(ts));
3174 while (!ts.atEnd())
3175 {
3176 tmp = removeAIPrefix(readLineFromDataStream(ts));
3177 if (tmp.startsWith("EndTextDocument"))
3178 {
3179 // QByteArray fData;
3180 // decodeA85(fData, dataStringT);
3181 break;
3182 }
3183 // else
3184 // dataStringT += tmp.mid(1);
3185 if (progressDialog)
3186 {
3187 progressDialog->setProgress("GI", ts.device()->pos());
3188 qApp->processEvents();
3189 }
3190 }
3191 }
3192 else if (tmp.startsWith("%%BeginProlog"))
3193 {
3194 while (!ts.atEnd())
3195 {
3196 tmp = removeAIPrefix(readLineFromDataStream(ts));
3197 if (tmp.startsWith("%%EndProlog"))
3198 break;
3199 if (progressDialog)
3200 {
3201 progressDialog->setProgress("GI", ts.device()->pos());
3202 qApp->processEvents();
3203 }
3204 }
3205 }
3206 else if (tmp.startsWith("%%BeginData"))
3207 {
3208 while (!ts.atEnd())
3209 {
3210 tmp = removeAIPrefix(readLineFromDataStream(ts));
3211 if (tmp.startsWith("%%EndData"))
3212 break;
3213 if (progressDialog)
3214 {
3215 progressDialog->setProgress("GI", ts.device()->pos());
3216 qApp->processEvents();
3217 }
3218 }
3219 }
3220 else if (tmp.startsWith("%%BeginCrops"))
3221 {
3222 while (!ts.atEnd())
3223 {
3224 tmp = removeAIPrefix(readLineFromDataStream(ts));
3225 if (tmp.startsWith("%%EndCrops"))
3226 break;
3227 if (progressDialog)
3228 {
3229 progressDialog->setProgress("GI", ts.device()->pos());
3230 qApp->processEvents();
3231 }
3232 }
3233 }
3234 else if (tmp.startsWith("BeginRaster"))
3235 {
3236 processRaster(ts);
3237 if (progressDialog)
3238 {
3239 progressDialog->setProgress("GI", ts.device()->pos());
3240 qApp->processEvents();
3241 }
3242 }
3243 else if (tmp.contains("BeginRaster") && (tmp.startsWith("%")))
3244 {
3245 while (!ts.atEnd())
3246 {
3247 tmp = readLineFromDataStream(ts);
3248 if (tmp.contains("EndRaster"))
3249 break;
3250 if (progressDialog)
3251 {
3252 progressDialog->setProgress("GI", ts.device()->pos());
3253 qApp->processEvents();
3254 }
3255 }
3256 }
3257 else if (tmp.startsWith("BeginSVGFilter"))
3258 {
3259 while (!ts.atEnd())
3260 {
3261 tmp = removeAIPrefix(readLineFromDataStream(ts));
3262 if (tmp.startsWith("EndSVGFilter"))
3263 break;
3264 if (progressDialog)
3265 {
3266 progressDialog->setProgress("GI", ts.device()->pos());
3267 qApp->processEvents();
3268 }
3269 }
3270 }
3271 else if (tmp.startsWith("BeginArtStyles"))
3272 {
3273 while (!ts.atEnd())
3274 {
3275 tmp = removeAIPrefix(readLineFromDataStream(ts));
3276 if (tmp.startsWith("EndArtStyles"))
3277 break;
3278 if (progressDialog)
3279 {
3280 progressDialog->setProgress("GI", ts.device()->pos());
3281 qApp->processEvents();
3282 }
3283 }
3284 }
3285 else if (tmp.startsWith("BeginPluginObject"))
3286 {
3287 while (!ts.atEnd())
3288 {
3289 tmp = removeAIPrefix(readLineFromDataStream(ts));
3290 if (tmp.startsWith("EndPluginObject"))
3291 break;
3292 if (progressDialog)
3293 {
3294 progressDialog->setProgress("GI", ts.device()->pos());
3295 qApp->processEvents();
3296 }
3297 }
3298 }
3299 else if (tmp.startsWith("BeginLayer"))
3300 {
3301 while (!ts.atEnd())
3302 {
3303 QString rl = readLineFromDataStream(ts);
3304 tmp = removeAIPrefix(rl);
3305 if (tmp.startsWith("BeginRaster"))
3306 {
3307 processRaster(ts);
3308 continue;
3309 }
3310 if (tmp.startsWith("EndLayer"))
3311 break;
3312 processData(rl);
3313 if (progressDialog)
3314 {
3315 progressDialog->setProgress("GI", ts.device()->pos());
3316 qApp->processEvents();
3317 }
3318 }
3319 }
3320 }
3321
convert(const QString & fn)3322 bool AIPlug::convert(const QString& fn)
3323 {
3324 QString tmp;
3325 LineW = 1.0;
3326 Opacity = 1.0;
3327 blendMode = 0;
3328 CurrColorFill = "White";
3329 CurrFillShade = 100.0;
3330 CurrColorStroke = "Black";
3331 CurrStrokeShade = 100.0;
3332 JoinStyle = Qt::MiterJoin;
3333 CapStyle = Qt::FlatCap;
3334 DashPattern.clear();
3335 DashOffset = 0.0;
3336 fillRule = false;
3337 FirstU = false;
3338 WasU = false;
3339 firstLayer = true;
3340 patternMode = false;
3341 symbolMode = false;
3342 meshMode = false;
3343 dataMode = false;
3344 fObjectMode = false;
3345 dataString.clear();
3346 itemLocked = false;
3347 patternX1 = 0.0;
3348 patternY1 = 0.0;
3349 patternX2 = 0.0;
3350 patternY2 = 0.0;
3351 Coords.resize(0);
3352 Coords.svgInit();
3353 clipCoords.resize(0);
3354 clipCoords.svgInit();
3355 currentSpecialPath.resize(0);
3356 currentSpecialPath.svgInit();
3357 currentPoint = FPoint(0.0, 0.0);
3358 currentLayer = 0;
3359 currentGradient = VGradient(VGradient::linear);
3360 currentGradient.clearStops();
3361 currentGradient.setRepeatMethod( VGradient::none );
3362 currentGradientName = "";
3363 currentGradientMatrix = QTransform();
3364 currentGradientOrigin = QPointF(0.0, 0.0);
3365 currentGradientAngle = 0.0;
3366 currentGradientLength = 1.0;
3367 currentPatternName.clear();
3368 currentPatternX = 0.0;
3369 currentPatternY = 0.0;
3370 currentPatternXScale = 1.0;
3371 currentPatternYScale = 1.0;
3372 currentPatternRotation = 0.0;
3373 currentStrokePatternName = "";
3374 currentStrokePatternX = 0.0;
3375 currentStrokePatternY = 0.0;
3376 currentStrokePatternXScale = 1.0;
3377 currentStrokePatternYScale = 1.0;
3378 currentStrokePatternRotation = 0.0;
3379 QList<PageItem*> gElements;
3380 groupStack.push(gElements);
3381 clipStack.push(clipCoords);
3382 commandList << "m" << "l" << "L" << "c" << "C" << "v" << "V" << "y" << "Y"; // Path construction
3383 commandList << "b" << "B" << "f" << "F" << "s" << "S" << "*u" << "*U"; // Object creation
3384 commandList << "u" << "U" << "W" << "q" << "Q"; // Object creation
3385 commandList << "A" << "w" << "j" << "J" << "Xy" << "XR"; // Graphic state
3386 commandList << "k" << "K" << "Xa" << "XA" << "x" << "X" << "XX" << "Xx"; // Color commands
3387 commandList << "Xk" << "g" << "G" << "p" << "P"; // Color commands
3388 commandList << "Ln" << "Lb" << "LB"; // Layer commands
3389 commandList << "Bd" << "BD" << "%_Bs" << "Bg" << "Bb" << "BB" << "Bm" << "Xm"; // Gradient commands
3390 commandList << "To" << "TO" << "Tf" << "Tp" << "Tx" << "TX" << "T*" << "Tk"; // Text commands
3391 commandList << "Tc" << "Tz"; // Text commands
3392 commandList << "XI" << "XG" << "Xh"; // Image commands
3393 commandList << "n" << "N" << "*" << "["; // Special commands
3394 commandList << "X!" << "X#"; // Mesh commands
3395 commandList << "M" << "d" << "D" << "E"; // unimplemented
3396 commandList << "h" << "H" << "i" << "I" << "Np" << "O"; // unimplemented
3397 commandList << "P" << "R"; // unimplemented
3398 commandList << "XI" << "XF" << "XG" << "XT" << "Z" << "`" << "~" << "_" << "@"; // unimplemented
3399 commandList << "&" << "*w" << "*W" << "Ap" << "Ar"; // unimplemented
3400 if (progressDialog)
3401 {
3402 progressDialog->setOverallProgress(2);
3403 progressDialog->setLabel("GI", tr("Generating Items"));
3404 qApp->processEvents();
3405 }
3406 QFile f(fn);
3407 if (f.open(QIODevice::ReadOnly))
3408 {
3409 int fSize = (int) f.size();
3410 if (progressDialog)
3411 {
3412 progressDialog->setTotalSteps("GI", fSize);
3413 qApp->processEvents();
3414 }
3415 QDataStream ts(&f);
3416 while (!ts.atEnd())
3417 {
3418 tmp = readLineFromDataStream(ts);
3419 if (tmp.startsWith("%"))
3420 processComment(ts, tmp);
3421 else
3422 processData(tmp);
3423 if (progressDialog)
3424 {
3425 progressDialog->setProgress("GI", ts.device()->pos());
3426 qApp->processEvents();
3427 }
3428 }
3429 f.close();
3430 }
3431 if (progressDialog)
3432 progressDialog->close();
3433 return true;
3434 }
3435