Subversion Repositories Scribus

Rev

Rev 24137 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4430 cbradney 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
*/
16546 jghali 7
 
10223 cbradney 8
#include <QCursor>
9
#include <QDir>
16546 jghali 10
#include <QDrag>
10223 cbradney 11
#include <QDomElement>
16546 jghali 12
#include <QFile>
13
#include <QMessageBox>
9764 jghali 14
#include <QMimeData>
16546 jghali 15
#include <QString>
16
#include <QRegExp>
17
#include <QWidget>
766 cbradney 18
 
541 fschmid 19
#include "oodrawimp.h"
766 cbradney 20
 
2688 craig 21
#include "scconfig.h"
22
 
10862 cbradney 23
#include "commonstrings.h"
24
#include "fpointarray.h"
766 cbradney 25
#include "pageitem.h"
10862 cbradney 26
#include "pluginmanager.h"
27
#include "prefscontext.h"
28
#include "prefsfile.h"
2856 cbradney 29
#include "prefsmanager.h"
541 fschmid 30
#include "prefstable.h"
13466 cbradney 31
#include "scclocale.h"
10862 cbradney 32
#include "sccolorengine.h"
12841 jghali 33
#include "scmimedata.h"
10862 cbradney 34
#include "scraction.h"
35
#include "scribusXml.h"
36
#include "scribuscore.h"
37
#include "scribusdoc.h"
19093 craig 38
#include "scribusview.h"
3934 cbradney 39
#include "selection.h"
544 fschmid 40
#include "serializer.h"
10862 cbradney 41
#include "stylestack.h"
19093 craig 42
#include "third_party/zip/scribus_zip.h"
14170 jghali 43
#include "ui/customfdialog.h"
44
#include "ui/propertiespalette.h"
19605 jghali 45
#include "ui/scmessagebox.h"
19093 craig 46
#include "ui/scmwmenumanager.h"
1436 tsoots 47
#include "undomanager.h"
2529 craig 48
#include "util.h"
10203 cbradney 49
#include "util_math.h"
541 fschmid 50
 
10862 cbradney 51
 
19093 craig 52
 
541 fschmid 53
using namespace std;
54
 
3207 craig 55
int oodrawimp_getPluginAPIVersion()
541 fschmid 56
{
3207 craig 57
        return PLUGIN_API_VERSION;
541 fschmid 58
}
59
 
3207 craig 60
ScPlugin* oodrawimp_getPlugin()
541 fschmid 61
{
3207 craig 62
        OODrawImportPlugin* plug = new OODrawImportPlugin();
63
        Q_CHECK_PTR(plug);
64
        return plug;
541 fschmid 65
}
66
 
3207 craig 67
void oodrawimp_freePlugin(ScPlugin* plugin)
541 fschmid 68
{
24137 craig 69
        OODrawImportPlugin* plug = qobject_cast<OODrawImportPlugin*>(plugin);
3207 craig 70
        Q_ASSERT(plug);
71
        delete plug;
541 fschmid 72
}
73
 
3207 craig 74
OODrawImportPlugin::OODrawImportPlugin() :
17118 craig 75
        importAction(new ScrAction(ScrAction::DLL, "", QKeySequence(), this))
1208 cbradney 76
{
3207 craig 77
        // Set action info in languageChange, so we only have to do
3686 craig 78
        // it in one place. This includes registering file formats.
18227 fschmid 79
        registerFormats();
3207 craig 80
        languageChange();
5243 cbradney 81
}
18227 fschmid 82
 
3686 craig 83
OODrawImportPlugin::~OODrawImportPlugin()
84
{
85
        unregisterAll();
3696 craig 86
        // note: importAction is automatically deleted by Qt
18254 fschmid 87
}
3207 craig 88
 
89
void OODrawImportPlugin::languageChange()
1208 cbradney 90
{
10427 cbradney 91
        importAction->setText( tr("Import &OpenOffice.org Draw..."));
18816 fschmid 92
//      FileFormat* fmt = getFormatByExt("odg");
93
//      fmt->trName = tr("OpenDocument 1.0 Draw", "Import/export format name");
94
//      fmt->filter = tr("OpenDocument 1.0 Draw (*.odg *.ODG)");
18227 fschmid 95
        FileFormat* fmt2 = getFormatByExt("sxd");
96
        fmt2->trName = tr("OpenOffice.org 1.x Draw", "Import/export format name");
97
        fmt2->filter = tr("OpenOffice.org 1.x Draw (*.sxd *.SXD)");
1208 cbradney 98
}
99
 
23705 craig 100
QString OODrawImportPlugin::fullTrName() const
1208 cbradney 101
{
3207 craig 102
        return QObject::tr("OpenOffice.org Draw Importer");
1208 cbradney 103
}
104
 
3207 craig 105
const ScActionPlugin::AboutData* OODrawImportPlugin::getAboutData() const
1208 cbradney 106
{
3241 craig 107
        AboutData* about = new AboutData;
3344 fschmid 108
        about->authors = "Franz Schmid <franz@scribus.info>";
3540 cbradney 109
        about->shortDescription = tr("Imports OpenOffice.org Draw Files");
110
        about->description = tr("Imports most OpenOffice.org Draw files into the current document, converting their vector data into Scribus objects.");
3344 fschmid 111
        about->license = "GPL";
3241 craig 112
        Q_CHECK_PTR(about);
113
        return about;
1208 cbradney 114
}
115
 
3241 craig 116
void OODrawImportPlugin::deleteAboutData(const AboutData* about) const
1208 cbradney 117
{
3241 craig 118
        Q_ASSERT(about);
119
        delete about;
1208 cbradney 120
}
121
 
3686 craig 122
void OODrawImportPlugin::registerFormats()
3487 craig 123
{
18816 fschmid 124
//      QString odtName = tr("OpenDocument 1.0 Draw", "Import/export format name");
125
//      FileFormat odtformat(this);
126
//      odtformat.trName = odtName; // Human readable name
127
//      odtformat.formatId = 0;
128
//      odtformat.filter = odtName + " (*.odg *.ODG)"; // QFileDialog filter
129
//      odtformat.fileExtensions = QStringList() << "odg";
130
//      odtformat.load = true;
131
//      odtformat.save = false;
132
//      odtformat.thumb = true;
133
//      odtformat.mimeTypes = QStringList("application/vnd.oasis.opendocument.graphics"); // MIME types
134
//      odtformat.priority = 64; // Priority
135
//      registerFormat(odtformat);
3686 craig 136
 
3487 craig 137
        QString sxdName = tr("OpenOffice.org 1.x Draw", "Import/export format name");
4024 craig 138
        FileFormat sxdformat(this);
3643 craig 139
        sxdformat.trName = sxdName; // Human readable name
18297 fschmid 140
        sxdformat.formatId = 0;
4309 craig 141
        sxdformat.filter = sxdName + " (*.sxd *.SXD)"; // QFileDialog filter
14665 fschmid 142
        sxdformat.fileExtensions = QStringList() << "sxd";
3686 craig 143
        sxdformat.load = true;
144
        sxdformat.save = false;
14719 fschmid 145
        sxdformat.thumb = true;
3643 craig 146
        sxdformat.mimeTypes = QStringList("application/vnd.sun.xml.draw"); // MIME types
147
        sxdformat.priority = 64; // Priority
3686 craig 148
        registerFormat(sxdformat);
3487 craig 149
}
150
 
5642 cbradney 151
bool OODrawImportPlugin::fileSupported(QIODevice* /* file */, const QString & fileName) const
3487 craig 152
{
153
        // TODO: try to identify .sxd / .odt files
154
        return true;
155
}
156
 
5539 mrdocs 157
bool OODrawImportPlugin::loadFile(const QString & fileName, const FileFormat &, int flags, int /*index*/)
541 fschmid 158
{
3696 craig 159
        // For this plugin, right now "load" and "import" are the same thing
5539 mrdocs 160
        return import(fileName, flags);
3696 craig 161
}
162
 
5539 mrdocs 163
bool OODrawImportPlugin::import(QString fileName, int flags)
3696 craig 164
{
5539 mrdocs 165
        if (!checkFlags(flags))
166
                return false;
3207 craig 167
        if (fileName.isEmpty())
541 fschmid 168
        {
5539 mrdocs 169
                flags |= lfInteractive;
23060 craig 170
                PrefsContext* prefs = PrefsManager::instance().prefsFile->getPluginContext("OODrawImport");
541 fschmid 171
                QString wdir = prefs->get("wdir", ".");
18816 fschmid 172
                CustomFDialog diaf(ScCore->primaryMainWindow(), wdir, QObject::tr("Open"), QObject::tr("OpenOffice.org Draw (*.sxd *.SXD);;All Files (*)"));
541 fschmid 173
                if (diaf.exec())
174
                {
175
                        fileName = diaf.selectedFile();
10427 cbradney 176
                        prefs->set("wdir", fileName.left(fileName.lastIndexOf("/")));
541 fschmid 177
                }
178
                else
3207 craig 179
                        return true;
541 fschmid 180
        }
5781 cbradney 181
        m_Doc=ScCore->primaryMainWindow()->doc;
19420 jghali 182
        UndoTransaction activeTransaction;
22516 craig 183
        bool emptyDoc = (m_Doc == nullptr);
13378 jghali 184
        bool hasCurrentPage = (m_Doc && m_Doc->currentPage());
13371 jghali 185
        TransactionSettings trSettings;
13378 jghali 186
        trSettings.targetName   = hasCurrentPage ? m_Doc->currentPage()->getUName() : "";
13371 jghali 187
        trSettings.targetPixmap = Um::IImageFrame;
188
        trSettings.actionName   = Um::ImportOOoDraw;
189
        trSettings.description  = fileName;
190
        trSettings.actionPixmap = Um::IImportOOoDraw;
191
        OODPlug dia(m_Doc);
192
        if (emptyDoc || !(flags & lfInteractive) || !(flags & lfScripted))
1439 tsoots 193
                UndoManager::instance()->setUndoEnabled(false);
13371 jghali 194
        if (UndoManager::undoEnabled())
19420 jghali 195
                activeTransaction = UndoManager::instance()->beginTransaction(trSettings);
13371 jghali 196
        bool importDone = dia.import(fileName, trSettings, flags);
11576 avox 197
        if (activeTransaction)
19420 jghali 198
                activeTransaction.commit();
13371 jghali 199
        if (emptyDoc || !(flags & lfInteractive) || !(flags & lfScripted))
1439 tsoots 200
                UndoManager::instance()->setUndoEnabled(true);
7795 fschmid 201
        if (dia.importCanceled)
202
        {
203
                if ((!importDone) || (dia.importFailed))
19605 jghali 204
                        ScMessageBox::warning(ScCore->primaryMainWindow(), CommonStrings::trWarning, tr("The file could not be imported"));
7795 fschmid 205
                else if (dia.unsupported)
19605 jghali 206
                        ScMessageBox::warning(ScCore->primaryMainWindow(), CommonStrings::trWarning, tr("This file contains some unsupported features"));
7795 fschmid 207
        }
4463 cbradney 208
        return importDone;
541 fschmid 209
}
210
 
14719 fschmid 211
QImage OODrawImportPlugin::readThumbnail(const QString& fileName)
212
{
22721 jghali 213
        if (fileName.isEmpty())
14719 fschmid 214
                return QImage();
17747 craig 215
        UndoManager::instance()->setUndoEnabled(false);
22516 craig 216
        m_Doc = nullptr;
14719 fschmid 217
        OODPlug *dia = new OODPlug(m_Doc);
218
        Q_CHECK_PTR(dia);
219
        QImage ret = dia->readThumbnail(fileName);
17747 craig 220
        UndoManager::instance()->setUndoEnabled(true);
14719 fschmid 221
        delete dia;
222
        return ret;
223
}
224
 
5781 cbradney 225
OODPlug::OODPlug(ScribusDoc* doc)
541 fschmid 226
{
5781 cbradney 227
        m_Doc=doc;
7271 jghali 228
        unsupported = false;
4463 cbradney 229
        interactive = false;
7794 fschmid 230
        importFailed = false;
7795 fschmid 231
        importCanceled = true;
7991 fschmid 232
        importedColors.clear();
7580 cbradney 233
        tmpSel=new Selection(this, false);
4463 cbradney 234
}
235
 
