Subversion Repositories Scribus

Rev

Rev 18642 | Rev 18657 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
18598 fschmid 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
                                                         -------------------
9
        begin                : Sat Oct 26 2013
10
        copyright            : (C) 2013 by Franz Schmid
11
        email                : Franz.Schmid@altmuehlnet.de
12
 ***************************************************************************/
13
 
14
#include <QByteArray>
15
#include <QCursor>
16
#include <QDrag>
17
#include <QFile>
18
#include <QList>
19
#include <QMimeData>
20
#include <QRegExp>
21
#include <QStack>
22
#include <QUrl>
23
#include <QDebug>
24
 
25
#if defined(_MSC_VER) && !defined(_USE_MATH_DEFINES)
26
#define _USE_MATH_DEFINES
27
#endif
28
 
29
#include <cstdlib>
30
#include <climits>
31
#include <limits>
32
 
33
#include "commonstrings.h"
34
 
35
#include "importxps.h"
36
#include "loadsaveplugin.h"
37
#include "pageitem_table.h"
38
#include "pagesize.h"
39
#include "prefscontext.h"
40
#include "prefsfile.h"
41
#include "prefsmanager.h"
42
#include "prefstable.h"
43
#include "rawimage.h"
44
#include "scclocale.h"
45
#include "sccolorengine.h"
46
#include "scconfig.h"
47
#include "scmimedata.h"
48
#include "scpaths.h"
49
#include "scribus.h"
50
#include "scribusXml.h"
51
#include "scribuscore.h"
52
#include "sctextstream.h"
53
#include "selection.h"
54
#include "undomanager.h"
55
#include "util.h"
56
#include "util_formats.h"
57
#include "util_icon.h"
58
#include "util_math.h"
59
 
60
#include "ui/customfdialog.h"
61
#include "ui/missing.h"
62
#include "ui/multiprogressdialog.h"
63
#include "ui/propertiespalette.h"
64
#include "xpsimportoptions.h"
65
 
66
#include "third_party/zip/scribus_zip.h"
67
 
68
extern SCRIBUS_API ScribusQApp * ScQApp;
69
 
70
XpsPlug::XpsPlug(ScribusDoc* doc, int flags)
71
{
72
        tmpSel = new Selection(this, false);
73
        m_Doc = doc;
74
        importerFlags = flags;
75
        interactive = (flags & LoadSavePlugin::lfInteractive);
76
        progressDialog = NULL;
77
        uz = NULL;
78
}
79
 
80
QImage XpsPlug::readThumbnail(QString fName)
81
{
82
        QImage tmp;
83
        if (!QFile::exists(fName))
84
                return QImage();
85
        progressDialog = NULL;
86
        uz = new ScZipHandler();
87
        if (!uz->open(fName))
88
        {
89
                delete uz;
90
                if (progressDialog)
91
                        progressDialog->close();
92
        }
93
        bool found = false;
94
        if (uz->contains("_rels/.rels"))
95
        {
96
                QByteArray f;
97
                QDomDocument designMapDom;
98
                if (!uz->read("_rels/.rels", f))
99
                        return QImage();
100
                if(designMapDom.setContent(f))
101
                {
102
                        QDomElement docElem = designMapDom.documentElement();
103
                        for(QDomElement drawPag = docElem.firstChildElement(); !drawPag.isNull(); drawPag = drawPag.nextSiblingElement())
104
                        {
18613 jghali 105
                                if (drawPag.tagName() != "Relationship")
106
                                        continue;
107
                                if ((!drawPag.hasAttribute("Target")) || (!drawPag.hasAttribute("Type")))
108
                                        continue;
109
                                if (drawPag.attribute("Type") != "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail")
110
                                        continue;
111
                                QString thumbRef = drawPag.attribute("Target");
112
                                if (thumbRef.startsWith("/"))
113
                                        thumbRef = thumbRef.mid(1);
114
                                QByteArray im;
115
                                if (uz->read(thumbRef, im))
18598 fschmid 116
                                {
18613 jghali 117
                                        tmp = QImage::fromData(im);
118
                                        found = true;
119
                                        break;
18598 fschmid 120
                                }
121
                        }
122
                }
123
        }
124
        if (!found)
125
        {
126
                QFileInfo fi = QFileInfo(fName);
127
                baseFile = QDir::cleanPath(QDir::toNativeSeparators(fi.absolutePath()+"/"));
128
                docWidth = PrefsManager::instance()->appPrefs.docSetupPrefs.pageWidth;
129
                docHeight = PrefsManager::instance()->appPrefs.docSetupPrefs.pageHeight;
130
                m_Doc = new ScribusDoc();
131
                m_Doc->setup(0, 1, 1, 1, 1, "Custom", "Custom");
132
                m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false);
133
                m_Doc->addPage(0);
134
                m_Doc->setGUI(false, ScCore->primaryMainWindow(), 0);
135
                baseX = m_Doc->currentPage()->xOffset();
136
                baseY = m_Doc->currentPage()->yOffset() + m_Doc->currentPage()->height() / 2.0;
137
                Elements.clear();
138
                m_Doc->setLoading(true);
139
                m_Doc->DoDrawing = false;
140
                m_Doc->scMW()->setScriptRunning(true);
141
                QString CurDirP = QDir::currentPath();
142
                QDir::setCurrent(fi.path());
143
                importedColors.clear();
144
                importedPatterns.clear();
145
                conversionFactor = 72.0 / 96.0;
146
                loadedFonts.clear();
147
                linkTargets.clear();
148
                linkSources.clear();
149
                if (uz->contains("FixedDocSeq.fdseq"))
150
                        parseDocSequence("FixedDocSeq.fdseq");
151
                else if (uz->contains("FixedDocumentSequence.fdseq"))
152
                        parseDocSequence("FixedDocumentSequence.fdseq");
153
                if (Elements.count() > 0)
154
                {
155
                        tmpSel->clear();
156
                        QDir::setCurrent(CurDirP);
157
                        if (Elements.count() > 1)
158
                                m_Doc->groupObjectsList(Elements);
159
                        m_Doc->DoDrawing = true;
160
                        m_Doc->m_Selection->delaySignalsOn();
161
                        if (Elements.count() > 0)
162
                        {
163
                                for (int dre=0; dre<Elements.count(); ++dre)
164
                                {
165
                                        tmpSel->addItem(Elements.at(dre), true);
166
                                }
167
                                tmpSel->setGroupRect();
168
                                double xs = tmpSel->width();
169
                                double ys = tmpSel->height();
170
                                tmp = Elements.at(0)->DrawObj_toImage(500);
171
                                tmp.setText("XSize", QString("%1").arg(xs));
172
                                tmp.setText("YSize", QString("%1").arg(ys));
173
                        }
174
                        m_Doc->scMW()->setScriptRunning(false);
175
                        m_Doc->setLoading(false);
176
                        m_Doc->m_Selection->delaySignalsOff();
177
                        delete m_Doc;
178
                }
179
                else
180
                {
181
                        QDir::setCurrent(CurDirP);
182
                        m_Doc->DoDrawing = true;
183
                        m_Doc->scMW()->setScriptRunning(false);
184
                        delete m_Doc;
185
                }
186
        }
187
        uz->close();
188
        delete uz;
189
        return tmp;
190
}
191
 
192
bool XpsPlug::import(QString fNameIn, const TransactionSettings& trSettings, int flags, bool showProgress)
193
{
194
        QString fName = fNameIn;
195
        bool success = false;
196
        interactive = (flags & LoadSavePlugin::lfInteractive);
197
        importerFlags = flags;
198
        cancel = false;
199
        bool ret = false;
200
        firstPage = true;
201
        pagecount = 1;
202
        QFileInfo fi = QFileInfo(fName);
203
        m_FileName = fi.fileName();
204
        if ( !ScCore->usingGUI() )
205
        {
206
                interactive = false;
207
                showProgress = false;
208
        }
209
        baseFile = QDir::cleanPath(QDir::toNativeSeparators(fi.absolutePath()+"/"));
210
        if ( showProgress )
211
        {
212
                ScribusMainWindow* mw=(m_Doc==0) ? ScCore->primaryMainWindow() : m_Doc->scMW();
213
                progressDialog = new MultiProgressDialog( tr("Importing: %1").arg(fi.fileName()), CommonStrings::tr_Cancel, mw );
214
                QStringList barNames, barTexts;
215
                barNames << "GI";
216
                barTexts << tr("Analyzing File:");
217
                QList<bool> barsNumeric;
218
                barsNumeric << false;
219
                progressDialog->addExtraProgressBars(barNames, barTexts, barsNumeric);
220
                progressDialog->setOverallTotalSteps(3);
221
                progressDialog->setOverallProgress(0);
222
                progressDialog->setProgress("GI", 0);
223
                progressDialog->show();
224
                connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelRequested()));
225
                qApp->processEvents();
226
        }
227
        else
228
                progressDialog = NULL;
229
        if (progressDialog)
230
        {
231
                progressDialog->setOverallProgress(1);
232
                qApp->processEvents();
233
        }
234
        /* Set default Page to size defined in Preferences */
235
        docWidth = PrefsManager::instance()->appPrefs.docSetupPrefs.pageWidth;
236
        docHeight = PrefsManager::instance()->appPrefs.docSetupPrefs.pageHeight;
237
        baseX = 0;
238
        baseY = 0;
239
        if (!interactive || (flags & LoadSavePlugin::lfInsertPage))
240
        {
241
                m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false);
242
                m_Doc->addPage(0);
243
                m_Doc->view()->addPage(0, true);
244
                baseX = 0;
245
                baseY = 0;
246
        }
247
        else
248
        {
249
                if (!m_Doc || (flags & LoadSavePlugin::lfCreateDoc))
250
                {
251
                        m_Doc=ScCore->primaryMainWindow()->doFileNew(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false, 0, false, 0, 1, "Custom", true);
252
                        ScCore->primaryMainWindow()->HaveNewDoc();
253
                        ret = true;
254
                        baseX = 0;
255
                        baseY = 0;
256
                        baseX = m_Doc->currentPage()->xOffset();
257
                        baseY = m_Doc->currentPage()->yOffset() + m_Doc->currentPage()->height() / 2.0;
258
                }
259
        }
260
        if ((!ret) && (interactive))
261
        {
262
                baseX = m_Doc->currentPage()->xOffset();
263
                baseY = m_Doc->currentPage()->yOffset() + m_Doc->currentPage()->height() / 2.0;
264
        }
265
        if ((ret) || (!interactive))
266
        {
267
                if (docWidth > docHeight)
268
                        m_Doc->setPageOrientation(1);
269
                else
270
                        m_Doc->setPageOrientation(0);
271
                m_Doc->setPageSize("Custom");
272
        }
273
        Elements.clear();
274
        m_Doc->setLoading(true);
275
        m_Doc->DoDrawing = false;
276
        if (!(flags & LoadSavePlugin::lfLoadAsPattern))
277
                m_Doc->view()->updatesOn(false);
278
        m_Doc->scMW()->setScriptRunning(true);
279
        qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
280
        QString CurDirP = QDir::currentPath();
281
        QDir::setCurrent(fi.path());
282
        if (convert(fName))
