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 : Sun Feb 9 2014
10 copyright : (C) 2014 by Franz Schmid
11 email : Franz.Schmid@altmuehlnet.de
12 ***************************************************************************/
13
14 #include <QByteArray>
15 #include <QCursor>
16 #include <QDebug>
17 #include <QDrag>
18 #include <QFile>
19 #include <QList>
20 #include <QMimeData>
21 #include <QRegExp>
22 #include <QStack>
23 #include <QUrl>
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 "importodg.h"
34
35 #include "fileloader.h"
36 #include "third_party/fparser/fparser.hh"
37 #include "loadsaveplugin.h"
38 #include "pageitem_table.h"
39 #include "pagesize.h"
40 #include "plugins/formatidlist.h"
41 #include "prefscontext.h"
42 #include "prefsfile.h"
43 #include "prefsmanager.h"
44 #include "prefstable.h"
45 #include "rawimage.h"
46 #include "scclocale.h"
47 #include "sccolorengine.h"
48 #include "scconfig.h"
49 #include "scmimedata.h"
50 #include "scpainter.h"
51 #include "scpaths.h"
52 #include "scribusXml.h"
53 #include "scribuscore.h"
54 #include "scribusdoc.h"
55 #include "scribusview.h"
56 #include "sctextstream.h"
57 #include "selection.h"
58 #include "third_party/zip/scribus_zip.h"
59 #include "ui/customfdialog.h"
60 #include "ui/missing.h"
61 #include "ui/multiprogressdialog.h"
62 #include "ui/propertiespalette.h"
63 #include "undomanager.h"
64 #include "util.h"
65 #include "util_file.h"
66 #include "util_formats.h"
67 #include "util_math.h"
68
OdgPlug(ScribusDoc * doc,int flags)69 OdgPlug::OdgPlug(ScribusDoc* doc, int flags)
70 {
71 tmpSel = new Selection(this, false);
72 m_Doc = doc;
73 importerFlags = flags;
74 interactive = (flags & LoadSavePlugin::lfInteractive);
75 progressDialog = nullptr;
76 uz = nullptr;
77 }
78
readThumbnail(const QString & fName)79 QImage OdgPlug::readThumbnail(const QString& fName)
80 {
81 QImage tmp;
82 if (!QFile::exists(fName))
83 return QImage();
84 progressDialog = nullptr;
85 uz = new ScZipHandler();
86 if (!uz->open(fName))
87 {
88 delete uz;
89 if (progressDialog)
90 progressDialog->close();
91 return QImage();
92 }
93 if (uz->contains("Thumbnails/thumbnail.png"))
94 {
95 QByteArray im;
96 if (!uz->read("Thumbnails/thumbnail.png", im))
97 {
98 delete uz;
99 return QImage();
100 }
101 tmp = QImage::fromData(im);
102 int xs = 0;
103 int ys = 0;
104 /* if (uz->contains("index.xml"))
105 {
106 if (uz->read("index.xml", f))
107 {
108 QDomDocument designMapDom;
109 QByteArray f;
110 if (designMapDom.setContent(f))
111 {
112 QDomElement docElem = designMapDom.documentElement();
113 for (QDomElement drawPag = docElem.firstChildElement(); !drawPag.isNull(); drawPag = drawPag.nextSiblingElement())
114 {
115 if (drawPag.tagName() == "sl:slprint-info")
116 {
117 xs = drawPag.attribute("sl:page-width", "0").toInt();
118 ys = drawPag.attribute("sl:page-height", "0").toInt();
119 }
120 }
121 }
122 }
123 }*/
124 tmp.setText("XSize", QString("%1").arg(xs));
125 tmp.setText("YSize", QString("%1").arg(ys));
126 }
127 uz->close();
128 delete uz;
129 return tmp;
130 }
131
import(const QString & fNameIn,const TransactionSettings & trSettings,int flags,bool showProgress)132 bool OdgPlug::import(const QString& fNameIn, const TransactionSettings& trSettings, int flags, bool showProgress)
133 {
134 bool success = false;
135 interactive = (flags & LoadSavePlugin::lfInteractive);
136 importerFlags = flags;
137 cancel = false;
138 bool ret = false;
139 firstPage = true;
140 pagecount = 1;
141 mpagecount = 0;
142 QFileInfo fi = QFileInfo(fNameIn);
143 if ( !ScCore->usingGUI() )
144 {
145 interactive = false;
146 showProgress = false;
147 }
148 if ( showProgress )
149 {
150 ScribusMainWindow* mw=(m_Doc==nullptr) ? ScCore->primaryMainWindow() : m_Doc->scMW();
151 progressDialog = new MultiProgressDialog( tr("Importing: %1").arg(fi.fileName()), CommonStrings::tr_Cancel, mw );
152 QStringList barNames, barTexts;
153 barNames << "GI";
154 barTexts << tr("Analyzing File:");
155 QList<bool> barsNumeric;
156 barsNumeric << false;
157 progressDialog->addExtraProgressBars(barNames, barTexts, barsNumeric);
158 progressDialog->setOverallTotalSteps(3);
159 progressDialog->setOverallProgress(0);
160 progressDialog->setProgress("GI", 0);
161 progressDialog->show();
162 connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelRequested()));
163 qApp->processEvents();
164 }
165 else
166 progressDialog = nullptr;
167 if (progressDialog)
168 {
169 progressDialog->setOverallProgress(1);
170 qApp->processEvents();
171 }
172 /* Set default Page to size defined in Preferences */
173 docWidth = PrefsManager::instance().appPrefs.docSetupPrefs.pageWidth;
174 docHeight = PrefsManager::instance().appPrefs.docSetupPrefs.pageHeight;
175 baseX = 0;
176 baseY = 0;
177 if (!interactive || (flags & LoadSavePlugin::lfInsertPage))
178 {
179 m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false);
180 m_Doc->addPage(0);
181 m_Doc->view()->addPage(0, true);
182 baseX = 0;
183 baseY = 0;
184 }
185 else
186 {
187 if (!m_Doc || (flags & LoadSavePlugin::lfCreateDoc))
188 {
189 m_Doc=ScCore->primaryMainWindow()->doFileNew(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false, 0, false, 0, 1, "Custom", true);
190 ScCore->primaryMainWindow()->HaveNewDoc();
191 ret = true;
192 baseX = 0;
193 baseY = 0;
194 baseX = m_Doc->currentPage()->xOffset();
195 baseY = m_Doc->currentPage()->yOffset() + m_Doc->currentPage()->height() / 2.0;
196 }
197 }
198 if ((!ret) && (interactive))
199 {
200 baseX = m_Doc->currentPage()->xOffset();
201 baseY = m_Doc->currentPage()->yOffset() + m_Doc->currentPage()->height() / 2.0;
202 }
203 if ((ret) || (!interactive))
204 {
205 if (docWidth > docHeight)
206 m_Doc->setPageOrientation(1);
207 else
208 m_Doc->setPageOrientation(0);
209 m_Doc->setPageSize("Custom");
210 }
211 Elements.clear();
212 if ((!(flags & LoadSavePlugin::lfLoadAsPattern)) && (m_Doc->view() != nullptr))
213 m_Doc->view()->deselectItems();
214 m_Doc->setLoading(true);
215 m_Doc->DoDrawing = false;
216 if ((!(flags & LoadSavePlugin::lfLoadAsPattern)) && (m_Doc->view() != nullptr))
217 m_Doc->view()->updatesOn(false);
218 m_Doc->scMW()->setScriptRunning(true);
219 qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
220 QString CurDirP = QDir::currentPath();
221 QDir::setCurrent(fi.path());
222 if (convert(fNameIn))
223 {
224 tmpSel->clear();
225 QDir::setCurrent(CurDirP);
226 if ((Elements.count() > 1) && (!(importerFlags & LoadSavePlugin::lfCreateDoc)))
227 m_Doc->groupObjectsList(Elements);
228 m_Doc->DoDrawing = true;
229 m_Doc->scMW()->setScriptRunning(false);
230 m_Doc->setLoading(false);
231 qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
232 if ((Elements.count() > 0) && (!ret) && (interactive))
233 {
234 if (flags & LoadSavePlugin::lfScripted)
235 {
236 bool loadF = m_Doc->isLoading();
237 m_Doc->setLoading(false);
238 m_Doc->changed();
239 m_Doc->setLoading(loadF);
240 if (!(flags & LoadSavePlugin::lfLoadAsPattern))
241 {
242 m_Doc->m_Selection->delaySignalsOn();
243 for (int dre=0; dre<Elements.count(); ++dre)
244 {
245 m_Doc->m_Selection->addItem(Elements.at(dre), true);
246 }
247 m_Doc->m_Selection->delaySignalsOff();
248 m_Doc->m_Selection->setGroupRect();
249 if (m_Doc->view() != nullptr)
250 m_Doc->view()->updatesOn(true);
251 }
252 }
253 else
254 {
255 m_Doc->DragP = true;
256 m_Doc->DraggedElem = nullptr;
257 m_Doc->DragElements.clear();
258 m_Doc->m_Selection->delaySignalsOn();
259 for (int dre=0; dre<Elements.count(); ++dre)
260 {
261 tmpSel->addItem(Elements.at(dre), true);
262 }
263 tmpSel->setGroupRect();
264 ScElemMimeData* md = ScriXmlDoc::writeToMimeData(m_Doc, tmpSel);
265 m_Doc->itemSelection_DeleteItem(tmpSel);
266 m_Doc->view()->updatesOn(true);
267 if ((importedColors.count() != 0) && (!((flags & LoadSavePlugin::lfKeepGradients) || (flags & LoadSavePlugin::lfKeepColors) || (flags & LoadSavePlugin::lfKeepPatterns))))
268 {
269 for (int cd = 0; cd < importedColors.count(); cd++)
270 {
271 m_Doc->PageColors.remove(importedColors[cd]);
272 }
273 }
274 if ((importedPatterns.count() != 0) && (!(flags & LoadSavePlugin::lfKeepPatterns)))
275 {
276 for (int cd = 0; cd < importedPatterns.count(); cd++)
277 {
278 m_Doc->docPatterns.remove(importedPatterns[cd]);
279 }
280 }
281 m_Doc->m_Selection->delaySignalsOff();
282 // We must copy the TransationSettings object as it is owned
283 // by handleObjectImport method afterwards
284 TransactionSettings* transacSettings = new TransactionSettings(trSettings);
285 m_Doc->view()->handleObjectImport(md, transacSettings);
286 m_Doc->DragP = false;
287 m_Doc->DraggedElem = nullptr;
288 m_Doc->DragElements.clear();
289 }
290 }
291 else
292 {
293 m_Doc->changed();
294 m_Doc->reformPages();
295 if (!(flags & LoadSavePlugin::lfLoadAsPattern))
296 m_Doc->view()->updatesOn(true);
297 }
298 success = true;
299 }
300 else
301 {
302 QDir::setCurrent(CurDirP);
303 m_Doc->DoDrawing = true;
304 m_Doc->scMW()->setScriptRunning(false);
305 if (!(flags & LoadSavePlugin::lfLoadAsPattern))
306 m_Doc->view()->updatesOn(true);
307 qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
308 success = false;
309 }
310 if (interactive)
311 m_Doc->setLoading(false);
312 //CB If we have a gui we must refresh it if we have used the progressbar
313 if (!(flags & LoadSavePlugin::lfLoadAsPattern))
314 {
315 if ((showProgress) && (!interactive))
316 m_Doc->view()->DrawNew();
317 }
318 qApp->restoreOverrideCursor();
319 return success;
320 }
321
~OdgPlug()322 OdgPlug::~OdgPlug()
323 {
324 delete progressDialog;
325 delete tmpSel;
326 }
327
convert(const QString & fn)328 bool OdgPlug::convert(const QString& fn)
329 {
330 bool retVal = true;
331 importedColors.clear();
332 importedPatterns.clear();
333 m_Styles.clear();
334 m_Layers.clear();
335 firstLayer = true;
336 if (progressDialog)
337 {
338 progressDialog->setOverallProgress(2);
339 progressDialog->setLabel("GI", tr("Generating Items"));
340 qApp->processEvents();
341 }
342
343 QFileInfo fi = QFileInfo(fn);
344 QString ext = fi.suffix().toLower();
345 if ((ext == "fodg") || (ext == "fodp"))
346 {
347 QByteArray f;
348 loadRawText(fn, f);
349 QDomDocument designMapDom;
350 QString errorMsg = "";
351 int errorLine = 0;
352 int errorColumn = 0;
353 if (!designMapDom.setContent(f, &errorMsg, &errorLine, &errorColumn))
354 {
355 qDebug() << "Error loading File" << errorMsg << "at Line" << errorLine << "Column" << errorColumn;
356 return false;
357 }
358 retVal = parseDocReferenceXML(designMapDom);
359 }
360 else
361 {
362 uz = new ScZipHandler();
363 if (!uz->open(fn))
364 {
365 delete uz;
366 QByteArray f;
367 loadRawText(fn, f);
368 QDomDocument designMapDom;
369 QString errorMsg = "";
370 int errorLine = 0;
371 int errorColumn = 0;
372 if (designMapDom.setContent(f, &errorMsg, &errorLine, &errorColumn))
373 {
374 retVal = parseDocReferenceXML(designMapDom);
375 }
376 else
377 {
378 qDebug() << "Error loading File" << errorMsg << "at Line" << errorLine << "Column" << errorColumn;
379 if (progressDialog)
380 progressDialog->close();
381 return false;
382 }
383 }
384 else
385 {
386 retVal = false;
387 if (uz->contains("styles.xml"))
388 retVal = parseStyleSheets("styles.xml");
389 if (uz->contains("content.xml"))
390 retVal = parseDocReference("content.xml");
391 uz->close();
392 delete uz;
393 }
394 }
395 if (progressDialog)
396 progressDialog->close();
397 return retVal;
398 }
399
parseStyleSheets(const QString & designMap)400 bool OdgPlug::parseStyleSheets(const QString& designMap)
401 {
402 QByteArray xmlData;
403 QDomDocument designMapDom;
404 if (!uz->read(designMap, xmlData))
405 return false;
406
407 QString errorMsg;
408 int errorLine = 0;
409 int errorColumn = 0;
410 if (!designMapDom.setContent(xmlData, false, &errorMsg, &errorLine, &errorColumn))
411 {
412 qDebug() << "Error loading File" << errorMsg << "at Line" << errorLine << "Column" << errorColumn;
413 return false;
414 }
415 return parseStyleSheetsXML(designMapDom);
416 }
417
parseStyleSheetsXML(QDomDocument & designMapDom)418 bool OdgPlug::parseStyleSheetsXML(QDomDocument &designMapDom)
419 {
420 QDomElement docElem = designMapDom.documentElement();
421 for (QDomElement sp = docElem.firstChildElement(); !sp.isNull(); sp = sp.nextSiblingElement())
422 {
423 if (sp.tagName() == "office:font-face-decls")
424 {
425 for (QDomElement spf = sp.firstChildElement(); !spf.isNull(); spf = spf.nextSiblingElement())
426 {
427 if (spf.tagName() == "style:font-face")
428 {
429 if (!spf.attribute("style:name").isEmpty())
430 m_fontMap.insert(spf.attribute("style:name"), spf.attribute("svg:font-family"));
431 }
432 }
433 }
434 else if ((sp.tagName() == "office:styles") || (sp.tagName() == "office:automatic-styles"))
435 parseStyles(sp);
436 if (sp.tagName() == "office:master-styles")
437 {
438 DrawStyle currStyle;
439 for (QDomElement spf = sp.firstChildElement(); !spf.isNull(); spf = spf.nextSiblingElement())
440 {
441 if (spf.tagName() == "style:master-page")
442 {
443 currStyle.page_layout_name = AttributeValue(spf.attribute("style:page-layout-name"));
444 QString backGroundStyle = spf.attribute("draw:style-name", "");
445 m_Styles.insert(spf.attribute("style:name"), currStyle);
446 if (importerFlags & LoadSavePlugin::lfCreateDoc)
447 {
448 m_Doc->setMasterPageMode(true);
449 ScPage *oldCur = m_Doc->currentPage();
450 ScPage *addedPage = m_Doc->addMasterPage(mpagecount, spf.attribute("style:name"));
451 m_Doc->setCurrentPage(addedPage);
452 addedPage->clearMasterPageName();
453 m_Doc->view()->addPage(mpagecount, true);
454 baseX = addedPage->xOffset();
455 baseY = addedPage->yOffset();
456 mpagecount++;
457 ObjStyle tmpOStyle;
458 resovleStyle(tmpOStyle, spf.attribute("style:name"));
459 m_Doc->currentPage()->setSize("Custom");
460 m_Doc->currentPage()->setInitialHeight(tmpOStyle.page_height);
461 m_Doc->currentPage()->setInitialWidth(tmpOStyle.page_width);
462 m_Doc->currentPage()->setHeight(tmpOStyle.page_height);
463 m_Doc->currentPage()->setWidth(tmpOStyle.page_width);
464 m_Doc->currentPage()->initialMargins.setTop(tmpOStyle.margin_top);
465 m_Doc->currentPage()->initialMargins.setBottom(tmpOStyle.margin_bottom);
466 m_Doc->currentPage()->initialMargins.setLeft(tmpOStyle.margin_left);
467 m_Doc->currentPage()->initialMargins.setRight(tmpOStyle.margin_right);
468 if (!backGroundStyle.isEmpty())
469 {
470 ObjStyle tmpBStyle;
471 resovleStyle(tmpBStyle, backGroundStyle);
472 int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, baseX, baseY, tmpOStyle.page_width, tmpOStyle.page_height, 0, tmpBStyle.currColorFill, CommonStrings::None);
473 PageItem *retObj = m_Doc->Items->at(z);
474 finishItem(retObj, tmpBStyle);
475 }
476 for (QDomElement spm = spf.firstChildElement(); !spm.isNull(); spm = spm.nextSiblingElement())
477 {
478 PageItem* retObj = parseObj(spm);
479 if (retObj != nullptr)
480 m_Doc->Items->append(retObj);
481 }
482 m_Doc->setCurrentPage(oldCur);
483 m_Doc->setMasterPageMode(false);
484 }
485 }
486 else if (spf.tagName() == "draw:layer-set")
487 {
488 if (importerFlags & LoadSavePlugin::lfCreateDoc)
489 {
490 for (QDomElement spp = spf.firstChildElement(); !spp.isNull(); spp = spp.nextSiblingElement())
491 {
492 if (spp.tagName() == "draw:layer")
493 {
494 QString layerName = spp.attribute("draw:name");
495 if (!layerName.isEmpty())
496 {
497 if (!firstLayer)
498 {
499 QStringList newNames;
500 m_Doc->orderedLayerList(&newNames);
501 if (!newNames.contains(layerName))
502 {
503 int currentLayer = m_Doc->addLayer(layerName);
504 m_Layers.insert(layerName, currentLayer);
505 }
506 }
507 else
508 {
509 m_Doc->changeLayerName(m_Doc->firstLayerID(), layerName);
510 m_Layers.insert(layerName, m_Doc->firstLayerID());
511 }
512 firstLayer = false;
513 }
514 }
515 }
516 }
517 }
518 }
519 }
520 }
521 return true;
522 }
523
parseDocReference(const QString & designMap)524 bool OdgPlug::parseDocReference(const QString& designMap)
525 {
526 QByteArray xmlData;
527 QDomDocument designMapDom;
528 if (!uz->read(designMap, xmlData))
529 return false;
530
531 QString errorMsg;
532 int errorLine = 0;
533 int errorColumn = 0;
534 if (!designMapDom.setContent(xmlData, false, &errorMsg, &errorLine, &errorColumn))
535 {
536 qDebug() << "Error loading File" << errorMsg << "at Line" << errorLine << "Column" << errorColumn;
537 return false;
538 }
539 return parseDocReferenceXML(designMapDom);
540 }
541
parseDocReferenceXML(QDomDocument & designMapDom)542 bool OdgPlug::parseDocReferenceXML(QDomDocument &designMapDom)
543 {
544 QDomElement docElem = designMapDom.documentElement();
545 for (QDomElement drawPag = docElem.firstChildElement(); !drawPag.isNull(); drawPag = drawPag.nextSiblingElement())
546 {
547 if (drawPag.tagName() == "office:font-face-decls")
548 {
549 for (QDomElement spf = drawPag.firstChildElement(); !spf.isNull(); spf = spf.nextSiblingElement() )
550 {
551 if (spf.tagName() == "style:font-face")
552 {
553 if (!spf.attribute("style:name").isEmpty())
554 m_fontMap.insert(spf.attribute("style:name"), spf.attribute("svg:font-family"));
555 }
556 }
557 }
558 else if ((drawPag.tagName() == "office:styles") || (drawPag.tagName() == "office:automatic-styles"))
559 parseStyles(drawPag);
560 if (drawPag.tagName() == "office:master-styles")
561 {
562 for (QDomElement spf = drawPag.firstChildElement(); !spf.isNull(); spf = spf.nextSiblingElement())
563 {
564 if (spf.tagName() == "style:master-page")
565 {
566 DrawStyle currStyle;
567 currStyle.page_layout_name = AttributeValue(spf.attribute("style:page-layout-name"));
568 m_Styles.insert(spf.attribute("style:name"), currStyle);
569 if (importerFlags & LoadSavePlugin::lfCreateDoc)
570 {
571 m_Doc->setMasterPageMode(true);
572 ScPage *oldCur = m_Doc->currentPage();
573 ScPage *addedPage = m_Doc->addMasterPage(mpagecount, spf.attribute("style:name"));
574 m_Doc->setCurrentPage(addedPage);
575 addedPage->clearMasterPageName();
576 m_Doc->view()->addPage(mpagecount, true);
577 baseX = addedPage->xOffset();
578 baseY = addedPage->yOffset();
579 mpagecount++;
580 ObjStyle tmpOStyle;
581 resovleStyle(tmpOStyle, spf.attribute("style:name"));
582 m_Doc->currentPage()->setSize("Custom");
583 m_Doc->currentPage()->setInitialHeight(tmpOStyle.page_height);
584 m_Doc->currentPage()->setInitialWidth(tmpOStyle.page_width);
585 m_Doc->currentPage()->setHeight(tmpOStyle.page_height);
586 m_Doc->currentPage()->setWidth(tmpOStyle.page_width);
587 m_Doc->currentPage()->initialMargins.setTop(tmpOStyle.margin_top);
588 m_Doc->currentPage()->initialMargins.setBottom(tmpOStyle.margin_bottom);
589 m_Doc->currentPage()->initialMargins.setLeft(tmpOStyle.margin_left);
590 m_Doc->currentPage()->initialMargins.setRight(tmpOStyle.margin_right);
591 if (!currStyle.page_layout_name.value.isEmpty())
592 {
593 ObjStyle tmpBStyle;
594 resovleStyle(tmpBStyle, currStyle.page_layout_name.value);
595 int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, baseX, baseY, tmpOStyle.page_width, tmpOStyle.page_height, 0, tmpBStyle.currColorFill, CommonStrings::None);
596 PageItem *retObj = m_Doc->Items->at(z);
597 finishItem(retObj, tmpBStyle);
598 }
599 for (QDomElement spm = spf.firstChildElement(); !spm.isNull(); spm = spm.nextSiblingElement())
600 {
601 PageItem* retObj = parseObj(spm);
602 if (retObj != nullptr)
603 m_Doc->Items->append(retObj);
604 }
605 m_Doc->setCurrentPage(oldCur);
606 m_Doc->setMasterPageMode(false);
607 }
608 }
609 else if (spf.tagName() == "draw:layer-set")
610 {
611 if (importerFlags & LoadSavePlugin::lfCreateDoc)
612 {
613 for (QDomElement spp = spf.firstChildElement(); !spp.isNull(); spp = spp.nextSiblingElement())
614 {
615 if (spp.tagName() == "draw:layer")
616 {
617 QString layerName = spp.attribute("draw:name");
618 if (!layerName.isEmpty())
619 {
620 if (!firstLayer)
621 {
622 QStringList newNames;
623 m_Doc->orderedLayerList(&newNames);
624 if (!newNames.contains(layerName))
625 {
626 int currentLayer = m_Doc->addLayer(layerName);
627 m_Layers.insert(layerName, currentLayer);
628 }
629 }
630 else
631 {
632 m_Doc->changeLayerName(m_Doc->firstLayerID(), layerName);
633 m_Layers.insert(layerName, m_Doc->firstLayerID());
634 }
635 firstLayer = false;
636 }
637 }
638 }
639 }
640 }
641 }
642 }
643 else if (drawPag.tagName() == "office:body")
644 {
645 for (QDomElement sp = drawPag.firstChildElement(); !sp.isNull(); sp = sp.nextSiblingElement())
646 {
647 if ((sp.tagName() == "office:drawing") || (sp.tagName() == "office:presentation"))
648 {
649 for (QDomElement spp = sp.firstChildElement(); !spp.isNull(); spp = spp.nextSiblingElement())
650 {
651 if (spp.tagName() == "draw:page")
652 {
653 ObjStyle tmpOStyle;
654 resovleStyle(tmpOStyle, spp.attribute("draw:master-page-name"));
655 docWidth = tmpOStyle.page_width;
656 docHeight = tmpOStyle.page_height;
657 topMargin = tmpOStyle.margin_top;
658 leftMargin = tmpOStyle.margin_left;
659 rightMargin = tmpOStyle.margin_right;
660 bottomMargin = tmpOStyle.margin_bottom;
661 if (importerFlags & LoadSavePlugin::lfCreateDoc)
662 {
663 if (firstPage)
664 {
665 m_Doc->setPage(docWidth, docHeight, topMargin, leftMargin, rightMargin, bottomMargin, m_Doc->PageSp, m_Doc->PageSpa, false, false);
666 m_Doc->setPageSize("Custom");
667 m_Doc->currentPage()->setSize("Custom");
668 m_Doc->currentPage()->setInitialHeight(docHeight);
669 m_Doc->currentPage()->setInitialWidth(docWidth);
670 m_Doc->currentPage()->setHeight(docHeight);
671 m_Doc->currentPage()->setWidth(docWidth);
672 m_Doc->currentPage()->initialMargins.setTop(topMargin);
673 m_Doc->currentPage()->initialMargins.setBottom(bottomMargin);
674 m_Doc->currentPage()->initialMargins.setLeft(leftMargin);
675 m_Doc->currentPage()->initialMargins.setRight(rightMargin);
676 m_Doc->reformPages(true);
677 }
678 else
679 {
680 m_Doc->addPage(pagecount);
681 m_Doc->currentPage()->setSize("Custom");
682 m_Doc->currentPage()->setInitialHeight(docHeight);
683 m_Doc->currentPage()->setInitialWidth(docWidth);
684 m_Doc->currentPage()->setHeight(docHeight);
685 m_Doc->currentPage()->setWidth(docWidth);
686 m_Doc->currentPage()->initialMargins.setTop(topMargin);
687 m_Doc->currentPage()->initialMargins.setBottom(bottomMargin);
688 m_Doc->currentPage()->initialMargins.setLeft(leftMargin);
689 m_Doc->currentPage()->initialMargins.setRight(rightMargin);
690 m_Doc->currentPage()->setMasterPageNameNormal();
691 m_Doc->view()->addPage(pagecount, true);
692 pagecount++;
693 }
694 m_Doc->applyMasterPage(spp.attribute("draw:master-page-name"), m_Doc->currentPageNumber());
695 }
696 firstPage = false;
697 baseX = m_Doc->currentPage()->xOffset();
698 baseY = m_Doc->currentPage()->yOffset();
699 for (QDomElement spe = spp.firstChildElement(); !spe.isNull(); spe = spe.nextSiblingElement())
700 {
701 PageItem* retObj = parseObj(spe);
702 if (retObj != nullptr)
703 {
704 m_Doc->Items->append(retObj);
705 Elements.append(retObj);
706 }
707 }
708 }
709 }
710 }
711 }
712 }
713 }
714 return true;
715 }
716
parseObj(QDomElement & draw)717 PageItem* OdgPlug::parseObj(QDomElement &draw)
718 {
719 StoryText itemText;
720 itemText.clear();
721 itemText.setDoc(m_Doc);
722 PageItem *retObj = nullptr;
723 if (draw.tagName() == "draw:g")
724 {
725 QList<PageItem*> GElements;
726 int gLayer = -1;
727 for (QDomElement spd = draw.firstChildElement(); !spd.isNull(); spd = spd.nextSiblingElement())
728 {
729 PageItem* ite = parseObj(spd);
730 if (ite != nullptr)
731 {
732 GElements.append(ite);
733 gLayer = ite->m_layerID;
734 }
735 }
736 if (GElements.count() > 0)
737 {
738 double minx = std::numeric_limits<double>::max();
739 double miny = std::numeric_limits<double>::max();
740 double maxx = -std::numeric_limits<double>::max();
741 double maxy = -std::numeric_limits<double>::max();
742 for (int ep = 0; ep < GElements.count(); ++ep)
743 {
744 PageItem* currItem = GElements.at(ep);
745 double x1, x2, y1, y2;
746 currItem->getVisualBoundingRect(&x1, &y1, &x2, &y2);
747 minx = qMin(minx, x1);
748 miny = qMin(miny, y1);
749 maxx = qMax(maxx, x2);
750 maxy = qMax(maxy, y2);
751 }
752 double gx = minx;
753 double gy = miny;
754 double gw = maxx - minx;
755 double gh = maxy - miny;
756 int z = m_Doc->itemAdd(PageItem::Group, PageItem::Rectangle, gx, gy, gw, gh, 0, CommonStrings::None, CommonStrings::None);
757 retObj = m_Doc->Items->at(z);
758 retObj->ClipEdited = true;
759 retObj->FrameType = 3;
760 retObj->setFillEvenOdd(false);
761 retObj->OldB2 = retObj->width();
762 retObj->OldH2 = retObj->height();
763 retObj->updateClip();
764 m_Doc->groupObjectsToItem(retObj, GElements);
765 retObj->OwnPage = m_Doc->OnPage(retObj);
766 m_Doc->GroupOnPage(retObj);
767 m_Doc->Items->removeLast();
768 if (gLayer > -1)
769 retObj->setLayer(gLayer);
770 }
771 }
772 else if (draw.tagName() == "draw:polygon")
773 retObj = parsePolygon(draw);
774 else if (draw.tagName() == "draw:polyline")
775 retObj = parsePolyline(draw);
776 else if (draw.tagName() == "draw:path")
777 retObj = parsePath(draw);
778 else if (draw.tagName() == "draw:rect")
779 retObj = parseRect(draw);
780 else if (draw.tagName() == "draw:circle" || draw.tagName() == "draw:ellipse")
781 retObj = parseEllipse(draw);
782 else if (draw.tagName() == "draw:line")
783 retObj = parseLine(draw);
784 else if (draw.tagName() == "draw:frame")
785 retObj = parseFrame(draw);
786 else if (draw.tagName() == "draw:measure")
787 retObj = parseMeasure(draw);
788 else if (draw.tagName() == "draw:custom-shape")
789 retObj = parseCustomShape(draw);
790 else if (draw.tagName() == "draw:connector")
791 retObj = parseConnector(draw);
792 else if (draw.tagName() == "office:forms")
793 retObj = parseForm(draw);
794 else
795 qDebug() << "Unhandled Tag" << draw.tagName();
796 if (retObj != nullptr)
797 {
798 if (draw.hasAttribute("draw:layer"))
799 {
800 if (m_Layers.contains(draw.attribute("draw:layer")))
801 retObj->setLayer(m_Layers[draw.attribute("draw:layer")]);
802 }
803 }
804 return retObj;
805 }
806
parseForm(QDomElement & e)807 PageItem* OdgPlug::parseForm(QDomElement &e)
808 {
809 PageItem *retObj = nullptr;
810 if (e.hasChildNodes())
811 qDebug() << "Unhandled Tag" << e.tagName();
812 return retObj;
813 }
814
parseConnector(QDomElement & e)815 PageItem* OdgPlug::parseConnector(QDomElement &e)
816 {
817 ObjStyle tmpOStyle;
818 PageItem *retObj = nullptr;
819 resovleStyle(tmpOStyle, "standard");
820 resovleStyle(tmpOStyle, getStyleName(e));
821 if ((tmpOStyle.fill_type == 0) && (tmpOStyle.stroke_type == 0))
822 return retObj;
823 if (e.hasAttribute("svg:d"))
824 {
825 FPointArray pArray;
826 pArray.svgInit();
827 pArray.parseSVG(e.attribute("svg:d"));
828 if (pArray.size() > 3)
829 {
830 int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, tmpOStyle.LineW, CommonStrings::None, tmpOStyle.currColorStroke);
831 retObj = m_Doc->Items->at(z);
832 retObj->PoLine = pArray.copy();
833 QTransform mat;
834 mat.scale(72.0 / 2540.0, 72.0 / 2540.0);
835 retObj->PoLine.map(mat);
836 if (e.hasAttribute("draw:transform"))
837 parseTransform(&retObj->PoLine, e.attribute("draw:transform"));
838 finishItem(retObj, tmpOStyle);
839 m_Doc->Items->removeLast();
840 if ((!tmpOStyle.startMarkerName.isEmpty()) || (!tmpOStyle.endMarkerName.isEmpty()))
841 {
842 QList<PageItem*> GElements;
843 GElements.append(retObj);
844 PageItem* startArrow = applyStartArrow(retObj, tmpOStyle);
845 if (startArrow != nullptr)
846 GElements.append(startArrow);
847 PageItem* endArrow = applyEndArrow(retObj, tmpOStyle);
848 if (endArrow != nullptr)
849 GElements.append(endArrow);
850 if (GElements.count() > 1)
851 retObj = groupObjects(GElements);
852 }
853 }
854 }
855 else if (e.hasAttribute("svg:x1") && e.hasAttribute("svg:x2") && e.hasAttribute("svg:y1") && e.hasAttribute("svg:y2"))
856 retObj = parseLine(e);
857 return retObj;
858 }
859
parseCustomShape(QDomElement & e)860 PageItem* OdgPlug::parseCustomShape(QDomElement &e)
861 {
862 ObjStyle tmpOStyle;
863 PageItem *retObj = nullptr;
864 QList<PageItem*> GElements;
865 double x = parseUnit(e.attribute("svg:x"));
866 double y = parseUnit(e.attribute("svg:y")) ;
867 double w = parseUnit(e.attribute("svg:width"));
868 double h = parseUnit(e.attribute("svg:height"));
869 resovleStyle(tmpOStyle, "standard");
870 resovleStyle(tmpOStyle, getStyleName(e));
871 bool has_Text = false;
872 for (QDomElement p = e.firstChildElement(); !p.isNull(); p = p.nextSiblingElement())
873 {
874 if (p.tagName() == "text:p")
875 {
876 if (p.hasChildNodes())
877 has_Text = true;
878 }
879 }
880 if ((tmpOStyle.fill_type == 0) && (tmpOStyle.stroke_type == 0) && (!has_Text))
881 return retObj;
882 QPolygonF texAreaPoints;
883 for (QDomElement p = e.firstChildElement(); !p.isNull(); p = p.nextSiblingElement())
884 {
885 if (p.tagName() == "draw:enhanced-geometry")
886 {
887 FunctionParser fpa;
888 double vx = 0;
889 double vy = 0;
890 double vw = 21600;
891 double vh = 21600;
892 if (p.hasAttribute("svg:viewBox"))
893 parseViewBox(p, &vx, &vy, &vw, &vh);
894 if (vw == 0)
895 vw = 21600;
896 if (vh == 0)
897 vh = 21600;
898 fpa.AddConstant("top", vy);
899 fpa.AddConstant("bottom", vh);
900 fpa.AddConstant("left", vx);
901 fpa.AddConstant("right", vw);
902 fpa.AddConstant("width", vw - vx);
903 fpa.AddConstant("height", vh - vy);
904 fpa.AddConstant("xstretch", parseUnit(p.attribute("draw:path-stretchpoint-x", "0")));
905 fpa.AddConstant("ystretch", parseUnit(p.attribute("draw:path-stretchpoint-y", "0")));
906 fpa.AddConstant("hasfill", tmpOStyle.fill_type == 0 ? 0 : 1);
907 fpa.AddConstant("hasstroke", tmpOStyle.stroke_type == 0 ? 0 : 1);
908 fpa.AddConstant("logheight", vh);
909 fpa.AddConstant("logwidth", vw);
910 fpa.AddConstant("pi", M_PI);
911 QString enhPath = p.attribute("draw:enhanced-path");
912 QString textArea = p.attribute("draw:text-areas");
913 if (!textArea.isEmpty())
914 textArea.append(" ");
915 QMap<QString, QString> func_Results;
916 QMap<QString, QString> modi_Values;
917 QString mods = p.attribute("draw:modifiers");
918 ScTextStream Code(&mods, QIODevice::ReadOnly);
919 int modCount = 0;
920 while (!Code.atEnd())
921 {
922 double d;
923 Code >> d;
924 QString modName = QString("Const_%1").arg(modCount);
925 fpa.AddConstant(modName.toStdString(), d);
926 modi_Values.insert(QString("$%1").arg(modCount), QString("%1").arg(d));
927 modCount++;
928 }
929 if (p.hasChildNodes())
930 {
931 QMap<QString, QString> formulaMap;
932 for (QDomElement f = p.firstChildElement(); !f.isNull(); f = f.nextSiblingElement())
933 {
934 if (f.tagName() == "draw:equation")
935 {
936 QString formName = f.attribute("draw:name");
937 QString formula = f.attribute("draw:formula", "0");
938 formula.replace("$", "Const_");
939 formula.replace("?", "Func_");
940 formula.replace("if(", "if(0<");
941 formulaMap.insert(formName, formula);
942 }
943 }
944 if (!formulaMap.isEmpty())
945 {
946 int maxTry = formulaMap.count() + 1;
947 int actTry = 0;
948 bool allResOK = false;
949 while (!allResOK)
950 {
951 allResOK = true;
952 QMap<QString, QString>::iterator itf = formulaMap.begin();
953 while (itf != formulaMap.end())
954 {
955 double erg = 0;
956 int ret = fpa.Parse(itf.value().toStdString(), "", false);
957 if (ret < 0)
958 {
959 QString formNam = itf.key();
960 erg = fpa.Eval(nullptr);
961 func_Results.insert("?" + formNam + " ", QString("%1 ").arg(erg));
962 formNam.prepend("Func_");
963 fpa.AddConstant(formNam.toStdString(), erg);
964 itf = formulaMap.erase(itf);
965 }
966 else
967 {
968 ++itf;
969 allResOK = false;
970 }
971 }
972 actTry++;
973 if (actTry > maxTry)
974 break;
975 if (formulaMap.isEmpty())
976 break;
977 }
978 }
979 }
980 if (!modi_Values.isEmpty())
981 {
982 QMapIterator<QString, QString> it(modi_Values);
983 it.toBack();
984 while (it.hasPrevious())
985 {
986 it.previous();
987 enhPath.replace(it.key(), it.value());
988 }
989 }
990 if (!func_Results.isEmpty())
991 {
992 QMapIterator<QString, QString> it(func_Results);
993 it.toBack();
994 while (it.hasPrevious())
995 {
996 it.previous();
997 enhPath.replace(it.key(), it.value());
998 if (!textArea.isEmpty())
999 textArea.replace(it.key(), it.value());
1000 }
1001 }
1002 if (enhPath.contains("?"))
1003 return retObj;
1004 QTransform mat;
1005 double sx = (vw != 0.0) ? (w / vw) : w;
1006 double sy = (vh != 0.0) ? (h / vh) : h;
1007 mat.scale(sx, sy);
1008 if (!textArea.isEmpty())
1009 {
1010 QStringList points = textArea.replace( QRegExp(","), " ").simplified().split( ' ', Qt::SkipEmptyParts );
1011 texAreaPoints.append(QPointF(ScCLocale::toDoubleC(points[0]), ScCLocale::toDoubleC(points[1])));
1012 texAreaPoints.append(QPointF(ScCLocale::toDoubleC(points[2]), ScCLocale::toDoubleC(points[3])));
1013 texAreaPoints = mat.map(texAreaPoints);
1014 }
1015 QString shapeType = p.attribute("draw:type");
1016 QStringList paths = enhPath.split("N", Qt::SkipEmptyParts);
1017 if (!paths.isEmpty())
1018 {
1019 for (int a = 0; a < paths.count(); a++)
1020 {
1021 FPointArray pArray;
1022 pArray.svgInit();
1023 bool filled = true;
1024 bool stroked = true;
1025 PageItem::ItemType itype = parseEnhPath(paths[a], pArray, filled, stroked) ? PageItem::PolyLine : PageItem::Polygon;
1026 if (pArray.size() > 3)
1027 {
1028 QString fillC = tmpOStyle.currColorFill;
1029 if (!filled)
1030 fillC = CommonStrings::None;
1031 else
1032 {
1033 if (shapeType == "can")
1034 {
1035 if (a == 1)
1036 fillC = modifyColor(fillC, false, 110);
1037 }
1038 else if (shapeType == "cube")
1039 {
1040 if (a == 1)
1041 fillC = modifyColor(fillC, false, 110);
1042 else if (a == 2)
1043 fillC = modifyColor(fillC, true, 120);
1044 }
1045 else if (shapeType == "paper")
1046 {
1047 if (a == 1)
1048 fillC = modifyColor(fillC, true, 120);
1049 }
1050 else if (shapeType == "smiley")
1051 {
1052 if (a == 1)
1053 fillC = modifyColor(fillC, true, 120);
1054 else if (a == 2)
1055 fillC = modifyColor(fillC, true, 120);
1056 }
1057 else if (shapeType == "quad-bevel")
1058 {
1059 if (a == 1)
1060 fillC = modifyColor(fillC, false, 110);
1061 else if (a == 2)
1062 fillC = modifyColor(fillC, true, 150);
1063 else if (a == 3)
1064 fillC = modifyColor(fillC, true, 120);
1065 else if (a == 4)
1066 fillC = modifyColor(fillC, false, 120);
1067 }
1068 else if (shapeType == "col-60da8460")
1069 {
1070 if (a == 1)
1071 fillC = modifyColor(fillC, true, 150);
1072 else if (a == 2)
1073 fillC = modifyColor(fillC, true, 300);
1074 else if (a == 3)
1075 fillC = modifyColor(fillC, false, 120);
1076 else if (a == 4)
1077 fillC = modifyColor(fillC, false, 120);
1078 else if (a == 5)
1079 fillC = modifyColor(fillC, false, 120);
1080 }
1081 else if (shapeType == "col-502ad400")
1082 {
1083 if (a == 1)
1084 fillC = modifyColor(fillC, false, 110);
1085 else if (a == 2)
1086 fillC = modifyColor(fillC, true, 120);
1087 else if (a == 3)
1088 fillC = modifyColor(fillC, false, 120);
1089 else if (a == 4)
1090 fillC = modifyColor(fillC, false, 120);
1091 }
1092 else if (shapeType == "vertical-scroll")
1093 {
1094 if (a == 1)
1095 fillC = modifyColor(fillC, true, 120);
1096 else if (a == 2)
1097 fillC = modifyColor(fillC, true, 120);
1098 }
1099 else if (shapeType == "horizontal-scroll")
1100 {
1101 if (a == 1)
1102 fillC = modifyColor(fillC, true, 120);
1103 else if (a == 2)
1104 fillC = modifyColor(fillC, true, 120);
1105 }
1106 }
1107 QString strokeC = tmpOStyle.currColorStroke;
1108 if (!stroked)
1109 strokeC = CommonStrings::None;
1110 int z = m_Doc->itemAdd(itype, PageItem::Unspecified, baseX + x, baseY + y, w, h, tmpOStyle.LineW, fillC, strokeC);
1111 retObj = m_Doc->Items->at(z);
1112 retObj->PoLine = pArray.copy();
1113 retObj->setFillEvenOdd(true);
1114 double stretchScale = 1.0;
1115 bool hasStretch = false;
1116 if ((w > h) && p.hasAttribute("draw:path-stretchpoint-x"))
1117 {
1118 double stretch = parseUnit(p.attribute("draw:path-stretchpoint-x", "0"));
1119 FPoint tp2(getMaxClipF(&retObj->PoLine));
1120 stretchScale = w / h;
1121 double endX = tp2.x() * stretchScale;
1122 double delX = endX - tp2.x();
1123 for (int ap = 0; ap < retObj->PoLine.size(); ap++)
1124 {
1125 FPoint pt = retObj->PoLine[ap];
1126 if (pt.x() > stretch)
1127 {
1128 if (pt.x() == tp2.x())
1129 retObj->PoLine[ap].setX(endX);
1130 else
1131 retObj->PoLine[ap].setX(pt.x() + delX);
1132 }
1133 }
1134 stretchScale = h / 21600.0;
1135 hasStretch = true;
1136 }
1137 if ((h > w) && p.hasAttribute("draw:path-stretchpoint-y"))
1138 {
1139 double stretch = parseUnit(p.attribute("draw:path-stretchpoint-y", "0"));
1140 FPoint tp2(getMaxClipF(&retObj->PoLine));
1141 stretchScale = h / w;
1142 double endY = tp2.y() * stretchScale;
1143 double delY = endY - tp2.y();
1144 for (int ap = 0; ap < retObj->PoLine.size(); ap++)
1145 {
1146 FPoint pt = retObj->PoLine[ap];
1147 if (pt.y() > stretch)
1148 {
1149 if (pt.y() == tp2.y())
1150 retObj->PoLine[ap].setY(endY);
1151 else
1152 retObj->PoLine[ap].setY(pt.y() + delY);
1153 }
1154 }
1155 stretchScale = w / 21600.0;
1156 hasStretch = true;
1157 }
1158 if (hasStretch)
1159 {
1160 QTransform smat;
1161 smat.scale(stretchScale, stretchScale);
1162 retObj->PoLine.map(smat);
1163 }
1164 else
1165 retObj->PoLine.map(mat);
1166 if (e.hasAttribute("draw:transform"))
1167 parseTransform(&retObj->PoLine, e.attribute("draw:transform"));
1168 finishItem(retObj, tmpOStyle);
1169 GElements.append(retObj);
1170 m_Doc->Items->removeLast();
1171 }
1172 }
1173 if (GElements.count() > 1)
1174 retObj = groupObjects(GElements);
1175 if (p.hasAttribute("draw:mirror-horizontal") && (p.attribute("draw:mirror-horizontal") == "true"))
1176 m_Doc->MirrorPolyH(retObj);
1177 if (p.hasAttribute("draw:mirror-vertical") && (p.attribute("draw:mirror-vertical") == "true"))
1178 m_Doc->MirrorPolyV(retObj);
1179 }
1180 }
1181 }
1182 if (has_Text)
1183 {
1184 double r = 0.0;
1185 if (e.hasAttribute("draw:transform"))
1186 parseTransform(e.attribute("draw:transform"), &r, &x, &y);
1187 double tx = x;
1188 double ty = y;
1189 double tw = w;
1190 double th = h;
1191 if (!texAreaPoints.isEmpty())
1192 {
1193 QTransform rmat;
1194 rmat.rotate(r);
1195 QPointF rt = rmat.map(texAreaPoints[0]);
1196 tx += rt.x();
1197 ty += rt.y();
1198 tw = texAreaPoints[1].x() - texAreaPoints[0].x();
1199 th = texAreaPoints[1].y() - texAreaPoints[0].y();
1200 }
1201 int z = m_Doc->itemAdd(PageItem::TextFrame, PageItem::Unspecified, baseX+tx, baseY+ty, tw, th, 0, CommonStrings::None, CommonStrings::None);
1202 retObj = m_Doc->Items->at(z);
1203 retObj->setTextToFrameDist(0.0, 0.0, 0.0, 0.0);
1204 retObj->setTextFlowMode(PageItem::TextFlowDisabled);
1205 retObj->setVerticalAlignment(tmpOStyle.verticalAlignment);
1206 finishItem(retObj, tmpOStyle);
1207 parseText(e, retObj, tmpOStyle);
1208 if (e.hasAttribute("draw:transform"))
1209 retObj->setRotation(r, true);
1210 m_Doc->Items->removeLast();
1211 GElements.append(retObj);
1212 }
1213 if (GElements.count() > 1)
1214 retObj = groupObjects(GElements);
1215 return retObj;
1216 }
1217
parseMeasure(QDomElement & e)1218 PageItem* OdgPlug::parseMeasure(QDomElement &e)
1219 {
1220 ObjStyle tmpOStyle;
1221 PageItem *retObj = nullptr;
1222 QList<PageItem*> GElements;
1223 double x1 = e.attribute( "svg:x1" ).isEmpty() ? 0.0 : parseUnit( e.attribute( "svg:x1" ) );
1224 double y1 = e.attribute( "svg:y1" ).isEmpty() ? 0.0 : parseUnit( e.attribute( "svg:y1" ) );
1225 double x2 = e.attribute( "svg:x2" ).isEmpty() ? 0.0 : parseUnit( e.attribute( "svg:x2" ) );
1226 double y2 = e.attribute( "svg:y2" ).isEmpty() ? 0.0 : parseUnit( e.attribute( "svg:y2" ) );
1227 resovleStyle(tmpOStyle, "standard");
1228 resovleStyle(tmpOStyle, getStyleName(e));
1229 if (tmpOStyle.measureDist == 0)
1230 tmpOStyle.measureDist = tmpOStyle.fontSize;
1231 QLineF refLine = QLineF(x1, y1, x2, y2);
1232 QLineF normRef = refLine.normalVector();
1233 normRef.setLength(tmpOStyle.measureDist);
1234 double dx = normRef.p2().x() - refLine.p1().x();
1235 double dy = normRef.p2().y() - refLine.p1().y();
1236 retObj = parseLine(e);
1237 if (retObj != nullptr)
1238 {
1239 retObj->moveBy(dx, dy, true);
1240 GElements.append(retObj);
1241 }
1242 normRef.setLength(tmpOStyle.measureDist + tmpOStyle.fontSize * 1.2);
1243 if (normRef.length() != 0)
1244 {
1245 int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, tmpOStyle.LineW, CommonStrings::None, tmpOStyle.currColorStroke);
1246 retObj = m_Doc->Items->at(z);
1247 retObj->PoLine.resize(4);
1248 retObj->PoLine.setPoint(0, FPoint(x1, y1));
1249 retObj->PoLine.setPoint(1, FPoint(x1, y1));
1250 retObj->PoLine.setPoint(2, FPoint(normRef.p2().x(), normRef.p2().y()));
1251 retObj->PoLine.setPoint(3, FPoint(normRef.p2().x(), normRef.p2().y()));
1252 if (e.hasAttribute("draw:transform"))
1253 parseTransform(&retObj->PoLine, e.attribute("draw:transform"));
1254 finishItem(retObj, tmpOStyle);
1255 m_Doc->Items->removeLast();
1256 GElements.append(retObj);
1257 }
1258 QLineF refLine2 = QLineF(x2, y2, x1, y1);
1259 QLineF normRef2 = refLine2.normalVector();
1260 normRef2.setAngle(normRef2.angle() + 180);
1261 normRef2.setLength(tmpOStyle.measureDist + tmpOStyle.fontSize / 2.0);
1262 if (normRef2.length() != 0)
1263 {
1264 int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, tmpOStyle.LineW, CommonStrings::None, tmpOStyle.currColorStroke);
1265 retObj = m_Doc->Items->at(z);
1266 retObj->PoLine.resize(4);
1267 retObj->PoLine.setPoint(0, FPoint(x2, y2));
1268 retObj->PoLine.setPoint(1, FPoint(x2, y2));
1269 retObj->PoLine.setPoint(2, FPoint(normRef2.p2().x(), normRef2.p2().y()));
1270 retObj->PoLine.setPoint(3, FPoint(normRef2.p2().x(), normRef2.p2().y()));
1271 if (e.hasAttribute("draw:transform"))
1272 parseTransform(&retObj->PoLine, e.attribute("draw:transform"));
1273 finishItem(retObj, tmpOStyle);
1274 m_Doc->Items->removeLast();
1275 GElements.append(retObj);
1276 }
1277 normRef2.setLength(tmpOStyle.measureDist + tmpOStyle.fontSize * 1.2);
1278 QLineF textLine = QLineF(normRef.p2(), normRef2.p2());
1279 if (textLine.length() != 0)
1280 {
1281 int z = m_Doc->itemAdd(PageItem::TextFrame, PageItem::Unspecified, baseX+normRef.p2().x(), baseY+normRef.p2().y(), textLine.length(), tmpOStyle.fontSize * 1.2, tmpOStyle.LineW, tmpOStyle.currColorFill, tmpOStyle.currColorStroke);
1282 retObj = m_Doc->Items->at(z);
1283 retObj->setFillColor(tmpOStyle.currColorFill);
1284 retObj->setTextToFrameDist(0.0, 0.0, 0.0, 0.0);
1285 retObj->setTextFlowMode(PageItem::TextFlowDisabled);
1286 finishItem(retObj, tmpOStyle);
1287 retObj->setRotation(-textLine.angle(), true);
1288 parseText(e, retObj, tmpOStyle);
1289 m_Doc->Items->removeLast();
1290 GElements.append(retObj);
1291 }
1292 if (GElements.count() > 1)
1293 retObj = groupObjects(GElements);
1294 return retObj;
1295 }
1296
parseLine(QDomElement & e)1297 PageItem* OdgPlug::parseLine( QDomElement &e)
1298 {
1299 ObjStyle tmpOStyle;
1300 PageItem *retObj = nullptr;
1301 double x1 = e.attribute( "svg:x1" ).isEmpty() ? 0.0 : parseUnit( e.attribute( "svg:x1" ) );
1302 double y1 = e.attribute( "svg:y1" ).isEmpty() ? 0.0 : parseUnit( e.attribute( "svg:y1" ) );
1303 double x2 = e.attribute( "svg:x2" ).isEmpty() ? 0.0 : parseUnit( e.attribute( "svg:x2" ) );
1304 double y2 = e.attribute( "svg:y2" ).isEmpty() ? 0.0 : parseUnit( e.attribute( "svg:y2" ) );
1305 resovleStyle(tmpOStyle, "standard");
1306 resovleStyle(tmpOStyle, getStyleName(e));
1307 if (tmpOStyle.stroke_type == 0)
1308 return retObj;
1309 int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, tmpOStyle.LineW, CommonStrings::None, tmpOStyle.currColorStroke);
1310 retObj = m_Doc->Items->at(z);
1311 retObj->PoLine.resize(4);
1312 retObj->PoLine.setPoint(0, FPoint(x1, y1));
1313 retObj->PoLine.setPoint(1, FPoint(x1, y1));
1314 retObj->PoLine.setPoint(2, FPoint(x2, y2));
1315 retObj->PoLine.setPoint(3, FPoint(x2, y2));
1316 if (e.hasAttribute("draw:transform"))
1317 parseTransform(&retObj->PoLine, e.attribute("draw:transform"));
1318 finishItem(retObj, tmpOStyle);
1319 m_Doc->Items->removeLast();
1320 if ((!tmpOStyle.startMarkerName.isEmpty()) || (!tmpOStyle.endMarkerName.isEmpty()))
1321 {
1322 QList<PageItem*> GElements;
1323 GElements.append(retObj);
1324 PageItem* startArrow = applyStartArrow(retObj, tmpOStyle);
1325 if (startArrow != nullptr)
1326 GElements.append(startArrow);
1327 PageItem* endArrow = applyEndArrow(retObj, tmpOStyle);
1328 if (endArrow != nullptr)
1329 GElements.append(endArrow);
1330 if (GElements.count() > 1)
1331 retObj = groupObjects(GElements);
1332 }
1333 return retObj;
1334 }
1335
parseEllipse(QDomElement & e)1336 PageItem* OdgPlug::parseEllipse(QDomElement &e)
1337 {
1338 ObjStyle tmpOStyle;
1339 PageItem *retObj = nullptr;
1340 double x = parseUnit(e.attribute("svg:x"));
1341 double y = parseUnit(e.attribute("svg:y")) ;
1342 double w = parseUnit(e.attribute("svg:width"));
1343 double h = parseUnit(e.attribute("svg:height"));
1344 resovleStyle(tmpOStyle, "standard");
1345 resovleStyle(tmpOStyle, getStyleName(e));
1346 if ((tmpOStyle.fill_type == 0) && (tmpOStyle.stroke_type == 0))
1347 return retObj;
1348 int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, baseX+x, baseY+y, w, h, tmpOStyle.LineW, tmpOStyle.currColorFill, tmpOStyle.currColorStroke);
1349 retObj = m_Doc->Items->at(z);
1350 if (e.hasAttribute("draw:transform"))
1351 parseTransform(&retObj->PoLine, e.attribute("draw:transform"));
1352 finishItem(retObj, tmpOStyle);
1353 m_Doc->Items->removeLast();
1354 return retObj;
1355 }
1356
parseRect(QDomElement & e)1357 PageItem* OdgPlug::parseRect(QDomElement &e)
1358 {
1359 ObjStyle tmpOStyle;
1360 PageItem *retObj = nullptr;
1361 double x = parseUnit(e.attribute("svg:x"));
1362 double y = parseUnit(e.attribute("svg:y")) ;
1363 double w = parseUnit(e.attribute("svg:width"));
1364 double h = parseUnit(e.attribute("svg:height"));
1365 double corner = parseUnit(e.attribute("draw:corner-radius"));
1366 resovleStyle(tmpOStyle, "standard");
1367 resovleStyle(tmpOStyle, getStyleName(e));
1368 if ((tmpOStyle.fill_type == 0) && (tmpOStyle.stroke_type == 0))
1369 return retObj;
1370 int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, baseX+x, baseY+y, w, h, tmpOStyle.LineW, tmpOStyle.currColorFill, tmpOStyle.currColorStroke);
1371 retObj = m_Doc->Items->at(z);
1372 if (corner != 0)
1373 {
1374 retObj->setCornerRadius(corner);
1375 retObj->SetFrameRound();
1376 m_Doc->setRedrawBounding(retObj);
1377 }
1378 if (e.hasAttribute("draw:transform"))
1379 parseTransform(&retObj->PoLine, e.attribute("draw:transform"));
1380 finishItem(retObj, tmpOStyle);
1381 m_Doc->Items->removeLast();
1382 return retObj;
1383 }
1384
parsePolygon(QDomElement & e)1385 PageItem* OdgPlug::parsePolygon(QDomElement &e)
1386 {
1387 ObjStyle tmpOStyle;
1388 PageItem *retObj = nullptr;
1389 resovleStyle(tmpOStyle, "standard");
1390 resovleStyle(tmpOStyle, getStyleName(e));
1391 if ((tmpOStyle.fill_type == 0) && (tmpOStyle.stroke_type == 0))
1392 return retObj;
1393 int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, tmpOStyle.LineW, tmpOStyle.currColorFill, tmpOStyle.currColorStroke);
1394 retObj = m_Doc->Items->at(z);
1395 retObj->PoLine.resize(0);
1396 appendPoints(&retObj->PoLine, e, true);
1397 if (e.hasAttribute("draw:transform"))
1398 parseTransform(&retObj->PoLine, e.attribute("draw:transform"));
1399 finishItem(retObj, tmpOStyle);
1400 m_Doc->Items->removeLast();
1401 return retObj;
1402 }
1403
parsePolyline(QDomElement & e)1404 PageItem* OdgPlug::parsePolyline(QDomElement &e)
1405 {
1406 ObjStyle tmpOStyle;
1407 PageItem *retObj = nullptr;
1408 resovleStyle(tmpOStyle, "standard");
1409 resovleStyle(tmpOStyle, getStyleName(e));
1410 if (tmpOStyle.stroke_type == 0)
1411 return retObj;
1412 int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, tmpOStyle.LineW, CommonStrings::None, tmpOStyle.currColorStroke);
1413 retObj = m_Doc->Items->at(z);
1414 retObj->PoLine.resize(0);
1415 appendPoints(&retObj->PoLine, e, false);
1416 if (e.hasAttribute("draw:transform"))
1417 parseTransform(&retObj->PoLine, e.attribute("draw:transform"));
1418 finishItem(retObj, tmpOStyle);
1419 m_Doc->Items->removeLast();
1420 if ((!tmpOStyle.startMarkerName.isEmpty()) || (!tmpOStyle.endMarkerName.isEmpty()))
1421 {
1422 QList<PageItem*> GElements;
1423 GElements.append(retObj);
1424 PageItem* startArrow = applyStartArrow(retObj, tmpOStyle);
1425 if (startArrow != nullptr)
1426 GElements.append(startArrow);
1427 PageItem* endArrow = applyEndArrow(retObj, tmpOStyle);
1428 if (endArrow != nullptr)
1429 GElements.append(endArrow);
1430 if (GElements.count() > 1)
1431 retObj = groupObjects(GElements);
1432 }
1433 return retObj;
1434 }
1435
parsePath(QDomElement & e)1436 PageItem* OdgPlug::parsePath(QDomElement &e)
1437 {
1438 ObjStyle tmpOStyle;
1439 PageItem *retObj = nullptr;
1440 resovleStyle(tmpOStyle, "standard");
1441 resovleStyle(tmpOStyle, getStyleName(e));
1442 if ((tmpOStyle.fill_type == 0) && (tmpOStyle.stroke_type == 0))
1443 return retObj;
1444 FPointArray pArray;
1445 pArray.svgInit();
1446 PageItem::ItemType itype = pArray.parseSVG(e.attribute("svg:d")) ? PageItem::PolyLine : PageItem::Polygon;
1447 if (pArray.size() > 3)
1448 {
1449 double x = parseUnit(e.attribute("svg:x"));
1450 double y = parseUnit(e.attribute("svg:y")) ;
1451 double w = parseUnit(e.attribute("svg:width"));
1452 double h = parseUnit(e.attribute("svg:height"));
1453 int z = m_Doc->itemAdd(itype, PageItem::Unspecified, baseX + x, baseY + y, w, h, tmpOStyle.LineW, tmpOStyle.currColorFill, tmpOStyle.currColorStroke);
1454 retObj = m_Doc->Items->at(z);
1455 retObj->PoLine = pArray.copy();
1456 QTransform mat;
1457 double vx = 0;
1458 double vy = 0;
1459 double vw = 1;
1460 double vh = 1;
1461 parseViewBox(e, &vx, &vy, &vw, &vh);
1462 double sx = (vw != 0.0) ? (w / vw) : w;
1463 double sy = (vh != 0.0) ? (h / vh) : h;
1464 mat.scale(sx, sy);
1465 retObj->PoLine.map(mat);
1466 if (e.hasAttribute("draw:transform"))
1467 {
1468 FPoint tp2(getMinClipF(&retObj->PoLine));
1469 retObj->PoLine.translate(-tp2.x(), -tp2.y());
1470 parseTransform(&retObj->PoLine, e.attribute("draw:transform"));
1471 }
1472 finishItem(retObj, tmpOStyle);
1473 m_Doc->Items->removeLast();
1474 if (itype == PageItem::PolyLine)
1475 {
1476 if ((!tmpOStyle.startMarkerName.isEmpty()) || (!tmpOStyle.endMarkerName.isEmpty()))
1477 {
1478 QList<PageItem*> GElements;
1479 GElements.append(retObj);
1480 PageItem* startArrow = applyStartArrow(retObj, tmpOStyle);
1481 if (startArrow != nullptr)
1482 GElements.append(startArrow);
1483 PageItem* endArrow = applyEndArrow(retObj, tmpOStyle);
1484 if (endArrow != nullptr)
1485 GElements.append(endArrow);
1486 if (GElements.count() > 1)
1487 retObj = groupObjects(GElements);
1488 }
1489 }
1490 }
1491 return retObj;
1492 }
1493
parseFrame(QDomElement & e)1494 PageItem* OdgPlug::parseFrame(QDomElement &e)
1495 {
1496 ObjStyle tmpOStyle;
1497 PageItem *retObj = nullptr;
1498 double x = parseUnit(e.attribute("svg:x"));
1499 double y = parseUnit(e.attribute("svg:y")) ;
1500 double w = parseUnit(e.attribute("svg:width"));
1501 double h = parseUnit(e.attribute("svg:height"));
1502 double r = 0.0;
1503 if (e.hasAttribute("draw:transform"))
1504 parseTransform(e.attribute("draw:transform"), &r, &x, &y);
1505 resovleStyle(tmpOStyle, "standard");
1506 resovleStyle(tmpOStyle, getStyleName(e));
1507 QDomElement n = e.firstChildElement();
1508 if (!n.isNull())
1509 {
1510 if (n.tagName() == "draw:text-box" )
1511 {
1512 if (n.text().isEmpty())
1513 return retObj;
1514 int z = m_Doc->itemAdd(PageItem::TextFrame, PageItem::Unspecified, baseX+x, baseY+y, w, h, tmpOStyle.LineW, tmpOStyle.currColorFill, tmpOStyle.currColorStroke);
1515 retObj = m_Doc->Items->at(z);
1516 retObj->setFillColor(tmpOStyle.currColorFill);
1517 retObj->setTextToFrameDist(0.0, 0.0, 0.0, 0.0);
1518 retObj->setTextFlowMode(PageItem::TextFlowDisabled);
1519 retObj->setVerticalAlignment(tmpOStyle.verticalAlignment);
1520 if (e.hasAttribute("draw:transform"))
1521 retObj->setRotation(r, true);
1522 finishItem(retObj, tmpOStyle);
1523 parseText(n, retObj, tmpOStyle);
1524 m_Doc->Items->removeLast();
1525 }
1526 else if (n.tagName() == "draw:image" )
1527 {
1528 QString imagePath = n.attribute("xlink:href", "");
1529 if (!imagePath.isEmpty())
1530 {
1531 QFileInfo fi(imagePath);
1532 QString ext = fi.suffix().toLower();
1533 QString formatD(FormatsManager::instance()->extensionListForFormat(FormatsManager::IMAGESIMGFRAME, 1));
1534 QStringList formats = formatD.split("|");
1535 formats.removeAll("pdf");
1536 QStringList allFormatsV = LoadSavePlugin::getExtensionsForImport(FORMATID_FIRSTUSER);
1537 if (formats.contains(ext.toUtf8()))
1538 {
1539 int z = m_Doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, baseX+x, baseY+y, w, h, tmpOStyle.LineW, tmpOStyle.currColorFill, tmpOStyle.currColorStroke);
1540 retObj = m_Doc->Items->at(z);
1541 if (e.hasAttribute("draw:transform"))
1542 retObj->setRotation(r, true);
1543 finishItem(retObj, tmpOStyle);
1544 QByteArray f;
1545 if (uz->read(imagePath, f))
1546 {
1547 QFileInfo fi(imagePath);
1548 QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_odg_XXXXXX." + fi.suffix());
1549 tempFile->setAutoRemove(false);
1550 if (tempFile->open())
1551 {
1552 QString fileName = getLongPathName(tempFile->fileName());
1553 if (!fileName.isEmpty())
1554 {
1555 tempFile->write(f);
1556 tempFile->close();
1557 retObj->isInlineImage = true;
1558 retObj->isTempFile = true;
1559 retObj->AspectRatio = false;
1560 retObj->ScaleType = false;
1561 m_Doc->loadPict(fileName, retObj);
1562 retObj->adjustPictScale();
1563 }
1564 }
1565 delete tempFile;
1566 }
1567 m_Doc->Items->removeLast();
1568 }
1569 else if (allFormatsV.contains(ext.toUtf8()))
1570 {
1571 QByteArray f;
1572 if (uz->read(imagePath, f))
1573 {
1574 QFileInfo fi(imagePath);
1575 QString ext = fi.suffix();
1576 if (ext == "wmf")
1577 {
1578 if ((f[0] == '\x01') && (f[1] == '\x00') && (f[2] == '\x00') && (f[3] == '\x00') && (f[40] == '\x20') && (f[41] == '\x45') && (f[42] == '\x4D') && (f[43] == '\x46'))
1579 ext = "emf";
1580 }
1581 retObj = getVectorFileFromData(m_Doc, f, ext, baseX + x, baseY + y, w, h);
1582 if (retObj != nullptr)
1583 m_Doc->Items->removeLast();
1584 }
1585 }
1586 }
1587 else if (n.hasChildNodes())
1588 {
1589 for (QDomElement nc = n.firstChildElement(); !nc.isNull(); nc = nc.nextSiblingElement())
1590 {
1591 if (nc.tagName() == "office:binary-data")
1592 {
1593 QString ext = "";
1594 QByteArray buf = QByteArray::fromBase64(nc.text().toLatin1());
1595 if ((buf[0] == '%') && (buf[1] == '!') && (buf[2] == 'P') && (buf[3] == 'S') && (buf[4] == '-') && (buf[5] == 'A'))
1596 ext = "eps";
1597 else if ((buf[0] == '\xC5') && (buf[1] == '\xD0') && (buf[2] == '\xD3') && (buf[3] == '\xC6'))
1598 ext = "eps";
1599 else if ((buf[0] == 'G') && (buf[1] == 'I') && (buf[2] == 'F') && (buf[3] == '8'))
1600 ext = "gif";
1601 else if ((buf[0] == '\xFF') && (buf[1] == '\xD8') && (buf[2] == '\xFF'))
1602 ext = "jpg";
1603 else if ((buf[0] == '%') && (buf[1] == 'P') && (buf[2] == 'D') && (buf[3] == 'F'))
1604 ext = "pdf";
1605 else if ((buf[0] == 'P') && (buf[1] == 'G') && (buf[2] == 'F'))
1606 ext = "pgf";
1607 else if ((buf[0] == '\x89') && (buf[1] == 'P') && (buf[2] == 'N') && (buf[3] == 'G'))
1608 ext = "png";
1609 else if ((buf[0] == '8') && (buf[1] == 'B') && (buf[2] == 'P') && (buf[3] == 'S'))
1610 ext = "psd";
1611 else if (((buf[0] == 'I') && (buf[1] == 'I') && (buf[2] == '\x2A')) || ((buf[0] == 'M') && (buf[1] == 'M') && (buf[3] == '\x2A')))
1612 ext = "tif";
1613 else if ((buf[0] == '/') && (buf[1] == '*') && (buf[2] == ' ') && (buf[3] == 'X') && (buf[4] == 'P') && (buf[5] == 'M'))
1614 ext = "xpm";
1615 else if ((buf[0] == '\xD7') && (buf[1] == '\xCD') && (buf[2] == '\xC6') && (buf[3] == '\x9A'))
1616 ext = "wmf";
1617 else if ((buf[0] == '\x01') && (buf[1] == '\x00') && (buf[2] == '\x00') && (buf[3] == '\x00') && (buf[40] == '\x20') && (buf[41] == '\x45') && (buf[42] == '\x4D') && (buf[43] == '\x46'))
1618 ext = "emf";
1619 else if ((buf[0] == '<') && (buf[1] == '?') && (buf[2] == 'x') && (buf[3] == 'm') && (buf[4] == 'l'))
1620 ext = "svg";
1621 else if ((buf[0] == 'V') && (buf[1] == 'C') && (buf[2] == 'L') && (buf[3] == 'M') && (buf[4] == 'T') && (buf[5] == 'F'))
1622 ext = "svm";
1623 if (!ext.isEmpty())
1624 {
1625 if ((ext == "eps") || (ext == "wmf") || (ext == "emf") || (ext == "svg") || (ext == "svm"))
1626 {
1627 retObj = getVectorFileFromData(m_Doc, buf, ext, baseX + x, baseY + y, w, h);
1628 if (retObj != nullptr)
1629 m_Doc->Items->removeLast();
1630 }
1631 else
1632 {
1633 int z = m_Doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, baseX+x, baseY+y, w, h, tmpOStyle.LineW, tmpOStyle.currColorFill, tmpOStyle.currColorStroke);
1634 retObj = m_Doc->Items->at(z);
1635 if (e.hasAttribute("draw:transform"))
1636 retObj->setRotation(r, true);
1637 finishItem(retObj, tmpOStyle);
1638 QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_odg_XXXXXX." + ext);
1639 tempFile->setAutoRemove(false);
1640 if (tempFile->open())
1641 {
1642 QString fileName = getLongPathName(tempFile->fileName());
1643 if (!fileName.isEmpty())
1644 {
1645 tempFile->write(buf);
1646 tempFile->close();
1647 retObj->isInlineImage = true;
1648 retObj->isTempFile = true;
1649 retObj->AspectRatio = false;
1650 retObj->ScaleType = false;
1651 m_Doc->loadPict(fileName, retObj);
1652 retObj->adjustPictScale();
1653 }
1654 }
1655 delete tempFile;
1656 m_Doc->Items->removeLast();
1657 }
1658 }
1659 }
1660 }
1661 }
1662 }
1663 }
1664 return retObj;
1665 }
1666
parseText(QDomElement & elem,PageItem * item,ObjStyle & tmpOStyle)1667 void OdgPlug::parseText(QDomElement &elem, PageItem* item, ObjStyle& tmpOStyle)
1668 {
1669 int posC = 0;
1670 QString pStyleD = CommonStrings::DefaultParagraphStyle;
1671 ParagraphStyle newStyle;
1672 newStyle.setDefaultStyle(false);
1673 newStyle.setParent(pStyleD);
1674 ParagraphStyle ttx = m_Doc->paragraphStyle(pStyleD);
1675 CharStyle nstyle = ttx.charStyle();
1676 newStyle.setLineSpacingMode(ParagraphStyle::AutomaticLineSpacing);
1677 newStyle.setLineSpacing(nstyle.fontSize() / 10.0);
1678 item->itemText.clear();
1679 item->itemText.setDefaultStyle(newStyle);
1680 item->setFirstLineOffset(FLOPFontAscent);
1681 ObjStyle pStyle = tmpOStyle;
1682 if (elem.hasAttribute("text:style-name"))
1683 resovleStyle(pStyle, elem.attribute("text:style-name"));
1684 for (QDomElement para = elem.firstChildElement(); !para.isNull(); para = para.nextSiblingElement())
1685 {
1686 pStyle = tmpOStyle;
1687 if ((para.tagName() != "text:p") && (para.tagName() != "text:list") && (para.tagName() != "text:h"))
1688 continue;
1689 if (para.hasChildNodes())
1690 {
1691 if (para.hasAttribute("text:style-name"))
1692 resovleStyle(pStyle, para.attribute("text:style-name"));
1693 ParagraphStyle tmpStyle = newStyle;
1694 applyParagraphStyle(tmpStyle, pStyle);
1695 double maxFsize = 0.0;
1696 if (para.firstChildElement().isNull())
1697 {
1698 CharStyle tmpCStyle = tmpStyle.charStyle();
1699 applyCharacterStyle(tmpCStyle, tmpOStyle);
1700 maxFsize = qMax(maxFsize, tmpOStyle.fontSize);
1701 QString txt = para.text();
1702 insertChars(item, txt, tmpStyle, tmpCStyle, posC);
1703 }
1704 else
1705 {
1706 for (QDomNode spn = para.firstChild(); !spn.isNull(); spn = spn.nextSibling())
1707 {
1708 CharStyle tmpCStyle = tmpStyle.charStyle();
1709 QDomElement sp = spn.toElement();
1710 ObjStyle cStyle = pStyle;
1711 if (spn.isElement() && (sp.tagName() == "text:span"))
1712 {
1713 if (sp.hasAttribute("text:style-name"))
1714 resovleStyle(cStyle, sp.attribute("text:style-name"));
1715 }
1716 applyCharacterStyle(tmpCStyle, cStyle);
1717 maxFsize = qMax(maxFsize, cStyle.fontSize);
1718 QString txt = "";
1719 if (spn.isElement())
1720 {
1721 if (sp.tagName() == "text:span")
1722 {
1723 if (sp.tagName() == "text:s")
1724 txt = " ";
1725 else if (sp.tagName() == "text:tab")
1726 txt = SpecialChars::TAB;
1727 else if (sp.tagName() == "text:line-break")
1728 txt = SpecialChars::LINEBREAK;
1729 else
1730 txt = sp.text();
1731 }
1732 else if (sp.tagName() == "text:measure")
1733 {
1734 QString kind = sp.attribute("text:kind");
1735 if (kind == "value")
1736 txt += sp.text();
1737 else if (kind == "unit")
1738 txt += " " + sp.text();
1739 }
1740 else if (sp.tagName() == "text:list-item")
1741 {
1742 for (QDomElement paral = sp.firstChildElement(); !paral.isNull(); paral = paral.nextSiblingElement())
1743 {
1744 ObjStyle plStyle = tmpOStyle;
1745 if (paral.hasAttribute("text:style-name"))
1746 resovleStyle(plStyle, paral.attribute("text:style-name"));
1747 ParagraphStyle tmpStyle = newStyle;
1748 applyParagraphStyle(tmpStyle, plStyle);
1749 for (QDomNode spnl = paral.firstChild(); !spnl.isNull(); spnl = spnl.nextSibling())
1750 {
1751 CharStyle tmpCStyle = tmpStyle.charStyle();
1752 QDomElement spl = spnl.toElement();
1753 ObjStyle clStyle = plStyle;
1754 if (spnl.isElement() && (spl.tagName() == "text:span"))
1755 {
1756 if (spl.hasAttribute("text:style-name"))
1757 resovleStyle(clStyle, spl.attribute("text:style-name"));
1758 }
1759 applyCharacterStyle(tmpCStyle, clStyle);
1760 maxFsize = qMax(maxFsize, clStyle.fontSize);
1761 if (spnl.isElement())
1762 {
1763 if (spl.tagName() == "text:span")
1764 {
1765 if (spl.tagName() == "text:s")
1766 txt = " ";
1767 else if (spl.tagName() == "text:tab")
1768 txt = SpecialChars::TAB;
1769 else if (spl.tagName() == "text:line-break")
1770 txt = SpecialChars::LINEBREAK;
1771 else
1772 txt = spl.text();
1773 }
1774 }
1775 else if (spnl.isText())
1776 {
1777 QDomText t = spnl.toText();
1778 }
1779 insertChars(item, txt, tmpStyle, tmpCStyle, posC);
1780 }
1781 item->itemText.insertChars(posC, SpecialChars::PARSEP);
1782 item->itemText.applyStyle(posC, tmpStyle);
1783 posC = item->itemText.length();
1784 }
1785 }
1786 }
1787 else if (spn.isText())
1788 {
1789 QDomText t = spn.toText();
1790 txt = t.data();
1791 }
1792 insertChars(item, txt, tmpStyle, tmpCStyle, posC);
1793 }
1794 }
1795 if (pStyle.lineHeight < 0.0)
1796 tmpStyle.setLineSpacingMode(ParagraphStyle::AutomaticLineSpacing);
1797 else
1798 {
1799 tmpStyle.setLineSpacingMode(ParagraphStyle::FixedLineSpacing);
1800 if (pStyle.absLineHeight)
1801 tmpStyle.setLineSpacing(pStyle.lineHeight);
1802 else
1803 tmpStyle.setLineSpacing(pStyle.lineHeight * maxFsize);
1804 }
1805 item->itemText.insertChars(posC, SpecialChars::PARSEP);
1806 item->itemText.applyStyle(posC, tmpStyle);
1807 posC = item->itemText.length();
1808 }
1809 else
1810 {
1811 QString txt = para.text();
1812 ParagraphStyle tmpStyle = newStyle;
1813 applyParagraphStyle(tmpStyle, tmpOStyle);
1814 CharStyle tmpCStyle = tmpStyle.charStyle();
1815 applyCharacterStyle(tmpCStyle, tmpOStyle);
1816 if (tmpOStyle.lineHeight < 0.0)
1817 tmpStyle.setLineSpacingMode(ParagraphStyle::AutomaticLineSpacing);
1818 else
1819 {
1820 tmpStyle.setLineSpacingMode(ParagraphStyle::FixedLineSpacing);
1821 if (tmpOStyle.absLineHeight)
1822 tmpStyle.setLineSpacing(tmpOStyle.lineHeight);
1823 else
1824 tmpStyle.setLineSpacing(tmpOStyle.lineHeight * tmpOStyle.fontSize);
1825 }
1826 insertChars(item, txt, tmpStyle, tmpCStyle, posC);
1827 item->itemText.insertChars(posC, SpecialChars::PARSEP);
1828 item->itemText.applyStyle(posC, tmpStyle);
1829 posC = item->itemText.length();
1830 }
1831 }
1832 item->itemText.trim();
1833 }
1834
insertChars(PageItem * item,QString & txt,ParagraphStyle & tmpStyle,CharStyle & tmpCStyle,int & posC)1835 void OdgPlug::insertChars(PageItem *item, QString &txt, ParagraphStyle &tmpStyle, CharStyle &tmpCStyle, int &posC)
1836 {
1837 if (txt.length() > 0)
1838 {
1839 item->itemText.insertChars(posC, txt);
1840 item->itemText.applyStyle(posC, tmpStyle);
1841 item->itemText.applyCharStyle(posC, txt.length(), tmpCStyle);
1842 posC = item->itemText.length();
1843 txt = "";
1844 }
1845 }
1846
applyCharacterStyle(CharStyle & tmpCStyle,ObjStyle & oStyle)1847 void OdgPlug::applyCharacterStyle(CharStyle &tmpCStyle, ObjStyle &oStyle)
1848 {
1849 tmpCStyle.setFont((*m_Doc->AllFonts)[oStyle.fontName]);
1850 tmpCStyle.setFontSize(oStyle.fontSize * 10);
1851 tmpCStyle.setFillColor(oStyle.currColorText);
1852 tmpCStyle.setBackColor(oStyle.currColorBText);
1853 StyleFlag styleEffects = tmpCStyle.effects();
1854 if ((oStyle.textPos.startsWith("super")) || (oStyle.textPos.startsWith("sub")))
1855 {
1856 if (oStyle.textPos.startsWith("super"))
1857 styleEffects |= ScStyle_Superscript;
1858 else
1859 styleEffects |= ScStyle_Subscript;
1860 }
1861 if (oStyle.textOutline == "true")
1862 {
1863 styleEffects |= ScStyle_Outline;
1864 tmpCStyle.setOutlineWidth(30);
1865 tmpCStyle.setFillColor("White");
1866 tmpCStyle.setStrokeColor(oStyle.currColorText);
1867 }
1868 if (oStyle.textUnderline)
1869 {
1870 styleEffects |= ScStyle_Underline;
1871 tmpCStyle.setUnderlineOffset(-1);
1872 tmpCStyle.setUnderlineWidth(-1);
1873 tmpCStyle.setStrokeColor(oStyle.textUnderlineColor);
1874 }
1875 if (oStyle.textStrikeThrough)
1876 {
1877 if (oStyle.textUnderlineWords)
1878 styleEffects |= ScStyle_UnderlineWords;
1879 else
1880 styleEffects |= ScStyle_Strikethrough;
1881 tmpCStyle.setStrikethruOffset(-1);
1882 tmpCStyle.setStrikethruWidth(-1);
1883 tmpCStyle.setStrokeColor(oStyle.currColorText);
1884 }
1885 if (oStyle.textShadow)
1886 {
1887 styleEffects |= ScStyle_Shadowed;
1888 tmpCStyle.setShadowXOffset(30);
1889 tmpCStyle.setShadowYOffset(-30);
1890 tmpCStyle.setStrokeColor(oStyle.currColorText);
1891 }
1892 tmpCStyle.setFeatures(styleEffects.featureList());
1893 }
1894
applyParagraphStyle(ParagraphStyle & tmpStyle,ObjStyle & oStyle)1895 void OdgPlug::applyParagraphStyle(ParagraphStyle &tmpStyle, ObjStyle &oStyle)
1896 {
1897 tmpStyle.setAlignment(oStyle.textAlign);
1898 tmpStyle.setLeftMargin(oStyle.margin_left);
1899 tmpStyle.setRightMargin(oStyle.margin_right);
1900 tmpStyle.setFirstIndent(oStyle.textIndent);
1901 tmpStyle.setGapAfter(oStyle.margin_bottom);
1902 tmpStyle.setGapBefore(oStyle.margin_top);
1903 }
1904
parseTransform(const QString & transform,double * rotation,double * transX,double * transY)1905 void OdgPlug::parseTransform(const QString &transform, double *rotation, double *transX, double *transY)
1906 {
1907 double dx, dy;
1908 QStringList subtransforms = transform.split(')', Qt::SkipEmptyParts);
1909 QStringList::ConstIterator it = subtransforms.begin();
1910 QStringList::ConstIterator end = subtransforms.end();
1911 for (; it != end; ++it)
1912 {
1913 QStringList subtransform = (*it).split('(', Qt::SkipEmptyParts);
1914 subtransform[0] = subtransform[0].trimmed().toLower();
1915 subtransform[1] = subtransform[1].simplified();
1916 QRegExp reg("[,( ]");
1917 QStringList params = subtransform[1].split(reg, Qt::SkipEmptyParts);
1918 if (subtransform[0].startsWith(";") || subtransform[0].startsWith(","))
1919 subtransform[0] = subtransform[0].right(subtransform[0].length() - 1);
1920 if (subtransform[0] == "rotate")
1921 {
1922 *rotation = -parseUnit(params[0]) * 180 / M_PI;
1923 }
1924 else if (subtransform[0] == "translate")
1925 {
1926 if (params.count() == 2)
1927 {
1928 dx = parseUnit(params[0]);
1929 dy = parseUnit(params[1]);
1930 }
1931 else
1932 {
1933 dx = parseUnit(params[0]);
1934 dy = 0.0;
1935 }
1936 *transX = dx;
1937 *transY = dy;
1938 }
1939 }
1940 }
1941
parseTransform(FPointArray * composite,const QString & transform)1942 void OdgPlug::parseTransform(FPointArray *composite, const QString &transform)
1943 {
1944 double dx, dy;
1945 QTransform result;
1946 QStringList subtransforms = transform.split(')', Qt::SkipEmptyParts);
1947 QStringList::ConstIterator it = subtransforms.begin();
1948 QStringList::ConstIterator end = subtransforms.end();
1949 for (; it != end; ++it)
1950 {
1951 QStringList subtransform = (*it).split('(', Qt::SkipEmptyParts);
1952 subtransform[0] = subtransform[0].trimmed().toLower();
1953 subtransform[1] = subtransform[1].simplified();
1954 QRegExp reg("[,( ]");
1955 QStringList params = subtransform[1].split(reg, Qt::SkipEmptyParts);
1956 if (subtransform[0].startsWith(";") || subtransform[0].startsWith(","))
1957 subtransform[0] = subtransform[0].right(subtransform[0].length() - 1);
1958 if (subtransform[0] == "rotate")
1959 {
1960 result = QTransform();
1961 result.rotate(-parseUnit(params[0]) * 180 / M_PI);
1962 composite->map(result);
1963 }
1964 else if (subtransform[0] == "translate")
1965 {
1966 if (params.count() == 2)
1967 {
1968 dx = parseUnit(params[0]);
1969 dy = parseUnit(params[1]);
1970 }
1971 else
1972 {
1973 dx = parseUnit(params[0]);
1974 dy =0.0;
1975 }
1976 result = QTransform();
1977 result.translate(dx, dy);
1978 composite->map(result);
1979 }
1980 else if (subtransform[0] == "skewx")
1981 {
1982 result = QTransform();
1983 result.shear(-tan(ScCLocale::toDoubleC(params[0])), 0.0);
1984 composite->map(result);
1985 }
1986 else if (subtransform[0] == "skewy")
1987 {
1988 result = QTransform();
1989 result.shear(0.0, -tan(ScCLocale::toDoubleC(params[0])));
1990 composite->map(result);
1991 }
1992 }
1993 }
1994
parseViewBox(const QDomElement & object,double * x,double * y,double * w,double * h)1995 void OdgPlug::parseViewBox( const QDomElement& object, double *x, double *y, double *w, double *h )
1996 {
1997 if (!object.attribute( "svg:viewBox" ).isEmpty())
1998 {
1999 QString viewbox( object.attribute( "svg:viewBox" ) );
2000 QStringList points = viewbox.replace( QRegExp(","), " ").simplified().split( ' ', Qt::SkipEmptyParts );
2001 *x = ScCLocale::toDoubleC(points[0]);
2002 *y = ScCLocale::toDoubleC(points[1]);
2003 *w = ScCLocale::toDoubleC(points[2]);
2004 *h = ScCLocale::toDoubleC(points[3]);
2005 }
2006 }
2007
appendPoints(FPointArray * composite,const QDomElement & object,bool closePath)2008 void OdgPlug::appendPoints(FPointArray *composite, const QDomElement& object, bool closePath)
2009 {
2010 double x = parseUnit(object.attribute("svg:x"));
2011 double y = parseUnit(object.attribute("svg:y")) ;
2012 double w = parseUnit(object.attribute("svg:width"));
2013 double h = parseUnit(object.attribute("svg:height"));
2014 double vx = 0;
2015 double vy = 0;
2016 double vw = 1;
2017 double vh = 1;
2018 parseViewBox(object, &vx, &vy, &vw, &vh);
2019 double sx = (vw != 0.0) ? (w / vw) : w;
2020 double sy = (vh != 0.0) ? (h / vh) : h;
2021 QStringList ptList = object.attribute( "draw:points" ).split( ' ', Qt::SkipEmptyParts );
2022 FPoint point, firstP;
2023 bool bFirst = true;
2024 for ( QStringList::Iterator it = ptList.begin(); it != ptList.end(); ++it)
2025 {
2026 point = FPoint(ScCLocale::toDoubleC((*it).section( ',', 0, 0 )), ScCLocale::toDoubleC((*it).section( ',', 1, 1 )));
2027 if (bFirst)
2028 {
2029 composite->addPoint(point);
2030 composite->addPoint(point);
2031 firstP = point;
2032 bFirst = false;
2033 }
2034 else
2035 {
2036 composite->addPoint(point);
2037 composite->addPoint(point);
2038 composite->addPoint(point);
2039 composite->addPoint(point);
2040 }
2041 }
2042 if (closePath)
2043 {
2044 composite->addPoint(firstP);
2045 composite->addPoint(firstP);
2046 }
2047 QTransform mat;
2048 mat.translate(x, y);
2049 mat.scale(sx, sy);
2050 composite->map(mat);
2051 }
2052
parseStyles(QDomElement & sp)2053 void OdgPlug::parseStyles(QDomElement &sp)
2054 {
2055 for (QDomElement spd = sp.firstChildElement(); !spd.isNull(); spd = spd.nextSiblingElement())
2056 {
2057 if (spd.tagName() == "draw:marker")
2058 {
2059 DrawStyle currStyle;
2060 currStyle.markerPath = AttributeValue(spd.attribute("svg:d", ""));
2061 currStyle.markerViewBox = AttributeValue(spd.attribute("svg:viewBox", ""));
2062 QString id = spd.attribute("draw:display-name");
2063 QString id2 = spd.attribute("draw:name");
2064 if (id2.isEmpty())
2065 m_Styles.insert(id, currStyle);
2066 else
2067 m_Styles.insert(id2, currStyle);
2068 }
2069 else if (spd.tagName() == "draw:stroke-dash")
2070 {
2071 DrawStyle currStyle;
2072 currStyle.stroke_dash_distance = AttributeValue(spd.attribute("draw:distance", ""));
2073 currStyle.stroke_dash_dots1 = AttributeValue(spd.attribute("draw:dots1", ""));
2074 currStyle.stroke_dash_dots1_length = AttributeValue(spd.attribute("draw:dots1-length", ""));
2075 currStyle.stroke_dash_dots2 = AttributeValue(spd.attribute("draw:dots2", ""));
2076 currStyle.stroke_dash_dots2_length = AttributeValue(spd.attribute("draw:dots2-length", ""));
2077 currStyle.stroke_dash_style = AttributeValue(spd.attribute("draw:style", ""));
2078 QString id = spd.attribute("draw:display-name");
2079 QString id2 = spd.attribute("draw:name");
2080 if (id2.isEmpty())
2081 m_Styles.insert(id, currStyle);
2082 else
2083 m_Styles.insert(id2, currStyle);
2084 }
2085 else if (spd.tagName() == "draw:gradient")
2086 {
2087 DrawStyle currStyle;
2088 currStyle.gradientAngle = AttributeValue(spd.attribute("draw:angle", ""));
2089 currStyle.gradientBorder = AttributeValue(spd.attribute("draw:border", ""));
2090 currStyle.gradientEndColor = AttributeValue(spd.attribute("draw:end-color", ""));
2091 currStyle.gradientEndShade = AttributeValue(spd.attribute("draw:end-intensity", ""));
2092 currStyle.gradientStartColor = AttributeValue(spd.attribute("draw:start-color", ""));
2093 currStyle.gradientStartShade = AttributeValue(spd.attribute("draw:start-intensity", ""));
2094 currStyle.gradientCenterX = AttributeValue(spd.attribute("draw:cx", ""));
2095 currStyle.gradientCenterY = AttributeValue(spd.attribute("draw:cy", ""));
2096 currStyle.gradientType = AttributeValue(spd.attribute("draw:style", ""));
2097 QString id = spd.attribute("draw:display-name");
2098 QString id2 = spd.attribute("draw:name");
2099 if (id2.isEmpty())
2100 m_Styles.insert(id, currStyle);
2101 else
2102 m_Styles.insert(id2, currStyle);
2103 }
2104 else if (spd.tagName() == "draw:opacity")
2105 {
2106 DrawStyle currStyle;
2107 currStyle.gradientAngle = AttributeValue(spd.attribute("draw:angle", ""));
2108 currStyle.gradientBorder = AttributeValue(spd.attribute("draw:border", ""));
2109 currStyle.opacityEnd = AttributeValue(spd.attribute("draw:end", ""));
2110 currStyle.opacityStart = AttributeValue(spd.attribute("draw:start", ""));
2111 currStyle.gradientCenterX = AttributeValue(spd.attribute("draw:cx", ""));
2112 currStyle.gradientCenterY = AttributeValue(spd.attribute("draw:cy", ""));
2113 currStyle.gradientType = AttributeValue(spd.attribute("draw:style", ""));
2114 QString id = spd.attribute("draw:display-name");
2115 QString id2 = spd.attribute("draw:name");
2116 if (id2.isEmpty())
2117 m_Styles.insert(id, currStyle);
2118 else
2119 m_Styles.insert(id2, currStyle);
2120 }
2121 else if (spd.tagName() == "draw:hatch")
2122 {
2123 DrawStyle currStyle;
2124 currStyle.hatchColor = AttributeValue(spd.attribute("draw:color", ""));
2125 currStyle.hatchDistance = AttributeValue(spd.attribute("draw:distance", ""));
2126 currStyle.hatchRotation = AttributeValue(spd.attribute("draw:rotation", ""));
2127 currStyle.hatchStyle = AttributeValue(spd.attribute("draw:style", ""));
2128 QString id = spd.attribute("draw:display-name");
2129 QString id2 = spd.attribute("draw:name");
2130 if (id2.isEmpty())
2131 m_Styles.insert(id, currStyle);
2132 else
2133 m_Styles.insert(id2, currStyle);
2134 }
2135 else if (spd.tagName() == "draw:fill-image")
2136 {
2137 DrawStyle currStyle;
2138 currStyle.patternPath = AttributeValue(spd.attribute("xlink:href", ""));
2139 if (!currStyle.patternPath.valid)
2140 {
2141 if (spd.hasChildNodes())
2142 {
2143 for (QDomElement nc = spd.firstChildElement(); !nc.isNull(); nc = nc.nextSiblingElement())
2144 {
2145 if (nc.tagName() == "office:binary-data")
2146 currStyle.patternData = AttributeValue(nc.text());
2147 }
2148 }
2149 }
2150 QString id = spd.attribute("draw:display-name");
2151 QString id2 = spd.attribute("draw:name");
2152 if (id2.isEmpty())
2153 m_Styles.insert(id, currStyle);
2154 else
2155 m_Styles.insert(id2, currStyle);
2156 }
2157 else if (spd.tagName() == "style:style")
2158 {
2159 DrawStyle currStyle;
2160 for (QDomElement spe = spd.firstChildElement(); !spe.isNull(); spe = spe.nextSiblingElement())
2161 {
2162 if (spe.tagName() == "style:graphic-properties")
2163 {
2164 currStyle.fillMode = AttributeValue(spe.attribute("draw:fill", ""));
2165 currStyle.currColorFill = AttributeValue(spe.attribute("draw:fill-color", ""));
2166 currStyle.strokeMode = AttributeValue(spe.attribute("draw:stroke", ""));
2167 currStyle.currColorStroke = AttributeValue(spe.attribute("svg:stroke-color", ""));
2168 currStyle.currColorShadow = AttributeValue(spe.attribute("draw:shadow-color", ""));
2169 currStyle.hasShadow = AttributeValue(spe.attribute("draw:shadow", ""));
2170 currStyle.shadowX = AttributeValue(spe.attribute("draw:shadow-offset-x", ""));
2171 currStyle.shadowY = AttributeValue(spe.attribute("draw:shadow-offset-y", ""));
2172 currStyle.shadowTrans = AttributeValue(spe.attribute("draw:shadow-opacity", ""));
2173 currStyle.strokeOpacity = AttributeValue(spe.attribute("svg:stroke-opacity", ""));
2174 currStyle.LineW = AttributeValue(spe.attribute("svg:stroke-width", ""));
2175 currStyle.fillOpacity = AttributeValue(spe.attribute("draw:opacity", ""));
2176 currStyle.gradientName = AttributeValue(spe.attribute("draw:fill-gradient-name", ""));
2177 currStyle.dashName = AttributeValue(spe.attribute("draw:stroke-dash", ""));
2178 currStyle.startMarkerName = AttributeValue(spe.attribute("draw:marker-start", ""));
2179 currStyle.startMarkerWidth = AttributeValue(spe.attribute("draw:marker-start-width", ""));
2180 currStyle.startMarkerCentered = AttributeValue(spe.attribute("draw:marker-start-center", ""));
2181 currStyle.endMarkerName = AttributeValue(spe.attribute("draw:marker-end", ""));
2182 currStyle.endMarkerWidth = AttributeValue(spe.attribute("draw:marker-end-width", ""));
2183 currStyle.endMarkerCentered = AttributeValue(spe.attribute("draw:marker-end-center", ""));
2184 currStyle.measureDist = AttributeValue(spe.attribute("draw:line-distance"));
2185 currStyle.patternName = AttributeValue(spe.attribute("draw:fill-image-name", ""));
2186 currStyle.patternWidth = AttributeValue(spe.attribute("draw:fill-image-width", ""));
2187 currStyle.patternHeight = AttributeValue(spe.attribute("draw:fill-image-height", ""));
2188 currStyle.patternX = AttributeValue(spe.attribute("draw:fill-image-ref-point-x", ""));
2189 currStyle.patternY = AttributeValue(spe.attribute("draw:fill-image-ref-point-y", ""));
2190 currStyle.patternStretch = AttributeValue(spe.attribute("style:repeat", ""));
2191 currStyle.hatchName = AttributeValue(spe.attribute("draw:fill-hatch-name", ""));
2192 currStyle.hatchSolidFill = AttributeValue(spe.attribute("draw:fill-hatch-solid", ""));
2193 currStyle.opacityName = AttributeValue(spe.attribute("draw:opacity-name", ""));
2194 currStyle.verticalAlignment = AttributeValue(spe.attribute("draw:textarea-vertical-align", ""));
2195 }
2196 else if (spe.tagName() == "style:paragraph-properties")
2197 {
2198 currStyle.margin_top = AttributeValue(spe.attribute("fo:margin-top", ""));
2199 currStyle.margin_bottom = AttributeValue(spe.attribute("fo:margin-bottom", ""));
2200 currStyle.margin_left = AttributeValue(spe.attribute("fo:margin-left", ""));
2201 currStyle.margin_right = AttributeValue(spe.attribute("fo:margin-right", ""));
2202 currStyle.textIndent = AttributeValue(spe.attribute("fo:text-indent", ""));
2203 currStyle.textAlign = AttributeValue(spe.attribute("fo:text-align", ""));
2204 currStyle.lineHeight = AttributeValue(spe.attribute("fo:line-height", ""));
2205 }
2206 else if (spe.tagName() == "style:text-properties")
2207 {
2208 currStyle.fontName = AttributeValue(spe.attribute("style:font-name", ""));
2209 if (!currStyle.fontName.valid)
2210 currStyle.fontName = AttributeValue(spe.attribute("fo:font-family", ""));
2211 currStyle.fontSize = AttributeValue(spe.attribute("fo:font-size", ""));
2212 currStyle.fontColor = AttributeValue(spe.attribute("fo:color", ""));
2213 currStyle.textBackgroundColor = AttributeValue(spe.attribute("fo:background-color", ""));
2214 currStyle.textPos = AttributeValue(spe.attribute("style:text-position", ""));
2215 currStyle.textOutline = AttributeValue(spe.attribute("style:text-outline", ""));
2216 currStyle.textUnderline = AttributeValue(spe.attribute("style:text-underline-style", ""));
2217 currStyle.textUnderlineWords = AttributeValue(spe.attribute("style:text-underline-mode", ""));
2218 currStyle.textUnderlineColor = AttributeValue(spe.attribute("style:text-underline-color", ""));
2219 currStyle.textStrikeThrough = AttributeValue(spe.attribute("style:text-line-through-style", ""));
2220 currStyle.textShadow = AttributeValue(spe.attribute("fo:text-shadow", ""));
2221 }
2222 else if (spe.tagName() == "style:drawing-page-properties")
2223 {
2224 currStyle.fillMode = AttributeValue(spe.attribute("draw:fill", ""));
2225 currStyle.currColorFill = AttributeValue(spe.attribute("draw:fill-color", ""));
2226 currStyle.patternName = AttributeValue(spe.attribute("draw:fill-image-name", ""));
2227 currStyle.gradientName = AttributeValue(spe.attribute("draw:fill-gradient-name", ""));
2228 currStyle.hatchName = AttributeValue(spe.attribute("draw:fill-hatch-name", ""));
2229 currStyle.hatchSolidFill = AttributeValue(spe.attribute("draw:fill-hatch-solid", ""));
2230 currStyle.opacityName = AttributeValue(spe.attribute("draw:opacity-name", ""));
2231 }
2232 }
2233 currStyle.parentStyle = AttributeValue(spd.attribute("style:parent-style-name", ""));
2234 m_Styles.insert(spd.attribute("style:name"), currStyle);
2235 }
2236 else if (spd.tagName() == "style:page-layout")
2237 {
2238 DrawStyle currStyle;
2239 for (QDomElement spe = spd.firstChildElement(); !spe.isNull(); spe = spe.nextSiblingElement())
2240 {
2241 if (spe.tagName() == "style:page-layout-properties")
2242 {
2243 currStyle.margin_top = AttributeValue(spe.attribute("fo:margin-top", ""));
2244 currStyle.margin_bottom = AttributeValue(spe.attribute("fo:margin-bottom", ""));
2245 currStyle.margin_left = AttributeValue(spe.attribute("fo:margin-left", ""));
2246 currStyle.margin_right = AttributeValue(spe.attribute("fo:margin-right", ""));
2247 currStyle.page_width = AttributeValue(spe.attribute("fo:page-width", ""));
2248 currStyle.page_height = AttributeValue(spe.attribute("fo:page-height", ""));
2249 }
2250 }
2251 currStyle.parentStyle = AttributeValue(spd.attribute("style:parent-style-name", ""));
2252 m_Styles.insert(spd.attribute("style:name"), currStyle);
2253 }
2254 }
2255 }
2256
getStyleName(QDomElement & e)2257 QString OdgPlug::getStyleName(QDomElement &e)
2258 {
2259 QString styleName = "standard";
2260 if (e.hasAttribute("draw:style-name"))
2261 styleName = e.attribute("draw:style-name");
2262 else if (e.hasAttribute("presentation:style-name"))
2263 styleName = e.attribute("presentation:style-name");
2264 return styleName;
2265 }
2266
resovleStyle(ObjStyle & tmpOStyle,const QString & pAttrs)2267 void OdgPlug::resovleStyle(ObjStyle &tmpOStyle, const QString& pAttrs)
2268 {
2269 if (m_Styles.contains(pAttrs))
2270 {
2271 DrawStyle actStyle;
2272 DrawStyle currStyle = m_Styles[pAttrs];
2273 QStringList parents;
2274 while (currStyle.parentStyle.valid)
2275 {
2276 if (m_Styles.contains(currStyle.parentStyle.value))
2277 {
2278 parents.prepend(currStyle.parentStyle.value);
2279 currStyle = m_Styles[currStyle.parentStyle.value];
2280 }
2281 else
2282 break;
2283 }
2284 parents.append(pAttrs);
2285 if (!parents.isEmpty())
2286 {
2287 for (int p = 0; p < parents.count(); p++)
2288 {
2289 currStyle = m_Styles[parents[p]];
2290 if (currStyle.markerViewBox.valid)
2291 actStyle.markerViewBox = AttributeValue(currStyle.markerViewBox.value);
2292 if (currStyle.markerPath.valid)
2293 actStyle.markerPath = AttributeValue(currStyle.markerPath.value);
2294 if (currStyle.startMarkerName.valid)
2295 actStyle.startMarkerName = AttributeValue(currStyle.startMarkerName.value);
2296 if (currStyle.startMarkerWidth.valid)
2297 actStyle.startMarkerWidth = AttributeValue(currStyle.startMarkerWidth.value);
2298 if (currStyle.startMarkerCentered.valid)
2299 actStyle.startMarkerCentered = AttributeValue(currStyle.startMarkerCentered.value);
2300 if (currStyle.endMarkerName.valid)
2301 actStyle.endMarkerName = AttributeValue(currStyle.endMarkerName.value);
2302 if (currStyle.endMarkerWidth.valid)
2303 actStyle.endMarkerWidth = AttributeValue(currStyle.endMarkerWidth.value);
2304 if (currStyle.endMarkerCentered.valid)
2305 actStyle.endMarkerCentered = AttributeValue(currStyle.endMarkerCentered.value);
2306 if (currStyle.stroke_dash_distance.valid)
2307 actStyle.stroke_dash_distance = AttributeValue(currStyle.stroke_dash_distance.value);
2308 if (currStyle.stroke_dash_dots1.valid)
2309 actStyle.stroke_dash_dots1 = AttributeValue(currStyle.stroke_dash_dots1.value);
2310 if (currStyle.stroke_dash_dots1_length.valid)
2311 actStyle.stroke_dash_dots1_length = AttributeValue(currStyle.stroke_dash_dots1_length.value);
2312 if (currStyle.stroke_dash_dots2.valid)
2313 actStyle.stroke_dash_dots2 = AttributeValue(currStyle.stroke_dash_dots2.value);
2314 if (currStyle.stroke_dash_dots2_length.valid)
2315 actStyle.stroke_dash_dots2_length = AttributeValue(currStyle.stroke_dash_dots2_length.value);
2316 if (currStyle.stroke_dash_style.valid)
2317 actStyle.stroke_dash_style = AttributeValue(currStyle.stroke_dash_style.value);
2318 if (currStyle.fillMode.valid)
2319 actStyle.fillMode = AttributeValue(currStyle.fillMode.value);
2320 if (currStyle.currColorFill.valid)
2321 actStyle.currColorFill = AttributeValue(currStyle.currColorFill.value);
2322 if (currStyle.strokeMode.valid)
2323 actStyle.strokeMode = AttributeValue(currStyle.strokeMode.value);
2324 if (currStyle.currColorStroke.valid)
2325 actStyle.currColorStroke = AttributeValue(currStyle.currColorStroke.value);
2326 if (currStyle.currColorShadow.valid)
2327 actStyle.currColorShadow = AttributeValue(currStyle.currColorShadow.value);
2328 if (currStyle.hasShadow.valid)
2329 actStyle.hasShadow = AttributeValue(currStyle.hasShadow.value);
2330 if (currStyle.shadowX.valid)
2331 actStyle.shadowX = AttributeValue(currStyle.shadowX.value);
2332 if (currStyle.shadowY.valid)
2333 actStyle.shadowY = AttributeValue(currStyle.shadowY.value);
2334 if (currStyle.shadowTrans.valid)
2335 actStyle.shadowTrans = AttributeValue(currStyle.shadowTrans.value);
2336 if (currStyle.fillOpacity.valid)
2337 actStyle.fillOpacity = AttributeValue(currStyle.fillOpacity.value);
2338 if (currStyle.strokeOpacity.valid)
2339 actStyle.strokeOpacity = AttributeValue(currStyle.strokeOpacity.value);
2340 if (currStyle.LineW.valid)
2341 actStyle.LineW = AttributeValue(currStyle.LineW.value);
2342 if (currStyle.fontName.valid)
2343 actStyle.fontName = AttributeValue(currStyle.fontName.value);
2344 if (currStyle.fontSize.valid)
2345 actStyle.fontSize = AttributeValue(currStyle.fontSize.value);
2346 if (currStyle.margin_top.valid)
2347 actStyle.margin_top = AttributeValue(currStyle.margin_top.value);
2348 if (currStyle.margin_bottom.valid)
2349 actStyle.margin_bottom = AttributeValue(currStyle.margin_bottom.value);
2350 if (currStyle.margin_left.valid)
2351 actStyle.margin_left = AttributeValue(currStyle.margin_left.value);
2352 if (currStyle.margin_right.valid)
2353 actStyle.margin_right = AttributeValue(currStyle.margin_right.value);
2354 if (currStyle.page_width.valid)
2355 actStyle.page_width = AttributeValue(currStyle.page_width.value);
2356 if (currStyle.page_height.valid)
2357 actStyle.page_height = AttributeValue(currStyle.page_height.value);
2358 if (currStyle.page_layout_name.valid)
2359 actStyle.page_layout_name = AttributeValue(currStyle.page_layout_name.value);
2360 if (currStyle.textIndent.valid)
2361 actStyle.textIndent = AttributeValue(currStyle.textIndent.value);
2362 if (currStyle.textAlign.valid)
2363 actStyle.textAlign = AttributeValue(currStyle.textAlign.value);
2364 if (currStyle.textPos.valid)
2365 actStyle.textPos = AttributeValue(currStyle.textPos.value);
2366 if (currStyle.textOutline.valid)
2367 actStyle.textOutline = AttributeValue(currStyle.textOutline.value);
2368 if (currStyle.textUnderline.valid)
2369 actStyle.textUnderline = AttributeValue(currStyle.textUnderline.value);
2370 if (currStyle.textUnderlineWords.valid)
2371 actStyle.textUnderlineWords = AttributeValue(currStyle.textUnderlineWords.value);
2372 if (currStyle.textUnderlineColor.valid)
2373 actStyle.textUnderlineColor = AttributeValue(currStyle.textUnderlineColor.value);
2374 if (currStyle.textStrikeThrough.valid)
2375 actStyle.textStrikeThrough = AttributeValue(currStyle.textStrikeThrough.value);
2376 if (currStyle.textShadow.valid)
2377 actStyle.textShadow = AttributeValue(currStyle.textShadow.value);
2378 if (currStyle.lineHeight.valid)
2379 actStyle.lineHeight = AttributeValue(currStyle.lineHeight.value);
2380 if (currStyle.fontColor.valid)
2381 actStyle.fontColor = AttributeValue(currStyle.fontColor.value);
2382 if (currStyle.textBackgroundColor.valid)
2383 actStyle.textBackgroundColor = AttributeValue(currStyle.textBackgroundColor.value);
2384 if (currStyle.gradientAngle.valid)
2385 actStyle.gradientAngle = AttributeValue(currStyle.gradientAngle.value);
2386 if (currStyle.gradientBorder.valid)
2387 actStyle.gradientBorder = AttributeValue(currStyle.gradientBorder.value);
2388 if (currStyle.gradientEndColor.valid)
2389 actStyle.gradientEndColor = AttributeValue(currStyle.gradientEndColor.value);
2390 if (currStyle.gradientEndShade.valid)
2391 actStyle.gradientEndShade = AttributeValue(currStyle.gradientEndShade.value);
2392 if (currStyle.gradientStartColor.valid)
2393 actStyle.gradientStartColor = AttributeValue(currStyle.gradientStartColor.value);
2394 if (currStyle.gradientStartShade.valid)
2395 actStyle.gradientStartShade = AttributeValue(currStyle.gradientStartShade.value);
2396 if (currStyle.gradientCenterX.valid)
2397 actStyle.gradientCenterX = AttributeValue(currStyle.gradientCenterX.value);
2398 if (currStyle.gradientCenterY.valid)
2399 actStyle.gradientCenterY = AttributeValue(currStyle.gradientCenterY.value);
2400 if (currStyle.gradientType.valid)
2401 actStyle.gradientType = AttributeValue(currStyle.gradientType.value);
2402 if (currStyle.gradientName.valid)
2403 actStyle.gradientName = AttributeValue(currStyle.gradientName.value);
2404 if (currStyle.dashName.valid)
2405 actStyle.dashName = AttributeValue(currStyle.dashName.value);
2406 if (currStyle.measureDist.valid)
2407 actStyle.measureDist = AttributeValue(currStyle.measureDist.value);
2408 if (currStyle.patternName.valid)
2409 actStyle.patternName = AttributeValue(currStyle.patternName.value);
2410 if (currStyle.patternPath.valid)
2411 actStyle.patternPath = AttributeValue(currStyle.patternPath.value);
2412 if (currStyle.patternData.valid)
2413 actStyle.patternData = AttributeValue(currStyle.patternData.value);
2414 if (currStyle.patternWidth.valid)
2415 actStyle.patternWidth = AttributeValue(currStyle.patternWidth.value);
2416 if (currStyle.patternHeight.valid)
2417 actStyle.patternHeight = AttributeValue(currStyle.patternHeight.value);
2418 if (currStyle.patternX.valid)
2419 actStyle.patternX = AttributeValue(currStyle.patternX.value);
2420 if (currStyle.patternY.valid)
2421 actStyle.patternY = AttributeValue(currStyle.patternY.value);
2422 if (currStyle.patternStretch.valid)
2423 actStyle.patternStretch = AttributeValue(currStyle.patternStretch.value);
2424 if (currStyle.hatchName.valid)
2425 actStyle.hatchName = AttributeValue(currStyle.hatchName.value);
2426 if (currStyle.hatchColor.valid)
2427 actStyle.hatchColor = AttributeValue(currStyle.hatchColor.value);
2428 if (currStyle.hatchDistance.valid)
2429 actStyle.hatchDistance = AttributeValue(currStyle.hatchDistance.value);
2430 if (currStyle.hatchRotation.valid)
2431 actStyle.hatchRotation = AttributeValue(currStyle.hatchRotation.value);
2432 if (currStyle.hatchStyle.valid)
2433 actStyle.hatchStyle = AttributeValue(currStyle.hatchStyle.value);
2434 if (currStyle.hatchSolidFill.valid)
2435 actStyle.hatchSolidFill = AttributeValue(currStyle.hatchSolidFill.value);
2436 if (currStyle.opacityName.valid)
2437 actStyle.opacityName = AttributeValue(currStyle.opacityName.value);
2438 if (currStyle.opacityEnd.valid)
2439 actStyle.opacityEnd = AttributeValue(currStyle.opacityEnd.value);
2440 if (currStyle.opacityStart.valid)
2441 actStyle.opacityStart = AttributeValue(currStyle.opacityStart.value);
2442 if (currStyle.verticalAlignment.valid)
2443 actStyle.verticalAlignment = AttributeValue(currStyle.verticalAlignment.value);
2444 }
2445 }
2446 tmpOStyle.stroke_dash_distance = -1;
2447 tmpOStyle.stroke_dash_dots1_length = -1;
2448 tmpOStyle.stroke_dash_dots2_length = -1;
2449 tmpOStyle.stroke_dash_dots1 = -1;
2450 tmpOStyle.stroke_dash_dots2 = -1;
2451 if (actStyle.stroke_dash_style.valid)
2452 tmpOStyle.stroke_dash_style = actStyle.stroke_dash_style.value;
2453 if (actStyle.stroke_dash_distance.valid)
2454 tmpOStyle.stroke_dash_distance = parseUnit(actStyle.stroke_dash_distance.value);
2455 if (actStyle.stroke_dash_dots1.valid)
2456 tmpOStyle.stroke_dash_dots1 = actStyle.stroke_dash_dots1.value.toInt();
2457 if (actStyle.stroke_dash_dots1_length.valid)
2458 tmpOStyle.stroke_dash_dots1_length = parseUnit(actStyle.stroke_dash_dots1_length.value);
2459 if (actStyle.stroke_dash_dots2.valid)
2460 tmpOStyle.stroke_dash_dots2 = actStyle.stroke_dash_dots2.value.toInt();
2461 if (actStyle.stroke_dash_dots2_length.valid)
2462 tmpOStyle.stroke_dash_dots2_length = parseUnit(actStyle.stroke_dash_dots2_length.value);
2463
2464 if (actStyle.currColorFill.valid)
2465 {
2466 if (actStyle.fillMode.valid && (actStyle.fillMode.value != "none"))
2467 tmpOStyle.currColorFill = parseColor(actStyle.currColorFill.value);
2468 else
2469 tmpOStyle.currColorFill = CommonStrings::None;
2470 }
2471 else
2472 tmpOStyle.currColorFill = CommonStrings::None;
2473 if (actStyle.fillMode.valid)
2474 {
2475 if (actStyle.fillMode.value == "none")
2476 tmpOStyle.fill_type = 0;
2477 else if (actStyle.fillMode.value == "solid")
2478 tmpOStyle.fill_type = 1;
2479 else if (actStyle.fillMode.value == "gradient")
2480 {
2481 tmpOStyle.fill_type = 2;
2482 if (actStyle.gradientName.valid)
2483 tmpOStyle.gradientName = actStyle.gradientName.value;
2484 }
2485 else if (actStyle.fillMode.value == "bitmap")
2486 {
2487 tmpOStyle.fill_type = 3;
2488 if (actStyle.patternName.valid)
2489 tmpOStyle.patternName = actStyle.patternName.value;
2490 }
2491 else if (actStyle.fillMode.value == "hatch")
2492 {
2493 tmpOStyle.fill_type = 4;
2494 if (actStyle.hatchName.valid)
2495 tmpOStyle.hatchName = actStyle.hatchName.value;
2496 }
2497 }
2498 if (actStyle.currColorStroke.valid)
2499 {
2500 if (actStyle.strokeMode.valid && (actStyle.strokeMode.value != "none"))
2501 tmpOStyle.currColorStroke = parseColor(actStyle.currColorStroke.value);
2502 else
2503 tmpOStyle.currColorStroke = CommonStrings::None;
2504 }
2505 else
2506 tmpOStyle.currColorStroke = CommonStrings::None;
2507 if (actStyle.strokeMode.valid)
2508 {
2509 if (actStyle.strokeMode.value == "none")
2510 tmpOStyle.stroke_type = 0;
2511 else if (actStyle.strokeMode.value == "solid")
2512 tmpOStyle.stroke_type = 1;
2513 else if (actStyle.strokeMode.value == "dash")
2514 {
2515 tmpOStyle.stroke_type = 2;
2516 if (actStyle.dashName.valid)
2517 tmpOStyle.dashName = actStyle.dashName.value;
2518 }
2519 }
2520 if (actStyle.currColorShadow.valid)
2521 tmpOStyle.currColorShadow = parseColor(actStyle.currColorShadow.value);
2522 if (actStyle.hasShadow.valid)
2523 tmpOStyle.hasShadow = actStyle.hasShadow.value == "visible";
2524 if (actStyle.shadowX.valid)
2525 tmpOStyle.shadowX = parseUnit(actStyle.shadowX.value);
2526 if (actStyle.shadowY.valid)
2527 tmpOStyle.shadowY = parseUnit(actStyle.shadowY.value);
2528 if (actStyle.shadowTrans.valid)
2529 {
2530 double transVal = parseUnit(actStyle.shadowTrans.value);
2531 if (transVal > 1.0)
2532 transVal /= 100.0;
2533 tmpOStyle.shadowTrans = 1.0 - transVal;
2534 }
2535 if (actStyle.fillOpacity.valid)
2536 {
2537 double transVal = parseUnit(actStyle.fillOpacity.value);
2538 if (transVal > 1.0)
2539 transVal /= 100.0;
2540 tmpOStyle.fillOpacity = 1.0 - transVal;
2541 }
2542 if (actStyle.strokeOpacity.valid)
2543 {
2544 double transVal = parseUnit(actStyle.strokeOpacity.value);
2545 if (transVal > 1.0)
2546 transVal /= 100.0;
2547 tmpOStyle.strokeOpacity = 1.0 - transVal;
2548 }
2549 if (actStyle.LineW.valid)
2550 tmpOStyle.LineW = parseUnit(actStyle.LineW.value);
2551 if (actStyle.fontName.valid)
2552 {
2553 if (m_fontMap.contains(actStyle.fontName.value))
2554 tmpOStyle.fontName = m_fontMap[actStyle.fontName.value];
2555 else
2556 tmpOStyle.fontName = actStyle.fontName.value;
2557 if (!PrefsManager::instance().appPrefs.fontPrefs.AvailFonts.contains(tmpOStyle.fontName))
2558 {
2559 tmpOStyle.fontName = constructFontName(tmpOStyle.fontName, "");
2560 m_fontMap[actStyle.fontName.value] = tmpOStyle.fontName;
2561 }
2562 }
2563 if (actStyle.fontSize.valid)
2564 tmpOStyle.fontSize = parseUnit(actStyle.fontSize.value);
2565 if (actStyle.fontColor.valid)
2566 tmpOStyle.currColorText = parseColor(actStyle.fontColor.value);
2567 if (actStyle.textBackgroundColor.valid)
2568 tmpOStyle.currColorBText = parseColor(actStyle.textBackgroundColor.value);
2569 if (actStyle.margin_top.valid)
2570 tmpOStyle.margin_top = parseUnit(actStyle.margin_top.value);
2571 if (actStyle.margin_bottom.valid)
2572 tmpOStyle.margin_bottom = parseUnit(actStyle.margin_bottom.value);
2573 if (actStyle.margin_left.valid)
2574 tmpOStyle.margin_left = parseUnit(actStyle.margin_left.value);
2575 if (actStyle.margin_right.valid)
2576 tmpOStyle.margin_right = parseUnit(actStyle.margin_right.value);
2577 if (actStyle.page_layout_name.valid)
2578 {
2579 tmpOStyle.page_layout_name = actStyle.page_layout_name.value;
2580 if (m_Styles.contains(tmpOStyle.page_layout_name))
2581 {
2582 actStyle = m_Styles[tmpOStyle.page_layout_name];
2583 if (actStyle.page_height.valid)
2584 tmpOStyle.page_height = parseUnit(actStyle.page_height.value);
2585 if (actStyle.page_width.valid)
2586 tmpOStyle.page_width = parseUnit(actStyle.page_width.value);
2587 if (actStyle.margin_top.valid)
2588 tmpOStyle.margin_top = parseUnit(actStyle.margin_top.value);
2589 if (actStyle.margin_bottom.valid)
2590 tmpOStyle.margin_bottom = parseUnit(actStyle.margin_bottom.value);
2591 if (actStyle.margin_left.valid)
2592 tmpOStyle.margin_left = parseUnit(actStyle.margin_left.value);
2593 if (actStyle.margin_right.valid)
2594 tmpOStyle.margin_right = parseUnit(actStyle.margin_right.value);
2595 }
2596 }
2597 if (actStyle.textIndent.valid)
2598 tmpOStyle.textIndent = parseUnit(actStyle.textIndent.value);
2599 if (actStyle.textAlign.valid)
2600 {
2601 QString attValue = actStyle.textAlign.value;
2602 if (attValue == "left")
2603 tmpOStyle.textAlign = ParagraphStyle::LeftAligned;
2604 else if (attValue == "center")
2605 tmpOStyle.textAlign = ParagraphStyle::Centered;
2606 else if (attValue == "right")
2607 tmpOStyle.textAlign = ParagraphStyle::RightAligned;
2608 else if (attValue == "justify")
2609 tmpOStyle.textAlign = ParagraphStyle::Justified;
2610 }
2611 if (actStyle.verticalAlignment.valid)
2612 {
2613 if (actStyle.verticalAlignment.value == "middle")
2614 tmpOStyle.verticalAlignment = 1;
2615 else if (actStyle.verticalAlignment.value == "bottom")
2616 tmpOStyle.verticalAlignment = 2;
2617 }
2618 if (actStyle.textPos.valid)
2619 tmpOStyle.textPos = actStyle.textPos.value;
2620 if (actStyle.textOutline.valid)
2621 tmpOStyle.textOutline = actStyle.textOutline.value;
2622 if (actStyle.textUnderline.valid)
2623 tmpOStyle.textUnderline = actStyle.textUnderline.value != "none";
2624 if (actStyle.textUnderlineWords.valid)
2625 tmpOStyle.textUnderlineWords = actStyle.textUnderlineWords.value != "continuous";
2626 if (actStyle.textUnderlineColor.valid)
2627 {
2628 if (actStyle.textUnderlineColor.value == "font-color")
2629 tmpOStyle.textUnderlineColor = tmpOStyle.currColorText;
2630 else
2631 tmpOStyle.textUnderlineColor = parseColor(actStyle.textUnderlineColor.value);
2632 }
2633 if (actStyle.textStrikeThrough.valid)
2634 tmpOStyle.textStrikeThrough = actStyle.textStrikeThrough.value != "none";
2635 if (actStyle.textShadow.valid)
2636 tmpOStyle.textShadow = actStyle.textShadow.value != "none";
2637 if (actStyle.lineHeight.valid)
2638 {
2639 if (actStyle.lineHeight.value == "normal")
2640 tmpOStyle.lineHeight = -1.0;
2641 else if (actStyle.lineHeight.value.right(1) != "%")
2642 {
2643 tmpOStyle.lineHeight = parseUnit(actStyle.lineHeight.value);
2644 tmpOStyle.absLineHeight = true;
2645 }
2646 else
2647 {
2648 tmpOStyle.lineHeight = parseUnit(actStyle.lineHeight.value);
2649 tmpOStyle.absLineHeight = false;
2650 }
2651 }
2652 if (actStyle.gradientAngle.valid)
2653 tmpOStyle.gradientAngle = actStyle.gradientAngle.value.toDouble() / 10.0;
2654 if (actStyle.gradientBorder.valid)
2655 tmpOStyle.gradientBorder = parseUnit(actStyle.gradientBorder.value);
2656 if (actStyle.gradientEndColor.valid)
2657 tmpOStyle.gradientEndColor = parseColor(actStyle.gradientEndColor.value);
2658 if (actStyle.gradientEndShade.valid)
2659 tmpOStyle.gradientEndShade = parseUnit(actStyle.gradientEndShade.value) * 100.0;
2660 if (actStyle.gradientStartColor.valid)
2661 tmpOStyle.gradientStartColor = parseColor(actStyle.gradientStartColor.value);
2662 if (actStyle.gradientStartShade.valid)
2663 tmpOStyle.gradientStartShade = parseUnit(actStyle.gradientStartShade.value) * 100.0;
2664 if (actStyle.gradientCenterX.valid)
2665 tmpOStyle.gradientCenterX = parseUnit(actStyle.gradientCenterX.value);
2666 if (actStyle.gradientCenterY.valid)
2667 tmpOStyle.gradientCenterY = parseUnit(actStyle.gradientCenterY.value);
2668 if (actStyle.gradientType.valid)
2669 tmpOStyle.gradientType = actStyle.gradientType.value;
2670 if (actStyle.markerViewBox.valid)
2671 {
2672 QString viewbox = actStyle.markerViewBox.value;
2673 QStringList points = viewbox.replace( QRegExp(","), " ").simplified().split( ' ', Qt::SkipEmptyParts );
2674 tmpOStyle.markerViewBox = QRectF(ScCLocale::toDoubleC(points[0]), ScCLocale::toDoubleC(points[1]), ScCLocale::toDoubleC(points[2]), ScCLocale::toDoubleC(points[3]));
2675 }
2676 else
2677 tmpOStyle.markerViewBox = QRectF();
2678 if (actStyle.markerPath.valid)
2679 {
2680 FPointArray mPath;
2681 mPath.svgInit();
2682 mPath.parseSVG(actStyle.markerPath.value);
2683 if (tmpOStyle.markerViewBox != QRect())
2684 {
2685 QRectF clipRect = mPath.toQPainterPath(false).boundingRect();
2686 QTransform mat;
2687 double vw = tmpOStyle.markerViewBox.width();
2688 double vh = tmpOStyle.markerViewBox.height();
2689 double sx = (vw != 0.0) ? (clipRect.width() / vw) : 1;
2690 double sy = (vh != 0.0) ? (clipRect.height() / vh) : 1;
2691 mat.scale(sx, sy);
2692 mPath.map(mat);
2693 }
2694 tmpOStyle.markerPath = mPath.toQPainterPath(true);
2695 }
2696 if (actStyle.startMarkerName.valid)
2697 tmpOStyle.startMarkerName = actStyle.startMarkerName.value;
2698 if (actStyle.startMarkerWidth.valid)
2699 tmpOStyle.startMarkerWidth = parseUnit(actStyle.startMarkerWidth.value);
2700 if (actStyle.startMarkerCentered.valid)
2701 tmpOStyle.startMarkerCentered = actStyle.startMarkerCentered.value == "true";
2702 if (actStyle.endMarkerName.valid)
2703 tmpOStyle.endMarkerName = actStyle.endMarkerName.value;
2704 if (actStyle.endMarkerWidth.valid)
2705 tmpOStyle.endMarkerWidth = parseUnit(actStyle.endMarkerWidth.value);
2706 if (actStyle.endMarkerCentered.valid)
2707 tmpOStyle.endMarkerCentered = actStyle.endMarkerCentered.value == "true";
2708 if (actStyle.measureDist.valid)
2709 tmpOStyle.measureDist = parseUnit(actStyle.measureDist.value);
2710 if (actStyle.patternPath.valid)
2711 tmpOStyle.patternPath = actStyle.patternPath.value;
2712 if (actStyle.patternData.valid)
2713 tmpOStyle.patternData = actStyle.patternData.value.toLatin1();
2714 if (actStyle.patternWidth.valid)
2715 {
2716 tmpOStyle.patternWidth = parseUnit(actStyle.patternWidth.value);
2717 if (actStyle.patternWidth.value.contains("%"))
2718 tmpOStyle.patternDim_W_in_Percent = true;
2719 }
2720 else
2721 tmpOStyle.patternWidth = -1;
2722 if (actStyle.patternHeight.valid)
2723 {
2724 tmpOStyle.patternHeight = parseUnit(actStyle.patternHeight.value);
2725 if (actStyle.patternHeight.value.contains("%"))
2726 tmpOStyle.patternDim_H_in_Percent = true;
2727 }
2728 else
2729 tmpOStyle.patternHeight = -1;
2730 if (actStyle.patternX.valid)
2731 tmpOStyle.patternX = parseUnit(actStyle.patternX.value);
2732 else
2733 tmpOStyle.patternX = -1;
2734 if (actStyle.patternY.valid)
2735 tmpOStyle.patternY = parseUnit(actStyle.patternY.value);
2736 else
2737 tmpOStyle.patternY = -1;
2738 if (actStyle.patternStretch.valid)
2739 tmpOStyle.patternStretch = actStyle.patternStretch.value;
2740 if (actStyle.hatchColor.valid)
2741 tmpOStyle.hatchColor = parseColor(actStyle.hatchColor.value);
2742 if (actStyle.hatchDistance.valid)
2743 tmpOStyle.hatchDistance = parseUnit(actStyle.hatchDistance.value);
2744 if (actStyle.hatchRotation.valid)
2745 tmpOStyle.hatchRotation = actStyle.hatchRotation.value.toDouble() / 10.0;
2746 if (actStyle.hatchStyle.valid)
2747 tmpOStyle.hatchStyle = actStyle.hatchStyle.value;
2748 if (actStyle.hatchSolidFill.valid)
2749 tmpOStyle.hatchSolidFill = actStyle.hatchSolidFill.value == "true";
2750 if (actStyle.opacityName.valid)
2751 tmpOStyle.opacityName = actStyle.opacityName.value;
2752 if (actStyle.opacityEnd.valid)
2753 tmpOStyle.opacityEnd = parseUnit(actStyle.opacityEnd.value) * 100.0;
2754 if (actStyle.opacityStart.valid)
2755 tmpOStyle.opacityStart = parseUnit(actStyle.opacityStart.value) * 100.0;
2756 }
2757 }
2758
parseUnit(const QString & unit)2759 double OdgPlug::parseUnit(const QString &unit)
2760 {
2761 QString unitval=unit;
2762 if (unit.isEmpty())
2763 return 0.0;
2764 if (unit.right( 2 ) == "pt")
2765 unitval.replace( "pt", "" );
2766 else if (unit.right( 2 ) == "cm")
2767 unitval.replace( "cm", "" );
2768 else if (unit.right( 2 ) == "mm")
2769 unitval.replace( "mm" , "" );
2770 else if (unit.right( 2 ) == "in")
2771 unitval.replace( "in", "" );
2772 else if (unit.right( 2 ) == "px")
2773 unitval.replace( "px", "" );
2774 else if (unit.right( 1 ) == "%")
2775 unitval.replace( "%", "" );
2776 double value = ScCLocale::toDoubleC(unitval);
2777 if (unit.right( 2 ) == "pt")
2778 {}/* value = value; */ //no change
2779 else if (unit.right( 2 ) == "cm")
2780 value = ( value / 2.54 ) * 72;
2781 else if (unit.right( 2 ) == "mm")
2782 value = ( value / 25.4 ) * 72;
2783 else if (unit.right( 2 ) == "in")
2784 value = value * 72;
2785 else if (unit.right( 2 ) == "px")
2786 {}/* value = value; */ //no change
2787 else if (unit.right( 1 ) == "%")
2788 value = value / 100.0;
2789 return value;
2790 }
2791
getCoord(const char * ptr,double & number)2792 const char * OdgPlug::getCoord( const char *ptr, double &number )
2793 {
2794 int integer, exponent;
2795 double decimal, frac;
2796 int sign, expsign;
2797
2798 exponent = 0;
2799 integer = 0;
2800 frac = 1.0;
2801 decimal = 0;
2802 sign = 1;
2803 expsign = 1;
2804
2805 // read the sign
2806 if (*ptr == '+')
2807 ptr++;
2808 else if (*ptr == '-')
2809 {
2810 ptr++;
2811 sign = -1;
2812 }
2813
2814 // read the integer part
2815 while (*ptr != '\0' && *ptr >= '0' && *ptr <= '9')
2816 integer = (integer * 10) + *(ptr++) - '0';
2817 if (*ptr == '.') // read the decimals
2818 {
2819 ptr++;
2820 while (*ptr != '\0' && *ptr >= '0' && *ptr <= '9')
2821 decimal += (*(ptr++) - '0') * (frac *= 0.1);
2822 }
2823
2824 if (*ptr == 'e' || *ptr == 'E') // read the exponent part
2825 {
2826 ptr++;
2827
2828 // read the sign of the exponent
2829 if (*ptr == '+')
2830 ptr++;
2831 else if (*ptr == '-')
2832 {
2833 ptr++;
2834 expsign = -1;
2835 }
2836
2837 exponent = 0;
2838 while (*ptr != '\0' && *ptr >= '0' && *ptr <= '9')
2839 {
2840 exponent *= 10;
2841 exponent += *ptr - '0';
2842 ptr++;
2843 }
2844 }
2845 number = integer + decimal;
2846 number *= sign * pow( static_cast<double>(10), static_cast<double>( expsign * exponent ) );
2847
2848 // skip the following space
2849 if (*ptr == ' ')
2850 ptr++;
2851
2852 return ptr;
2853 }
2854
parseEnhPath(const QString & svgPath,FPointArray & result,bool & fill,bool & stroke)2855 bool OdgPlug::parseEnhPath(const QString& svgPath, FPointArray &result, bool &fill, bool &stroke)
2856 {
2857 QString d = svgPath;
2858 d = d.replace( QRegExp( "," ), " ");
2859 bool ret = false;
2860 fill = true;
2861 stroke = true;
2862 if (!d.isEmpty())
2863 {
2864 bool xDir = true;
2865 bool yDir = false;
2866 double rad2deg = 180.0/M_PI;
2867 QPainterPath pPath;
2868 d = d.simplified();
2869 QByteArray pathData = d.toLatin1();
2870 const char *ptr = pathData.constData();
2871 const char *end = pathData.constData() + pathData.length() + 1;
2872 double tox, toy, x1, y1, x2, y2;
2873 double px1, py1, px2, py2, px3, py3;
2874 int moveCount = 0;
2875 result.svgInit();
2876 char command = *(ptr++), lastCommand = ' ';
2877 while (ptr < end)
2878 {
2879 if (*ptr == ' ')
2880 ptr++;
2881 switch (command)
2882 {
2883 case 'A':
2884 case 'B':
2885 case 'V':
2886 case 'W':
2887 {
2888 ptr = getCoord( ptr, tox );
2889 ptr = getCoord( ptr, toy );
2890 ptr = getCoord( ptr, px1 );
2891 ptr = getCoord( ptr, py1 );
2892 ptr = getCoord( ptr, px2 );
2893 ptr = getCoord( ptr, py2 );
2894 ptr = getCoord( ptr, px3 );
2895 ptr = getCoord( ptr, py3 );
2896 bool lineTo = ((command == 'A') || (command == 'W'));
2897 bool clockwise = ((command == 'W') || (command == 'V'));
2898 QRectF bbox = QRectF(QPointF(tox, toy), QPointF(px1, py1)).normalized();
2899 QPointF center = bbox.center();
2900 double rx = 0.5 * bbox.width();
2901 double ry = 0.5 * bbox.height();
2902 if (rx == 0)
2903 rx = 1;
2904 if (ry == 0)
2905 ry = 1;
2906 QPointF startRadialVector = QPointF(px2, py2) - center;
2907 QPointF endRadialVector = QPointF(px3, py3) - center;
2908 // convert from ellipse space to unit-circle space
2909 double x0 = startRadialVector.x() / rx;
2910 double y0 = startRadialVector.y() / ry;
2911
2912 double x1 = endRadialVector.x() / rx;
2913 double y1 = endRadialVector.y() / ry;
2914
2915 double startAngle = angleFromPoint(QPointF(x0,y0));
2916 double stopAngle = angleFromPoint(QPointF(x1,y1));
2917
2918 // we are moving counter-clockwise to the end angle
2919 double sweepAngle = radSweepAngle(startAngle, stopAngle, clockwise);
2920 // compute the starting point to draw the line to
2921 // as the point x3 y3 is not on the ellipse, spec says the point define radial vector
2922 QPointF startPoint(rx * cos(startAngle), ry * sin(2*M_PI - startAngle));
2923
2924 // if A or W is first command in enhanced path
2925 // move to the starting point
2926 bool isFirstCommandInPath = (pPath.elementCount() == 0);
2927 bool isFirstCommandInSubpath = lastCommand == 'Z';
2928 if (lineTo && !isFirstCommandInPath && !isFirstCommandInSubpath)
2929 pPath.lineTo(center + startPoint);
2930 else
2931 pPath.moveTo(center + startPoint);
2932 arcTo(pPath, pPath.currentPosition(), rx, ry, startAngle * rad2deg, sweepAngle * rad2deg);
2933 break;
2934 }
2935 case 'C':
2936 {
2937 ptr = getCoord( ptr, x1 );
2938 ptr = getCoord( ptr, y1 );
2939 ptr = getCoord( ptr, x2 );
2940 ptr = getCoord( ptr, y2 );
2941 ptr = getCoord( ptr, tox );
2942 ptr = getCoord( ptr, toy );
2943 pPath.cubicTo(x1, y1, x2, y2, tox, toy);
2944 break;
2945 }
2946 case 'F':
2947 {
2948 fill = false;
2949 break;
2950 }
2951 case 'L':
2952 {
2953 ptr = getCoord( ptr, tox );
2954 ptr = getCoord( ptr, toy );
2955 pPath.lineTo(tox, toy);
2956 break;
2957 }
2958 case 'M':
2959 {
2960 ptr = getCoord( ptr, tox );
2961 ptr = getCoord( ptr, toy );
2962 pPath.moveTo(tox, toy);
2963 moveCount++;
2964 break;
2965 }
2966 case 'Q':
2967 {
2968 ptr = getCoord( ptr, x1 );
2969 ptr = getCoord( ptr, y1 );
2970 ptr = getCoord( ptr, tox );
2971 ptr = getCoord( ptr, toy );
2972 pPath.quadTo(x1, y1, tox, toy);
2973 break;
2974 }
2975 case 'S':
2976 {
2977 stroke = false;
2978 break;
2979 }
2980 case 'T':
2981 case 'U':
2982 {
2983 ptr = getCoord(ptr, px1);
2984 ptr = getCoord(ptr, py1);
2985 ptr = getCoord(ptr, px2);
2986 ptr = getCoord(ptr, py2);
2987 ptr = getCoord(ptr, tox);
2988 ptr = getCoord(ptr, toy);
2989 bool lineTo = (command == 'T');
2990 const QPointF &radii = QPointF(px2, py2);
2991 const QPointF &angles = QPointF(tox, toy) / (180.0/M_PI);
2992 QPointF start(radii.x() * cos(angles.x()), -1 * radii.y() * sin(angles.x()));
2993 double sweepAngle = degSweepAngle(tox, toy, false);
2994 if (lineTo)
2995 pPath.lineTo(QPointF(px1, py1) + start);
2996 else
2997 pPath.moveTo(QPointF(px1, py1) + start);
2998 arcTo(pPath, pPath.currentPosition(), radii.x(), radii.y(), tox, sweepAngle);
2999 break;
3000 }
3001 case 'X':
3002 {
3003 ptr = getCoord( ptr, tox );
3004 ptr = getCoord( ptr, toy );
3005 double rx = tox - pPath.currentPosition().x();
3006 double ry = toy - pPath.currentPosition().y();
3007 double startAngle = xDir ? (ry > 0.0 ? 90.0 : 270.0) : (rx < 0.0 ? 0.0 : 180.0);
3008 double sweepAngle = xDir ? (rx*ry < 0.0 ? 90.0 : -90.0) : (rx*ry > 0.0 ? 90.0 : -90.0);
3009 arcTo(pPath, pPath.currentPosition(), fabs(rx), fabs(ry), startAngle, sweepAngle);
3010 xDir = !xDir;
3011 break;
3012 }
3013 case 'Y':
3014 {
3015 ptr = getCoord( ptr, tox );
3016 ptr = getCoord( ptr, toy );
3017 double rx = tox - pPath.currentPosition().x();
3018 double ry = toy - pPath.currentPosition().y();
3019 double startAngle = yDir ? (ry > 0.0 ? 90.0 : 270.0) : (rx < 0.0 ? 0.0 : 180.0);
3020 double sweepAngle = yDir ? (rx*ry < 0.0 ? 90.0 : -90.0) : (rx*ry > 0.0 ? 90.0 : -90.0);
3021 arcTo(pPath, pPath.currentPosition(), fabs(rx), fabs(ry), startAngle, sweepAngle);
3022 yDir = !yDir;
3023 break;
3024 }
3025 case 'Z':
3026 {
3027 pPath.closeSubpath();
3028 break;
3029 }
3030 }
3031 lastCommand = command;
3032 if (*ptr == '+' || *ptr == '-' || (*ptr >= '0' && *ptr <= '9'))
3033 {
3034 // there are still coords in this command
3035 if (command == 'M')
3036 command = 'L';
3037 }
3038 else
3039 {
3040 command = *(ptr++);
3041 xDir = true;
3042 yDir = false;
3043 }
3044 }
3045 if ((lastCommand != 'Z') || (moveCount > 1))
3046 ret = true;
3047 result.fromQPainterPath(pPath, !ret);
3048 }
3049 return ret;
3050 }
3051
angleFromPoint(const QPointF & point)3052 double OdgPlug::angleFromPoint(const QPointF &point)
3053 {
3054 double angle = atan2(point.y(), point.x());
3055 if (angle < 0.0)
3056 angle += 2*M_PI;
3057 return 2*M_PI - angle;
3058 }
3059
radSweepAngle(double start,double stop,bool clockwise)3060 double OdgPlug::radSweepAngle(double start, double stop, bool clockwise)
3061 {
3062 double sweepAngle = stop - start;
3063 if (fabs(sweepAngle) < 0.1) {
3064 return 2*M_PI;
3065 }
3066 if (clockwise) {
3067 // we are moving clockwise to the end angle
3068 if (stop > start)
3069 sweepAngle = (stop - start) - 2*M_PI;
3070 } else {
3071 // we are moving counter-clockwise to the stop angle
3072 if (start > stop)
3073 sweepAngle = 2*M_PI - (start-stop);
3074 }
3075
3076 return sweepAngle;
3077 }
3078
degSweepAngle(double start,double stop,bool clockwise)3079 double OdgPlug::degSweepAngle(double start, double stop, bool clockwise)
3080 {
3081 double sweepAngle = stop - start;
3082 if (fabs(sweepAngle) < 0.1) {
3083 return 360.0;
3084 }
3085 if (clockwise) {
3086 // we are moving clockwise to the end angle
3087 if (stop > start)
3088 sweepAngle = (stop - start) - 360.0;
3089 } else {
3090 // we are moving counter-clockwise to the stop angle
3091 if (start > stop)
3092 sweepAngle = 360.0 - (start-stop);
3093 }
3094 return sweepAngle;
3095 }
3096
arcTo(QPainterPath & path,QPointF startpoint,double rx,double ry,double startAngle,double sweepAngle)3097 void OdgPlug::arcTo(QPainterPath &path, QPointF startpoint, double rx, double ry, double startAngle, double sweepAngle)
3098 {
3099 QPointF curvePoints[12];
3100 int pointCnt = arcToCurve(rx, ry, startAngle, sweepAngle, startpoint, curvePoints);
3101 for (int i = 0; i < pointCnt; i += 3)
3102 {
3103 path.cubicTo(curvePoints[i], curvePoints[i+1], curvePoints[i+2]);
3104 }
3105 }
3106
arcToCurve(double rx,double ry,double startAngle,double sweepAngle,const QPointF & offset,QPointF * curvePoints)3107 int OdgPlug::arcToCurve(double rx, double ry, double startAngle, double sweepAngle, const QPointF & offset, QPointF * curvePoints)
3108 {
3109 int pointCnt = 0;
3110
3111 // check Parameters
3112 if (sweepAngle == 0)
3113 return pointCnt;
3114 if (sweepAngle > 360)
3115 sweepAngle = 360;
3116 else if (sweepAngle < -360)
3117 sweepAngle = - 360;
3118
3119 if (rx == 0 || ry == 0) {
3120 //TODO
3121 }
3122
3123 // split angles bigger than 90° so that it gives a good aproximation to the circle
3124 double parts = ceil(qAbs(sweepAngle / 90.0));
3125
3126 double sa_rad = startAngle * M_PI / 180.0;
3127 double partangle = sweepAngle / parts;
3128 double endangle = startAngle + partangle;
3129 double se_rad = endangle * M_PI / 180.0;
3130 double sinsa = sin(sa_rad);
3131 double cossa = cos(sa_rad);
3132 double kappa = 4.0 / 3.0 * tan((se_rad - sa_rad) / 4);
3133
3134 // startpoint is at the last point is the path but when it is closed
3135 // it is at the first point
3136 QPointF startpoint(offset);
3137
3138 //center berechnen
3139 QPointF center(startpoint - QPointF(cossa * rx, -sinsa * ry));
3140
3141 //kDebug(30006) <<"kappa" << kappa <<"parts" << parts;;
3142
3143 for (int part = 0; part < parts; ++part) {
3144 // start tangent
3145 curvePoints[pointCnt++] = QPointF(startpoint - QPointF(sinsa * rx * kappa, cossa * ry * kappa));
3146
3147 double sinse = sin(se_rad);
3148 double cosse = cos(se_rad);
3149
3150 // end point
3151 QPointF endpoint(center + QPointF(cosse * rx, -sinse * ry));
3152 // end tangent
3153 curvePoints[pointCnt++] = QPointF(endpoint - QPointF(-sinse * rx * kappa, -cosse * ry * kappa));
3154 curvePoints[pointCnt++] = endpoint;
3155
3156 // set the endpoint as next start point
3157 startpoint = endpoint;
3158 sinsa = sinse;
3159 cossa = cosse;
3160 endangle += partangle;
3161 se_rad = endangle * M_PI / 180.0;
3162 }
3163
3164 return pointCnt;
3165 }
3166
groupObjects(QList<PageItem * > & GElements)3167 PageItem* OdgPlug::groupObjects(QList<PageItem *> &GElements)
3168 {
3169 double minx = std::numeric_limits<double>::max();
3170 double miny = std::numeric_limits<double>::max();
3171 double maxx = -std::numeric_limits<double>::max();
3172 double maxy = -std::numeric_limits<double>::max();
3173 for (int ep = 0; ep < GElements.count(); ++ep)
3174 {
3175 PageItem* currItem = GElements.at(ep);
3176 double x1, x2, y1, y2;
3177 currItem->getVisualBoundingRect(&x1, &y1, &x2, &y2);
3178 minx = qMin(minx, x1);
3179 miny = qMin(miny, y1);
3180 maxx = qMax(maxx, x2);
3181 maxy = qMax(maxy, y2);
3182 }
3183 double gx = minx;
3184 double gy = miny;
3185 double gw = maxx - minx;
3186 double gh = maxy - miny;
3187 int z = m_Doc->itemAdd(PageItem::Group, PageItem::Rectangle, gx, gy, gw, gh, 0, CommonStrings::None, CommonStrings::None);
3188 PageItem* retObj = m_Doc->Items->at(z);
3189 retObj->ClipEdited = true;
3190 retObj->FrameType = 3;
3191 retObj->setFillEvenOdd(false);
3192 retObj->OldB2 = retObj->width();
3193 retObj->OldH2 = retObj->height();
3194 retObj->updateClip();
3195 m_Doc->groupObjectsToItem(retObj, GElements);
3196 retObj->OwnPage = m_Doc->OnPage(retObj);
3197 m_Doc->GroupOnPage(retObj);
3198 m_Doc->Items->removeLast();
3199 return retObj;
3200 }
3201
modifyColor(const QString & name,bool darker,int amount)3202 QString OdgPlug::modifyColor(const QString& name, bool darker, int amount)
3203 {
3204 const ScColor& col = m_Doc->PageColors[name];
3205 QColor c = ScColorEngine::getShadeColorProof(col, m_Doc, 100);
3206 QColor mo;
3207 if (darker)
3208 mo = c.darker(amount);
3209 else
3210 mo = c.lighter(amount);
3211 ScColor tmp;
3212 tmp.fromQColor(mo);
3213 tmp.setSpotColor(false);
3214 tmp.setRegistrationColor(false);
3215 QString fNam = m_Doc->PageColors.tryAddColor("FromOdg"+mo.name(), tmp);
3216 if (fNam == "FromOdg"+mo.name())
3217 importedColors.append(fNam);
3218 return fNam;
3219 }
3220
parseColor(const QString & s)3221 QString OdgPlug::parseColor( const QString &s )
3222 {
3223 QColor c;
3224 QString ret = CommonStrings::None;
3225 if ((s == "") || s.isEmpty())
3226 return ret;
3227 if (s.startsWith( "rgb(" ))
3228 {
3229 QString parse = s.trimmed();
3230 QStringList colors = parse.split( ',', Qt::SkipEmptyParts );
3231 QString r = colors[0].right( ( colors[0].length() - 4 ) );
3232 QString g = colors[1];
3233 QString b = colors[2].left( ( colors[2].length() - 1 ) );
3234 if (r.contains( "%" ))
3235 {
3236 r.chop(1);
3237 r = QString::number( static_cast<int>( ( static_cast<double>( 255 * ScCLocale::toDoubleC(r) ) / 100.0 ) ) );
3238 }
3239 if (g.contains( "%" ))
3240 {
3241 g.chop(1);
3242 g = QString::number( static_cast<int>( ( static_cast<double>( 255 * ScCLocale::toDoubleC(g) ) / 100.0 ) ) );
3243 }
3244 if (b.contains( "%" ))
3245 {
3246 b.chop(1);
3247 b = QString::number( static_cast<int>( ( static_cast<double>( 255 * ScCLocale::toDoubleC(b) ) / 100.0 ) ) );
3248 }
3249 c = QColor(r.toInt(), g.toInt(), b.toInt());
3250 }
3251 else
3252 c.setNamedColor(s.trimmed());
3253
3254 ScColor tmp;
3255 tmp.fromQColor(c);
3256 tmp.setSpotColor(false);
3257 tmp.setRegistrationColor(false);
3258 QString fNam = m_Doc->PageColors.tryAddColor("FromOdg"+c.name(), tmp);
3259 if (fNam == "FromOdg"+c.name())
3260 importedColors.append(fNam);
3261 ret = fNam;
3262 return ret;
3263 }
3264
constructFontName(const QString & fontBaseName,const QString & fontStyle)3265 QString OdgPlug::constructFontName(const QString& fontBaseName, const QString& fontStyle)
3266 {
3267 QString fontName;
3268 bool found = false;
3269 SCFontsIterator it(PrefsManager::instance().appPrefs.fontPrefs.AvailFonts);
3270 for ( ; it.hasNext(); it.next())
3271 {
3272 if (fontBaseName.toLower() == it.current().family().toLower())
3273 {
3274 // found the font family, now go for the style
3275 QStringList slist = PrefsManager::instance().appPrefs.fontPrefs.AvailFonts.fontMap[it.current().family()];
3276 slist.sort();
3277 if (slist.count() > 0)
3278 {
3279 for (int a = 0; a < slist.count(); a++)
3280 {
3281 if (fontStyle.toLower() == slist[a].toLower())
3282 {
3283 found = true;
3284 fontName = it.current().family() + " " + slist[a];
3285 break;
3286 }
3287 }
3288 if (!found)
3289 {
3290 int reInd = slist.indexOf("Regular");
3291 if (reInd < 0)
3292 fontName = it.current().family() + " " + slist[0];
3293 else
3294 fontName = it.current().family() + " " + slist[reInd];
3295 found = true;
3296 }
3297 }
3298 else
3299 {
3300 fontName = it.current().family();
3301 found = true;
3302 }
3303 break;
3304 }
3305 }
3306 if (!found)
3307 {
3308 if (importerFlags & LoadSavePlugin::lfCreateThumbnail)
3309 fontName = PrefsManager::instance().appPrefs.itemToolPrefs.textFont;
3310 else
3311 {
3312 QString family = fontBaseName;
3313 if (!fontStyle.isEmpty())
3314 family += " " + fontStyle;
3315 if (!PrefsManager::instance().appPrefs.fontPrefs.GFontSub.contains(family))
3316 {
3317 qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
3318 MissingFont *dia = new MissingFont(nullptr, family, m_Doc);
3319 dia->exec();
3320 fontName = dia->getReplacementFont();
3321 delete dia;
3322 qApp->changeOverrideCursor(QCursor(Qt::WaitCursor));
3323 PrefsManager::instance().appPrefs.fontPrefs.GFontSub[family] = fontName;
3324 }
3325 else
3326 fontName = PrefsManager::instance().appPrefs.fontPrefs.GFontSub[family];
3327 }
3328 }
3329 return fontName;
3330 }
3331
intersectBoundingRect(PageItem * item,QLineF gradientVector)3332 QPointF OdgPlug::intersectBoundingRect(PageItem *item, QLineF gradientVector)
3333 {
3334 QPointF interPoint;
3335 QPointF gradEnd;
3336 if (gradientVector.intersects(QLineF(0, 0, item->width(), 0), &interPoint) == QLineF::BoundedIntersection)
3337 gradEnd = interPoint;
3338 else if (gradientVector.intersects(QLineF(item->width(), 0, item->width(), item->height()), &interPoint) == QLineF::BoundedIntersection)
3339 gradEnd = interPoint;
3340 else if (gradientVector.intersects(QLineF(item->width(), item->height(), 0, item->height()), &interPoint) == QLineF::BoundedIntersection)
3341 gradEnd = interPoint;
3342 else if (gradientVector.intersects(QLineF(0, item->height(), 0, 0), &interPoint) == QLineF::BoundedIntersection)
3343 gradEnd = interPoint;
3344 return gradEnd;
3345 }
3346
applyStartArrow(PageItem * ite,ObjStyle & obState)3347 PageItem* OdgPlug::applyStartArrow(PageItem* ite, ObjStyle &obState)
3348 {
3349 PageItem *iteS = nullptr;
3350 if (!obState.startMarkerName.isEmpty())
3351 {
3352 ObjStyle mStyle;
3353 resovleStyle(mStyle, obState.startMarkerName);
3354 QPainterPath pa = mStyle.markerPath;
3355 FPointArray EndArrow;
3356 EndArrow.fromQPainterPath(pa);
3357 QRectF br = pa.boundingRect();
3358 double EndArrowWidth = obState.startMarkerWidth;
3359 if (EndArrowWidth > 0)
3360 {
3361 FPoint Start = ite->PoLine.point(0);
3362 for (int xx = 1; xx < ite->PoLine.size(); xx += 2)
3363 {
3364 FPoint Vector = ite->PoLine.point(xx);
3365 if ((Start.x() != Vector.x()) || (Start.y() != Vector.y()))
3366 {
3367 double r = atan2(Start.y()-Vector.y(),Start.x()-Vector.x())*(180.0/M_PI);
3368 QPointF refP;
3369 if (obState.startMarkerCentered)
3370 refP = QPointF(br.width() / 2.0, br.height() / 2.0);
3371 else
3372 refP = QPointF(br.width() / 2.0, 0);
3373 QTransform m;
3374 m.translate(br.width() / 2.0, br.height() / 2.0);
3375 m.rotate(r + 90);
3376 m.translate(-br.width() / 2.0, -br.height() / 2.0);
3377 m.scale(EndArrowWidth / br.width(), EndArrowWidth / br.width());
3378 EndArrow.map(m);
3379 refP = m.map(refP);
3380 QPainterPath pa2 = EndArrow.toQPainterPath(true);
3381 QTransform m2;
3382 FPoint grOffset2(getMinClipF(&EndArrow));
3383 m2.translate(-grOffset2.x(), -grOffset2.y());
3384 EndArrow.map(m2);
3385 refP = m2.map(refP);
3386 EndArrow.translate(-refP.x(), -refP.y());
3387 QTransform arrowTrans;
3388 arrowTrans.translate(-m_Doc->currentPage()->xOffset(), -m_Doc->currentPage()->yOffset());
3389 arrowTrans.translate(Start.x() + ite->xPos(), Start.y() + ite->yPos());
3390 EndArrow.map(arrowTrans);
3391 int zS = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, obState.currColorStroke, CommonStrings::None);
3392 iteS = m_Doc->Items->at(zS);
3393 iteS->PoLine = EndArrow.copy();
3394 iteS->ClipEdited = true;
3395 iteS->FrameType = 3;
3396 FPoint wh = getMaxClipF(&iteS->PoLine);
3397 iteS->setWidthHeight(wh.x(), wh.y());
3398 m_Doc->adjustItemSize(iteS, true);
3399 iteS->setFillEvenOdd(false);
3400 iteS->OldB2 = iteS->width();
3401 iteS->OldH2 = iteS->height();
3402 iteS->updateClip();
3403 iteS->OwnPage = m_Doc->OnPage(iteS);
3404 iteS->setFillTransparency(obState.strokeOpacity);
3405 m_Doc->Items->removeLast();
3406 break;
3407 }
3408 }
3409 }
3410
3411 }
3412 return iteS;
3413 }
3414
applyEndArrow(PageItem * ite,ObjStyle & obState)3415 PageItem* OdgPlug::applyEndArrow(PageItem* ite, ObjStyle &obState)
3416 {
3417 PageItem *iteS = nullptr;
3418 if (!obState.endMarkerName.isEmpty())
3419 {
3420 ObjStyle mStyle;
3421 resovleStyle(mStyle, obState.endMarkerName);
3422 double EndArrowWidth = obState.endMarkerWidth;
3423 QPainterPath pa = mStyle.markerPath;
3424 FPointArray EndArrow;
3425 EndArrow.fromQPainterPath(pa);
3426 QRectF br = pa.boundingRect();
3427 if (EndArrowWidth > 0)
3428 {
3429 FPoint End = ite->PoLine.point(ite->PoLine.size()-2);
3430 for (uint xx = ite->PoLine.size()-1; xx > 0; xx -= 2)
3431 {
3432 FPoint Vector = ite->PoLine.point(xx);
3433 if ((End.x() != Vector.x()) || (End.y() != Vector.y()))
3434 {
3435 double r = atan2(End.y()-Vector.y(),End.x()-Vector.x())*(180.0/M_PI);
3436 QPointF refP;
3437 if (obState.endMarkerCentered)
3438 refP = QPointF(br.width() / 2.0, br.height() / 2.0);
3439 else
3440 refP = QPointF(br.width() / 2.0, 0);
3441 QTransform m;
3442 m.translate(br.width() / 2.0, br.height() / 2.0);
3443 m.rotate(r + 90);
3444 m.translate(-br.width() / 2.0, -br.height() / 2.0);
3445 m.scale(EndArrowWidth / br.width(), EndArrowWidth / br.width());
3446 EndArrow.map(m);
3447 refP = m.map(refP);
3448 QTransform m2;
3449 FPoint grOffset2(getMinClipF(&EndArrow));
3450 m2.translate(-grOffset2.x(), -grOffset2.y());
3451 EndArrow.map(m2);
3452 refP = m2.map(refP);
3453 EndArrow.translate(-refP.x(), -refP.y());
3454 QTransform arrowTrans;
3455 arrowTrans.translate(-m_Doc->currentPage()->xOffset(), -m_Doc->currentPage()->yOffset());
3456 arrowTrans.translate(End.x() + ite->xPos(), End.y() + ite->yPos());
3457 EndArrow.map(arrowTrans);
3458 int zE = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, obState.currColorStroke, CommonStrings::None);
3459 iteS = m_Doc->Items->at(zE);
3460 iteS->PoLine = EndArrow.copy();
3461 iteS->ClipEdited = true;
3462 iteS->FrameType = 3;
3463 FPoint wh = getMaxClipF(&iteS->PoLine);
3464 iteS->setWidthHeight(wh.x(), wh.y());
3465 m_Doc->adjustItemSize(iteS, true);
3466 iteS->setFillEvenOdd(false);
3467 iteS->OldB2 = iteS->width();
3468 iteS->OldH2 = iteS->height();
3469 iteS->updateClip();
3470 iteS->OwnPage = m_Doc->OnPage(iteS);
3471 iteS->setFillTransparency(obState.strokeOpacity);
3472 m_Doc->Items->removeLast();
3473 break;
3474 }
3475 }
3476 }
3477 }
3478 return iteS;
3479 }
3480
finishItem(PageItem * item,ObjStyle & obState)3481 void OdgPlug::finishItem(PageItem* item, ObjStyle &obState)
3482 {
3483 item->ClipEdited = true;
3484 item->FrameType = 3;
3485 FPoint wh = getMaxClipF(&item->PoLine);
3486 item->setWidthHeight(wh.x(), wh.y());
3487 item->Clip = flattenPath(item->PoLine, item->Segments);
3488 m_Doc->adjustItemSize(item, true);
3489 item->OldB2 = item->width();
3490 item->OldH2 = item->height();
3491 item->updateClip();
3492 item->OwnPage = m_Doc->OnPage(item);
3493 item->setFillTransparency(obState.fillOpacity);
3494 item->setLineTransparency(obState.strokeOpacity);
3495 item->setStartArrowIndex(0);
3496 item->setEndArrowIndex(0);
3497 if (obState.stroke_type == 2)
3498 {
3499 ObjStyle dStyle;
3500 resovleStyle(dStyle, obState.dashName);
3501 item->DashValues.clear();
3502 double gap = 0;
3503 if (dStyle.stroke_dash_distance < 0)
3504 gap = item->lineWidth();
3505 else
3506 gap = dStyle.stroke_dash_distance;
3507 int dots1 = dStyle.stroke_dash_dots1;
3508 double dots1len = item->lineWidth();
3509 if (dStyle.stroke_dash_dots1_length < 0)
3510 dots1len = item->lineWidth();
3511 else
3512 dots1len = dStyle.stroke_dash_dots1_length;
3513 int dots2 = dStyle.stroke_dash_dots2;
3514 double dots2len = item->lineWidth();
3515 if (dStyle.stroke_dash_dots2_length < 0)
3516 dots2len = item->lineWidth();
3517 else
3518 dots2len = dStyle.stroke_dash_dots2_length;
3519 for (int i = 0; i < dots1; i++)
3520 {
3521 item->DashValues << qMax(dots1len, 0.1) << qMax(gap, 0.1);
3522 }
3523 for (int j = 0; j < dots2; j++)
3524 {
3525 item->DashValues << qMax(dots2len, 0.1) << qMax(gap, 0.1);
3526 }
3527 }
3528 if (obState.fill_type == 2)
3529 {
3530 ObjStyle gStyle;
3531 resovleStyle(gStyle, obState.gradientName);
3532 if (gStyle.gradientType == "linear")
3533 {
3534 double angle = gStyle.gradientAngle + 90;
3535 item->fill_gradient = VGradient(VGradient::linear);
3536 item->fill_gradient.clearStops();
3537 item->fill_gradient.setRepeatMethod( VGradient::none );
3538 const ScColor& gradC = m_Doc->PageColors[gStyle.gradientEndColor];
3539 item->fill_gradient.addStop(ScColorEngine::getRGBColor(gradC, m_Doc), 0.0, 0.5, 1.0, gStyle.gradientEndColor, gStyle.gradientEndShade);
3540 const ScColor& gradC2 = m_Doc->PageColors[gStyle.gradientStartColor];
3541 item->fill_gradient.addStop(ScColorEngine::getRGBColor(gradC2, m_Doc), 1.0 - gStyle.gradientBorder, 0.5, 1.0, gStyle.gradientStartColor, gStyle.gradientStartShade);
3542 QLineF gradientVectorE;
3543 gradientVectorE.setP1(QPointF(item->width() / 2.0, item->height() / 2.0));
3544 gradientVectorE.setAngle(angle);
3545 gradientVectorE.setLength(sqrt(item->width() * item->width() + item->height() * item->height()) / 2.0 + 1.0);
3546 QPointF gradEnd = intersectBoundingRect(item, gradientVectorE);
3547 QLineF gradientVectorS;
3548 gradientVectorS.setP1(QPointF(item->width() / 2.0, item->height() / 2.0));
3549 gradientVectorS.setAngle(angle + 180);
3550 gradientVectorS.setLength(sqrt(item->width() * item->width() + item->height() * item->height()) / 2.0 + 1.0);
3551 QPointF gradStart = intersectBoundingRect(item, gradientVectorS);
3552 item->setGradientVector(gradStart.x(), gradStart.y(), gradEnd.x(), gradEnd.y(), gradStart.x(), gradStart.y(), 1, 0);
3553 item->setGradientType(6);
3554 }
3555 else if (gStyle.gradientType == "axial")
3556 {
3557 double angle = gStyle.gradientAngle + 90;
3558 item->fill_gradient = VGradient(VGradient::linear);
3559 item->fill_gradient.clearStops();
3560 item->fill_gradient.setRepeatMethod( VGradient::none );
3561 const ScColor& gradC = m_Doc->PageColors[gStyle.gradientEndColor];
3562 item->fill_gradient.addStop(ScColorEngine::getRGBColor(gradC, m_Doc), 0.0 + (gStyle.gradientBorder / 2.0), 0.5, 1.0, gStyle.gradientEndColor, gStyle.gradientEndShade);
3563 const ScColor& gradC2 = m_Doc->PageColors[gStyle.gradientStartColor];
3564 item->fill_gradient.addStop(ScColorEngine::getRGBColor(gradC2, m_Doc), 0.5, 0.5, 1.0, gStyle.gradientStartColor, gStyle.gradientStartShade);
3565 item->fill_gradient.addStop(ScColorEngine::getRGBColor(gradC, m_Doc), 1.0 - (gStyle.gradientBorder / 2.0), 0.5, 1.0, gStyle.gradientEndColor, gStyle.gradientEndShade);
3566 QLineF gradientVectorE;
3567 gradientVectorE.setP1(QPointF(item->width() / 2.0, item->height() / 2.0));
3568 gradientVectorE.setAngle(angle);
3569 gradientVectorE.setLength(sqrt(item->width() * item->width() + item->height() * item->height()) / 2.0 + 1.0);
3570 QPointF gradEnd = intersectBoundingRect(item, gradientVectorE);
3571 QLineF gradientVectorS;
3572 gradientVectorS.setP1(QPointF(item->width() / 2.0, item->height() / 2.0));
3573 gradientVectorS.setAngle(angle + 180);
3574 gradientVectorS.setLength(sqrt(item->width() * item->width() + item->height() * item->height()) / 2.0 + 1.0);
3575 QPointF gradStart = intersectBoundingRect(item, gradientVectorS);
3576 item->setGradientVector(gradStart.x(), gradStart.y(), gradEnd.x(), gradEnd.y(), gradStart.x(), gradStart.y(), 1, 0);
3577 item->setGradientType(6);
3578 }
3579 else if (gStyle.gradientType == "radial")
3580 {
3581 item->fill_gradient = VGradient(VGradient::radial);
3582 item->fill_gradient.clearStops();
3583 item->fill_gradient.setRepeatMethod( VGradient::none );
3584 const ScColor& gradC = m_Doc->PageColors[gStyle.gradientEndColor];
3585 item->fill_gradient.addStop(ScColorEngine::getRGBColor(gradC, m_Doc), 0.0, 0.5, 1.0, gStyle.gradientEndColor, gStyle.gradientEndShade);
3586 const ScColor& gradC2 = m_Doc->PageColors[gStyle.gradientStartColor];
3587 item->fill_gradient.addStop(ScColorEngine::getRGBColor(gradC2, m_Doc), 1.0 - gStyle.gradientBorder, 0.5, 1.0, gStyle.gradientStartColor, gStyle.gradientStartShade);
3588 item->GrType = Gradient_Radial;
3589 item->GrStartX = item->width() * gStyle.gradientCenterX;
3590 item->GrStartY = item->height()* gStyle.gradientCenterY;
3591 item->GrFocalX = item->width() * gStyle.gradientCenterX;
3592 item->GrFocalY = item->height()* gStyle.gradientCenterY;
3593 if (item->width() >= item->height())
3594 {
3595 item->GrEndX = item->width();
3596 item->GrEndY = item->height() / 2.0;
3597 }
3598 else
3599 {
3600 item->GrEndX = item->width() / 2.0;
3601 item->GrEndY = item->height();
3602 }
3603 item->updateGradientVectors();
3604 }
3605 else if (gStyle.gradientType == "ellipsoid")
3606 {
3607 item->fill_gradient = VGradient(VGradient::radial);
3608 item->fill_gradient.clearStops();
3609 item->fill_gradient.setRepeatMethod( VGradient::none );
3610 const ScColor& gradC = m_Doc->PageColors[gStyle.gradientEndColor];
3611 item->fill_gradient.addStop(ScColorEngine::getRGBColor(gradC, m_Doc), 0.0, 0.5, 1.0, gStyle.gradientEndColor, gStyle.gradientEndShade);
3612 const ScColor& gradC2 = m_Doc->PageColors[gStyle.gradientStartColor];
3613 item->fill_gradient.addStop(ScColorEngine::getRGBColor(gradC2, m_Doc), 1.0 - gStyle.gradientBorder, 0.5, 1.0, gStyle.gradientStartColor, gStyle.gradientStartShade);
3614 item->GrType = Gradient_Radial;
3615 item->GrStartX = item->width() * gStyle.gradientCenterX;
3616 item->GrStartY = item->height()* gStyle.gradientCenterY;
3617 item->GrFocalX = item->width() * gStyle.gradientCenterX;
3618 item->GrFocalY = item->height()* gStyle.gradientCenterY;
3619 if (item->width() >= item->height())
3620 {
3621 item->GrEndX = item->width();
3622 item->GrEndY = item->height() / 2.0;
3623 }
3624 else
3625 {
3626 item->GrEndX = item->width() / 2.0;
3627 item->GrEndY = item->height();
3628 }
3629 QLineF gradientVectorE = QLineF(item->GrStartX, item->GrStartY, item->GrEndX, item->GrEndY);
3630 gradientVectorE.setAngle(gStyle.gradientAngle);
3631 item->GrEndX = gradientVectorE.p2().x();
3632 item->GrEndY = gradientVectorE.p2().y();
3633 item->updateGradientVectors();
3634 }
3635 else if (gStyle.gradientType == "square")
3636 {
3637 item->fill_gradient = VGradient(VGradient::radial);
3638 item->fill_gradient.clearStops();
3639 item->fill_gradient.setRepeatMethod( VGradient::none );
3640 const ScColor& gradC = m_Doc->PageColors[gStyle.gradientEndColor];
3641 item->fill_gradient.addStop(ScColorEngine::getRGBColor(gradC, m_Doc), 0.0, 0.5, 1.0, gStyle.gradientEndColor, gStyle.gradientEndShade);
3642 const ScColor& gradC2 = m_Doc->PageColors[gStyle.gradientStartColor];
3643 item->fill_gradient.addStop(ScColorEngine::getRGBColor(gradC2, m_Doc), 1.0 - gStyle.gradientBorder, 0.5, 1.0, gStyle.gradientStartColor, gStyle.gradientStartShade);
3644 if (gStyle.gradientBorder != 0)
3645 item->fill_gradient.addStop(ScColorEngine::getRGBColor(gradC2, m_Doc), 1.0, 0.5, 1.0, gStyle.gradientStartColor, gStyle.gradientStartShade);
3646 FPoint cp = FPoint(item->width() * gStyle.gradientCenterX, item->height()* gStyle.gradientCenterY);
3647 double gLen = qMin(item->width(), item->height()) / 2.0;
3648 QLineF p1 = QLineF(cp.x(), cp.y(), cp.x() - gLen, cp.y() - gLen);
3649 p1.setAngle(p1.angle() + gStyle.gradientAngle);
3650 QLineF p2 = QLineF(cp.x(), cp.y(), cp.x() + gLen, cp.y() - gLen);
3651 p2.setAngle(p2.angle() + gStyle.gradientAngle);
3652 QLineF p3 = QLineF(cp.x(), cp.y(), cp.x() + gLen, cp.y() + gLen);
3653 p3.setAngle(p3.angle() + gStyle.gradientAngle);
3654 QLineF p4 = QLineF(cp.x(), cp.y(), cp.x() - gLen, cp.y() + gLen);
3655 p4.setAngle(p4.angle() + gStyle.gradientAngle);
3656 item->setDiamondGeometry(FPoint(p1.p2().x(), p1.p2().y()), FPoint(p2.p2().x(), p2.p2().y()), FPoint(p3.p2().x(), p3.p2().y()), FPoint(p4.p2().x(), p4.p2().y()), cp);
3657 item->GrType = Gradient_Diamond;
3658 }
3659 else if (gStyle.gradientType == "rectangular")
3660 {
3661 item->fill_gradient = VGradient(VGradient::radial);
3662 item->fill_gradient.clearStops();
3663 item->fill_gradient.setRepeatMethod( VGradient::none );
3664 const ScColor& gradC = m_Doc->PageColors[gStyle.gradientEndColor];
3665 QColor gradColor1 = ScColorEngine::getRGBColor(gradC, m_Doc);
3666 item->fill_gradient.addStop(gradColor1, 0.0, 0.5, 1.0, gStyle.gradientEndColor, gStyle.gradientEndShade);
3667 const ScColor& gradC2 = m_Doc->PageColors[gStyle.gradientStartColor];
3668 QColor gradColor2 = ScColorEngine::getRGBColor(gradC2, m_Doc);
3669 item->fill_gradient.addStop(gradColor2, 1.0 - gStyle.gradientBorder, 0.5, 1.0, gStyle.gradientStartColor, gStyle.gradientStartShade);
3670 if (gStyle.gradientBorder != 0)
3671 item->fill_gradient.addStop(ScColorEngine::getRGBColor(gradC2, m_Doc), 1.0, 0.5, 1.0, gStyle.gradientStartColor, gStyle.gradientStartShade);
3672 FPoint cp = FPoint(item->width() * gStyle.gradientCenterX, item->height()* gStyle.gradientCenterY);
3673 double gLenW = item->width() / 2.0;
3674 double gLenH = item->height() / 2.0;
3675
3676 QPointF P1 = QPointF(0.0, 0.0);
3677 QPointF P2 = QPointF(item->width(), 0.0);
3678 QPointF P3 = QPointF(item->width(), item->height());
3679 QPointF P4 = QPointF(0.0, item->height());
3680 QLineF L1 = QLineF(0.0, 0.0, item->width(), 0.0);
3681 L1.setAngle(-45);
3682 QLineF LCW = QLineF(0.0, item->height() / 2.0, item->width(), item->height() / 2.0);
3683 QPointF P5;
3684 LCW.intersects(L1, &P5);
3685 QPointF P6 = QPointF(item->width() - P5.x(), P5.y());
3686 QPolygonF pPoints;
3687 pPoints << P1 << P2 << P3 << P4 << P5 << P6;
3688 QTransform mat;
3689 pPoints.translate(-item->width() / 2.0, -item->height() / 2.0);
3690 mat.translate(item->width() * gStyle.gradientCenterX, item->height()* gStyle.gradientCenterY);
3691 mat.rotate(-gStyle.gradientAngle);
3692 mat.scale(1.0 - gStyle.gradientBorder, 1.0 - gStyle.gradientBorder);
3693 pPoints = mat.map(pPoints);
3694 P1 = pPoints[0];
3695 P2 = pPoints[1];
3696 P3 = pPoints[2];
3697 P4 = pPoints[3];
3698 P5 = pPoints[4];
3699 P6 = pPoints[5];
3700 /*
3701 QPointF cpL = QPointF(item->width() * gStyle.gradientCenterX, item->height()* gStyle.gradientCenterY);
3702 double lineLen = sqrt(gLenW * gLenW + gLenH * gLenH) * 2.0;
3703 QLineF iLineP1 = QLineF(cpL, P1);
3704 iLineP1.setLength(lineLen);
3705 P1 = intersectBoundingRect(item, iLineP1);
3706 QLineF iLineP2 = QLineF(cpL, P2);
3707 iLineP2.setLength(lineLen);
3708 P2 = intersectBoundingRect(item, iLineP2);
3709 QLineF iLineP3 = QLineF(cpL, P3);
3710 iLineP3.setLength(lineLen);
3711 P3 = intersectBoundingRect(item, iLineP3);
3712 QLineF iLineP4 = QLineF(cpL, P4);
3713 iLineP4.setLength(lineLen);
3714 P4 = intersectBoundingRect(item, iLineP4);
3715 item->setDiamondGeometry(FPoint(P1.x(), P1.y()), FPoint(P2.x(), P2.y()), FPoint(P3.x(), P3.y()), FPoint(P4.x(), P4.y()), cp);
3716 item->GrType = Gradient_Diamond;
3717 */
3718 /*
3719 item->meshGradientPatches.clear();
3720 meshGradientPatch patch1;
3721 meshPoint outer;
3722 outer.resetTo(FPoint(P1.x(), P1.y()));
3723 outer.transparency = 1.0;
3724 outer.shade = gStyle.gradientStartShade;
3725 outer.colorName = gStyle.gradientStartColor;
3726 outer.color = gradColor2;
3727 patch1.TL = outer;
3728 outer.resetTo(FPoint(P2.x(), P2.y()));
3729 patch1.TR = outer;
3730 meshPoint inner;
3731 inner.resetTo(FPoint(P6.x(), P6.y()));
3732 inner.transparency = 1.0;
3733 inner.shade = gStyle.gradientEndShade;
3734 inner.colorName = gStyle.gradientEndColor;
3735 inner.color = gradColor1;
3736 patch1.BR = inner;
3737 inner.resetTo(FPoint(P5.x(), P5.y()));
3738 patch1.BL = inner;
3739 item->meshGradientPatches.append(patch1);
3740
3741 outer.resetTo(FPoint(P2.x(), P2.y()));
3742 patch1.TL = outer;
3743 outer.resetTo(FPoint(P3.x(), P3.y()));
3744 patch1.TR = outer;
3745 inner.resetTo(FPoint(P6.x(), P6.y()));
3746 patch1.BL = inner;
3747 patch1.BR = inner;
3748 item->meshGradientPatches.append(patch1);
3749
3750 inner.resetTo(FPoint(P5.x(), P5.y()));
3751 patch1.TL = inner;
3752 inner.resetTo(FPoint(P6.x(), P6.y()));
3753 patch1.TR = inner;
3754 outer.resetTo(FPoint(P4.x(), P4.y()));
3755 patch1.BL = outer;
3756 outer.resetTo(FPoint(P3.x(), P3.y()));
3757 patch1.BR = outer;
3758 item->meshGradientPatches.append(patch1);
3759
3760 outer.resetTo(FPoint(P4.x(), P4.y()));
3761 patch1.BL = outer;
3762 outer.resetTo(FPoint(P1.x(), P1.y()));
3763 patch1.TL = outer;
3764 inner.resetTo(FPoint(P5.x(), P5.y()));
3765 patch1.BR = inner;
3766 patch1.TR = inner;
3767 item->meshGradientPatches.append(patch1);
3768 item->GrType = Gradient_PatchMesh;
3769 */
3770
3771 QLineF p1 = QLineF(cp.x(), cp.y(), cp.x() - gLenW, cp.y() - gLenH);
3772 p1.setAngle(p1.angle() + gStyle.gradientAngle);
3773 QLineF p2 = QLineF(cp.x(), cp.y(), cp.x() + gLenW, cp.y() - gLenH);
3774 p2.setAngle(p2.angle() + gStyle.gradientAngle);
3775 QLineF p3 = QLineF(cp.x(), cp.y(), cp.x() + gLenW, cp.y() + gLenH);
3776 p3.setAngle(p3.angle() + gStyle.gradientAngle);
3777 QLineF p4 = QLineF(cp.x(), cp.y(), cp.x() - gLenW, cp.y() + gLenH);
3778 p4.setAngle(p4.angle() + gStyle.gradientAngle);
3779 item->setDiamondGeometry(FPoint(p1.p2().x(), p1.p2().y()), FPoint(p2.p2().x(), p2.p2().y()), FPoint(p3.p2().x(), p3.p2().y()), FPoint(p4.p2().x(), p4.p2().y()), cp);
3780 item->GrType = Gradient_Diamond;
3781 }
3782 }
3783 else if (obState.fill_type == 3)
3784 {
3785 ObjStyle gStyle;
3786 resovleStyle(gStyle, obState.patternName);
3787 QString patternName = "Pattern_" + obState.patternName;
3788 if (m_Doc->docPatterns.contains(patternName))
3789 {
3790 ScPattern pat = m_Doc->docPatterns[patternName];
3791 double sy = 100.0;
3792 double sx = 100.0;
3793 double dx = 0;
3794 double dy = 0;
3795 if (obState.patternStretch == "stretch")
3796 {
3797 sx = item->width() / pat.width * 100;
3798 sy = item->height() / pat.height * 100;
3799 }
3800 else
3801 {
3802 if (obState.patternDim_H_in_Percent)
3803 sy = obState.patternHeight * 100.0;
3804 else
3805 {
3806 if (obState.patternHeight > 0.0)
3807 sy = obState.patternHeight / pat.height * 100.0;
3808 }
3809 if (obState.patternDim_W_in_Percent)
3810 sx = obState.patternWidth * 100.0;
3811 else
3812 {
3813 if (obState.patternWidth > 0.0)
3814 sx = obState.patternWidth / pat.width * 100.0;
3815 }
3816 if (obState.patternX > 0.0)
3817 dx = pat.width * obState.patternX;
3818 if (obState.patternY > 0.0)
3819 dy = pat.height * obState.patternY;
3820 }
3821 item->setPatternTransform(sx, sy, dx, dy, 0, 0, 0);
3822 item->setPattern(patternName);
3823 item->GrType = Gradient_Pattern;
3824 }
3825 else
3826 {
3827 if (!gStyle.patternPath.isEmpty())
3828 {
3829 QByteArray f;
3830 if (uz->read(gStyle.patternPath, f))
3831 {
3832 QFileInfo fi(gStyle.patternPath);
3833 QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_odg_XXXXXX." + fi.suffix());
3834 tempFile->setAutoRemove(false);
3835 if (tempFile->open())
3836 {
3837 QString fileName = getLongPathName(tempFile->fileName());
3838 if (!fileName.isEmpty())
3839 {
3840 tempFile->write(f);
3841 tempFile->close();
3842 ScPattern pat = ScPattern();
3843 pat.setDoc(m_Doc);
3844 int z = m_Doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, 0, 0, 1, 1, 0, CommonStrings::None, CommonStrings::None);
3845 PageItem* newItem = m_Doc->Items->at(z);
3846 m_Doc->loadPict(fileName, newItem);
3847 m_Doc->Items->takeAt(z);
3848 newItem->isInlineImage = true;
3849 newItem->isTempFile = true;
3850 pat.width = newItem->pixm.qImage().width();
3851 pat.height = newItem->pixm.qImage().height();
3852 pat.scaleX = (72.0 / newItem->pixm.imgInfo.xres) * newItem->pixm.imgInfo.lowResScale;
3853 pat.scaleY = (72.0 / newItem->pixm.imgInfo.xres) * newItem->pixm.imgInfo.lowResScale;
3854 pat.pattern = newItem->pixm.qImage().copy();
3855 newItem->setWidth(pat.pattern.width());
3856 newItem->setHeight(pat.pattern.height());
3857 newItem->SetRectFrame();
3858 newItem->gXpos = 0.0;
3859 newItem->gYpos = 0.0;
3860 newItem->gWidth = pat.pattern.width();
3861 newItem->gHeight = pat.pattern.height();
3862 pat.items.append(newItem);
3863 patternName = patternName.trimmed().simplified().replace(" ", "_");
3864 m_Doc->addPattern(patternName, pat);
3865 item->setPattern(patternName);
3866 double sy = 100.0;
3867 double sx = 100.0;
3868 double dx = 0;
3869 double dy = 0;
3870 if (obState.patternStretch == "stretch")
3871 {
3872 sx = item->width() / pat.width * 100;
3873 sy = item->height() / pat.height * 100;
3874 }
3875 else
3876 {
3877 if (obState.patternDim_H_in_Percent)
3878 sy = obState.patternHeight * 100.0;
3879 else
3880 {
3881 if (obState.patternHeight > 0.0)
3882 sy = obState.patternHeight / pat.height * 100.0;
3883 }
3884 if (obState.patternDim_W_in_Percent)
3885 sx = obState.patternWidth * 100.0;
3886 else
3887 {
3888 if (obState.patternWidth > 0.0)
3889 sx = obState.patternWidth / pat.width * 100.0;
3890 }
3891 if (obState.patternX > 0.0)
3892 dx = pat.width * obState.patternX;
3893 if (obState.patternY > 0.0)
3894 dy = pat.height * obState.patternY;
3895 }
3896 item->setPatternTransform(sx, sy, dx, dy, 0, 0, 0);
3897 item->GrType = Gradient_Pattern;
3898 }
3899 }
3900 delete tempFile;
3901 }
3902 }
3903 else if (!gStyle.patternData.isEmpty())
3904 {
3905 QString ext = "";
3906 QByteArray buf = QByteArray::fromBase64(gStyle.patternData);
3907 if ((buf[0] == '%') && (buf[1] == '!') && (buf[2] == 'P') && (buf[3] == 'S') && (buf[4] == '-') && (buf[5] == 'A'))
3908 ext = "eps";
3909 else if ((buf[0] == '\xC5') && (buf[1] == '\xD0') && (buf[2] == '\xD3') && (buf[3] == '\xC6'))
3910 ext = "eps";
3911 else if ((buf[0] == 'G') && (buf[1] == 'I') && (buf[2] == 'F') && (buf[3] == '8'))
3912 ext = "gif";
3913 else if ((buf[0] == '\xFF') && (buf[1] == '\xD8') && (buf[2] == '\xFF'))
3914 ext = "jpg";
3915 else if ((buf[0] == 'P') && (buf[1] == 'G') && (buf[2] == 'F'))
3916 ext = "pgf";
3917 else if ((buf[0] == '\x89') && (buf[1] == 'P') && (buf[2] == 'N') && (buf[3] == 'G'))
3918 ext = "png";
3919 else if ((buf[0] == '8') && (buf[1] == 'B') && (buf[2] == 'P') && (buf[3] == 'S'))
3920 ext = "psd";
3921 else if (((buf[0] == 'I') && (buf[1] == 'I') && (buf[2] == '\x2A')) || ((buf[0] == 'M') && (buf[1] == 'M') && (buf[3] == '\x2A')))
3922 ext = "tif";
3923 else if ((buf[0] == '/') && (buf[1] == '*') && (buf[2] == ' ') && (buf[3] == 'X') && (buf[4] == 'P') && (buf[5] == 'M'))
3924 ext = "xpm";
3925 else if ((buf[0] == 'V') && (buf[1] == 'C') && (buf[2] == 'L') && (buf[3] == 'M') && (buf[4] == 'T') && (buf[5] == 'F'))
3926 ext = "svm";
3927 if (!ext.isEmpty())
3928 {
3929 QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_odg_XXXXXX." + ext);
3930 tempFile->setAutoRemove(false);
3931 if (tempFile->open())
3932 {
3933 QString fileName = getLongPathName(tempFile->fileName());
3934 if (!fileName.isEmpty())
3935 {
3936 tempFile->write(buf);
3937 tempFile->close();
3938 ScPattern pat = ScPattern();
3939 pat.setDoc(m_Doc);
3940 int z = m_Doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, 0, 0, 1, 1, 0, CommonStrings::None, CommonStrings::None);
3941 PageItem* newItem = m_Doc->Items->at(z);
3942 m_Doc->loadPict(fileName, newItem);
3943 m_Doc->Items->takeAt(z);
3944 newItem->isInlineImage = true;
3945 newItem->isTempFile = true;
3946 pat.width = newItem->pixm.qImage().width();
3947 pat.height = newItem->pixm.qImage().height();
3948 pat.scaleX = (72.0 / newItem->pixm.imgInfo.xres) * newItem->pixm.imgInfo.lowResScale;
3949 pat.scaleY = (72.0 / newItem->pixm.imgInfo.xres) * newItem->pixm.imgInfo.lowResScale;
3950 pat.pattern = newItem->pixm.qImage().copy();
3951 newItem->setWidth(pat.pattern.width());
3952 newItem->setHeight(pat.pattern.height());
3953 newItem->SetRectFrame();
3954 newItem->gXpos = 0.0;
3955 newItem->gYpos = 0.0;
3956 newItem->gWidth = pat.pattern.width();
3957 newItem->gHeight = pat.pattern.height();
3958 pat.items.append(newItem);
3959 patternName = patternName.trimmed().simplified().replace(" ", "_");
3960 m_Doc->addPattern(patternName, pat);
3961 item->setPattern(patternName);
3962 double sy = 100.0;
3963 double sx = 100.0;
3964 double dx = 0;
3965 double dy = 0;
3966 if (obState.patternStretch == "stretch")
3967 {
3968 sx = item->width() / pat.width * 100;
3969 sy = item->height() / pat.height * 100;
3970 }
3971 else
3972 {
3973 if (obState.patternDim_H_in_Percent)
3974 sy = obState.patternHeight * 100.0;
3975 else
3976 {
3977 if (obState.patternHeight > 0.0)
3978 sy = obState.patternHeight / pat.height * 100.0;
3979 }
3980 if (obState.patternDim_W_in_Percent)
3981 sx = obState.patternWidth * 100.0;
3982 else
3983 {
3984 if (obState.patternWidth > 0.0)
3985 sx = obState.patternWidth / pat.width * 100.0;
3986 }
3987 if (obState.patternX > 0.0)
3988 dx = pat.width * obState.patternX;
3989 if (obState.patternY > 0.0)
3990 dy = pat.height * obState.patternY;
3991 }
3992 item->setPatternTransform(sx, sy, dx, dy, 0, 0, 0);
3993 item->GrType = Gradient_Pattern;
3994 }
3995 }
3996 delete tempFile;
3997 }
3998 }
3999 }
4000 }
4001 else if (obState.fill_type == 4)
4002 {
4003 ObjStyle gStyle;
4004 resovleStyle(gStyle, obState.hatchName);
4005 int hatchS = 0;
4006 if (gStyle.hatchStyle == "double")
4007 hatchS = 1;
4008 else if (gStyle.hatchStyle == "triple")
4009 hatchS = 2;
4010 item->setHatchParameters(hatchS, gStyle.hatchDistance, gStyle.hatchRotation, obState.hatchSolidFill, obState.currColorFill, gStyle.hatchColor);
4011 item->GrType = Gradient_Hatch;
4012 }
4013 if (!obState.opacityName.isEmpty())
4014 {
4015 ObjStyle gStyle;
4016 resovleStyle(gStyle, obState.opacityName);
4017 if (gStyle.gradientType == "linear")
4018 {
4019 double angle = gStyle.gradientAngle + 90;
4020 VGradient maskGradient;
4021 maskGradient = VGradient(VGradient::linear);
4022 maskGradient.clearStops();
4023 maskGradient.setRepeatMethod( VGradient::none );
4024 maskGradient.addStop(ScColorEngine::getShadeColorProof(m_Doc->PageColors["Black"], m_Doc, gStyle.opacityStart), 0.0, 0.5, 1.0, "Black", gStyle.opacityStart);
4025 maskGradient.addStop(ScColorEngine::getShadeColorProof(m_Doc->PageColors["Black"], m_Doc, gStyle.opacityEnd), 1.0 - gStyle.gradientBorder, 0.5, 1.0, "Black", gStyle.opacityEnd);
4026 QLineF gradientVectorE;
4027 gradientVectorE.setP1(QPointF(item->width() / 2.0, item->height() / 2.0));
4028 gradientVectorE.setAngle(angle);
4029 gradientVectorE.setLength(sqrt(item->width() * item->width() + item->height() * item->height()) / 2.0 + 1.0);
4030 QPointF gradEnd = intersectBoundingRect(item, gradientVectorE);
4031 QLineF gradientVectorS;
4032 gradientVectorS.setP1(QPointF(item->width() / 2.0, item->height() / 2.0));
4033 gradientVectorS.setAngle(angle + 180);
4034 gradientVectorS.setLength(sqrt(item->width() * item->width() + item->height() * item->height()) / 2.0 + 1.0);
4035 QPointF gradStart = intersectBoundingRect(item, gradientVectorS);
4036 item->setMaskGradient(maskGradient);
4037 item->setMaskVector(gradStart.x(), gradStart.y(), gradEnd.x(), gradEnd.y(), gradStart.x(), gradStart.y(), 1, 0);
4038 item->setMaskType(4);
4039 }
4040 else if (gStyle.gradientType == "axial")
4041 {
4042 double angle = gStyle.gradientAngle + 90;
4043 VGradient maskGradient;
4044 maskGradient = VGradient(VGradient::linear);
4045 maskGradient.clearStops();
4046 maskGradient.setRepeatMethod( VGradient::none );
4047 maskGradient.addStop(ScColorEngine::getShadeColorProof(m_Doc->PageColors["Black"], m_Doc, gStyle.opacityEnd), 1.0 + (gStyle.gradientBorder / 2.0), 0.5, 1.0, "Black", gStyle.opacityEnd);
4048 maskGradient.addStop(ScColorEngine::getShadeColorProof(m_Doc->PageColors["Black"], m_Doc, gStyle.opacityStart), 0.0, 0.5, 1.0, "Black", gStyle.opacityStart);
4049 maskGradient.addStop(ScColorEngine::getShadeColorProof(m_Doc->PageColors["Black"], m_Doc, gStyle.opacityEnd), 1.0 - (gStyle.gradientBorder / 2.0), 0.5, 1.0, "Black", gStyle.opacityEnd);
4050 QLineF gradientVectorE;
4051 gradientVectorE.setP1(QPointF(item->width() / 2.0, item->height() / 2.0));
4052 gradientVectorE.setAngle(angle);
4053 gradientVectorE.setLength(sqrt(item->width() * item->width() + item->height() * item->height()) / 2.0 + 1.0);
4054 QPointF gradEnd = intersectBoundingRect(item, gradientVectorE);
4055 QLineF gradientVectorS;
4056 gradientVectorS.setP1(QPointF(item->width() / 2.0, item->height() / 2.0));
4057 gradientVectorS.setAngle(angle + 180);
4058 gradientVectorS.setLength(sqrt(item->width() * item->width() + item->height() * item->height()) / 2.0 + 1.0);
4059 QPointF gradStart = intersectBoundingRect(item, gradientVectorS);
4060 item->setMaskGradient(maskGradient);
4061 item->setMaskVector(gradStart.x(), gradStart.y(), gradEnd.x(), gradEnd.y(), gradStart.x(), gradStart.y(), 1, 0);
4062 item->setGradientType(4);
4063 }
4064 else if (gStyle.gradientType == "radial")
4065 {
4066 VGradient maskGradient;
4067 maskGradient = VGradient(VGradient::radial);
4068 maskGradient.clearStops();
4069 maskGradient.setRepeatMethod( VGradient::none );
4070 maskGradient.addStop(ScColorEngine::getShadeColorProof(m_Doc->PageColors["Black"], m_Doc, gStyle.opacityStart), 0.0, 0.5, 1.0, "Black", gStyle.opacityStart);
4071 maskGradient.addStop(ScColorEngine::getShadeColorProof(m_Doc->PageColors["Black"], m_Doc, gStyle.opacityEnd), 1.0 - gStyle.gradientBorder, 0.5, 1.0, "Black", gStyle.opacityEnd);
4072 double GrStartX = item->width() * gStyle.gradientCenterX;
4073 double GrStartY = item->height()* gStyle.gradientCenterY;
4074 double GrEndX = 0;
4075 double GrEndY = 0;
4076 if (item->width() >= item->height())
4077 {
4078 GrEndX = item->width();
4079 GrEndY = item->height() / 2.0;
4080 }
4081 else
4082 {
4083 GrEndX = item->width() / 2.0;
4084 GrEndY = item->height();
4085 }
4086 item->setMaskGradient(maskGradient);
4087 item->setMaskVector(GrStartX, GrStartY, GrEndX, GrEndY, GrStartX, GrStartY, 1, 0);
4088 item->setMaskType(5);
4089 }
4090 else if (gStyle.gradientType == "ellipsoid")
4091 {
4092 VGradient maskGradient;
4093 maskGradient = VGradient(VGradient::radial);
4094 maskGradient.clearStops();
4095 maskGradient.setRepeatMethod( VGradient::none );
4096 maskGradient.addStop(ScColorEngine::getShadeColorProof(m_Doc->PageColors["Black"], m_Doc, gStyle.opacityStart), 0.0, 0.5, 1.0, "Black", gStyle.opacityStart);
4097 maskGradient.addStop(ScColorEngine::getShadeColorProof(m_Doc->PageColors["Black"], m_Doc, gStyle.opacityEnd), 1.0 - gStyle.gradientBorder, 0.5, 1.0, "Black", gStyle.opacityEnd);
4098 double GrStartX = item->width() * gStyle.gradientCenterX;
4099 double GrStartY = item->height()* gStyle.gradientCenterY;
4100 double GrEndX = 0;
4101 double GrEndY = 0;
4102 if (item->width() >= item->height())
4103 {
4104 GrEndX = item->width();
4105 GrEndY = item->height() / 2.0;
4106 }
4107 else
4108 {
4109 GrEndX = item->width() / 2.0;
4110 GrEndY = item->height();
4111 }
4112 QLineF gradientVectorE = QLineF(GrStartX, GrStartY, GrEndX, GrEndY);
4113 gradientVectorE.setAngle(gStyle.gradientAngle);
4114 GrEndX = gradientVectorE.p2().x();
4115 GrEndY = gradientVectorE.p2().y();
4116 item->setMaskGradient(maskGradient);
4117 item->setMaskVector(GrStartX, GrStartY, GrEndX, GrEndY, GrStartX, GrStartY, 1, 0);
4118 item->setMaskType(5);
4119 }
4120 }
4121 if (obState.hasShadow)
4122 {
4123 item->setHasSoftShadow(true);
4124 item->setSoftShadowColor(obState.currColorShadow);
4125 item->setSoftShadowXOffset(obState.shadowX);
4126 item->setSoftShadowYOffset(obState.shadowY);
4127 item->setSoftShadowBlurRadius(0);
4128 item->setSoftShadowShade(100);
4129 item->setSoftShadowOpacity(obState.shadowTrans);
4130 item->setSoftShadowBlendMode(0);
4131 item->setSoftShadowErasedByObject(false);
4132 item->setSoftShadowHasObjectTransparency(false);
4133 }
4134 }
4135