22721 jghali 236
QImage OODPlug::readThumbnail(const QString& fileName)
14719 fschmid 237
{
238
        QByteArray f, f2, f3;
22721 jghali 239
        if (!QFile::exists(fileName))
14719 fschmid 240
                return QImage();
18913 fschmid 241
        ScZipHandler* fun = new ScZipHandler();
242
        if (!fun->open(fileName))
14719 fschmid 243
        {
18913 fschmid 244
                delete fun;
245
                return QImage();
14719 fschmid 246
        }
18913 fschmid 247
        if (fun->contains("styles.xml"))
248
                fun->read("styles.xml", f);
249
        if (fun->contains("content.xml"))
250
                fun->read("content.xml", f2);
251
        if (fun->contains("meta.xml"))
252
                fun->read("meta.xml", f3);
17170 fschmid 253
        delete fun;
18913 fschmid 254
        HaveMeta = inpMeta.setContent(f3);
255
        QString docname = fileName.right(fileName.length() - fileName.lastIndexOf("/") - 1);
256
        docname = docname.left(docname.lastIndexOf("."));
257
        if (f.isEmpty())
258
                return QImage();
259
        if (f2.isEmpty())
260
                return QImage();
22721 jghali 261
        if (!inpStyles.setContent(f))
17170 fschmid 262
                return QImage();
22721 jghali 263
        if (!inpContents.setContent(f2))
17170 fschmid 264
                return QImage();
14719 fschmid 265
        QString CurDirP = QDir::currentPath();
266
        QFileInfo efp(fileName);
267
        QDir::setCurrent(efp.path());
268
        bool isOODraw2 = false;
269
        QDomNode drawPagePNode;
270
        QList<PageItem*> Elements;
271
        createStyleMap( inpStyles );
272
        QDomElement docElem = inpContents.documentElement();
273
        QDomNode automaticStyles = docElem.namedItem( "office:automatic-styles" );
22721 jghali 274
        if (!automaticStyles.isNull())
14719 fschmid 275
                insertStyles( automaticStyles.toElement() );
276
        QDomNode body = docElem.namedItem( "office:body" );
277
        QDomNode drawPage = body.namedItem( "draw:page" );
22721 jghali 278
        if (drawPage.isNull())
14719 fschmid 279
        {
280
                QDomNode offDraw = body.namedItem( "office:drawing" );
281
                drawPage = offDraw.namedItem( "draw:page" );
282
                if (drawPage.isNull())
283
                        return QImage();
22609 craig 284
                isOODraw2 = true;
285
                drawPagePNode = body.namedItem( "office:drawing" );
14719 fschmid 286
        }
18816 fschmid 287
        else
14719 fschmid 288
                drawPagePNode = body;
289
        StyleStack::Mode mode = isOODraw2 ? StyleStack::OODraw2x : StyleStack::OODraw1x;
290
        m_styleStack.setMode( mode );
291
        QDomElement dp = drawPage.toElement();
292
        QDomElement *master = m_styles[dp.attribute( "draw:master-page-name" )];
22516 craig 293
        QDomElement *style = nullptr;
14719 fschmid 294
        QDomElement properties;
295
        if (isOODraw2)
296
        {
22516 craig 297
                style = m_styles.value(master->attribute( "style:page-layout-name" ), nullptr);
14719 fschmid 298
                if (style)
299
                        properties = style->namedItem("style:page-layout-properties" ).toElement();
300
        }
301
        else
302
        {
22516 craig 303
                style = m_styles.value(master->attribute( "style:page-master-name" ), nullptr);
14719 fschmid 304
                if (style)
305
                        properties = style->namedItem( "style:properties" ).toElement();
306
        }
307
        double width = !properties.attribute( "fo:page-width" ).isEmpty() ? parseUnit(properties.attribute( "fo:page-width" ) ) : 550.0;
308
        double height = !properties.attribute( "fo:page-height" ).isEmpty() ? parseUnit(properties.attribute( "fo:page-height" ) ) : 841.0;
309
        m_Doc = new ScribusDoc();
310
        m_Doc->setup(0, 1, 1, 1, 1, "Custom", "Custom");
311
        m_Doc->setPage(width, height, 0, 0, 0, 0, 0, 0, false, false);
312
        m_Doc->addPage(0);
22609 craig 313
        m_Doc->setGUI(false, ScCore->primaryMainWindow(), nullptr);
14719 fschmid 314
        Elements.clear();
315
        m_Doc->setLoading(true);
316
        m_Doc->DoDrawing = false;
14754 jghali 317
        m_Doc->scMW()->setScriptRunning(true);
14719 fschmid 318
        if (!m_Doc->PageColors.contains("Black"))
319
                m_Doc->PageColors.insert("Black", ScColor(0, 0, 0, 255));
320
        QDomNode drawPag = drawPagePNode.firstChild();
321
        QDomElement dpg = drawPag.toElement();
322
        m_styleStack.clear();
323
        fillStyleStack( dpg );
324
        QList<PageItem*> el = parseGroup( dpg );
325
        for (int ec = 0; ec < el.count(); ++ec)
326
                Elements.append(el.at(ec));
327
        tmpSel->clear();
328
        QImage tmpImage = QImage();
329
        if (Elements.count() > 0)
330
        {
16105 fschmid 331
                if (Elements.count() > 1)
332
                        m_Doc->groupObjectsList(Elements);
14719 fschmid 333
                m_Doc->DoDrawing = true;
334
                m_Doc->m_Selection->delaySignalsOn();
335
                for (int dre=0; dre<Elements.count(); ++dre)
336
                {
337
                        tmpSel->addItem(Elements.at(dre), true);
338
                }
339
                tmpSel->setGroupRect();
340
                double xs = tmpSel->width();
341
                double ys = tmpSel->height();
16504 fschmid 342
                tmpImage = Elements.at(0)->DrawObj_toImage(500);
14719 fschmid 343
                tmpImage.setText("XSize", QString("%1").arg(xs));
344
                tmpImage.setText("YSize", QString("%1").arg(ys));
345
                m_Doc->m_Selection->delaySignalsOff();
346
                m_Doc->setLoading(false);
347
        }
14754 jghali 348
        m_Doc->scMW()->setScriptRunning(false);
14719 fschmid 349
        delete m_Doc;
350
        QDir::setCurrent(CurDirP);
351
        return tmpImage;
352
}
353
 
22721 jghali 354
bool OODPlug::import(const QString& fileName, const TransactionSettings& trSettings, int flags)
4463 cbradney 355
{
356
        bool importDone = false;
5539 mrdocs 357
        interactive = (flags & LoadSavePlugin::lfInteractive);
12189 jghali 358
        QByteArray f, f2, f3;
22721 jghali 359
        if (!QFile::exists(fileName))
4463 cbradney 360
                return false;
18913 fschmid 361
        ScZipHandler* fun = new ScZipHandler();
362
        if (!fun->open(fileName))
541 fschmid 363
        {
18913 fschmid 364
                delete fun;
365
                return false;
541 fschmid 366
        }
18913 fschmid 367
        if (fun->contains("styles.xml"))
368
                fun->read("styles.xml", f);
369
        if (fun->contains("content.xml"))
370
                fun->read("content.xml", f2);
371
        if (fun->contains("meta.xml"))
372
                fun->read("meta.xml", f3);
17170 fschmid 373
        delete fun;
18913 fschmid 374
        HaveMeta = inpMeta.setContent(f3);
375
        QString docname = fileName.right(fileName.length() - fileName.lastIndexOf("/") - 1);
376
        docname = docname.left(docname.lastIndexOf("."));
377
        if (f.isEmpty())
378
                return false;
379
        if (f2.isEmpty())
380
                return false;
22721 jghali 381
        if (!inpStyles.setContent(f))
17170 fschmid 382
                return false;
22721 jghali 383
        if (!inpContents.setContent(f2))
17170 fschmid 384
                return false;
10398 cbradney 385
        QString CurDirP = QDir::currentPath();
541 fschmid 386
        QFileInfo efp(fileName);
10593 fschmid 387
        QDir::setCurrent(efp.path());
13371 jghali 388
        importDone = convert(trSettings, flags);
541 fschmid 389
        QDir::setCurrent(CurDirP);
4463 cbradney 390
        return importDone;
541 fschmid 391
}
392
 