283
        {
284
                tmpSel->clear();
285
                QDir::setCurrent(CurDirP);
286
                if ((Elements.count() > 1) && (!(importerFlags & LoadSavePlugin::lfCreateDoc)))
287
                        m_Doc->groupObjectsList(Elements);
288
                m_Doc->DoDrawing = true;
289
                m_Doc->scMW()->setScriptRunning(false);
290
                m_Doc->setLoading(false);
291
                qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
292
                if ((Elements.count() > 0) && (!ret) && (interactive))
293
                {
294
                        if (flags & LoadSavePlugin::lfScripted)
295
                        {
296
                                bool loadF = m_Doc->isLoading();
297
                                m_Doc->setLoading(false);
298
                                m_Doc->changed();
299
                                m_Doc->setLoading(loadF);
300
                                if (!(flags & LoadSavePlugin::lfLoadAsPattern))
301
                                {
302
                                        m_Doc->m_Selection->delaySignalsOn();
303
                                        for (int dre=0; dre<Elements.count(); ++dre)
304
                                        {
305
                                                m_Doc->m_Selection->addItem(Elements.at(dre), true);
306
                                        }
307
                                        m_Doc->m_Selection->delaySignalsOff();
308
                                        m_Doc->m_Selection->setGroupRect();
309
                                        m_Doc->view()->updatesOn(true);
310
                                }
311
                        }
312
                        else
313
                        {
314
                                m_Doc->DragP = true;
315
                                m_Doc->DraggedElem = 0;
316
                                m_Doc->DragElements.clear();
317
                                m_Doc->m_Selection->delaySignalsOn();
318
                                for (int dre=0; dre<Elements.count(); ++dre)
319
                                {
320
                                        tmpSel->addItem(Elements.at(dre), true);
321
                                }
322
                                tmpSel->setGroupRect();
323
                                ScElemMimeData* md = ScriXmlDoc::WriteToMimeData(m_Doc, tmpSel);
324
                                m_Doc->itemSelection_DeleteItem(tmpSel);
325
                                m_Doc->view()->updatesOn(true);
326
                                if ((importedColors.count() != 0) && (!((flags & LoadSavePlugin::lfKeepGradients) || (flags & LoadSavePlugin::lfKeepColors) || (flags & LoadSavePlugin::lfKeepPatterns))))
327
                                {
328
                                        for (int cd = 0; cd < importedColors.count(); cd++)
329
                                        {
330
                                                m_Doc->PageColors.remove(importedColors[cd]);
331
                                        }
332
                                }
333
                                if ((importedPatterns.count() != 0) && (!(flags & LoadSavePlugin::lfKeepPatterns)))
334
                                {
335
                                        for (int cd = 0; cd < importedPatterns.count(); cd++)
336
                                        {
337
                                                m_Doc->docPatterns.remove(importedPatterns[cd]);
338
                                        }
339
                                }
340
                                m_Doc->m_Selection->delaySignalsOff();
341
                                // We must copy the TransationSettings object as it is owned
342
                                // by handleObjectImport method afterwards
343
                                TransactionSettings* transacSettings = new TransactionSettings(trSettings);
344
                                m_Doc->view()->handleObjectImport(md, transacSettings);
345
                                m_Doc->DragP = false;
346
                                m_Doc->DraggedElem = 0;
347
                                m_Doc->DragElements.clear();
348
                        }
349
                }
350
                else
351
                {
352
                        m_Doc->changed();
353
                        m_Doc->reformPages();
354
                        if (!(flags & LoadSavePlugin::lfLoadAsPattern))
355
                                m_Doc->view()->updatesOn(true);
356
                }
357
                success = true;
358
        }
359
        else
360
        {
361
                QDir::setCurrent(CurDirP);
362
                m_Doc->DoDrawing = true;
363
                m_Doc->scMW()->setScriptRunning(false);
364
                if (!(flags & LoadSavePlugin::lfLoadAsPattern))
365
                        m_Doc->view()->updatesOn(true);
366
                qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
367
        }
368
        if (interactive)
369
                m_Doc->setLoading(false);
370
        //CB If we have a gui we must refresh it if we have used the progressbar
371
        if (!(flags & LoadSavePlugin::lfLoadAsPattern))
372
        {
373
                if ((showProgress) && (!interactive))
374
                        m_Doc->view()->DrawNew();
375
        }
376
        qApp->restoreOverrideCursor();
377
        return success;
378
}
379
 
380
XpsPlug::~XpsPlug()
381
{
382
        if (progressDialog)
383
                delete progressDialog;
384
        delete tmpSel;
385
        for (int a = 0; a < tempFontFiles.count(); a++)
386
        {
387
                QFile::remove(tempFontFiles[a]);
388
        }
389
}
390
 
391
bool XpsPlug::convert(QString fn)
392
{
393
        bool retVal = true;
394
        importedColors.clear();
395
        importedPatterns.clear();
396
        conversionFactor = 72.0 / 96.0;
397
        loadedFonts.clear();
398
        linkTargets.clear();
399
        linkSources.clear();
400
        pathResources.clear();
401
        if(progressDialog)
402
        {
403
                progressDialog->setOverallProgress(2);
404
                progressDialog->setLabel("GI", tr("Generating Items"));
405
                qApp->processEvents();
406
        }
407
 
408
        uz = new ScZipHandler();
409
        if (!uz->open(fn))
410
        {
411
                delete uz;
412
                if (progressDialog)
413
                        progressDialog->close();
414
        }
415
        if (uz->contains("FixedDocSeq.fdseq"))
416
        {
417
                parseDocSequence("FixedDocSeq.fdseq");
418
                resolveLinks();
419
        }
420
        else if (uz->contains("FixedDocumentSequence.fdseq"))
421
        {
422
                parseDocSequence("FixedDocumentSequence.fdseq");
423
                resolveLinks();
424
        }
425
        else
426
                retVal = false;
427
        uz->close();
428
        delete uz;
429
        if (progressDialog)
430
                progressDialog->close();
431
        return retVal;
432
}
433
 
434
void XpsPlug::parseDocSequence(QString designMap)
435
{
436
        QByteArray f;
437
        QDomDocument designMapDom;
438
        if (!uz->read(designMap, f))
439
                return;
440
        if(designMapDom.setContent(f))
441
        {
442
                QString DocumentReference = "";
443
                QDomElement docElem = designMapDom.documentElement();
444
                for(QDomNode drawPag = docElem.firstChild(); !drawPag.isNull(); drawPag = drawPag.nextSibling() )
445
                {
446
                        QDomElement dpg = drawPag.toElement();
447
                        if (dpg.tagName() == "DocumentReference")
448
                        {
449
                                if (dpg.hasAttribute("Source"))
450
                                {
451
                                        DocumentReference = dpg.attribute("Source", "");
452
                                        if (DocumentReference.startsWith("/"))
453
                                                DocumentReference = DocumentReference.mid(1);
454
                                        parseDocReference(DocumentReference);
455
                                }
456
                        }
457
                }
458
        }
459
}
460
 
461
void XpsPlug::parseDocReference(QString designMap)
462
{
463
        QByteArray f;
464
        QFileInfo fi(designMap);
465
        QString path = fi.path();
466
        if (uz->read(designMap, f))
467
        {
468
                QDomDocument designMapDom;
469
                if(designMapDom.setContent(f))
470
                {
471
                        QString PageReference = "";
472
                        QDomElement docElem = designMapDom.documentElement();
473
                        if (importerFlags & LoadSavePlugin::lfCreateThumbnail)
474
                        {
475
                                QDomNodeList pgList = docElem.childNodes();
476
                                QDomNode drawPag = pgList.item(0);
477
                                QDomElement dpg = drawPag.toElement();
478
                                if (dpg.tagName() == "PageContent")
479
                                {
480
                                        if (dpg.hasAttribute("Source"))
481
                                        {
482
                                                PageReference = dpg.attribute("Source", "");
483
                                                if (PageReference.startsWith("/"))
484
                                                {
485
                                                        PageReference = PageReference.mid(1);
486
                                                        parsePageReference(PageReference);
487
                                                }
488
                                                else
489
                                                {
490
                                                        if (!PageReference.startsWith(path))
18603 fschmid 491
                                                        {
18598 fschmid 492
                                                                PageReference = path + "/" + PageReference;
18603 fschmid 493
                                                                PageReference = QDir::cleanPath(PageReference);
494
                                                        }
18598 fschmid 495
                                                        parsePageReference(PageReference);
496
                                                }
497
                                        }
498
                                }
499
                        }
500
                        else
501
                        {
502
                                std::vector<int> pageNs;
503
                                QString pageString = "*";
504
                                int pgCount = 0;
505
                                int maxPages = docElem.childNodes().count();
506
                                if (((interactive) || (importerFlags & LoadSavePlugin::lfCreateDoc)) && (maxPages > 1))
507
                                {
508
                                        if (progressDialog)
509
                                                progressDialog->hide();
510
                                        qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
511
                                        XpsImportOptions *optImp = new XpsImportOptions(ScCore->primaryMainWindow());
512
                                        optImp->setUpOptions(m_FileName, 1, maxPages, interactive);
513
                                        optImp->exec();
514
                                        pageString = optImp->getPagesString();
515
                                        delete optImp;
516
                                        qApp->changeOverrideCursor(QCursor(Qt::WaitCursor));
517
                                        if (progressDialog)
518
                                                progressDialog->show();
519
                                        qApp->processEvents();
520
                                }
521
                                parsePagesString(pageString, &pageNs, maxPages);
522
                                if (pageString != "*")
523
                                        maxPages = pageNs.size();
524
                                if (progressDialog)
525
                                {
526
                                        progressDialog->setTotalSteps("GI", maxPages);
527
                                        progressDialog->setProgress("GI", pgCount);
528
                                        qApp->processEvents();
529
                                }
530
                                QDomNodeList pgList = docElem.childNodes();
531
                                for (uint ap = 0; ap < pageNs.size(); ++ap)
532
                                {
533
                                        QDomNode drawPag = pgList.item(pageNs[ap] - 1);
534
                                        QDomElement dpg = drawPag.toElement();
535
                                        if (dpg.tagName() == "PageContent")
536
                                        {
537
                                                if (dpg.hasAttribute("Source"))
538
                                                {
539
                                                        PageReference = dpg.attribute("Source", "");
540
                                                        if (PageReference.startsWith("/"))
541
                                                        {
542
                                                                PageReference = PageReference.mid(1);
543
                                                                parsePageReference(PageReference);
544
                                                        }
545
                                                        else
546
                                                        {
547
                                                                if (!PageReference.startsWith(path))
18603 fschmid 548
                                                                {
18598 fschmid 549
                                                                        PageReference = path + "/" + PageReference;
18603 fschmid 550
                                                                        PageReference = QDir::cleanPath(PageReference);
551
                                                                }
18598 fschmid 552
                                                                parsePageReference(PageReference);
553
                                                        }
554
                                                }
555
                                        }
556
                                        pgCount++;
557
                                        if (progressDialog)
558
                                        {
559
                                                progressDialog->setProgress("GI", pgCount);
560
                                                qApp->processEvents();
561
                                        }
562
                                }
563
                        }
564
                }
565
        }
566
}
567
 
568
void XpsPlug::parsePageReference(QString designMap)
569
{
570
        QByteArray f;
571
        QFileInfo fi(designMap);
572
        QString path = fi.path();
573
        if (uz->read(designMap, f))
574
        {
575
                QDomDocument designMapDom;
576
                if(designMapDom.setContent(f))
577
                {
578
                        QDomElement docElem = designMapDom.documentElement();
579
                        docWidth = docElem.attribute("Width", QString("%1").arg(PrefsManager::instance()->appPrefs.docSetupPrefs.pageWidth)).toDouble() * conversionFactor;
580
                        docHeight = docElem.attribute("Height", QString("%1").arg(PrefsManager::instance()->appPrefs.docSetupPrefs.pageHeight)).toDouble() * conversionFactor;
581
                        if (importerFlags & LoadSavePlugin::lfCreateDoc)
582
                        {
583
                                if (firstPage)
584
                                {
585
                                        topMargin = m_Doc->marginsVal().Top;
586
                                        leftMargin = m_Doc->marginsVal().Left;
587
                                        rightMargin = m_Doc->marginsVal().Right;
588
                                        bottomMargin = m_Doc->marginsVal().Bottom;
589
                                        double pgCols = m_Doc->PageSp;
590
                                        double pgGap = m_Doc->PageSpa;
591
                                        m_Doc->setPage(docWidth, docHeight, topMargin, leftMargin, rightMargin, bottomMargin, pgCols, pgGap, false, false);
592
                                        m_Doc->setPageSize("Custom");
593
                                        m_Doc->currentPage()->m_pageSize = "Custom";
594
                                        m_Doc->currentPage()->setInitialHeight(docHeight);
595
                                        m_Doc->currentPage()->setInitialWidth(docWidth);
596
                                        m_Doc->currentPage()->setHeight(docHeight);
597
                                        m_Doc->currentPage()->setWidth(docWidth);
598
                                        m_Doc->currentPage()->initialMargins.Top = topMargin;
599
                                        m_Doc->currentPage()->initialMargins.Bottom = bottomMargin;
600
                                        m_Doc->currentPage()->initialMargins.Left = leftMargin;
601
                                        m_Doc->currentPage()->initialMargins.Right = rightMargin;
602
                                        m_Doc->reformPages(true);
603
                                }
604
                                else
605
                                {
606
                                        m_Doc->addPage(pagecount);
607
                                        m_Doc->currentPage()->m_pageSize = "Custom";
608
                                        m_Doc->currentPage()->setInitialHeight(docHeight);
609
                                        m_Doc->currentPage()->setInitialWidth(docWidth);
610
                                        m_Doc->currentPage()->setHeight(docHeight);
611
                                        m_Doc->currentPage()->setWidth(docWidth);
612
                                        m_Doc->currentPage()->initialMargins.Top = topMargin;
613
                                        m_Doc->currentPage()->initialMargins.Bottom = bottomMargin;
614
                                        m_Doc->currentPage()->initialMargins.Left = leftMargin;
615
                                        m_Doc->currentPage()->initialMargins.Right = rightMargin;
616
                                        m_Doc->currentPage()->MPageNam = CommonStrings::trMasterPageNormal;
617
                                        m_Doc->view()->addPage(pagecount, true);
618
                                        pagecount++;
619
                                }
620
                        }
621
                        firstPage = false;
622
                        baseX = m_Doc->currentPage()->xOffset();
623
                        baseY = m_Doc->currentPage()->yOffset();
624
                        for(QDomNode drawPag = docElem.firstChild(); !drawPag.isNull(); drawPag = drawPag.nextSibling() )
625
                        {
626
                                QDomElement dpg = drawPag.toElement();
627
                                if ((dpg.tagName() == "Path") || (dpg.tagName() == "Glyphs") || (dpg.tagName() == "Canvas"))
628
                                {
629
                                        PageItem* item = parseObjectXML(dpg, path);
630
                                        if (item != NULL)
631
                                        {
632
                                                m_Doc->Items->append(item);
633
                                                Elements.append(item);
634
                                        }
635
                                }
636
                                else if (dpg.tagName() == "FixedPage.Resources")
637
                                {
638
                                        for(QDomNode sp = dpg.firstChild(); !sp.isNull(); sp = sp.nextSibling() )
639
                                        {
640
                                                QDomElement spe = sp.toElement();
641
                                                if (spe.tagName() == "ResourceDictionary")
642
                                                {
643
                                                        if (spe.hasAttribute("Source"))
644
                                                        {
645
                                                                QString resFile = spe.attribute("Source", "");
646
                                                                if (resFile.startsWith("/"))
647
                                                                {
648
                                                                        resFile = resFile.mid(1);
649
                                                                        parseResourceFile(resFile);
650
                                                                }
651
                                                                else
652
                                                                {
653
                                                                        if (!resFile.startsWith(path))
18603 fschmid 654
                                                                        {
18598 fschmid 655
                                                                                resFile = path + "/" + resFile;
18603 fschmid 656
                                                                                resFile = QDir::cleanPath(resFile);
657
                                                                        }
18598 fschmid 658
                                                                        parseResourceFile(resFile);
659
                                                                }
660
                                                        }
661
                                                        else if (spe.hasChildNodes())
662
                                                        {
663
                                                                for(QDomElement dpgp = spe.firstChildElement(); !dpgp.isNull(); dpgp = dpgp.nextSiblingElement() )
664
                                                                {
665
                                                                        if (dpgp.tagName() == "PathGeometry")
666
                                                                        {
667
                                                                                Coords.resize(0);
668
                                                                                Coords.svgInit();
669
                                                                                QString pdata = "";
670
                                                                                QString key = dpg.attribute("x:Key");
671
                                                                                if (dpg.hasAttribute("Figures"))
672
                                                                                        pdata = dpg.attribute("Figures");
673
                                                                                else if (dpg.hasChildNodes())
674
                                                                                        pdata = parsePathGeometryXML(dpg);
675
                                                                                if (!pdata.isEmpty())
676
                                                                                {
677
                                                                                        bool currentPathClosed = Coords.parseSVG(pdata);
678
                                                                                        Coords.scale(conversionFactor, conversionFactor);
679
                                                                                        QPainterPath path = Coords.toQPainterPath(!currentPathClosed);
680
                                                                                        if (dpg.attribute("FillRule") == "NonZero")
681
                                                                                                path.setFillRule(Qt::WindingFill);
682
                                                                                        pathResources.insert(key, path);
683
                                                                                }
684
                                                                        }
685
                                                                }
686
                                                        }
687
                                                }
688
                                        }
689
                                }
690
                        }
691
                }
692
        }
693
}
694
 