13371 jghali 393
bool OODPlug::convert(const TransactionSettings& trSettings, int flags)
541 fschmid 394
{
395
        bool ret = false;
4590 cbradney 396
        bool isOODraw2 = false;
397
        QDomNode drawPagePNode;
544 fschmid 398
        int PageCounter = 0;
9856 fschmid 399
        QList<PageItem*> Elements;
541 fschmid 400
        createStyleMap( inpStyles );
401
        QDomElement docElem = inpContents.documentElement();
402
        QDomNode automaticStyles = docElem.namedItem( "office:automatic-styles" );
22721 jghali 403
        if (!automaticStyles.isNull() )
541 fschmid 404
                insertStyles( automaticStyles.toElement() );
405
        QDomNode body = docElem.namedItem( "office:body" );
406
        QDomNode drawPage = body.namedItem( "draw:page" );
22721 jghali 407
        if (drawPage.isNull())
4463 cbradney 408
        {
409
                QDomNode offDraw = body.namedItem( "office:drawing" );
410
                drawPage = offDraw.namedItem( "draw:page" );
411
                if (drawPage.isNull())
412
                {
19605 jghali 413
                        ScMessageBox::warning( m_Doc->scMW(), CommonStrings::trWarning, tr("This document does not seem to be an OpenOffice Draw file.") );
4463 cbradney 414
                        return false;
415
                }
22609 craig 416
                isOODraw2 = true;
417
                drawPagePNode = body.namedItem( "office:drawing" );
4463 cbradney 418
        }
18816 fschmid 419
        else
4590 cbradney 420
                drawPagePNode = body;
421
        StyleStack::Mode mode = isOODraw2 ? StyleStack::OODraw2x : StyleStack::OODraw1x;
422
        m_styleStack.setMode( mode );
541 fschmid 423
        QDomElement dp = drawPage.toElement();
424
        QDomElement *master = m_styles[dp.attribute( "draw:master-page-name" )];
22516 craig 425
        QDomElement *style = nullptr;
4590 cbradney 426
        QDomElement properties;
427
        if (isOODraw2)
428
        {
22516 craig 429
                style = m_styles.value(master->attribute( "style:page-layout-name" ), nullptr);
14017 jghali 430
                if (style)
431
                        properties = style->namedItem("style:page-layout-properties" ).toElement();
4590 cbradney 432
        }
433
        else
434
        {
22516 craig 435
                style = m_styles.value(master->attribute( "style:page-master-name" ), nullptr);
14017 jghali 436
                if (style)
437
                        properties = style->namedItem( "style:properties" ).toElement();
4590 cbradney 438
        }
541 fschmid 439
        double width = !properties.attribute( "fo:page-width" ).isEmpty() ? parseUnit(properties.attribute( "fo:page-width" ) ) : 550.0;
440
        double height = !properties.attribute( "fo:page-height" ).isEmpty() ? parseUnit(properties.attribute( "fo:page-height" ) ) : 841.0;
5539 mrdocs 441
        if (!interactive || (flags & LoadSavePlugin::lfInsertPage))
5781 cbradney 442
                m_Doc->setPage(width, height, 0, 0, 0, 0, 0, 0, false, false);
541 fschmid 443
        else
444
        {
5781 cbradney 445
                if (!m_Doc || (flags & LoadSavePlugin::lfCreateDoc))
541 fschmid 446
                {
5798 jghali 447
                        m_Doc=ScCore->primaryMainWindow()->doFileNew(width, height, 0, 0, 0, 0, 0, 0, false, false, 0, false, 0, 1, "Custom", true);
5781 cbradney 448
                        ScCore->primaryMainWindow()->HaveNewDoc();
541 fschmid 449
                        ret = true;
450
                }
451
        }
3207 craig 452
        if ((ret) || (!interactive))
550 fschmid 453
        {
454
                if (width > height)
14991 cbradney 455
                        m_Doc->setPageOrientation(1);
550 fschmid 456
                else
14991 cbradney 457
                        m_Doc->setPageOrientation(0);
458
                m_Doc->setPageSize("Custom");
550 fschmid 459
                QDomNode mpg;
460
                QDomElement metaElem = inpMeta.documentElement();
461
                QDomElement mp = metaElem.namedItem( "office:meta" ).toElement();
462
                mpg = mp.namedItem( "dc:title" );
463
                if (!mpg.isNull())
15037 cbradney 464
                        m_Doc->documentInfo().setTitle(mpg.toElement().text());
550 fschmid 465
                mpg = mp.namedItem( "meta:initial-creator" );
466
                if (!mpg.isNull())
15037 cbradney 467
                        m_Doc->documentInfo().setAuthor(mpg.toElement().text());
550 fschmid 468
                mpg = mp.namedItem( "dc:description" );
469
                if (!mpg.isNull())
15037 cbradney 470
                        m_Doc->documentInfo().setComments(mpg.toElement().text());
550 fschmid 471
                mpg = mp.namedItem( "dc:language" );
472
                if (!mpg.isNull())
15037 cbradney 473
                        m_Doc->documentInfo().setLangInfo(mpg.toElement().text());
550 fschmid 474
                mpg = mp.namedItem( "meta:creation-date" );
475
                if (!mpg.isNull())
15037 cbradney 476
                        m_Doc->documentInfo().setDate(mpg.toElement().text());
550 fschmid 477
                mpg = mp.namedItem( "dc:creator" );
478
                if (!mpg.isNull())
15037 cbradney 479
                        m_Doc->documentInfo().setContrib(mpg.toElement().text());
550 fschmid 480
                mpg = mp.namedItem( "meta:keywords" );
481
                if (!mpg.isNull())
482
                {
483
                        QString Keys = "";
22721 jghali 484
                        for (QDomNode n = mpg.firstChild(); !n.isNull(); n = n.nextSibling())
550 fschmid 485
                        {
10593 fschmid 486
                                Keys += n.toElement().text()+", ";
550 fschmid 487
                        }
488
                        if (Keys.length() > 2)
15037 cbradney 489
                                m_Doc->documentInfo().setKeywords(Keys.left(Keys.length()-2));
550 fschmid 490
                }
491
        }
16105 fschmid 492
        if (!(flags & LoadSavePlugin::lfLoadAsPattern))
23390 craig 493
                m_Doc->view()->deselectItems();
541 fschmid 494
        Elements.clear();
5781 cbradney 495
        m_Doc->setLoading(true);
496
        m_Doc->DoDrawing = false;
16105 fschmid 497
        if (!(flags & LoadSavePlugin::lfLoadAsPattern))
16016 fschmid 498
                m_Doc->view()->updatesOn(false);
14754 jghali 499
        m_Doc->scMW()->setScriptRunning(true);
18181 fschmid 500
        qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
5781 cbradney 501
        if (!m_Doc->PageColors.contains("Black"))
502
                m_Doc->PageColors.insert("Black", ScColor(0, 0, 0, 255));
22721 jghali 503
        for (QDomNode drawPag = drawPagePNode.firstChild(); !drawPag.isNull(); drawPag = drawPag.nextSibling())
541 fschmid 504
        {
505
                QDomElement dpg = drawPag.toElement();
3207 craig 506
                if (!interactive)
4025 cbradney 507
                {
5781 cbradney 508
                        m_Doc->addPage(PageCounter);
509
                        m_Doc->view()->addPage(PageCounter);
4025 cbradney 510
                }
545 fschmid 511
                PageCounter++;
541 fschmid 512
                m_styleStack.clear();
513
                fillStyleStack( dpg );
9856 fschmid 514
                QList<PageItem*> el = parseGroup( dpg );
515
                for (int ec = 0; ec < el.count(); ++ec)
8216 jghali 516
                        Elements.append(el.at(ec));
7234 fschmid 517
                if ((interactive) && (PageCounter == 1))
518
                        break;
541 fschmid 519
        }
7580 cbradney 520
        tmpSel->clear();
7691 fschmid 521
//      if ((Elements.count() > 1) && (interactive))
7794 fschmid 522
        if (Elements.count() == 0)
7991 fschmid 523
        {
7794 fschmid 524
                importFailed = true;
7991 fschmid 525
                if (importedColors.count() != 0)
526
                {
8613 cbradney 527
                        for (int cd = 0; cd < importedColors.count(); cd++)
7991 fschmid 528
                        {
529
                                m_Doc->PageColors.remove(importedColors[cd]);
530
                        }
531
                }
532
        }
7691 fschmid 533
        if (Elements.count() > 1)
16105 fschmid 534
                m_Doc->groupObjectsList(Elements);
5781 cbradney 535
        m_Doc->DoDrawing = true;
14754 jghali 536
        m_Doc->scMW()->setScriptRunning(false);
3207 craig 537
        if (interactive)
5781 cbradney 538
                m_Doc->setLoading(false);
9380 fschmid 539
        qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
3207 craig 540
        if ((Elements.count() > 0) && (!ret) && (interactive))
541 fschmid 541
        {
8262 fschmid 542
                if (flags & LoadSavePlugin::lfScripted)
541 fschmid 543
                {
8262 fschmid 544
                        bool loadF = m_Doc->isLoading();
545
                        m_Doc->setLoading(false);
546
                        m_Doc->changed();
547
                        m_Doc->setLoading(loadF);
16105 fschmid 548
                        if (!(flags & LoadSavePlugin::lfLoadAsPattern))
8262 fschmid 549
                        {
16016 fschmid 550
                                m_Doc->m_Selection->delaySignalsOn();
551
                                for (int dre=0; dre<Elements.count(); ++dre)
552
                                {
553
                                        m_Doc->m_Selection->addItem(Elements.at(dre), true);
554
                                }
555
                                m_Doc->m_Selection->delaySignalsOff();
556
                                m_Doc->m_Selection->setGroupRect();
557
                                m_Doc->view()->updatesOn(true);
8262 fschmid 558
                        }
559
                        importCanceled = false;
541 fschmid 560
                }
8262 fschmid 561
                else
562
                {
563
                        m_Doc->DragP = true;
22609 craig 564
                        m_Doc->DraggedElem = nullptr;
8262 fschmid 565
                        m_Doc->DragElements.clear();
11835 fschmid 566
                        m_Doc->m_Selection->delaySignalsOn();
9856 fschmid 567
                        for (int dre=0; dre<Elements.count(); ++dre)
8262 fschmid 568
                        {
569
                                tmpSel->addItem(Elements.at(dre), true);
570
                        }
571
                        tmpSel->setGroupRect();
22686 jghali 572
                        ScElemMimeData* md = ScriXmlDoc::writeToMimeData(m_Doc, tmpSel);
8262 fschmid 573
                        m_Doc->itemSelection_DeleteItem(tmpSel);
574
                        m_Doc->view()->updatesOn(true);
11835 fschmid 575
                        m_Doc->m_Selection->delaySignalsOff();
13371 jghali 576
                        // We must copy the TransationSettings object as it is owned
577
                        // by handleObjectImport method afterwards
578
                        TransactionSettings* transacSettings = new TransactionSettings(trSettings);
579
                        m_Doc->view()->handleObjectImport(md, transacSettings);
8262 fschmid 580
                        m_Doc->DragP = false;
22609 craig 581
                        m_Doc->DraggedElem = nullptr;
8262 fschmid 582
                        m_Doc->DragElements.clear();
7991 fschmid 583
                }
541 fschmid 584
        }
585
        else
586
        {
7351 fschmid 587
                bool loadF = m_Doc->isLoading();
588
                m_Doc->setLoading(false);
5781 cbradney 589
                m_Doc->changed();
6556 fschmid 590
                m_Doc->reformPages();
16105 fschmid 591
                if (!(flags & LoadSavePlugin::lfLoadAsPattern))
16016 fschmid 592
                        m_Doc->view()->updatesOn(true);
7351 fschmid 593
                m_Doc->setLoading(loadF);
541 fschmid 594
        }
18181 fschmid 595
        qApp->restoreOverrideCursor();
4463 cbradney 596
        return true;
541 fschmid 597
}
598
 
9856 fschmid 599
QList<PageItem*> OODPlug::parseGroup(const QDomElement &e)
541 fschmid 600
{
8216 jghali 601
        OODrawStyle oostyle;
541 fschmid 602
        FPointArray ImgClip;
9856 fschmid 603
        QList<PageItem*> elements, cElements;
16105 fschmid 604
//      double BaseX = m_Doc->currentPage()->xOffset();
605
//      double BaseY = m_Doc->currentPage()->yOffset();
8216 jghali 606
        storeObjectStyles(e);
607
        parseStyle(oostyle, e);
21951 craig 608
//      QString drawID = e.attribute("draw:name");
20561 jghali 609
//      int zn = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, BaseX, BaseY, 1, 1, 0, CommonStrings::None, CommonStrings::None);
16105 fschmid 610
//      PageItem *neu = m_Doc->Items->at(zn);
541 fschmid 611
        for (QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling())
612
        {
613
                QDomElement b = n.toElement();
22721 jghali 614
                if (b.isNull() )
541 fschmid 615
                        continue;
9856 fschmid 616
                QList<PageItem*> el = parseElement(b);
617
                for (int ec = 0; ec < el.count(); ++ec)
8216 jghali 618
                        cElements.append(el.at(ec));
619
        }
620
        if (cElements.count() < 2)
621
        {
9856 fschmid 622
                for (int gr = 0; gr < cElements.count(); ++gr)
541 fschmid 623
                {
8216 jghali 624
                        elements.append(cElements.at(gr));
541 fschmid 625
                }
8216 jghali 626
        }
627
        else
628
        {
16105 fschmid 629
                PageItem *neu = m_Doc->groupObjectsList(cElements);
8216 jghali 630
                elements.append(neu);
22721 jghali 631
                if (!e.attribute("id").isEmpty() )
8216 jghali 632
                        neu->setItemName(e.attribute("id"));
633
                else
16105 fschmid 634
                        neu->setItemName( tr("Group%1").arg(m_Doc->GroupCounter));
8216 jghali 635
        }
636
        return elements;
637
}
638
 
9856 fschmid 639
QList<PageItem*> OODPlug::parseElement(const QDomElement &e)
8216 jghali 640
{
9856 fschmid 641
        QList<PageItem*> GElements;
8216 jghali 642
        QString STag = e.tagName();
22721 jghali 643
        if (STag == "draw:g")
8216 jghali 644
        {
645
                GElements = parseGroup(e);
646
                return GElements;
647
        }
22721 jghali 648
        if (STag == "draw:rect")
8216 jghali 649
                GElements = parseRect(e);
22721 jghali 650
        else if (STag == "draw:circle" || STag == "draw:ellipse")
8216 jghali 651
                GElements = parseEllipse(e);
22721 jghali 652
        else if (STag == "draw:line")
8216 jghali 653
                GElements = parseLine(e);
22721 jghali 654
        else if (STag == "draw:polygon")
8216 jghali 655
                GElements = parsePolygon(e);
22721 jghali 656
        else if (STag == "draw:polyline")
8216 jghali 657
                GElements = parsePolyline(e);
22721 jghali 658
        else if (STag == "draw:path")
8216 jghali 659
                GElements = parsePath(e);
22721 jghali 660
        else if (STag == "draw:text-box")
8216 jghali 661
                GElements = parseTextBox(e);
22721 jghali 662
        else if (STag == "draw:frame")
8216 jghali 663
                GElements = parseFrame(e);
22721 jghali 664
        else if (STag == "draw:connector")
8222 jghali 665
                GElements = parseConnector(e);
8216 jghali 666
        else
667
        {
668
                // warn if unsupported feature are encountered
669
                unsupported = true;
10493 fschmid 670
                qDebug("Not supported yet: %s", STag.toLocal8Bit().data());
8216 jghali 671
        }
672
        return GElements;
673
}
674
 
9856 fschmid 675
QList<PageItem*> OODPlug::parseRect(const QDomElement &e)
8216 jghali 676
{
677
        OODrawStyle style;
9856 fschmid 678
        QList<PageItem*> elements;
8216 jghali 679
        double BaseX = m_Doc->currentPage()->xOffset();
680
        double BaseY = m_Doc->currentPage()->yOffset();
681
        double x = parseUnit(e.attribute("svg:x"));
682
        double y = parseUnit(e.attribute("svg:y")) ;
683
        double w = parseUnit(e.attribute("svg:width"));
684
        double h = parseUnit(e.attribute("svg:height"));
685
        double corner = parseUnit(e.attribute("draw:corner-radius"));
686
        storeObjectStyles(e);
687
        parseStyle(style, e);
20561 jghali 688
        int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, BaseX+x, BaseY+y, w, h, style.strokeWidth, style.fillColor, style.strokeColor);
8216 jghali 689
        PageItem* ite = m_Doc->Items->at(z);
690
        if (corner != 0)
691
        {
692
                ite->setCornerRadius(corner);
693
                ite->SetFrameRound();
694
                m_Doc->setRedrawBounding(ite);
695
        }
8278 jghali 696
        ite = finishNodeParsing(e, ite, style);
8216 jghali 697
        elements.append(ite);
698
        return elements;
699
}
700
 
9856 fschmid 701
QList<PageItem*> OODPlug::parseEllipse(const QDomElement &e)
8216 jghali 702
{
703
        OODrawStyle style;
9856 fschmid 704
        QList<PageItem*> elements;
8216 jghali 705
        double BaseX = m_Doc->currentPage()->xOffset();
706
        double BaseY = m_Doc->currentPage()->yOffset();
707
        double x = parseUnit(e.attribute("svg:x"));
708
        double y = parseUnit(e.attribute("svg:y")) ;
709
        double w = parseUnit(e.attribute("svg:width"));
710
        double h = parseUnit(e.attribute("svg:height"));
711
        storeObjectStyles(e);
712
        parseStyle(style, e);
20561 jghali 713
        int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, BaseX+x, BaseY+y, w, h, style.strokeWidth, style.fillColor, style.strokeColor);