695
PageItem* XpsPlug::parseObjectXML(QDomElement &dpg, QString path)
696
{
697
        PageItem *retObj = NULL;
698
        ObjState obState;
699
        obState.currentPath = QPainterPath();
700
        obState.clipPath = QPainterPath();
701
        obState.transform = QTransform();
702
        obState.CurrColorFill = CommonStrings::None;
703
        obState.fillOpacity = 0.0;
704
        obState.CurrColorStroke = CommonStrings::None;
705
        obState.strokeOpacity = 0.0;
706
        obState.LineW = 1.0;
707
        obState.fillGradientTyp = 0;
708
        obState.gradientScale = 1.0;
709
        obState.maskTyp = 0;
710
        obState.strokeTyp = 0;
711
        obState.imagePath = "";
712
        obState.itemType = 0;
713
        obState.patternName = "";
714
        obState.patternMask = "";
715
        obState.CapStyle = Qt::FlatCap;
716
        obState.JoinStyle = Qt::MiterJoin;
18628 fschmid 717
        obState.DashOffset = 0;
718
        obState.DashPattern.clear();
18598 fschmid 719
        QString itemName = "";
720
        QString itemTarget = "";
721
        if (dpg.hasAttribute("Name"))
722
                itemName = dpg.attribute("Name");
723
        if (dpg.hasAttribute("FixedPage.NavigateUri"))
724
        {
725
                QString iTg = dpg.attribute("FixedPage.NavigateUri");
726
                QStringList tg = iTg.split("#");
727
                if (tg.count() > 1)
728
                        itemTarget = tg[1];
729
        }
730
        if (dpg.hasAttribute("RenderTransform"))
731
        {
732
                QString trans = dpg.attribute("RenderTransform", "1 0 0 1 0 0");
733
                trans.replace(",", " ");
734
                ScTextStream list(&trans, QIODevice::ReadOnly);
735
                double a, b, c, d, e, f;
736
                list >> a >> b >> c >> d >> e >> f;
737
                obState.transform = QTransform(a, b, c, d, e * conversionFactor, f * conversionFactor);
738
        }
739
        if (dpg.hasAttribute("Fill"))
740
                obState.CurrColorFill = handleColor(dpg.attribute("Fill", "#FF000000"), obState.fillOpacity);
741
        if (dpg.hasAttribute("Stroke"))
742
                obState.CurrColorStroke = handleColor(dpg.attribute("Stroke", "#FF000000"), obState.strokeOpacity);
743
        if (dpg.hasAttribute("Opacity"))
744
        {
745
                double opacity = dpg.attribute("Opacity", "1.0").toDouble();
746
                obState.fillOpacity = 1.0 - ((1.0 - obState.fillOpacity) * opacity);
747
                obState.strokeOpacity = 1.0 - ((1.0 - obState.strokeOpacity) * opacity);
748
        }
749
        if (dpg.hasAttribute("StrokeThickness"))
750
                obState.LineW = dpg.attribute("StrokeThickness", "1.0").toDouble() * conversionFactor;
751
        if (dpg.hasAttribute("StrokeDashCap"))
752
        {
753
                if (dpg.attribute("StrokeDashCap") == "Flat")
754
                        obState.CapStyle = Qt::FlatCap;
755
                else if (dpg.attribute("StrokeDashCap") == "Round")
756
                        obState.CapStyle = Qt::RoundCap;
757
                else if (dpg.attribute("StrokeDashCap") == "Square")
758
                        obState.CapStyle = Qt::SquareCap;
759
                else
760
                        obState.CapStyle = Qt::FlatCap;
761
        }
762
        if (dpg.hasAttribute("StrokeLineJoin"))
763
        {
764
                if (dpg.attribute("StrokeLineJoin") == "Miter")
765
                        obState.JoinStyle = Qt::MiterJoin;
766
                else if (dpg.attribute("StrokeLineJoin") == "Round")
767
                        obState.JoinStyle = Qt::RoundJoin;
768
                else if (dpg.attribute("StrokeLineJoin") == "Bevel")
769
                        obState.JoinStyle = Qt::BevelJoin;
770
                else
771
                        obState.JoinStyle = Qt::MiterJoin;
772
        }
18628 fschmid 773
        if (dpg.hasAttribute("StrokeDashOffset"))
774
                obState.DashOffset = dpg.attribute("StrokeDashOffset", "0.0").toDouble();
775
        if (dpg.hasAttribute("StrokeDashArray"))
776
        {
777
                QString trans = dpg.attribute("StrokeDashArray", "");
778
                if (!trans.isEmpty())
779
                {
780
                        ScTextStream list(&trans, QIODevice::ReadOnly);
781
                        while (!list.atEnd())
782
                        {
783
                                double d;
784
                                list >> d;
785
                                obState.DashPattern.append(d);
786
                        }
787
                }
788
        }
18598 fschmid 789
        if (dpg.hasAttribute("Clip"))
790
        {
791
                QString cdata = dpg.attribute("Clip");
792
                if (!cdata.startsWith("{"))
793
                {
794
                        Coords.resize(0);
795
                        Coords.svgInit();
796
                        Coords.parseSVG(cdata);
797
                        Coords.scale(conversionFactor, conversionFactor);
798
                        obState.clipPath = Coords.toQPainterPath(true);
799
                        obState.clipPath = obState.transform.map(obState.clipPath);
800
                }
801
                else
802
                {
803
                        cdata.remove("{StaticResource ");
804
                        cdata.remove("}");
805
                        cdata = cdata.trimmed();
806
                        if (pathResources.contains(cdata))
807
                                obState.clipPath = obState.transform.map(pathResources[cdata]);
808
                }
809
        }
810
        if (dpg.tagName() == "Glyphs")
811
        {
812
                if (dpg.hasChildNodes())
813
                {
814
                        for(QDomNode sp = dpg.firstChild(); !sp.isNull(); sp = sp.nextSibling() )
815
                        {
816
                                QDomElement spe = sp.toElement();
817
                                if (spe.tagName() == "Glyphs.Fill")
818
                                        parseFillXML(spe, path, obState);
819
                                else if (spe.tagName() == "Glyphs.OpacityMask")
820
                                        parseOpacityXML(spe, path, obState);
821
                                else if (spe.tagName() == "Glyphs.Clip")
822
                                        parsePathDataXML(spe, obState, true);
823
                        }
824
                }
825
                QString utfString = dpg.attribute("UnicodeString");
826
                if (utfString.startsWith("{}"))
827
                        utfString = utfString.mid(2);
828
                QString Indices = dpg.attribute("Indices");
829
                QString tstStr = utfString.trimmed();
830
                if (tstStr.isEmpty() && Indices.isEmpty())
831
                        return retObj;
832
                QString fontUrl = dpg.attribute("FontUri");
833
                if (fontUrl.startsWith("/"))
834
                {
835
                        fontUrl = fontUrl.mid(1);
836
                }
837
                else
838
                {
839
                        if (!fontUrl.startsWith(path))
18603 fschmid 840
                        {
18598 fschmid 841
                                fontUrl = path + "/" + fontUrl;
18603 fschmid 842
                                fontUrl = QDir::cleanPath(fontUrl);
843
                        }
18598 fschmid 844
                }
845
                ScFace iteFont = loadFontByName(fontUrl);
846
                if (iteFont.usable())
847
                {
848
                        double fontSize = dpg.attribute("FontRenderingEmSize", "0").toDouble() * conversionFactor;
849
                        bool bold = false;
850
                        bool italic = false;
851
                        if (dpg.hasAttribute("StyleSimulations"))
852
                        {
853
                                bold = dpg.attribute("StyleSimulations") == "BoldSimulation";
854
                                italic = dpg.attribute("StyleSimulations") == "ItalicSimulation";
855
                                if (dpg.attribute("StyleSimulations") == "BoldItalicSimulation")
856
                                {
857
                                        bold = true;
858
                                        italic = true;
859
                                }
860
                        }
861
                        double fontSizeEM = fontSize;
862
                        if (fontSize > 1)
863
                        {
864
                                double xPos = dpg.attribute("OriginX", "0").toDouble() * conversionFactor;
865
                                double yPos = dpg.attribute("OriginY", "0").toDouble() * conversionFactor;
866
                                QPointF origin(xPos, yPos);
867
                                QStringList glIndices = Indices.split(";");
868
                                double asc = iteFont.ascent() - iteFont.descent();
869
                                fontSize /= asc;
870
                                int glInd = 0;
871
                                if (!utfString.isEmpty())
872
                                {
873
                                        for (int sti = 0; sti < utfString.length(); sti++)
874
                                        {
875
                                                QChar utfChar = utfString[sti];
876
                                                if (iteFont.canRender(utfChar))
877
                                                {
878
                                                        uint chr = utfChar.unicode();
879
                                                        uint gl = iteFont.char2CMap(chr);
880
                                                        double adv = iteFont.glyphWidth(gl, fontSize);
881
                                                        double offX = 0;
882
                                                        double offY = 0;
883
                                                        FPointArray pts;
884
                                                        if (Indices.isEmpty())
885
                                                        {
886
                                                                if (!utfChar.isSpace())
887
                                                                        pts = iteFont.glyphOutline(gl, fontSize);
888
                                                        }
889
                                                        else
890
                                                        {
891
                                                                if (glInd < glIndices.count())
892
                                                                {
893
                                                                        QStringList glyInd = glIndices[glInd].split(",");
894
                                                                        if (glyInd.count() > 1)
895
                                                                        {
896
                                                                                if (glyInd.count() > 2)
897
                                                                                        offX = glyInd[2].toDouble() * fontSizeEM / 100.0;
898
                                                                                if (glyInd.count() > 3)
899
                                                                                        offY = glyInd[3].toDouble() * fontSizeEM / 100.0;
900
                                                                                if (!glyInd[1].isEmpty())
901
                                                                                        adv = glyInd[1].toDouble() * fontSizeEM / 100.0;
902
                                                                        }
903
                                                                        if (glyInd.count() > 0)
904
                                                                        {
905
                                                                                if (!glyInd[0].isEmpty())
906
                                                                                {
907
                                                                                        if (glyInd[0].startsWith("("))
908
                                                                                        {
909
                                                                                                int r = glyInd[0].indexOf(")");
910
                                                                                                QString comb = glyInd[0].mid(1, r-1);
911
                                                                                                QStringList combInd = comb.split(":");
912
                                                                                                int advUtf = combInd[0].toInt() - 1;
913
                                                                                                sti += advUtf;
914
                                                                                                glyInd[0].remove(0, r+1);
915
                                                                                        }
916
                                                                                        uint gli = glyInd[0].toUInt();
917
                                                                                        pts = iteFont.glyphOutline(gli, fontSize);
918
                                                                                        if (((glyInd.count() > 1) && (glyInd[1].isEmpty())) || (glyInd.count() == 1))
919
                                                                                                adv = iteFont.glyphWidth(gli, fontSize);
920
                                                                                }
921
                                                                                else if (!utfChar.isSpace())
922
                                                                                        pts = iteFont.glyphOutline(gl, fontSize);
923
                                                                        }
924
                                                                }
925
                                                        }
926
                                                        if (pts.count() > 3)
927
                                                        {
928
                                                                QTransform cht;
929
                                                                cht.scale(0.1, 0.1);
930
                                                                pts.map(cht);
931
                                                                pts.translate(0, -fontSize);
932
                                                                if (bold)
933
                                                                {
934
                                                                        QTransform bot;
935
                                                                        bot.scale(1.02, 1.02);
936
                                                                        pts.map(bot);
937
                                                                        adv *= 1.02;
938
                                                                }
939
                                                                if (italic)
940
                                                                {
941
                                                                        QTransform bot;
942
                                                                        bot.shear(-0.3491, 0);
943
                                                                        pts.map(bot);
944
                                                                }
945
                                                                pts.translate(origin.x() + offX, origin.y() + offY);
946
                                                                obState.currentPath.addPath(pts.toQPainterPath(true));
947
                                                        }
948
                                                        origin += QPointF(adv, 0);
949
                                                }
950
                                                else
951
                                                {
952
                                                        QFont eFont(iteFont.family());
953
                                                        eFont.setPointSizeF(fontSize);
954
                                                        eFont.setBold(bold);
955
                                                        eFont.setItalic(italic);
956
                                                        QFontMetricsF ft(eFont);
957
                                                        obState.currentPath.addText(origin, eFont, utfChar);
958
                                                        origin += QPointF(ft.width(utfChar), 0);
959
                                                }
960
                                                glInd++;
961
                                        }
962
                                }
963
                                else if (!Indices.isEmpty())
964
                                {
965
                                        double adv = 0;
966
                                        double offX = 0;
967
                                        double offY = 0;
968
                                        for (int glInd = 0; glInd < glIndices.count(); glInd++)
969
                                        {
970
                                                FPointArray pts;
971
                                                QStringList glyInd = glIndices[glInd].split(",");
972
                                                if (glyInd.count() > 1)
973
                                                {
974
                                                        if (glyInd.count() > 2)
975
                                                                offX = glyInd[2].toDouble() * fontSizeEM / 100.0;
976
                                                        if (glyInd.count() > 3)
977
                                                                offY = glyInd[3].toDouble() * fontSizeEM / 100.0;
978
                                                        if (!glyInd[1].isEmpty())
979
                                                                adv = glyInd[1].toDouble() * fontSizeEM / 100.0;
980
                                                }
981
                                                if (glyInd.count() > 0)
982
                                                {
983
                                                        if (!glyInd[0].isEmpty())
984
                                                        {
985
                                                                if (glyInd[0].startsWith("("))
986
                                                                {
987
                                                                        int r = glyInd[0].indexOf(")");
988
                                                                        QString comb = glyInd[0].mid(1, r-1);
989
                                                                        QStringList combInd = comb.split(":");
990
                                                                        int advUtf = combInd[0].toInt() - 1;
991
                                                                        glInd += advUtf;
992
                                                                        glyInd[0].remove(0, r+1);
993
                                                                }
994
                                                                uint gli = glyInd[0].toUInt();
995
                                                                pts = iteFont.glyphOutline(gli, fontSize);
996
                                                                if (((glyInd.count() > 1) && (glyInd[1].isEmpty())) || (glyInd.count() == 1))
997
                                                                        adv = iteFont.glyphWidth(gli, fontSize);
998
                                                        }
999
                                                }
1000
                                                if (pts.count() > 3)
1001
                                                {
1002
                                                        QTransform cht;
1003
                                                        cht.scale(0.1, 0.1);
1004
                                                        pts.map(cht);
1005
                                                        pts.translate(0, -fontSize);
1006
                                                        if (bold)
1007
                                                        {
1008
                                                                QTransform bot;
1009
                                                                bot.scale(1.02, 1.02);
1010
                                                                pts.map(bot);
1011
                                                                adv *= 1.02;
1012
                                                        }
1013
                                                        if (italic)
1014
                                                        {
1015
                                                                QTransform bot;
1016
                                                                bot.shear(-0.3491, 0);
1017
                                                                pts.map(bot);
1018
                                                        }
1019
                                                        pts.translate(origin.x() + offX, origin.y() + offY);
1020
                                                        obState.currentPath.addPath(pts.toQPainterPath(true));
1021
                                                }
1022
                                                origin += QPointF(adv, 0);
1023
                                        }
1024
                                }
1025
                                if (!obState.currentPath.isEmpty())
1026
                                {
1027
                                        obState.currentPath = obState.transform.map(obState.currentPath);
1028
                                        retObj = createItem(dpg, obState);
1029
                                        if (!obState.clipPath.isEmpty())
1030
                                                retObj = addClip(retObj, obState);
1031
                                }
1032
                        }
1033
                }
1034
        }
1035
        else if (dpg.tagName() == "Path")
1036
        {
1037
                bool pathFromChild = false;
1038
                if (dpg.hasChildNodes())
1039
                {
1040
                        for(QDomNode sp = dpg.firstChild(); !sp.isNull(); sp = sp.nextSibling() )
1041
                        {
1042
                                QDomElement spe = sp.toElement();
1043
                                if (spe.tagName() == "Path.Fill")
1044
                                        parseFillXML(spe, path, obState);
1045
                                else if (spe.tagName() == "Path.OpacityMask")
1046
                                        parseOpacityXML(spe, path, obState);
1047
                                else if (spe.tagName() == "Path.Stroke")
1048
                                        parseStrokeXML(spe, path, obState);
1049
                                else if (spe.tagName() == "Path.RenderTransform")
1050
                                {
1051
                                        for(QDomNode obg = spe.firstChild(); !obg.isNull(); obg = obg.nextSibling() )
1052
                                        {
1053
                                                QDomElement eog = obg.toElement();
1054
                                                if (eog.tagName() == "MatrixTransform")
1055
                                                {
1056
                                                        QString trans = eog.attribute("Matrix", "1 0 0 1 0 0");
1057
                                                        trans.replace(",", " ");
1058
                                                        ScTextStream list(&trans, QIODevice::ReadOnly);
1059
                                                        double a, b, c, d, e, f;
1060
                                                        list >> a >> b >> c >> d >> e >> f;
1061
                                                        obState.transform = QTransform(a, b, c, d, e * conversionFactor, f * conversionFactor);
1062
                                                }
1063
                                        }
1064
                                }
1065
                                else if (spe.tagName() == "Path.Data")
1066
                                {
1067
                                        parsePathDataXML(spe, obState);
1068
                                        pathFromChild = true;
1069
                                }
1070
                                else if (spe.tagName() == "Path.Clip")
1071
                                        parsePathDataXML(spe, obState, true);
1072
                        }
1073
                }
1074
                if (!pathFromChild)
1075
                {
1076
                        QString pdata = dpg.attribute("Data");
1077
                        if (!pdata.startsWith("{"))
1078
                        {
1079
                                Coords.resize(0);
1080
                                Coords.svgInit();
1081
                                obState.currentPathClosed = Coords.parseSVG(pdata);
1082
                                Coords.scale(conversionFactor, conversionFactor);
1083
                                obState.currentPath = Coords.toQPainterPath(!obState.currentPathClosed);
1084
                                if (obState.currentPath.isEmpty())
1085
                                        return retObj;
1086
                                obState.currentPath = obState.transform.map(obState.currentPath);
1087
                        }
1088
                        else
1089
                        {
1090
                                pdata.remove("{StaticResource ");
1091
                                pdata.remove("}");
1092
                                pdata = pdata.trimmed();
1093
                                if (pathResources.contains(pdata))
1094
                                        obState.currentPath = obState.transform.map(pathResources[pdata]);
1095
                                if (obState.currentPath.isEmpty())
1096
                                        return retObj;
1097
                        }
1098
                }
1099
                if (obState.currentPath.isEmpty())
1100
                        return retObj;
1101
                retObj = createItem(dpg, obState);
1102
                if (!obState.clipPath.isEmpty())
1103
                        retObj = addClip(retObj, obState);
1104
        }
1105
        else if (dpg.tagName() == "Canvas")
1106
        {
1107
                QList<PageItem*> GElements;
1108
                for(QDomNode sp = dpg.firstChild(); !sp.isNull(); sp = sp.nextSibling() )
1109
                {
1110
                        QDomElement spe = sp.toElement();
18609 fschmid 1111
                        if (spe.tagName() == "Canvas.RenderTransform")
18598 fschmid 1112
                        {
1113
                                for(QDomNode obg = spe.firstChild(); !obg.isNull(); obg = obg.nextSibling() )
1114
                                {
1115
                                        QDomElement eog = obg.toElement();
1116
                                        if (eog.tagName() == "MatrixTransform")
1117
                                        {
1118
                                                QString trans = eog.attribute("Matrix", "1 0 0 1 0 0");
1119
                                                trans.replace(",", " ");
1120
                                                ScTextStream list(&trans, QIODevice::ReadOnly);
1121
                                                double a, b, c, d, e, f;
1122
                                                list >> a >> b >> c >> d >> e >> f;
1123
                                                obState.transform = QTransform(a, b, c, d, e * conversionFactor, f * conversionFactor);
1124
                                        }
1125
                                }
1126
                        }
18609 fschmid 1127
                        else if ((spe.tagName() == "Path") || (spe.tagName() == "Glyphs") || (spe.tagName() == "Canvas"))
1128
                        {
1129
                                PageItem* ite = parseObjectXML(spe, path);
1130
                                if (ite != NULL)
1131
                                        GElements.append(ite);
1132
                        }
18598 fschmid 1133
                        else if (spe.tagName() == "Canvas.OpacityMask")
1134
                                parseOpacityXML(spe, path, obState);
1135
                        else if (spe.tagName() == "Canvas.Resources")
1136
                        {
1137
                                for(QDomNode obg = spe.firstChild(); !obg.isNull(); obg = obg.nextSibling() )
1138
                                {
1139
                                        QDomElement eog = obg.toElement();
1140
                                        if (eog.tagName() == "ResourceDictionary")
1141
                                        {
1142
                                                if (eog.hasAttribute("Source"))
1143
                                                {
1144
                                                        QString resFile = eog.attribute("Source", "");
1145
                                                        if (resFile.startsWith("/"))
1146
                                                        {
1147
                                                                resFile = resFile.mid(1);
1148
                                                                parseResourceFile(resFile);
1149
                                                        }
1150
                                                        else
1151
                                                        {
1152
                                                                if (!resFile.startsWith(path))
18603 fschmid 1153
                                                                {
18598 fschmid 1154
                                                                        resFile = path + "/" + resFile;
18603 fschmid 1155
                                                                        resFile = QDir::cleanPath(resFile);
1156
                                                                }
18598 fschmid 1157
                                                                parseResourceFile(resFile);
1158
                                                        }
1159
                                                }
1160
                                                else if (eog.hasChildNodes())
1161
                                                {
1162
                                                        for(QDomElement dpgp = eog.firstChildElement(); !dpgp.isNull(); dpgp = dpgp.nextSiblingElement() )
1163
                                                        {
1164
                                                                if (dpgp.tagName() == "PathGeometry")
1165
                                                                {
1166
                                                                        Coords.resize(0);
1167
                                                                        Coords.svgInit();
1168
                                                                        QString pdata = "";
1169
                                                                        QString key = dpg.attribute("x:Key");
1170
                                                                        if (dpg.hasAttribute("Figures"))
1171
                                                                                pdata = dpg.attribute("Figures");
1172
                                                                        else if (dpg.hasChildNodes())
1173
                                                                                pdata = parsePathGeometryXML(dpg);
1174
                                                                        if (!pdata.isEmpty())
1175
                                                                        {
1176
                                                                                bool currentPathClosed = Coords.parseSVG(pdata);
1177
                                                                                Coords.scale(conversionFactor, conversionFactor);
1178
                                                                                QPainterPath path = Coords.toQPainterPath(!currentPathClosed);
1179
                                                                                if (dpg.attribute("FillRule") == "NonZero")
1180
                                                                                        path.setFillRule(Qt::WindingFill);
1181
                                                                                pathResources.insert(key, path);
1182
                                                                        }
1183
                                                                }
1184
                                                        }
1185
                                                }
1186
                                        }
1187
                                }
1188
                        }
1189
                        else if (spe.tagName() == "Canvas.Clip")
1190
                                parsePathDataXML(spe, obState, true);
1191
                }
1192
                if (GElements.count() > 0)
1193
                {
1194
                        double minx =  std::numeric_limits<double>::max();
1195
                        double miny =  std::numeric_limits<double>::max();
1196
                        double maxx = -std::numeric_limits<double>::max();
1197
                        double maxy = -std::numeric_limits<double>::max();
1198
                        for (int ep = 0; ep < GElements.count(); ++ep)
1199
                        {
1200
                                PageItem* currItem = GElements.at(ep);
1201
                                double x1, x2, y1, y2;
1202
                                currItem->getVisualBoundingRect(&x1, &y1, &x2, &y2);
1203
                                minx = qMin(minx, x1);
1204
                                miny = qMin(miny, y1);
1205
                                maxx = qMax(maxx, x2);
1206
                                maxy = qMax(maxy, y2);
1207
                        }
18609 fschmid 1208
                        double gx = qMin(baseX, minx);
1209
                        double gy = qMin(baseY, miny);
1210
                        double gw = maxx - qMin(baseX, minx);
1211
                        double gh = maxy - qMin(baseY, miny);
18598 fschmid 1212
                        int z = m_Doc->itemAdd(PageItem::Group, PageItem::Rectangle, gx, gy, gw, gh, 0, CommonStrings::None, CommonStrings::None, true);
1213
                        if (z >= 0)
1214
                        {
1215
                                retObj = m_Doc->Items->at(z);
1216
                                retObj->ClipEdited = true;
1217
                                retObj->FrameType = 3;
1218
                                retObj->setFillEvenOdd(false);
1219
                                retObj->OldB2 = retObj->width();
1220
                                retObj->OldH2 = retObj->height();
1221
                                retObj->updateClip();
1222
                                m_Doc->groupObjectsToItem(retObj, GElements);
18647 fschmid 1223
                                double scX = 1.0;
1224
                                double scY = 1.0;
1225
                                double rot = 0.0;
1226
                                double dx = 0.0;
1227
                                double dy = 0.0;
1228
                                getTransformValuesFromMatrix( obState.transform, scX, scY, rot, dx, dy);
1229
                                if ((scX != 1.0) || (scY != 1.0))
1230
                                        retObj->PoLine.scale(scX, scY);
18609 fschmid 1231
                                FPoint wh = getMaxClipF(&retObj->PoLine);
1232
                                retObj->setWidthHeight(wh.x(),wh.y());
1233
                                m_Doc->AdjustItemSize(retObj, true);
1234
                                retObj->OldB2 = retObj->width();
1235
                                retObj->OldH2 = retObj->height();
18647 fschmid 1236
                                if ((dx != 0.0) || (dy != 0.0))
1237
                                        retObj->moveBy(dx, dy, true);
18598 fschmid 1238
                                if (obState.maskTyp != 0)
1239
                                {
1240
                                        double xp = retObj->xPos() - m_Doc->currentPage()->xOffset();
1241
                                        double yp = retObj->yPos() - m_Doc->currentPage()->yOffset();
1242
                                        retObj->setMaskGradient(obState.gradientMask);
1243
                                        retObj->setMaskVector(obState.maskStart.x() - xp, obState.maskStart.y() - yp, obState.maskEnd.x() - xp, obState.maskEnd.y() - yp, obState.maskFocus.x() - xp, obState.maskFocus.y() - yp, obState.maskScale, 0);
1244
                                        retObj->setMaskType(obState.maskTyp);
1245
                                }
18647 fschmid 1246
                                if (rot != 0)
1247
                                        retObj->setRotation(-rot, true);
18637 fschmid 1248
                                m_Doc->resizeGroupToContents(retObj);
18598 fschmid 1249
                                retObj->OwnPage = m_Doc->OnPage(retObj);
1250
                                m_Doc->GroupOnPage(retObj);
1251
                                m_Doc->Items->removeLast();
1252
                                if (!obState.clipPath.isEmpty())
1253
                                        retObj = addClip(retObj, obState);
1254
                        }
1255
                }
1256
        }
1257
        if (retObj != NULL)
1258
        {
1259
                if (!itemName.isEmpty())
1260
                {
1261
                        linkTargets.insert(itemName, retObj);
1262
                        retObj->setItemName(itemName);
1263
                }
1264
                if ((!itemTarget.isEmpty()) && (dpg.tagName() != "Canvas"))
1265
                {
1266
                        linkSources.insert(retObj, itemTarget);
1267
                        retObj->setIsAnnotation(true);
1268
                        retObj->annotation().setType(Annotation::Link);
1269
                        retObj->annotation().setZiel(m_Doc->currentPage()->pageNr());
1270
                        retObj->annotation().setAction("0 0");
1271
                        retObj->setTextFlowMode(PageItem::TextFlowDisabled);
1272
                }
1273
        }
1274
        return retObj;
1275
}
1276
 
1277
void XpsPlug::parseOpacityXML(QDomElement &spe, QString path, ObjState &obState)
1278
{
1279
        ObjState opaState;
1280
        opaState.CurrColorFill = CommonStrings::None;
1281
        opaState.fillOpacity = 0.0;
1282
        opaState.fillGradientTyp = 0;
1283
        opaState.gradientScale = 1.0;
1284
        opaState.imagePath = "";
1285
        opaState.patternName = "";
1286
        parseFillXML(spe, path, opaState);
1287
        if (opaState.fillGradientTyp != 0)
1288
        {
1289
                obState.gradientMask = opaState.currentGradient;
1290
                obState.maskStart = opaState.gradientStart;
1291
                obState.maskEnd = opaState.gradientEnd;
1292
                obState.maskFocus = opaState.gradientFocus;
1293
                obState.maskScale = opaState.gradientScale;
1294
                obState.maskTyp = opaState.fillGradientTyp == 6 ? 1 : 3;
1295
        }
1296
        if (!opaState.patternName.isEmpty())
1297
        {
1298
                obState.patternMask = opaState.patternName;
1299
                obState.maskTyp = 3;
1300
        }
1301
}
1302
 
1303
void XpsPlug::parseStrokeXML(QDomElement &spe, QString path, ObjState &obState)
1304
{
1305
        ObjState opaState;
1306
        opaState.CurrColorFill = CommonStrings::None;
1307
        opaState.fillOpacity = 0.0;
1308
        opaState.fillGradientTyp = 0;
1309
        opaState.gradientScale = 1.0;
1310
        opaState.imagePath = "";
1311
        opaState.patternName = "";
1312
        parseFillXML(spe, path, opaState);
1313
        if (opaState.fillGradientTyp != 0)
1314
        {
1315
                obState.gradientStroke = opaState.currentGradient;
1316
                obState.strokeStart = opaState.gradientStart;
1317
                obState.strokeEnd = opaState.gradientEnd;
1318
                obState.strokeFocus = opaState.gradientFocus;
1319
                obState.strokeScale = opaState.gradientScale;
1320
                obState.strokeTyp = opaState.fillGradientTyp;
1321
        }
1322
        if (!opaState.patternName.isEmpty())
1323
                obState.patternStroke = opaState.patternName;
1324
}
1325
 