8216 jghali 714
        PageItem* ite = m_Doc->Items->at(z);
8278 jghali 715
        ite = finishNodeParsing(e, ite, style);
8216 jghali 716
        elements.append(ite);
717
        return elements;
718
}
719
 
9856 fschmid 720
QList<PageItem*> OODPlug::parseLine(const QDomElement &e)
8216 jghali 721
{
722
        OODrawStyle style;
9856 fschmid 723
        QList<PageItem*> elements;
8216 jghali 724
        double BaseX = m_Doc->currentPage()->xOffset();
725
        double BaseY = m_Doc->currentPage()->yOffset();
726
        double x1 = e.attribute( "svg:x1" ).isEmpty() ? 0.0 : parseUnit( e.attribute( "svg:x1" ) );
727
        double y1 = e.attribute( "svg:y1" ).isEmpty() ? 0.0 : parseUnit( e.attribute( "svg:y1" ) );
728
        double x2 = e.attribute( "svg:x2" ).isEmpty() ? 0.0 : parseUnit( e.attribute( "svg:x2" ) );
729
        double y2 = e.attribute( "svg:y2" ).isEmpty() ? 0.0 : parseUnit( e.attribute( "svg:y2" ) );
730
        storeObjectStyles(e);
731
        parseStyle(style, e);
20561 jghali 732
        int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, BaseX, BaseY, 10, 10, style.strokeWidth, CommonStrings::None, style.strokeColor);
8216 jghali 733
        PageItem* ite = m_Doc->Items->at(z);
734
        ite->PoLine.resize(4);
735
        ite->PoLine.setPoint(0, FPoint(x1, y1));
736
        ite->PoLine.setPoint(1, FPoint(x1, y1));
737
        ite->PoLine.setPoint(2, FPoint(x2, y2));
738
        ite->PoLine.setPoint(3, FPoint(x2, y2));
739
        FPoint wh = getMaxClipF(&ite->PoLine);
740
        ite->setWidthHeight(wh.x(), wh.y());
741
        ite->ClipEdited = true;
742
        ite->FrameType = 3;
743
        if (!e.hasAttribute("draw:transform"))
744
        {
23040 jghali 745
                ite->Clip = flattenPath(ite->PoLine, ite->Segments);
20694 craig 746
                m_Doc->adjustItemSize(ite);
8216 jghali 747
        }
8278 jghali 748
        ite = finishNodeParsing(e, ite, style);
8216 jghali 749
        elements.append(ite);
750
        return elements;
751
}
752
 
9856 fschmid 753
QList<PageItem*> OODPlug::parsePolygon(const QDomElement &e)
8216 jghali 754
{
755
        OODrawStyle style;
9856 fschmid 756
        QList<PageItem*> elements;
8216 jghali 757
        double BaseX = m_Doc->currentPage()->xOffset();
758
        double BaseY = m_Doc->currentPage()->yOffset();
759
        storeObjectStyles(e);
760
        parseStyle(style, e);
20561 jghali 761
        int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, BaseX, BaseY, 10, 10, style.strokeWidth, style.fillColor, style.strokeColor);
8216 jghali 762
        PageItem* ite = m_Doc->Items->at(z);
763
        ite->PoLine.resize(0);
10414 jghali 764
        appendPoints(&ite->PoLine, e, true);
8216 jghali 765
        FPoint wh = getMaxClipF(&ite->PoLine);
766
        ite->setWidthHeight(wh.x(), wh.y());
767
        ite->ClipEdited = true;
768
        ite->FrameType = 3;
769
        if (!e.hasAttribute("draw:transform"))
770
        {
23040 jghali 771
                ite->Clip = flattenPath(ite->PoLine, ite->Segments);
20694 craig 772
                m_Doc->adjustItemSize(ite);
8216 jghali 773
        }
8278 jghali 774
        ite = finishNodeParsing(e, ite, style);
8216 jghali 775
        elements.append(ite);
776
        return elements;
777
}
778
 
9856 fschmid 779
QList<PageItem*> OODPlug::parsePolyline(const QDomElement &e)
8216 jghali 780
{
781
        OODrawStyle style;
9856 fschmid 782
        QList<PageItem*> elements;
8216 jghali 783
        double BaseX = m_Doc->currentPage()->xOffset();
784
        double BaseY = m_Doc->currentPage()->yOffset();
785
        storeObjectStyles(e);
786
        parseStyle(style, e);
20561 jghali 787
        int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, BaseX, BaseY, 10, 10, style.strokeWidth, CommonStrings::None, style.strokeColor);
8216 jghali 788
        PageItem* ite = m_Doc->Items->at(z);
789
        ite->PoLine.resize(0);
10414 jghali 790
        appendPoints(&ite->PoLine, e, false);
8216 jghali 791
        FPoint wh = getMaxClipF(&ite->PoLine);
792
        ite->setWidthHeight(wh.x(), wh.y());
793
        ite->ClipEdited = true;
794
        ite->FrameType = 3;
795
        if (!e.hasAttribute("draw:transform"))
796
        {
23040 jghali 797
                ite->Clip = flattenPath(ite->PoLine, ite->Segments);
20694 craig 798
                m_Doc->adjustItemSize(ite);
8216 jghali 799
        }
8278 jghali 800
        ite = finishNodeParsing(e, ite, style);
8216 jghali 801
        elements.append(ite);
802
        return elements;
803
}
804
 
9856 fschmid 805
QList<PageItem*> OODPlug::parsePath(const QDomElement &e)
8216 jghali 806
{
807
        OODrawStyle style;
808
        FPointArray pArray;
9856 fschmid 809
        QList<PageItem*> elements;
8216 jghali 810
        double BaseX = m_Doc->currentPage()->xOffset();
811
        double BaseY = m_Doc->currentPage()->yOffset();
812
        storeObjectStyles(e);
813
        parseStyle(style, e);
814
        PageItem::ItemType itype = parseSVG(e.attribute("svg:d"), &pArray) ? PageItem::PolyLine : PageItem::Polygon;
20561 jghali 815
        int z = m_Doc->itemAdd(itype, PageItem::Unspecified, BaseX, BaseY, 10, 10, style.strokeWidth, style.fillColor, style.strokeColor);
8216 jghali 816
        PageItem* ite = m_Doc->Items->at(z);
817
        ite->PoLine.resize(0);
818
        ite->PoLine = pArray;
819
        if (ite->PoLine.size() < 4)
820
        {
821
//              m_Doc->m_Selection->addItem(ite);
822
                tmpSel->addItem(ite);
823
//              m_Doc->itemSelection_DeleteItem();
824
                m_Doc->itemSelection_DeleteItem(tmpSel);
825
        }
826
        else
827
        {
13951 fschmid 828
                QTransform mat;
8216 jghali 829
                double x = parseUnit(e.attribute("svg:x"));
830
                double y = parseUnit(e.attribute("svg:y")) ;
831
                double w = parseUnit(e.attribute("svg:width"));
832
                double h = parseUnit(e.attribute("svg:height"));
833
                double vx = 0;
834
                double vy = 0;
835
                double vw = 1;
836
                double vh = 1;
837
                parseViewBox(e, &vx, &vy, &vw, &vh);
10938 jghali 838
                double sx = (vw != 0.0) ? (w / vw) : w;
839
                double sy = (vh != 0.0) ? (h / vh) : h;
8216 jghali 840
                mat.translate(x, y);
10938 jghali 841
                mat.scale(sx, sy);
8216 jghali 842
                ite->PoLine.map(mat);
843
                FPoint wh = getMaxClipF(&ite->PoLine);
844
                ite->setWidthHeight(wh.x(), wh.y());
845
                ite->ClipEdited = true;
846
                ite->FrameType = 3;
847
                if (!e.hasAttribute("draw:transform"))
544 fschmid 848
                {
23040 jghali 849
                        ite->Clip = flattenPath(ite->PoLine, ite->Segments);
20694 craig 850
                        m_Doc->adjustItemSize(ite);
544 fschmid 851
                }
8278 jghali 852
                ite = finishNodeParsing(e, ite, style);
8216 jghali 853
                elements.append(ite);
854
        }
855
        return elements;
856
}
857
 
9856 fschmid 858
QList<PageItem*> OODPlug::parseTextBox(const QDomElement &e)
8216 jghali 859
{
860
        OODrawStyle style;
9856 fschmid 861
        QList<PageItem*> elements;
8216 jghali 862
        double BaseX = m_Doc->currentPage()->xOffset();
863
        double BaseY = m_Doc->currentPage()->yOffset();
864
        double x = parseUnit(e.attribute("svg:x"));
865
        double y = parseUnit(e.attribute("svg:y")) ;
866
        double w = parseUnit(e.attribute("svg:width"));
867
        double h = parseUnit(e.attribute("svg:height"));
868
        storeObjectStyles(e);
869
        parseStyle(style, e);
20561 jghali 870
        int z = m_Doc->itemAdd(PageItem::TextFrame, PageItem::Unspecified, BaseX+x, BaseY+y, w, h+(h*0.1), style.strokeWidth, CommonStrings::None, style.strokeColor);
8216 jghali 871
        PageItem* ite = m_Doc->Items->at(z);
872
        ite->setFillColor(style.fillColor);
873
        ite->setLineColor(style.strokeColor);
8278 jghali 874
        ite = finishNodeParsing(e, ite, style);
8216 jghali 875
        elements.append(ite);
876
        return elements;
877
}
878
 
9856 fschmid 879
QList<PageItem*> OODPlug::parseFrame(const QDomElement &e)
8216 jghali 880
{
881
        OODrawStyle oostyle;
9856 fschmid 882
        QList<PageItem*> elements;
8216 jghali 883
        QString drawID = e.attribute("draw:name");
884
        double BaseX = m_Doc->currentPage()->xOffset();
885
        double BaseY = m_Doc->currentPage()->yOffset();
886
        double x = parseUnit(e.attribute("svg:x"));
887
        double y = parseUnit(e.attribute("svg:y")) ;
888
        double w = parseUnit(e.attribute("svg:width"));
889
        double h = parseUnit(e.attribute("svg:height"));
890
        storeObjectStyles(e);
891
        parseStyle(oostyle, e);
892
        QDomNode n = e.firstChild();
893
        QString STag2 = n.toElement().tagName();
22721 jghali 894
        if (STag2 == "draw:text-box")
8216 jghali 895
        {
20561 jghali 896
                int z = m_Doc->itemAdd(PageItem::TextFrame, PageItem::Unspecified, BaseX+x, BaseY+y, w, h+(h*0.1), oostyle.strokeWidth, CommonStrings::None, oostyle.strokeColor);
8216 jghali 897
                PageItem* ite = m_Doc->Items->at(z);
898
                ite->setTextToFrameDist(0.0, 0.0, 0.0, 0.0);
899
                ite->setFillTransparency(oostyle.fillTrans);
900
                ite->setLineTransparency(oostyle.strokeTrans);
11705 fschmid 901
                ite->setTextFlowMode(PageItem::TextFlowDisabled);
8216 jghali 902
                if (!drawID.isEmpty())
903
                        ite->setItemName(drawID);
8387 jghali 904
                ite = parseTextP(n.toElement(), ite);
8216 jghali 905
                elements.append(ite);
906
        }
907
        return elements;
908
}
909
 
9856 fschmid 910
QList<PageItem*> OODPlug::parseConnector(const QDomElement &e)
8222 jghali 911
{
9856 fschmid 912
        QList<PageItem*> elements;
8222 jghali 913
        if (e.hasAttribute("svg:x1") && e.hasAttribute("svg:x2") && e.hasAttribute("svg:y1") && e.hasAttribute("svg:y2"))
914
        {
915
                elements = parseLine(e);
916
        }
917
        else
918
        {
919
                unsupported = true;
920
                qDebug("an unsupported form of connector was found");
921
        }
922
        return elements;
923
}
924
 
8216 jghali 925
void OODPlug::parseStyle(OODrawStyle& oostyle, const QDomElement &e)
926
{
927
        oostyle.haveGradient = false;
928
        oostyle.gradient.clearStops();
22721 jghali 929
        if (m_styleStack.hasAttribute("draw:stroke") )
8216 jghali 930
        {
22721 jghali 931
                if (m_styleStack.attribute( "draw:stroke" ) == "none" )
8216 jghali 932
                        oostyle.strokeWidth = 0.0;
933
                else
544 fschmid 934
                {
22721 jghali 935
                        if (m_styleStack.hasAttribute("svg:stroke-width"))
548 fschmid 936
                        {
8216 jghali 937
                                oostyle.strokeWidth = parseUnit(m_styleStack.attribute("svg:stroke-width"));
938
                                if (oostyle.strokeWidth == 0)
939
                                        oostyle.strokeWidth = 1;
548 fschmid 940
                        }
22721 jghali 941
                        if (m_styleStack.hasAttribute("svg:stroke-color"))
8216 jghali 942
                                oostyle.strokeColor = parseColor(m_styleStack.attribute("svg:stroke-color"));
22721 jghali 943
                        if (m_styleStack.hasAttribute( "svg:stroke-opacity" ) )
18816 fschmid 944
                                oostyle.strokeTrans = 1.0 - ScCLocale::toDoubleC(m_styleStack.attribute( "svg:stroke-opacity" ).remove( '%' )) / 100.0;
22721 jghali 945
                        if (m_styleStack.attribute( "draw:stroke" ) == "dash" )
548 fschmid 946
                        {
8216 jghali 947
                                QString style = m_styleStack.attribute( "draw:stroke-dash" );
22721 jghali 948
                                if (style == "Ultrafine Dashed")
8216 jghali 949
                                        oostyle.dashes << 1.4 << 1.4;
22721 jghali 950
                                else if (style == "Fine Dashed" )
8216 jghali 951
                                        oostyle.dashes << 14.4 << 14.4;
22721 jghali 952
                                else if (style == "Fine Dotted")
8216 jghali 953
                                        oostyle.dashes << 13 << 13;
22721 jghali 954
                                else if (style == "Ultrafine 2 Dots 3 Dashes")
8216 jghali 955
                                        oostyle.dashes << 1.45 << 3.6 << 1.45 << 3.6 << 7.2 << 3.6 << 7.2 << 3.6 << 7.2 << 3.6;
22721 jghali 956
                                else if (style == "Line with Fine Dots")
548 fschmid 957
                                {
8216 jghali 958
                                        oostyle.dashes << 56.9 << 4.31;
959
                                        for (int dd = 0; dd < 10; ++ dd)
960
                                        {
961
                                                oostyle.dashes << 8.6 << 4.31;
962
                                        }
548 fschmid 963
                                }
22721 jghali 964
                                else if (style == "2 Dots 1 Dash" )
8216 jghali 965
                                        oostyle.dashes << 2.8 << 5.75 << 2.8 << 5.75 << 5.75 << 5.75;
544 fschmid 966
                        }
967
                }
8216 jghali 968
        }
22721 jghali 969
        if (m_styleStack.hasAttribute( "draw:fill" ) )
8216 jghali 970
        {
971
                QString fill = m_styleStack.attribute( "draw:fill" );
22721 jghali 972
                if (fill == "solid" )
544 fschmid 973
                {
22721 jghali 974
                        if (m_styleStack.hasAttribute( "draw:fill-color" ) )
8216 jghali 975
                                oostyle.fillColor = parseColor( m_styleStack.attribute("draw:fill-color"));
22721 jghali 976
                        if (m_styleStack.hasAttribute( "draw:transparency" ) )
18816 fschmid 977
                                oostyle.fillTrans = 1.0 - ScCLocale::toDoubleC(m_styleStack.attribute( "draw:transparency" ).remove( '%' )) / 100.0;
592 fschmid 978
                }
22721 jghali 979
                else if (fill == "gradient" )
7293 fschmid 980
                {
8216 jghali 981
                        oostyle.haveGradient = true;
982
                        oostyle.gradientAngle = 0;
983
                        oostyle.gradient.clearStops();
984
                        oostyle.gradient.setRepeatMethod( VGradient::none );
985
                        QString style = m_styleStack.attribute( "draw:fill-gradient-name" );
986
                        QDomElement* draw = m_draws[style];
22721 jghali 987
                        if (draw )
7293 fschmid 988
                        {
8216 jghali 989
                                double border = 0.0;
990
                                int shadeS = 100;
991
                                int shadeE = 100;
22721 jghali 992
                                if (draw->hasAttribute( "draw:border" ) )
13466 cbradney 993
                                        border += ScCLocale::toDoubleC(draw->attribute( "draw:border" ).remove( '%' )) / 100.0;
22721 jghali 994
                                if (draw->hasAttribute( "draw:start-intensity" ) )
8216 jghali 995
                                        shadeS = draw->attribute( "draw:start-intensity" ).remove( '%' ).toInt();
22721 jghali 996
                                if (draw->hasAttribute( "draw:end-intensity" ) )
8216 jghali 997
                                        shadeE = draw->attribute( "draw:end-intensity" ).remove( '%' ).toInt();
998
                                QString type = draw->attribute( "draw:style" );
22721 jghali 999
                                if (type == "linear" || type == "axial" )
7293 fschmid 1000
                                {
8216 jghali 1001
                                        oostyle.gradient.setType( VGradient::linear );
13466 cbradney 1002
                                        oostyle.gradientAngle = ScCLocale::toDoubleC(draw->attribute( "draw:angle" )) / 10;
8216 jghali 1003
                                        oostyle.gradientType = 1;
7293 fschmid 1004
                                }
22721 jghali 1005
                                else if (type == "radial" || type == "ellipsoid" )
8216 jghali 1006
                                {
22721 jghali 1007
                                        if (draw->hasAttribute( "draw:cx" ) )
13466 cbradney 1008
                                                oostyle.gradientPointX = ScCLocale::toDoubleC(draw->attribute( "draw:cx" ).remove( '%' )) / 100.0;
8216 jghali 1009
                                        else
1010
                                                oostyle.gradientPointX = 0.5;
22721 jghali 1011
                                        if (draw->hasAttribute( "draw:cy" ) )
13466 cbradney 1012
                                                oostyle.gradientPointY = ScCLocale::toDoubleC(draw->attribute( "draw:cy" ).remove( '%' )) / 100.0;
8216 jghali 1013
                                        else
1014
                                                oostyle.gradientPointY = 0.5;
1015
                                        oostyle.gradientType = 2;
1016
                                }
1017
                                QString c, c2;
1018
                                c = parseColor( draw->attribute( "draw:start-color" ) );
1019
                                c2 = parseColor( draw->attribute( "draw:end-color" ) );
1020
                                const ScColor& col1 = m_Doc->PageColors[c];
1021
                                const ScColor& col2 = m_Doc->PageColors[c2];
1022
                                if (((oostyle.gradientAngle > 90) && (oostyle.gradientAngle < 271)) || (oostyle.gradientType == 2))
1023
                                {
1024
                                        const ScColor& col1 = m_Doc->PageColors[c];
1025
                                        const ScColor& col2 = m_Doc->PageColors[c2];
18128 jghali 1026
                                        oostyle.gradient.addStop( ScColorEngine::getShadeColor(col2, m_Doc, shadeE), 0.0, 0.5, 1, c2, shadeE );
1027
                                        oostyle.gradient.addStop( ScColorEngine::getShadeColor(col1, m_Doc, shadeS), 1.0 - border, 0.5, 1, c, shadeS );
8216 jghali 1028
                                }
1029
                                else
1030
                                {
18128 jghali 1031
                                        oostyle.gradient.addStop( ScColorEngine::getShadeColor(col1, m_Doc, shadeS), border, 0.5, 1, c, shadeS );
1032
                                        oostyle.gradient.addStop( ScColorEngine::getShadeColor(col2, m_Doc, shadeE), 1.0, 0.5, 1, c2, shadeE );
8216 jghali 1033
                                }
7293 fschmid 1034
                        }
1035
                }
8216 jghali 1036
        }
1037
}
1038
 
8368 jghali 1039
void OODPlug::parseCharStyle(CharStyle& style, const QDomElement &e)
8216 jghali 1040
{
22721 jghali 1041
        if (m_styleStack.hasAttribute("fo:font-size"))
8368 jghali 1042
        {
1043
                QString fs = m_styleStack.attribute("fo:font-size").remove( "pt" );
13469 cbradney 1044
                int FontSize = (int) (ScCLocale::toFloatC(fs) * 10.0);
8368 jghali 1045
                style.setFontSize(FontSize);
1046
        }
1047
}
1048
 
1049
void OODPlug::parseParagraphStyle(ParagraphStyle& style, const QDomElement &e)
1050
{
22721 jghali 1051
        if (m_styleStack.hasAttribute("fo:text-align"))
8368 jghali 1052
        {
1053
                QString attValue = m_styleStack.attribute("fo:text-align");
1054
                if (attValue == "left")
23126 jghali 1055
                        style.setAlignment(ParagraphStyle::LeftAligned);
8368 jghali 1056
                if (attValue == "center")
1057
                        style.setAlignment(ParagraphStyle::Centered);
1058
                if (attValue == "right")
23126 jghali 1059
                        style.setAlignment(ParagraphStyle::RightAligned);
8368 jghali 1060
        }
22721 jghali 1061
        if (m_styleStack.hasAttribute("fo:font-size"))
8368 jghali 1062
        {
1063
                QString fs = m_styleStack.attribute("fo:font-size").remove( "pt" );
13469 cbradney 1064
                int FontSize = (int) (ScCLocale::toFloatC(fs) * 10.0);
8368 jghali 1065
                style.charStyle().setFontSize(FontSize);
1066
                style.setLineSpacing((FontSize + FontSize * 0.2) / 10.0);
1067
        }
1068
}
1069
 
1070
PageItem* OODPlug::parseTextP (const QDomElement& elm, PageItem* item)
1071
{
8216 jghali 1072
        for ( QDomNode n = elm.firstChild(); !n.isNull(); n = n.nextSibling() )
1073
        {
22721 jghali 1074
                if (!n.hasAttributes() && !n.hasChildNodes())
8216 jghali 1075
                        continue;
1076
                QDomElement e = n.toElement();
22721 jghali 1077
                if (e.text().isEmpty())
8216 jghali 1078
                        continue;
8368 jghali 1079
                storeObjectStyles(e);
8278 jghali 1080
                item->itemText.insertChars(-1, SpecialChars::PARSEP);
12189 jghali 1081
                item = parseTextSpans(e, item);
8368 jghali 1082
        }
1083
        return item;
1084
}
1085
 
1086
PageItem* OODPlug::parseTextSpans(const QDomElement& elm, PageItem* item)
1087
{
1088
        bool firstSpan = true;
1089
        for ( QDomNode n = elm.firstChild(); !n.isNull(); n = n.nextSibling() )
1090
        {
12189 jghali 1091
                QString chars;
8368 jghali 1092
                QDomElement e = n.toElement();
12189 jghali 1093
                if (n.isElement() && (e.tagName() == "text:span"))
1094
                {
1095
                        chars = e.text().simplified();
1096
                        storeObjectStyles(e);
1097
                }
1098
                if (n.isText())
1099
                {
1100
                        QDomText t = n.toText();
1101
                        chars = t.data().simplified();
1102
                }
1103
                if (chars.isEmpty())
8368 jghali 1104
                        continue;
1105
                int pos = item->itemText.length();
22721 jghali 1106
                if (firstSpan && (m_styleStack.hasAttribute("fo:text-align") || m_styleStack.hasAttribute("fo:font-size")))
8368 jghali 1107
                {
1108
                        ParagraphStyle newStyle;
12189 jghali 1109
                        parseParagraphStyle(newStyle, n.isElement() ? e : elm);
8278 jghali 1110
                        item->itemText.applyStyle(-1, newStyle);
592 fschmid 1111
                }
8368 jghali 1112
                item->itemText.insertChars( -2, chars);
22721 jghali 1113
                if (!firstSpan && m_styleStack.hasAttribute("fo:font-size"))
8368 jghali 1114
                {
1115
                        CharStyle newStyle;
12189 jghali 1116
                        parseCharStyle(newStyle, n.isElement() ? e : elm);
8368 jghali 1117
                        item->itemText.applyCharStyle(pos, chars.length(), newStyle);
1118
                }
23800 jghali 1119
                if (!item->isPolyLine() && !item->isTextFrame())
8278 jghali 1120
                        item = m_Doc->convertItemTo(item, PageItem::TextFrame);
8368 jghali 1121
                firstSpan = false;
8216 jghali 1122
        }
8368 jghali 1123
        return item;
1124
}
1125
 