1326
void XpsPlug::parseFillXML(QDomElement &spe, QString path, ObjState &obState)
1327
{
1328
        for(QDomNode obg = spe.firstChild(); !obg.isNull(); obg = obg.nextSibling() )
1329
        {
1330
                QDomElement eog = obg.toElement();
1331
                if (eog.tagName() == "SolidColorBrush")
1332
                        obState.CurrColorFill = handleColor(eog.attribute("Color", "#FF000000"), obState.fillOpacity);
1333
                else if (eog.tagName() == "ImageBrush")
1334
                {
1335
                        obState.imagePath = eog.attribute("ImageSource", "");
1336
                        if (obState.imagePath.startsWith("/"))
1337
                        {
1338
                                obState.imagePath = obState.imagePath.mid(1);
1339
                        }
1340
                        else
1341
                        {
1342
                                if (!obState.imagePath.startsWith(path))
18603 fschmid 1343
                                {
18598 fschmid 1344
                                        obState.imagePath = path + "/" + obState.imagePath;
18603 fschmid 1345
                                        obState.imagePath = QDir::cleanPath(obState.imagePath);
1346
                                }
18598 fschmid 1347
                        }
1348
                        if (eog.hasAttribute("Opacity"))
1349
                        {
1350
                                double opacity = eog.attribute("Opacity", "1.0").toDouble();
1351
                                obState.fillOpacity = 1.0 - ((1.0 - obState.fillOpacity) * opacity);
1352
                                obState.strokeOpacity = 1.0 - ((1.0 - obState.strokeOpacity) * opacity);
1353
                        }
1354
                        obState.itemType = 1;
1355
                }
1356
                else if (eog.tagName() == "LinearGradientBrush")
1357
                {
1358
                        obState.currentGradient = VGradient(VGradient::linear);
1359
                        obState.currentGradient.clearStops();
1360
                        double gen_opacity = 1.0;
1361
                        if (eog.hasAttribute("Opacity"))
1362
                                gen_opacity = eog.attribute("Opacity", "1.0").toDouble();
1363
                        for(QDomNode gr = eog.firstChild(); !gr.isNull(); gr = gr.nextSibling() )
1364
                        {
1365
                                QDomElement grs = gr.toElement();
1366
                                if (grs.tagName() == "LinearGradientBrush.GradientStops")
1367
                                {
1368
                                        for(QDomNode spo = grs.firstChild(); !spo.isNull(); spo = spo.nextSibling() )
1369
                                        {
1370
                                                QDomElement eo = spo.toElement();
1371
                                                if (eo.tagName() == "GradientStop")
1372
                                                {
1373
                                                        double opacity = 1.0;
1374
                                                        QString stopName = handleColor(eo.attribute("Color", "#FF000000"), opacity);
1375
                                                        double stopOffset = eo.attribute("Offset", "0.0").toDouble();
1376
                                                        const ScColor& gradC = m_Doc->PageColors[stopName];
1377
                                                        obState.currentGradient.addStop(ScColorEngine::getRGBColor(gradC, m_Doc), stopOffset, 0.5, 1.0 - (opacity * gen_opacity), stopName, 100);
1378
                                                }
1379
                                        }
1380
                                }
1381
                        }
1382
                        QString vectS = eog.attribute("StartPoint", "0,0");
1383
                        vectS.replace(",", " ");
1384
                        ScTextStream list(&vectS, QIODevice::ReadOnly);
1385
                        double x, y;
1386
                        list >> x >> y;
1387
                        obState.gradientStart = QPointF(x * conversionFactor, y * conversionFactor);
1388
                        obState.gradientFocus = obState.gradientStart;
1389
                        QString vectE = eog.attribute("EndPoint", "0,0");
1390
                        vectE.replace(",", " ");
1391
                        ScTextStream listE(&vectE, QIODevice::ReadOnly);
1392
                        double x2, y2;
1393
                        listE >> x2 >> y2;
1394
                        obState.gradientEnd = QPointF(x2 * conversionFactor, y2 * conversionFactor);
1395
                        obState.gradientScale = 1.0;
1396
                        obState.fillGradientTyp = 6;
1397
                }
1398
                else if (eog.tagName() == "RadialGradientBrush")
1399
                {
1400
                        obState.currentGradient = VGradient(VGradient::radial);
1401
                        obState.currentGradient.clearStops();
1402
                        double gen_opacity = 1.0;
1403
                        if (eog.hasAttribute("Opacity"))
1404
                                gen_opacity = eog.attribute("Opacity", "1.0").toDouble();
1405
                        for(QDomElement grs = eog.firstChildElement(); !grs.isNull(); grs = grs.nextSiblingElement())
1406
                        {
1407
                                if (grs.tagName() == "RadialGradientBrush.GradientStops")
1408
                                {
1409
                                        for(QDomElement eo = grs.firstChildElement(); !eo.isNull(); eo = eo.nextSiblingElement() )
1410
                                        {
1411
                                                if (eo.tagName() == "GradientStop")
1412
                                                {
1413
                                                        double opacity = 1.0;
1414
                                                        QString stopName = handleColor(eo.attribute("Color", "#FF000000"), opacity);
1415
                                                        double stopOffset = eo.attribute("Offset", "0.0").toDouble();
1416
                                                        const ScColor& gradC = m_Doc->PageColors[stopName];
1417
                                                        obState.currentGradient.addStop(ScColorEngine::getRGBColor(gradC, m_Doc), stopOffset, 0.5, 1.0 - (opacity * gen_opacity), stopName, 100);
1418
                                                }
1419
                                        }
1420
                                }
1421
                        }
1422
                        QString vectS = eog.attribute("Center", "0,0");
1423
                        vectS.replace(",", " ");
1424
                        ScTextStream list(&vectS, QIODevice::ReadOnly);
1425
                        double x, y;
1426
                        list >> x >> y;
1427
                        obState.gradientStart = QPointF(x * conversionFactor, y * conversionFactor);
1428
                        QString vectE = eog.attribute("GradientOrigin", "0,0");
1429
                        vectE.replace(",", " ");
1430
                        ScTextStream listE(&vectE, QIODevice::ReadOnly);
1431
                        double x2, y2;
1432
                        listE >> x2 >> y2;
1433
                        obState.gradientFocus = QPointF(x2 * conversionFactor, y2 * conversionFactor);
1434
                        double rx = eog.attribute("RadiusX", "1").toDouble() * conversionFactor;
1435
                        double ry = eog.attribute("RadiusY", "1").toDouble() * conversionFactor;
1436
                        obState.gradientEnd = QPointF(obState.gradientStart.x() + rx, obState.gradientStart.y());
1437
                        obState.gradientScale = rx / ry;
1438
                        obState.fillGradientTyp = 7;
1439
                }
1440
                else if (eog.tagName() == "VisualBrush")
1441
                {
1442
                        QString viewb = eog.attribute("Viewbox", "0,0,1,1");
1443
                        viewb.replace(",", " ");
1444
                        ScTextStream listb(&viewb, QIODevice::ReadOnly);
1445
                        double Viewbox_x1, Viewbox_y1, Viewbox_x2, Viewbox_y2;
1446
                        listb >> Viewbox_x1 >> Viewbox_y1 >> Viewbox_x2 >> Viewbox_y2;
1447
                        QString vectE = eog.attribute("Viewport", "0,0,1,1");
1448
                        vectE.replace(",", " ");
1449
                        ScTextStream listE(&vectE, QIODevice::ReadOnly);
1450
                        double Viewport_x1, Viewport_y1, Viewport_x2, Viewport_y2;
1451
                        listE >> Viewport_x1 >> Viewport_y1 >> Viewport_x2 >> Viewport_y2;
1452
                        double vw = (Viewport_x2 * conversionFactor) / (Viewbox_x2 - Viewbox_x1);
1453
                        double vh = (Viewport_y2 * conversionFactor) / (Viewbox_y2 - Viewbox_y1);
1454
                        for(QDomElement grs = eog.firstChildElement(); !grs.isNull(); grs = grs.nextSiblingElement())
1455
                        {
1456
                                if (grs.tagName() == "VisualBrush.Visual")
1457
                                {
1458
                                        for(QDomElement eo = grs.firstChildElement(); !eo.isNull(); eo = eo.nextSiblingElement() )
1459
                                        {
1460
                                                if ((eo.tagName() == "Path") || (eo.tagName() == "Glyphs") || (eo.tagName() == "Canvas"))
1461
                                                {
1462
                                                        PageItem* item = parseObjectXML(eo, path);
1463
                                                        if (item != NULL)
1464
                                                        {
1465
                                                                m_Doc->SizeItem((item->width() / conversionFactor) * vw, (item->height() / conversionFactor) * vh, item, false, true, false);
1466
                                                                ScPattern pat = ScPattern();
1467
                                                                pat.setDoc(m_Doc);
1468
                                                                m_Doc->DoDrawing = true;
1469
                                                                QImage tmpImg = item->DrawObj_toImage(qMax(item->width(), item->height()));
1470
                                                                if (!tmpImg.isNull())
1471
                                                                {
1472
                                                                        QImage retImg = QImage(qRound(Viewport_x2 * conversionFactor), qRound(Viewport_y2 * conversionFactor), QImage::Format_ARGB32_Premultiplied);
1473
                                                                        retImg.fill( qRgba(0, 0, 0, 0) );
1474
                                                                        QPainter p;
1475
                                                                        p.begin(&retImg);
1476
                                                                        p.drawImage(0, 0, tmpImg);
1477
                                                                        p.end();
1478
                                                                        pat.pattern = retImg;
1479
                                                                        pat.xoffset = 0;
1480
                                                                        pat.yoffset = 0;
1481
                                                                        m_Doc->DoDrawing = false;
1482
                                                                        pat.width = Viewport_x2 * conversionFactor;
1483
                                                                        pat.height = Viewport_y2 * conversionFactor;
1484
                                                                        item->gXpos = 0;
1485
                                                                        item->gYpos = 0;
1486
                                                                        item->setXYPos(item->gXpos, item->gYpos, true);
1487
                                                                        pat.items.append(item);
1488
                                                                        obState.patternName = QString("Pattern_from_XPS_%1").arg(m_Doc->docPatterns.count() + 1);
1489
                                                                        m_Doc->addPattern(obState.patternName, pat);
1490
                                                                        importedPatterns.append(obState.patternName);
1491
                                                                }
1492
                                                        }
1493
                                                }
1494
                                        }
1495
                                }
1496
                        }
1497
                }
1498
        }
1499
}
1500
 
1501
void XpsPlug::parsePathDataXML(QDomElement &spe, ObjState &obState, bool forClip)
1502
{
1503
        Coords.resize(0);
1504
        Coords.svgInit();
1505
        QString svgString = "";
1506
        bool windFill = false;
1507
        for(QDomElement dpgp = spe.firstChildElement(); !dpgp.isNull(); dpgp = dpgp.nextSiblingElement() )
1508
        {
1509
                if (dpgp.tagName() == "PathGeometry")
1510
                        svgString += parsePathGeometryXML(dpgp);
1511
                if (dpgp.attribute("FillRule") == "NonZero")
1512
                        windFill = true;
1513
        }
1514
        bool currentPathClosed = Coords.parseSVG(svgString);
1515
        Coords.scale(conversionFactor, conversionFactor);
1516
        if (forClip)
1517
        {
1518
                obState.clipPath = Coords.toQPainterPath(!currentPathClosed);
1519
                if (windFill)
1520
                        obState.clipPath.setFillRule(Qt::WindingFill);
1521
        }
1522
        else
1523
        {
1524
                obState.currentPathClosed = currentPathClosed;
1525
                obState.currentPath = Coords.toQPainterPath(!obState.currentPathClosed);
1526
                if (windFill)
1527
                        obState.currentPath.setFillRule(Qt::WindingFill);
1528
        }
1529
}
1530
 
1531
QString XpsPlug::parsePathGeometryXML(QDomElement &spe)
1532
{
1533
        QString svgString = "";
18605 fschmid 1534
        for(QDomElement dpg = spe.firstChildElement(); !dpg.isNull(); dpg = dpg.nextSiblingElement() )
18598 fschmid 1535
        {
1536
                if (dpg.tagName() == "PathFigure")
1537
                {
1538
                        if (dpg.hasAttribute("StartPoint"))
1539
                                svgString += "M " + dpg.attribute("StartPoint") + " ";
1540
                        for(QDomElement dp = dpg.firstChildElement(); !dp.isNull(); dp = dp.nextSiblingElement() )
1541
                        {
1542
                                if (dp.tagName() == "PolyLineSegment")
1543
                                        svgString += "L " + dp.attribute("Points") + " ";
1544
                                else if (dp.tagName() == "PolyQuadraticBezierSegment")
1545
                                        svgString += "Q " + dp.attribute("Points") + " ";
1546
                                else if (dp.tagName() == "PolyBezierSegment")
1547
                                        svgString += "C " + dp.attribute("Points") + " ";
1548
                                else if (dp.tagName() == "ArcSegment")
1549
                                {
1550
                                        svgString += "A " + dp.attribute("Size") + " "  + dp.attribute("RotationAngle") + " ";
1551
                                        if (dp.hasAttribute("IsLargeArc"))
1552
                                        {
1553
                                                if (dp.attribute("IsLargeArc").toLower() == "true")
1554
                                                        svgString += "1 ";
1555
                                                else
1556
                                                        svgString += "0 ";
1557
                                        }
1558
                                        else
1559
                                                svgString += "0 ";
1560
                                        if (dp.hasAttribute("SweepDirection"))
1561
                                        {
1562
                                                if (dp.attribute("SweepDirection").toLower() == "counterclockwise")
1563
                                                        svgString += "0 ";
1564
                                                else
1565
                                                        svgString += "1 ";
1566
                                        }
1567
                                        else
1568
                                                svgString += "0 ";
1569
                                        svgString += dp.attribute("Point") + " ";
1570
                                }
1571
                        }
1572
                        if (dpg.hasAttribute("IsClosed") && (dpg.attribute("IsClosed").toLower() == "true"))
1573
                                svgString += "Z ";
1574
                }
1575
        }
1576
        return svgString;
1577
}
1578
 
1579
void XpsPlug::parseResourceFile(QString resFile)
1580
{
1581
        QByteArray f;
1582
        if (uz->read(resFile, f))
1583
        {
1584
                QDomDocument designMapDom;
1585
                if(designMapDom.setContent(f))
1586
                {
1587
                        QDomElement docElem = designMapDom.documentElement();
1588
                        for(QDomNode drawPag = docElem.firstChild(); !drawPag.isNull(); drawPag = drawPag.nextSibling() )
1589
                        {
1590
                                QDomElement dpg = drawPag.toElement();
1591
                                if (dpg.tagName() == "PathGeometry")
1592
                                {
1593
                                        Coords.resize(0);
1594
                                        Coords.svgInit();
1595
                                        QString pdata = "";
1596
                                        QString key = dpg.attribute("x:Key");
1597
                                        if (dpg.hasAttribute("Figures"))
1598
                                                pdata = dpg.attribute("Figures");
1599
                                        else if (dpg.hasChildNodes())
1600
                                                pdata = parsePathGeometryXML(dpg);
1601
                                        if (!pdata.isEmpty())
1602
                                        {
1603
                                                bool currentPathClosed = Coords.parseSVG(pdata);
1604
                                                Coords.scale(conversionFactor, conversionFactor);
1605
                                                QPainterPath path = Coords.toQPainterPath(!currentPathClosed);
1606
                                                if (dpg.attribute("FillRule") == "NonZero")
1607
                                                        path.setFillRule(Qt::WindingFill);
1608
                                                pathResources.insert(key, path);
1609
                                        }
1610
                                }
1611
                        }
1612
                }
1613
        }
1614
}
1615
 
1616
void XpsPlug::resolveLinks()
1617
{
1618
        if (!linkSources.isEmpty())
1619
        {
1620
                QHash<PageItem*, QString>::iterator it;
1621
                for (it = linkSources.begin(); it != linkSources.end(); ++it)
1622
                {
1623
                        PageItem* linkS = it.key();
1624
                        QString target = it.value();
1625
                        if (linkTargets.contains(target))
1626
                        {
1627
                                PageItem* linkT = linkTargets[target];
1628
                                if (linkT != NULL)
1629
                                {
1630
                                        int op = linkT->OwnPage;
1631
                                        if (op > -1)
1632
                                        {
1633
                                                QTransform tf = linkT->getTransform();
1634
                                                double xp = tf.dx() - m_Doc->Pages->at(op)->xOffset();
1635
                                                double yp = tf.dy() - m_Doc->Pages->at(op)->yOffset();
1636
                                                linkS->annotation().setZiel(linkT->OwnPage);
1637
                                                linkS->annotation().setActionType(2);
1638
                                                linkS->annotation().setAction(QString("%0 %1").arg(qRound(xp)).arg(qRound(m_Doc->Pages->at(op)->height() - yp)));
1639
                                        }
1640
                                }
1641
                        }
1642
                }
1643
        }
1644
}
1645
 
1646
PageItem* XpsPlug::addClip(PageItem* retObj, ObjState &obState)
1647
{
1648
        if (!obState.clipPath.isEmpty())
1649
        {
1650
                int z = m_Doc->itemAdd(PageItem::Group, PageItem::Rectangle, baseX, baseY, 10, 10, 0, CommonStrings::None, CommonStrings::None, true);
1651
                PageItem *itemg = m_Doc->Items->at(z);
1652
                itemg->PoLine.fromQPainterPath(obState.clipPath);
1653
                FPoint wh = getMaxClipF(&itemg->PoLine);
1654
                itemg->setWidthHeight(wh.x(),wh.y());
1655
                m_Doc->AdjustItemSize(itemg, true);
1656
                itemg->ClipEdited = true;
1657
                itemg->FrameType = 3;
1658
                itemg->setFillEvenOdd(false);
1659
                itemg->OldB2 = itemg->width();
1660
                itemg->OldH2 = itemg->height();
1661
                itemg->updateClip();
1662
                itemg->OwnPage = m_Doc->OnPage(itemg);
1663
                itemg->ContourLine = itemg->PoLine.copy();
1664
                QList<PageItem*> GElements;
1665
                GElements.append(retObj);
1666
                m_Doc->groupObjectsToItem(itemg, GElements);
18642 fschmid 1667
                m_Doc->resizeGroupToContents(itemg);
18598 fschmid 1668
                m_Doc->GroupOnPage(itemg);
1669
                retObj = itemg;
1670
                m_Doc->Items->removeLast();
1671
        }
1672
        return retObj;
1673
}
1674
 
1675
PageItem* XpsPlug::createItem(QDomElement &dpg, ObjState &obState)
1676
{
1677
        int z = -1;
1678
        PageItem* retObj = NULL;
1679
        if (!obState.currentPath.isEmpty())
1680
        {
1681
                if (obState.itemType == 0)
1682
                {
1683
                        if (dpg.hasAttribute("FixedPage.NavigateUri"))
1684
                                z = m_Doc->itemAdd(PageItem::TextFrame, PageItem::Unspecified, baseX, baseY, 10, 10, obState.LineW, obState.CurrColorFill, CommonStrings::None, true);
1685
                        else
1686
                        {
1687
                                if (!obState.currentPathClosed)
1688
                                        z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, obState.LineW, obState.CurrColorFill, obState.CurrColorStroke, true);
1689
                                else
1690
                                        z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, obState.LineW, obState.CurrColorFill, obState.CurrColorStroke, true);
1691
                        }
1692
                        retObj = m_Doc->Items->at(z);
1693
                        finishItem(retObj, obState);
1694
                        retObj = m_Doc->Items->takeAt(z);
1695
                }
1696
                else if (obState.itemType == 1)
1697
                {
1698
                        z = m_Doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, baseX, baseY, 10, 10, obState.LineW, obState.CurrColorFill, obState.CurrColorStroke, true);
1699
                        retObj = m_Doc->Items->at(z);
1700
                        finishItem(retObj, obState);