1126
PageItem* OODPlug::finishNodeParsing(const QDomElement &elm, PageItem* item, OODrawStyle& oostyle)
1127
{
1128
        item->setTextToFrameDist(0.0, 0.0, 0.0, 0.0);
18843 fschmid 1129
        item->itemText.trim();
8405 fschmid 1130
//      bool firstPa = false;
8368 jghali 1131
        QString drawID = elm.attribute("draw:name");
1132
        item = parseTextP(elm, item);
8278 jghali 1133
        item->setFillTransparency(oostyle.fillTrans);
1134
        item->setLineTransparency(oostyle.strokeTrans);
8216 jghali 1135
        if (oostyle.dashes.count() != 0)
8278 jghali 1136
                item->DashValues = oostyle.dashes;
8216 jghali 1137
        if (!drawID.isEmpty())
8278 jghali 1138
                item->setItemName(drawID);
8216 jghali 1139
        if (elm.hasAttribute("draw:transform"))
1140
        {
8278 jghali 1141
                parseTransform(&item->PoLine, elm.attribute("draw:transform"));
1142
                item->ClipEdited = true;
1143
                item->FrameType = 3;
1144
                FPoint wh = getMaxClipF(&item->PoLine);
1145
                item->setWidthHeight(wh.x(), wh.y());
23040 jghali 1146
                item->Clip = flattenPath(item->PoLine, item->Segments);
20694 craig 1147
                m_Doc->adjustItemSize(item);
8216 jghali 1148
        }
8278 jghali 1149
        item->OwnPage = m_Doc->OnPage(item);
8216 jghali 1150
        //ite->setTextFlowMode(PageItem::TextFlowUsesFrameShape);
8278 jghali 1151
        item->setTextFlowMode(PageItem::TextFlowDisabled);
8216 jghali 1152
        if (oostyle.haveGradient)
1153
        {
8278 jghali 1154
                item->GrType = 0;
22725 jghali 1155
                if (oostyle.gradient.stops() > 1)
592 fschmid 1156
                {
8278 jghali 1157
                        item->fill_gradient = oostyle.gradient;
8216 jghali 1158
                        if (oostyle.gradientType == 1)
544 fschmid 1159
                        {
8216 jghali 1160
                                bool flipped = false;
1161
                                double gradientAngle(oostyle.gradientAngle);
1162
                                if ((gradientAngle == 0) || (gradientAngle == 180) || (gradientAngle == 90) || (gradientAngle == 270))
592 fschmid 1163
                                {
23904 jghali 1164
                                        item->GrType = Gradient_Linear;
8216 jghali 1165
                                        if ((gradientAngle == 0) || (gradientAngle == 180))
8048 avox 1166
                                        {
8278 jghali 1167
                                                item->GrStartX = item->width() / 2.0;
1168
                                                item->GrStartY = 0;
1169
                                                item->GrEndX = item->width() / 2.0;
1170
                                                item->GrEndY = item->height();
8048 avox 1171
                                        }
8216 jghali 1172
                                        else if ((gradientAngle == 90) || (gradientAngle == 270))
1173
                                        {
8278 jghali 1174
                                                item->GrStartX = 0;
1175
                                                item->GrStartY = item->height() / 2.0;
1176
                                                item->GrEndX = item->width();
1177
                                                item->GrEndY = item->height() / 2.0;
8216 jghali 1178
                                        }
547 fschmid 1179
                                }
8216 jghali 1180
                                else
545 fschmid 1181
                                {
8216 jghali 1182
                                        if ((gradientAngle > 90) && (gradientAngle < 270))
1183
                                                gradientAngle -= 180;
1184
                                        else if ((gradientAngle > 270) && (gradientAngle < 360))
546 fschmid 1185
                                        {
8216 jghali 1186
                                                gradientAngle = 360 - gradientAngle;
1187
                                                flipped = true;
7351 fschmid 1188
                                        }
8216 jghali 1189
                                        double xpos;
8278 jghali 1190
                                        xpos = (item->width() / 2) * tan(gradientAngle* M_PI / 180.0) * (item->height() / item->width()) + (item->width() / 2);
1191
                                        if ((xpos < 0) || (xpos > item->width()))
7351 fschmid 1192
                                        {
8278 jghali 1193
                                                xpos = (item->height() / 2)- (item->height() / 2) * tan(gradientAngle* M_PI / 180.0) * (item->height() / item->width());
8216 jghali 1194
                                                if (flipped)
546 fschmid 1195
                                                {
8278 jghali 1196
                                                        item->GrEndX = item->width();
1197
                                                        item->GrEndY = item->height() - xpos;
1198
                                                        item->GrStartX = 0;
1199
                                                        item->GrStartY = xpos;
546 fschmid 1200
                                                }
7351 fschmid 1201
                                                else
546 fschmid 1202
                                                {
8278 jghali 1203
                                                        item->GrEndY = xpos;
1204
                                                        item->GrEndX = item->width();
1205
                                                        item->GrStartX = 0;
1206
                                                        item->GrStartY = item->height() - xpos;
546 fschmid 1207
                                                }
1208
                                        }
8216 jghali 1209
                                        else
1210
                                        {
8278 jghali 1211
                                                item->GrEndX = xpos;
1212
                                                item->GrEndY = item->height();
1213
                                                item->GrStartX = item->width() - xpos;
1214
                                                item->GrStartY = 0;
8216 jghali 1215
                                        }
1216
                                        if (flipped)
1217
                                        {
8278 jghali 1218
                                                item->GrEndX = item->width() - xpos;
1219
                                                item->GrEndY = item->height();
1220
                                                item->GrStartX = xpos;
1221
                                                item->GrStartY = 0;
8216 jghali 1222
                                        }
23904 jghali 1223
                                        item->GrType = Gradient_Linear;
545 fschmid 1224
                                }
8216 jghali 1225
                        }
1226
                        if (oostyle.gradientType == 2)
1227
                        {
23904 jghali 1228
                                item->GrType = Gradient_Radial;
8278 jghali 1229
                                item->GrStartX = item->width() * oostyle.gradientPointX;
1230
                                item->GrStartY = item->height()* oostyle.gradientPointY;
1231
                                if (item->width() >= item->height())
8216 jghali 1232
                                {
8278 jghali 1233
                                        item->GrEndX = item->width();
1234
                                        item->GrEndY = item->height() / 2.0;
8216 jghali 1235
                                }
7351 fschmid 1236
                                else
592 fschmid 1237
                                {
8278 jghali 1238
                                        item->GrEndX = item->width() / 2.0;
1239
                                        item->GrEndY = item->height();
592 fschmid 1240
                                }
8216 jghali 1241
                                //m_Doc->view()->updateGradientVectors(ite);
8278 jghali 1242
                                item->updateGradientVectors();
545 fschmid 1243
                        }
541 fschmid 1244
                }
8216 jghali 1245
                else
1246
                {
10009 jghali 1247
                        QList<VColorStop*> cstops = oostyle.gradient.colorStops();
8278 jghali 1248
                        item->setFillColor(cstops.at(0)->name);
1249
                        item->setFillShade(cstops.at(0)->shade);
8216 jghali 1250
                }
541 fschmid 1251
        }
8278 jghali 1252
        return item;
541 fschmid 1253
}
1254
 
22721 jghali 1255
void OODPlug::createStyleMap( QDomDocument &docstyles)
541 fschmid 1256
{
1257
        QDomElement styles = docstyles.documentElement();
22721 jghali 1258
        if (styles.isNull())
541 fschmid 1259
                return;
1260
 
1261
        QDomNode fixedStyles = styles.namedItem( "office:styles" );
22721 jghali 1262
        if (!fixedStyles.isNull())
541 fschmid 1263
        {
545 fschmid 1264
                insertDraws( fixedStyles.toElement() );
541 fschmid 1265
                insertStyles( fixedStyles.toElement() );
1266
        }
1267
        QDomNode automaticStyles = styles.namedItem( "office:automatic-styles" );
22721 jghali 1268
        if (!automaticStyles.isNull())
541 fschmid 1269
                insertStyles( automaticStyles.toElement() );
1270
 
1271
        QDomNode masterStyles = styles.namedItem( "office:master-styles" );
22721 jghali 1272
        if (!masterStyles.isNull())
541 fschmid 1273
                insertStyles( masterStyles.toElement() );
1274
}
1275
 
22721 jghali 1276
void OODPlug::insertDraws(const QDomElement& styles)
545 fschmid 1277
{
22721 jghali 1278
        for (QDomNode n = styles.firstChild(); !n.isNull(); n = n.nextSibling())
545 fschmid 1279
        {
1280
                QDomElement e = n.toElement();
22721 jghali 1281
                if (!e.hasAttribute( "draw:name" ))
545 fschmid 1282
                        continue;
1283
                QString name = e.attribute( "draw:name" );
22721 jghali 1284
                m_draws.insert(name, new QDomElement(e) );
545 fschmid 1285
        }
1286
}
1287
 
541 fschmid 1288
void OODPlug::insertStyles( const QDomElement& styles )
1289
{
22721 jghali 1290
        for (QDomNode n = styles.firstChild(); !n.isNull(); n = n.nextSibling())
541 fschmid 1291
        {
1292
                QDomElement e = n.toElement();
22721 jghali 1293
                if (!e.hasAttribute( "style:name" ))
541 fschmid 1294
                        continue;
1295
                QString name = e.attribute( "style:name" );
22721 jghali 1296
                m_styles.insert(name, new QDomElement(e));
541 fschmid 1297
        }
1298
}
1299
 
1300
void OODPlug::fillStyleStack( const QDomElement& object )
1301
{
22721 jghali 1302
        if (object.hasAttribute( "presentation:style-name" ))
22516 craig 1303
                addStyles( m_styles.value(object.attribute( "presentation:style-name" ), nullptr) );
22721 jghali 1304
        if (object.hasAttribute( "draw:style-name" ))
22516 craig 1305
                addStyles( m_styles.value(object.attribute( "draw:style-name" ), nullptr) );
22721 jghali 1306
        if (object.hasAttribute( "draw:text-style-name" ))
22516 craig 1307
                addStyles( m_styles.value(object.attribute( "draw:text-style-name" ), nullptr) );
22721 jghali 1308
        if (object.hasAttribute( "text:style-name" ))
22516 craig 1309
                addStyles( m_styles.value(object.attribute( "text:style-name" ), nullptr) );
541 fschmid 1310
}
1311
 
22721 jghali 1312
void OODPlug::addStyles(const QDomElement* style)
541 fschmid 1313
{
14017 jghali 1314
        if (style)
1315
        {
22721 jghali 1316
                if (style->hasAttribute( "style:parent-style-name" ))
1317
                        addStyles(m_styles.value(style->attribute( "style:parent-style-name" ), nullptr));
1318
                m_styleStack.push(*style);
14017 jghali 1319
        }
541 fschmid 1320
}
1321
 
22721 jghali 1322
void OODPlug::storeObjectStyles(const QDomElement& object)
541 fschmid 1323
{
22721 jghali 1324
        fillStyleStack(object);
541 fschmid 1325
}
1326
 
1327
double OODPlug::parseUnit(const QString &unit)
1328
{
1329
        QString unitval=unit;
2877 cbradney 1330
        if (unit.isEmpty())
541 fschmid 1331
                return 0.0;
22721 jghali 1332
        if (unit.right( 2 ) == "pt")
541 fschmid 1333
                unitval.replace( "pt", "" );
22721 jghali 1334
        else if (unit.right( 2 ) == "cm")
541 fschmid 1335
                unitval.replace( "cm", "" );
22721 jghali 1336
        else if (unit.right( 2 ) == "mm")
541 fschmid 1337
                unitval.replace( "mm" , "" );
22721 jghali 1338
        else if (unit.right( 2 ) == "in")
541 fschmid 1339
                unitval.replace( "in", "" );
22721 jghali 1340
        else if (unit.right( 2 ) == "px")
541 fschmid 1341
                unitval.replace( "px", "" );
13466 cbradney 1342
        double value = ScCLocale::toDoubleC(unitval);
22721 jghali 1343
        if (unit.right( 2 ) == "pt")
19592 jghali 1344
                {}/* value = value; */ // no change
22721 jghali 1345
        else if (unit.right( 2 ) == "cm")
541 fschmid 1346
                value = ( value / 2.54 ) * 72;
22721 jghali 1347
        else if (unit.right( 2 ) == "mm")
541 fschmid 1348
                value = ( value / 25.4 ) * 72;
22721 jghali 1349
        else if (unit.right( 2 ) == "in")
541 fschmid 1350
                value = value * 72;
22721 jghali 1351
        else if (unit.right( 2 ) == "px")
19592 jghali 1352
                {}/* value = value; */ // no change
541 fschmid 1353
        return value;
1354
}
1355
 