1701
                        if (!obState.imagePath.isEmpty())
1702
                        {
1703
                                QByteArray f;
1704
                                if (uz->read(obState.imagePath, f))
1705
                                {
1706
                                        QFileInfo fi(obState.imagePath);
1707
                                        QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_xps_XXXXXX." + fi.suffix());
1708
                                        tempFile->setAutoRemove(false);
1709
                                        if (tempFile->open())
1710
                                        {
1711
                                                QString fileName = getLongPathName(tempFile->fileName());
1712
                                                if (!fileName.isEmpty())
1713
                                                {
1714
                                                        tempFile->write(f);
1715
                                                        tempFile->close();
1716
                                                        retObj->isInlineImage = true;
1717
                                                        retObj->isTempFile = true;
1718
                                                        retObj->AspectRatio = false;
1719
                                                        retObj->ScaleType   = false;
1720
                                                        m_Doc->loadPict(fileName, retObj);
1721
                                                        retObj->AdjustPictScale();
1722
                                                }
1723
                                        }
1724
                                        delete tempFile;
1725
                                }
1726
                        }
1727
                        retObj = m_Doc->Items->takeAt(z);
1728
                }
1729
        }
1730
        return retObj;
1731
}
1732
 
1733
void XpsPlug::finishItem(PageItem* item, ObjState &obState)
1734
{
1735
        item->PoLine.fromQPainterPath(obState.currentPath, !obState.currentPathClosed);
1736
        FPoint wh = getMaxClipF(&item->PoLine);
1737
        item->setWidthHeight(wh.x(),wh.y());
1738
        m_Doc->AdjustItemSize(item, true);
1739
        item->ClipEdited = true;
1740
        item->FrameType = 3;
1741
        item->setFillEvenOdd(false);
1742
        item->OldB2 = item->width();
1743
        item->OldH2 = item->height();
1744
        item->updateClip();
1745
        item->OwnPage = m_Doc->OnPage(item);
1746
        item->ContourLine = item->PoLine.copy();
1747
        item->setFillColor(obState.CurrColorFill);
1748
        item->setFillTransparency(obState.fillOpacity);
1749
        item->setLineColor(obState.CurrColorStroke);
1750
        item->setLineTransparency(obState.strokeOpacity);
1751
        item->setLineWidth(obState.LineW);
1752
        item->setLineEnd(obState.CapStyle);
1753
        item->setLineJoin(obState.JoinStyle);
1754
        double xp = item->xPos() - m_Doc->currentPage()->xOffset();
1755
        double yp = item->yPos() - m_Doc->currentPage()->yOffset();
1756
        if (obState.fillGradientTyp != 0)
1757
        {
1758
                item->fill_gradient = obState.currentGradient;
1759
                item->setGradientVector(obState.gradientStart.x() - xp, obState.gradientStart.y() - yp, obState.gradientEnd.x() - xp, obState.gradientEnd.y() - yp, obState.gradientFocus.x() - xp, obState.gradientFocus.y() - yp, obState.gradientScale, 0);
1760
                item->setGradientType(obState.fillGradientTyp);
1761
        }
1762
        else if (!obState.patternName.isEmpty())
1763
        {
1764
                item->setPattern(obState.patternName);
1765
                item->GrType = 8;
1766
        }
1767
        if (obState.maskTyp != 0)
1768
        {
1769
                item->setMaskGradient(obState.gradientMask);
1770
                item->setMaskVector(obState.maskStart.x() - xp, obState.maskStart.y() - yp, obState.maskEnd.x() - xp, obState.maskEnd.y() - yp, obState.maskFocus.x() - xp, obState.maskFocus.y() - yp, obState.maskScale, 0);
1771
                item->setMaskType(obState.maskTyp);
1772
        }
1773
        if (!obState.patternMask.isEmpty())
1774
        {
1775
                item->setPatternMask(obState.patternMask);
1776
                item->setMaskType(obState.maskTyp);
1777
        }
1778
        if (obState.strokeTyp != 0)
1779
        {
1780
                item->setStrokeGradient(obState.gradientStroke);
1781
                item->setStrokeGradientVector(obState.strokeStart.x() - xp, obState.strokeStart.y() - yp, obState.strokeEnd.x() - xp, obState.strokeEnd.y() - yp, obState.strokeFocus.x() - xp, obState.strokeFocus.y() - yp, obState.strokeScale, 0);
1782
                item->setStrokeGradientType(obState.strokeTyp);
1783
        }
1784
        if (!obState.patternStroke.isEmpty())
18637 fschmid 1785
        {
1786
                item->GrTypeStroke = 8;
18598 fschmid 1787
                item->setStrokePattern(obState.patternStroke);
18637 fschmid 1788
        }
18628 fschmid 1789
        if (!obState.DashPattern.isEmpty())
1790
        {
1791
                item->setDashOffset(obState.DashOffset);
1792
                QVector<double> pattern(obState.DashPattern.count());
1793
                for (int i = 0; i < obState.DashPattern.count(); ++i)
1794
                {
1795
                        pattern[i] = obState.DashPattern[i] * obState.LineW;
1796
                }
1797
                item->setDashes(pattern);
1798
        }
18598 fschmid 1799
}
1800
 
1801
QString XpsPlug::handleColor(QString rgbColor, double &opacity)
1802
{
1803
        QString fNam = CommonStrings::None;
1804
        QString alpha = "FF";
1805
        if (rgbColor.startsWith( "sc#" ))
1806
        {
1807
                QColor c;
1808
                rgbColor = rgbColor.remove(0,3);
1809
                QStringList co = rgbColor.split(",");
1810
                if (co.size() == 3)
1811
                {
1812
                        rgbColor.replace(",", " ");
1813
                        ScTextStream list(&rgbColor, QIODevice::ReadOnly);
1814
                        double r, g, b;
1815
                        list >> r >> g >> b;
1816
                        c.setRgbF(r, g, b);
1817
                }
1818
                else if (co.size() == 4)
1819
                {
1820
                        rgbColor.replace(",", " ");
1821
                        ScTextStream list(&rgbColor, QIODevice::ReadOnly);
1822
                        double r, g, b;
1823
                        list >> opacity >> r >> g >> b;
1824
                        c.setRgbF(r, g, b);
1825
                }
1826
                else
1827
                {
1828
                        opacity = 0;
1829
                        return fNam;
1830
                }
1831
                ScColor tmp;
1832
                tmp.fromQColor(c);
1833
                tmp.setSpotColor(false);
1834
                tmp.setRegistrationColor(false);
1835
                QString newColorName = "FromXPS"+c.name();
1836
                fNam = m_Doc->PageColors.tryAddColor(newColorName, tmp);
1837
                if (fNam == newColorName)
1838
                        importedColors.append(newColorName);
1839
        }
1840
        else if (rgbColor.startsWith( "#" ))
1841
        {
1842
                QColor c;
1843
                if (rgbColor.length() == 9)
1844
                {
1845
                        alpha = rgbColor.mid(1,2);
1846
                        bool ok;
1847
                        int hex = alpha.toInt(&ok, 16);
1848
                        opacity = 1.0 - (hex / 255.0);
1849
                        rgbColor = rgbColor.remove(1,2);
1850
                }
1851
                else
1852
                        opacity = 0;
1853
                c.setNamedColor(rgbColor);
1854
                ScColor tmp;
1855
                tmp.fromQColor(c);
1856
                tmp.setSpotColor(false);
1857
                tmp.setRegistrationColor(false);
1858
                QString newColorName = "FromXPS"+c.name();
1859
                fNam = m_Doc->PageColors.tryAddColor(newColorName, tmp);
1860
                if (fNam == newColorName)
1861
                        importedColors.append(newColorName);
1862
        }
1863
        return fNam;
1864
}
1865
 
1866
int XpsPlug::hex2int(char hex)
1867
{
1868
        QChar hexchar = QLatin1Char(hex);
1869
        int v;
1870
        if (hexchar.isDigit())
1871
                v = hexchar.digitValue();
1872
        else if (hexchar >= QLatin1Char('A') && hexchar <= QLatin1Char('F'))
1873
                v = hexchar.cell() - 'A' + 10;
1874
        else if (hexchar >= QLatin1Char('a') && hexchar <= QLatin1Char('f'))
1875
                v = hexchar.cell() - 'a' + 10;
1876
        else
1877
                v = -1;
1878
        return v;
1879
}
1880
 
1881
bool XpsPlug::parseGUID( const QString &guidString, unsigned short guid[16])
1882
{
1883
        if (guidString.length() <= 35)
1884
                return false;
1885
        // Maps bytes to positions in guidString
1886
        const static int indexes[] = {6, 4, 2, 0, 11, 9, 16, 14, 19, 21, 24, 26, 28, 30, 32, 34};
1887
        for (int i = 0; i < 16; i++)
1888
        {
1889
                int hex1 = hex2int(guidString[indexes[i]].cell());
1890
                int hex2 = hex2int(guidString[indexes[i]+1].cell());
1891
                if ((hex1 < 0) || (hex2 < 0))
1892
                        return false;
1893
                guid[i] = hex1 * 16 + hex2;
1894
        }
1895
        return true;
1896
}
1897
 
1898
 
1899
ScFace XpsPlug::loadFontByName(const QString &fileName)
1900
{
1901
        ScFace t;
1902
        if (loadedFonts.contains(fileName))
1903
                return loadedFonts[fileName];
1904
        QByteArray fontData;
1905
        if (!uz->read(fileName, fontData))
1906
                return t;
1907
        QTemporaryFile *tempImageFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_zip_XXXXXX.dat");
1908
        if (tempImageFile == NULL)
1909
                return t;
1910
        tempImageFile->setAutoRemove(false);
1911
        tempImageFile->open();
1912
        QString fname = getLongPathName(tempImageFile->fileName());
1913
        tempImageFile->close();
1914
        delete tempImageFile;
1915
        tempFontFiles.append(fname);
1916
        QFileInfo fi(fileName);
1917
        QString ext = fi.suffix().toLower();
1918
        if (ext.startsWith("od"))
1919
        {
1920
                const QString baseName = fi.baseName();
1921
                unsigned short guid[16];
1922
                if (!parseGUID(baseName, guid))
1923
                        return t;
1924
                else
1925
                {
1926
                        if (fontData.length() < 32)
1927
                        {
1928
                                qDebug() << "Font file is too small";
1929
                                return t;
1930
                        }
1931
                        else
1932
                        {
1933
                                // Obfuscation - xor bytes in font binary with bytes from guid (font's filename)
1934
                                const static int mapping[] = {15, 14, 13, 12, 11, 10, 9, 8, 6, 7, 4, 5, 0, 1, 2, 3};
1935
                                for (int i = 0; i < 16; i++)
1936
                                {
1937
                                        fontData[i] = fontData[i] ^ guid[mapping[i]];
1938
                                        fontData[i+16] = fontData[i+16] ^ guid[mapping[i]];
1939
                                }
1940
                        }
1941
                }
1942
        }
1943
        QFile ft(fname);
1944
        if (ft.open(QIODevice::WriteOnly))
1945
        {
1946
                ft.write(fontData);
1947
                ft.close();
1948
                t = PrefsManager::instance()->appPrefs.fontPrefs.AvailFonts.LoadScalableFont(fname);
1949
                loadedFonts.insert(fileName, t);
1950
                return t;
1951
        }
1952
        return t;
1953
}