1356
QString OODPlug::parseColor( const QString &s )
1357
{
1358
        QColor c;
4546 subik 1359
        QString ret = CommonStrings::None;
22721 jghali 1360
        if (s.startsWith( "rgb(" ))
541 fschmid 1361
        {
10394 cbradney 1362
                QString parse = s.trimmed();
24202 craig 1363
                QStringList colors = parse.split( ',', Qt::SkipEmptyParts );
541 fschmid 1364
                QString r = colors[0].right( ( colors[0].length() - 4 ) );
1365
                QString g = colors[1];
1366
                QString b = colors[2].left( ( colors[2].length() - 1 ) );
22721 jghali 1367
                if (r.contains( "%" ))
541 fschmid 1368
                {
15498 jghali 1369
                        r.chop(1);
13466 cbradney 1370
                        r = QString::number( static_cast<int>( ( static_cast<double>( 255 * ScCLocale::toDoubleC(r) ) / 100.0 ) ) );
541 fschmid 1371
                }
22721 jghali 1372
                if (g.contains( "%" ))
541 fschmid 1373
                {
15498 jghali 1374
                        g.chop(1);
13466 cbradney 1375
                        g = QString::number( static_cast<int>( ( static_cast<double>( 255 * ScCLocale::toDoubleC(g) ) / 100.0 ) ) );
541 fschmid 1376
                }
22721 jghali 1377
                if (b.contains( "%" ) )
541 fschmid 1378
                {
15498 jghali 1379
                        b.chop(1);
13466 cbradney 1380
                        b = QString::number( static_cast<int>( ( static_cast<double>( 255 * ScCLocale::toDoubleC(b) ) / 100.0 ) ) );
541 fschmid 1381
                }
1382
                c = QColor(r.toInt(), g.toInt(), b.toInt());
1383
        }
1384
        else
23131 craig 1385
                c.setNamedColor(s.trimmed());
1386
 
15771 fschmid 1387
        ScColor tmp;
1388
        tmp.fromQColor(c);
1389
        tmp.setSpotColor(false);
1390
        tmp.setRegistrationColor(false);
1391
        QString fNam = m_Doc->PageColors.tryAddColor("FromOODraw"+c.name(), tmp);
1392
        if (fNam == "FromOODraw"+c.name())
1393
                importedColors.append(fNam);
1394
        ret = fNam;
541 fschmid 1395
        return ret;
1396
}
1397
 
546 fschmid 1398
void OODPlug::parseTransform(FPointArray *composite, const QString &transform)
541 fschmid 1399
{
545 fschmid 1400
        double dx, dy;
13951 fschmid 1401
        QTransform result;
24202 craig 1402
        QStringList subtransforms = transform.split(')', Qt::SkipEmptyParts);
541 fschmid 1403
        QStringList::ConstIterator it = subtransforms.begin();
1404
        QStringList::ConstIterator end = subtransforms.end();
546 fschmid 1405
        for (; it != end; ++it)
541 fschmid 1406
        {
24202 craig 1407
                QStringList subtransform = (*it).split('(', Qt::SkipEmptyParts);
10398 cbradney 1408
                subtransform[0] = subtransform[0].trimmed().toLower();
10394 cbradney 1409
                subtransform[1] = subtransform[1].simplified();
541 fschmid 1410
                QRegExp reg("[,( ]");
24202 craig 1411
                QStringList params = subtransform[1].split(reg, Qt::SkipEmptyParts);
22721 jghali 1412
                if (subtransform[0].startsWith(";") || subtransform[0].startsWith(","))
541 fschmid 1413
                        subtransform[0] = subtransform[0].right(subtransform[0].length() - 1);
22721 jghali 1414
                if (subtransform[0] == "rotate")
546 fschmid 1415
                {
13951 fschmid 1416
                        result = QTransform();
1795 cbradney 1417
                        result.rotate(-parseUnit(params[0]) * 180 / M_PI);
546 fschmid 1418
                        composite->map(result);
1419
                }
22721 jghali 1420
                else if (subtransform[0] == "translate")
541 fschmid 1421
                {
22721 jghali 1422
                        if (params.count() == 2)
541 fschmid 1423
                        {
545 fschmid 1424
                                dx = parseUnit(params[0]);
1425
                                dy = parseUnit(params[1]);
541 fschmid 1426
                        }
1427
                        else
1428
                        {
545 fschmid 1429
                                dx = parseUnit(params[0]);
1430
                                dy =0.0;
541 fschmid 1431
                        }
13951 fschmid 1432
                        result = QTransform();
545 fschmid 1433
                        result.translate(dx, dy);
546 fschmid 1434
                        composite->map(result);
541 fschmid 1435
                }
22721 jghali 1436
                else if (subtransform[0] == "skewx")
546 fschmid 1437
                {
13951 fschmid 1438
                        result = QTransform();
13466 cbradney 1439
                        result.shear(-tan(ScCLocale::toDoubleC(params[0])), 0.0);
546 fschmid 1440
                        composite->map(result);
1441
                }
22721 jghali 1442
                else if (subtransform[0] == "skewy")
546 fschmid 1443
                {
13951 fschmid 1444
                        result = QTransform();
13466 cbradney 1445
                        result.shear(0.0, -tan(ScCLocale::toDoubleC(params[0])));
546 fschmid 1446
                        composite->map(result);
1447
                }
541 fschmid 1448
        }
1449
}
1450
 
22721 jghali 1451
void OODPlug::parseViewBox(const QDomElement& object, double *x, double *y, double *w, double *h)
541 fschmid 1452
{
22721 jghali 1453
        if (!object.attribute( "svg:viewBox" ).isEmpty())
544 fschmid 1454
        {
1455
                QString viewbox( object.attribute( "svg:viewBox" ) );
24202 craig 1456
                QStringList points = viewbox.replace( QRegExp(","), " ").simplified().split(' ', Qt::SkipEmptyParts);
13466 cbradney 1457
                *x = ScCLocale::toDoubleC(points[0]);
1458
                *y = ScCLocale::toDoubleC(points[1]);
1459
                *w = ScCLocale::toDoubleC(points[2]);
1460
                *h = ScCLocale::toDoubleC(points[3]);
544 fschmid 1461
        }
541 fschmid 1462
}
1463
 
10414 jghali 1464
void OODPlug::appendPoints(FPointArray *composite, const QDomElement& object, bool closePath)
541 fschmid 1465
{
544 fschmid 1466
        double x = parseUnit(object.attribute("svg:x"));
1467
        double y = parseUnit(object.attribute("svg:y")) ;
1468
        double w = parseUnit(object.attribute("svg:width"));
1469
        double h = parseUnit(object.attribute("svg:height"));
1470
        double vx = 0;
1471
        double vy = 0;
1472
        double vw = 1;
1473
        double vh = 1;
1474
        parseViewBox(object, &vx, &vy, &vw, &vh);
10938 jghali 1475
        double sx = (vw != 0.0) ? (w / vw) : w;
1476
        double sy = (vh != 0.0) ? (h / vh) : h;
24202 craig 1477
        QStringList ptList = object.attribute( "draw:points" ).split( ' ', Qt::SkipEmptyParts );
544 fschmid 1478
        FPoint point, firstP;
1479
        bool bFirst = true;
22721 jghali 1480
        for (QStringList::Iterator it = ptList.begin(); it != ptList.end(); ++it)
544 fschmid 1481
        {
13466 cbradney 1482
                point = FPoint(ScCLocale::toDoubleC((*it).section( ',', 0, 0 )), ScCLocale::toDoubleC((*it).section( ',', 1, 1 )));
544 fschmid 1483
                if (bFirst)
1484
                {
1485
                        composite->addPoint(point);
1486
                        composite->addPoint(point);
1487
                        firstP = point;
1488
                        bFirst = false;
1489
                }
1490
                else
1491
                {
1492
                        composite->addPoint(point);
1493
                        composite->addPoint(point);
1494
                        composite->addPoint(point);
1495
                        composite->addPoint(point);
1496
                }
20424 jghali 1497
        }
10414 jghali 1498
        if (closePath)
1499
        {
1500
                composite->addPoint(firstP);
1501
                composite->addPoint(firstP);
1502
        }
13951 fschmid 1503
        QTransform mat;
544 fschmid 1504
        mat.translate(x, y);
10938 jghali 1505
        mat.scale(sx, sy);
544 fschmid 1506
        composite->map(mat);
541 fschmid 1507
}
1508
 
544 fschmid 1509
const char * OODPlug::getCoord( const char *ptr, double &number )
541 fschmid 1510
{
1511
        int integer, exponent;
1512
        double decimal, frac;
1513
        int sign, expsign;
1514
 
1515
        exponent = 0;
1516
        integer = 0;
1517
        frac = 1.0;
1518
        decimal = 0;
1519
        sign = 1;
1520
        expsign = 1;
1521
 
544 fschmid 1522
        // read the sign
22721 jghali 1523
        if (*ptr == '+')
541 fschmid 1524
                ptr++;
22721 jghali 1525
        else if (*ptr == '-')
541 fschmid 1526
        {
1527
                ptr++;
1528
                sign = -1;
1529
        }
1530
 
544 fschmid 1531
        // read the integer part
22721 jghali 1532
        while (*ptr != '\0' && *ptr >= '0' && *ptr <= '9')
541 fschmid 1533
                integer = (integer * 10) + *(ptr++) - '0';
22721 jghali 1534
        if (*ptr == '.') // read the decimals
541 fschmid 1535
        {
1536
                ptr++;
22721 jghali 1537
                while (*ptr != '\0' && *ptr >= '0' && *ptr <= '9')
541 fschmid 1538
                        decimal += (*(ptr++) - '0') * (frac *= 0.1);
1539
        }
1540
 
22721 jghali 1541
        if (*ptr == 'e' || *ptr == 'E') // read the exponent part
541 fschmid 1542
        {
1543
                ptr++;
1544
 
544 fschmid 1545
                // read the sign of the exponent
22721 jghali 1546
                if (*ptr == '+')
541 fschmid 1547
                        ptr++;
22721 jghali 1548
                else if (*ptr == '-')
541 fschmid 1549
                {
1550
                        ptr++;
1551
                        expsign = -1;
1552
                }
1553
 
1554
                exponent = 0;
22721 jghali 1555
                while (*ptr != '\0' && *ptr >= '0' && *ptr <= '9')
541 fschmid 1556
                {
1557
                        exponent *= 10;
1558
                        exponent += *ptr - '0';
1559
                        ptr++;
1560
                }
1561
        }
1562
        number = integer + decimal;
1563
        number *= sign * pow( static_cast<double>(10), static_cast<double>( expsign * exponent ) );
1564
 
544 fschmid 1565
        // skip the following space
22721 jghali 1566
        if (*ptr == ' ')
541 fschmid 1567
                ptr++;
1568
 
1569
        return ptr;
1570
}
1571
 
22721 jghali 1572
bool OODPlug::parseSVG(const QString &s, FPointArray *ite)
541 fschmid 1573
{
1574
        QString d = s;
1575
        d = d.replace( QRegExp( "," ), " ");
1576
        bool ret = false;
22721 jghali 1577
        if (!d.isEmpty())
541 fschmid 1578
        {
10394 cbradney 1579
                d = d.simplified();
10868 jghali 1580
                QByteArray data = d.toLatin1();
1581
                const char *ptr = data.constData();
1582
                const char *end = data.constData() + data.length() + 1;
17034 jghali 1583
                double contrlx, contrly, curx, cury, tox, toy, x1, y1, x2, y2, xc, yc;
541 fschmid 1584
                double px1, py1, px2, py2, px3, py3;
1585
                bool relative;
1586
                FirstM = true;
1587
                char command = *(ptr++), lastCommand = ' ';
17034 jghali 1588
                curx = cury = contrlx = contrly = 0.0;
22721 jghali 1589
                while (ptr < end)
541 fschmid 1590
                {
22721 jghali 1591
                        if (*ptr == ' ')
541 fschmid 1592
                                ptr++;
1593
                        relative = false;
22721 jghali 1594
                        switch (command)
541 fschmid 1595
                        {
1596
                        case 'm':
1597
                                relative = true;
1598
                        case 'M':
1599
                                {
1600
                                        ptr = getCoord( ptr, tox );
1601
                                        ptr = getCoord( ptr, toy );
1602
                                        WasM = true;
17034 jghali 1603
                                        curx = relative ? curx + tox : tox;
1604
                                        cury = relative ? cury + toy : toy;
541 fschmid 1605
                                        svgMoveTo(curx, cury );
1606
                                        break;
1607
                                }
1608
                        case 'l':
1609
                                relative = true;
1610
                        case 'L':
1611
                                {
1612
                                        ptr = getCoord( ptr, tox );
1613
                                        ptr = getCoord( ptr, toy );
1614
                                        curx = relative ? curx + tox : tox;
1615
                                        cury = relative ? cury + toy : toy;
1616
                                        svgLineTo(ite, curx, cury );
1617
                                        break;
1618
                                }
1619
                        case 'h':
1620
                                {
1621
                                        ptr = getCoord( ptr, tox );
1622
                                        curx = curx + tox;
1623
                                        svgLineTo(ite, curx, cury );
1624
                                        break;
1625
                                }
1626
                        case 'H':
1627
                                {
1628
                                        ptr = getCoord( ptr, tox );
1629
                                        curx = tox;
1630
                                        svgLineTo(ite, curx, cury );
1631
                                        break;
1632
                                }
1633
                        case 'v':
1634
                                {
1635
                                        ptr = getCoord( ptr, toy );
1636
                                        cury = cury + toy;
1637
                                        svgLineTo(ite, curx, cury );
1638
                                        break;
1639
                                }
1640
                        case 'V':
1641
                                {
1642
                                        ptr = getCoord( ptr, toy );
1643
                                        cury = toy;
1644
                                        svgLineTo(ite,  curx, cury );
1645
                                        break;
1646
                                }
1647
                        case 'z':
1648
                        case 'Z':
1649
                                {
1650
                                        svgClosePath(ite);
1651
                                        break;
1652
                                }
1653
                        case 'c':
1654
                                relative = true;
1655
                        case 'C':
1656
                                {
1657
                                        ptr = getCoord( ptr, x1 );
1658
                                        ptr = getCoord( ptr, y1 );
1659
                                        ptr = getCoord( ptr, x2 );
1660
                                        ptr = getCoord( ptr, y2 );
1661
                                        ptr = getCoord( ptr, tox );
1662
                                        ptr = getCoord( ptr, toy );
1663
                                        px1 = relative ? curx + x1 : x1;
1664
                                        py1 = relative ? cury + y1 : y1;
1665
                                        px2 = relative ? curx + x2 : x2;
1666
                                        py2 = relative ? cury + y2 : y2;
1667
                                        px3 = relative ? curx + tox : tox;
1668
                                        py3 = relative ? cury + toy : toy;
1669
                                        svgCurveToCubic(ite, px1, py1, px2, py2, px3, py3 );
1670
                                        contrlx = relative ? curx + x2 : x2;
1671
                                        contrly = relative ? cury + y2 : y2;
1672
                                        curx = relative ? curx + tox : tox;
1673
                                        cury = relative ? cury + toy : toy;
1674
                                        break;
1675
                                }
1676
                        case 's':
1677
                                relative = true;
1678
                        case 'S':
1679
                                {
1680
                                        ptr = getCoord( ptr, x2 );
1681
                                        ptr = getCoord( ptr, y2 );
1682
                                        ptr = getCoord( ptr, tox );
1683
                                        ptr = getCoord( ptr, toy );
1684
                                        px1 = 2 * curx - contrlx;
1685
                                        py1 = 2 * cury - contrly;
1686
                                        px2 = relative ? curx + x2 : x2;
1687
                                        py2 = relative ? cury + y2 : y2;
1688
                                        px3 = relative ? curx + tox : tox;
1689
                                        py3 = relative ? cury + toy : toy;
1690
                                        svgCurveToCubic(ite, px1, py1, px2, py2, px3, py3 );
1691
                                        contrlx = relative ? curx + x2 : x2;
1692
                                        contrly = relative ? cury + y2 : y2;
1693
                                        curx = relative ? curx + tox : tox;
1694
                                        cury = relative ? cury + toy : toy;
1695
                                        break;
1696
                                }
1697
                        case 'q':
1698
                                relative = true;
1699
                        case 'Q':
1700
                                {
1701
                                        ptr = getCoord( ptr, x1 );
1702
                                        ptr = getCoord( ptr, y1 );
1703
                                        ptr = getCoord( ptr, tox );
1704
                                        ptr = getCoord( ptr, toy );
1705
                                        px1 = relative ? (curx + 2 * (x1 + curx)) * (1.0 / 3.0) : (curx + 2 * x1) * (1.0 / 3.0);
1706
                                        py1 = relative ? (cury + 2 * (y1 + cury)) * (1.0 / 3.0) : (cury + 2 * y1) * (1.0 / 3.0);
1707
                                        px2 = relative ? ((curx + tox) + 2 * (x1 + curx)) * (1.0 / 3.0) : (tox + 2 * x1) * (1.0 / 3.0);
1708
                                        py2 = relative ? ((cury + toy) + 2 * (y1 + cury)) * (1.0 / 3.0) : (toy + 2 * y1) * (1.0 / 3.0);
1709
                                        px3 = relative ? curx + tox : tox;
1710
                                        py3 = relative ? cury + toy : toy;
1711
                                        svgCurveToCubic(ite, px1, py1, px2, py2, px3, py3 );
1712
                                        contrlx = relative ? curx + x1 : (tox + 2 * x1) * (1.0 / 3.0);
1713
                                        contrly = relative ? cury + y1 : (toy + 2 * y1) * (1.0 / 3.0);
1714
                                        curx = relative ? curx + tox : tox;
1715
                                        cury = relative ? cury + toy : toy;
1716
                                        break;
1717
                                }
1718
                        case 't':
1719
                                relative = true;
1720
                        case 'T':
1721
                                {
1722
                                        ptr = getCoord(ptr, tox);
1723
                                        ptr = getCoord(ptr, toy);
1724
                                        xc = 2 * curx - contrlx;
1725
                                        yc = 2 * cury - contrly;
1726
                                        px1 = relative ? (curx + 2 * xc) * (1.0 / 3.0) : (curx + 2 * xc) * (1.0 / 3.0);
1727
                                        py1 = relative ? (cury + 2 * yc) * (1.0 / 3.0) : (cury + 2 * yc) * (1.0 / 3.0);
1728
                                        px2 = relative ? ((curx + tox) + 2 * xc) * (1.0 / 3.0) : (tox + 2 * xc) * (1.0 / 3.0);
1729
                                        py2 = relative ? ((cury + toy) + 2 * yc) * (1.0 / 3.0) : (toy + 2 * yc) * (1.0 / 3.0);
1730
                                        px3 = relative ? curx + tox : tox;
1731
                                        py3 = relative ? cury + toy : toy;
1732
                                        svgCurveToCubic(ite, px1, py1, px2, py2, px3, py3 );
1733
                                        contrlx = xc;
1734
                                        contrly = yc;
1735
                                        curx = relative ? curx + tox : tox;
1736
                                        cury = relative ? cury + toy : toy;
1737
                                        break;
1738
                                }
1739
                        case 'a':
1740
                                relative = true;
1741
                        case 'A':
1742
                                {
1743
                                        bool largeArc, sweep;
1744
                                        double angle, rx, ry;
1745
                                        ptr = getCoord( ptr, rx );
1746
                                        ptr = getCoord( ptr, ry );
1747
                                        ptr = getCoord( ptr, angle );
1748
                                        ptr = getCoord( ptr, tox );
1749
                                        largeArc = tox == 1;
1750
                                        ptr = getCoord( ptr, tox );
1751
                                        sweep = tox == 1;
1752
                                        ptr = getCoord( ptr, tox );
1753
                                        ptr = getCoord( ptr, toy );
1754
                                        calculateArc(ite, relative, curx, cury, angle, tox, toy, rx, ry, largeArc, sweep );
1755
                                }
1756
                        }
1757
                        lastCommand = command;
22721 jghali 1758
                        if (*ptr == '+' || *ptr == '-' || (*ptr >= '0' && *ptr <= '9'))
541 fschmid 1759
                        {
1760
                                // there are still coords in this command
22721 jghali 1761
                                if (command == 'M')
541 fschmid 1762
                                        command = 'L';
22721 jghali 1763
                                else if (command == 'm')
541 fschmid 1764
                                        command = 'l';
1765
                        }
1766
                        else
1767
                                command = *(ptr++);
1768
 
22721 jghali 1769
                        if (lastCommand != 'C' && lastCommand != 'c' &&
541 fschmid 1770
                                lastCommand != 'S' && lastCommand != 's' &&
1771
                                lastCommand != 'Q' && lastCommand != 'q' &&
1772
                                lastCommand != 'T' && lastCommand != 't')
1773
                        {
1774
                                contrlx = curx;
1775
                                contrly = cury;
1776
                        }
1777
                }
1778
                if ((lastCommand != 'z') && (lastCommand != 'Z'))
1779
                        ret = true;
1780
                if (ite->size() > 2)
1781
                {
1782
                        if ((ite->point(0).x() == ite->point(ite->size()-2).x()) && (ite->point(0).y() == ite->point(ite->size()-2).y()))
1783
                                ret = false;
1784
                }
1785
        }
1786
        return ret;
1787
}
1788
 
544 fschmid 1789
void OODPlug::calculateArc(FPointArray *ite, bool relative, double &curx, double &cury, double angle, double x, double y, double r1, double r2, bool largeArcFlag, bool sweepFlag)
541 fschmid 1790
{
1791
        double sin_th, cos_th;
1792
        double a00, a01, a10, a11;
1793
        double x0, y0, x1, y1, xc, yc;
1794
        double d, sfactor, sfactor_sq;
1795
        double th0, th1, th_arc;
1796
        int i, n_segs;
1797
        sin_th = sin(angle * (M_PI / 180.0));
1798
        cos_th = cos(angle * (M_PI / 180.0));
1799
        double dx;
22721 jghali 1800
        if (!relative)
541 fschmid 1801
                dx = (curx - x) / 2.0;
1802
        else
1803
                dx = -x / 2.0;
1804
        double dy;
22721 jghali 1805
        if (!relative)
541 fschmid 1806
                dy = (cury - y) / 2.0;
1807
        else
1808
                dy = -y / 2.0;
1809
        double _x1 =  cos_th * dx + sin_th * dy;
1810
        double _y1 = -sin_th * dx + cos_th * dy;
1811
        double Pr1 = r1 * r1;
1812
        double Pr2 = r2 * r2;
1813
        double Px = _x1 * _x1;
1814
        double Py = _y1 * _y1;
1815
        double check = Px / Pr1 + Py / Pr2;
22721 jghali 1816
        if (check > 1)
541 fschmid 1817
        {
1818
                r1 = r1 * sqrt(check);
1819
                r2 = r2 * sqrt(check);
1820
        }
1821
        a00 = cos_th / r1;
1822
        a01 = sin_th / r1;
1823
        a10 = -sin_th / r2;
1824
        a11 = cos_th / r2;
1825
        x0 = a00 * curx + a01 * cury;
1826
        y0 = a10 * curx + a11 * cury;
22721 jghali 1827
        if (!relative)
541 fschmid 1828
                x1 = a00 * x + a01 * y;
1829
        else
1830
                x1 = a00 * (curx + x) + a01 * (cury + y);
22721 jghali 1831
        if (!relative)
541 fschmid 1832
                y1 = a10 * x + a11 * y;
1833
        else
1834
                y1 = a10 * (curx + x) + a11 * (cury + y);
1835
        d = (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0);
1836
        sfactor_sq = 1.0 / d - 0.25;
22721 jghali 1837
        if (sfactor_sq < 0)
541 fschmid 1838
                sfactor_sq = 0;
1839
        sfactor = sqrt(sfactor_sq);
22721 jghali 1840
        if (sweepFlag == largeArcFlag)
541 fschmid 1841
                sfactor = -sfactor;
1842
        xc = 0.5 * (x0 + x1) - sfactor * (y1 - y0);
1843
        yc = 0.5 * (y0 + y1) + sfactor * (x1 - x0);
1844
 
1845
        th0 = atan2(y0 - yc, x0 - xc);
1846
        th1 = atan2(y1 - yc, x1 - xc);
1847
        th_arc = th1 - th0;
22721 jghali 1848
        if (th_arc < 0 && sweepFlag)
541 fschmid 1849
                th_arc += 2 * M_PI;
22721 jghali 1850
        else if (th_arc > 0 && !sweepFlag)
541 fschmid 1851
                th_arc -= 2 * M_PI;
1852
        n_segs = static_cast<int>(ceil(fabs(th_arc / (M_PI * 0.5 + 0.001))));
22723 jghali 1853
        for (i = 0; i < n_segs; i++)
541 fschmid 1854
        {
1855
                {
1856
                        double sin_th, cos_th;
1857
                        double a00, a01, a10, a11;
1858
                        double x1, y1, x2, y2, x3, y3;
1859
                        double t;
1860
                        double th_half;
1861
                        double _th0 = th0 + i * th_arc / n_segs;
1862
                        double _th1 = th0 + (i + 1) * th_arc / n_segs;
1863
                        sin_th = sin(angle * (M_PI / 180.0));
1864
                        cos_th = cos(angle * (M_PI / 180.0));
1865
                        a00 = cos_th * r1;
1866
                        a01 = -sin_th * r2;
1867
                        a10 = sin_th * r1;
1868
                        a11 = cos_th * r2;
1869
                        th_half = 0.5 * (_th1 - _th0);
1870
                        t = (8.0 / 3.0) * sin(th_half * 0.5) * sin(th_half * 0.5) / sin(th_half);
1871
                        x1 = xc + cos(_th0) - t * sin(_th0);
1872
                        y1 = yc + sin(_th0) + t * cos(_th0);
1873
                        x3 = xc + cos(_th1);
1874
                        y3 = yc + sin(_th1);
1875
                        x2 = x3 + t * sin(_th1);
1876
                        y2 = y3 - t * cos(_th1);
1877
                        svgCurveToCubic(ite, a00 * x1 + a01 * y1, a10 * x1 + a11 * y1, a00 * x2 + a01 * y2, a10 * x2 + a11 * y2, a00 * x3 + a01 * y3, a10 * x3 + a11 * y3 );
1878
                }
1879
        }
22721 jghali 1880
        if (!relative)