Subversion Repositories Scribus

Rev

Rev 10417 | Rev 12190 | Go to most recent revision | 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
*/
766 cbradney 7
#include <qwidget.h>
8
#include <qfile.h>
9
#include <qtextstream.h>
10
#include <qregexp.h>
11
#include <qcursor.h>
12
#include <qdragobject.h>
13
#include <qdir.h>
14
#include <qstring.h>
3207 craig 15
#include <qdom.h>
766 cbradney 16
#include <cmath>
17
 
541 fschmid 18
#include "oodrawimp.h"
19
#include "oodrawimp.moc"
766 cbradney 20
 
2688 craig 21
#include "scconfig.h"
22
 
766 cbradney 23
#include "scribus.h"
24
#include "scribusdoc.h"
25
#include "pageitem.h"
26
#include "fpointarray.h"
541 fschmid 27
#include "customfdialog.h"
4463 cbradney 28
#include "commonstrings.h"
541 fschmid 29
#include "color.h"
30
#include "scribusXml.h"
31
#include "mpalette.h"
2856 cbradney 32
#include "prefsmanager.h"
541 fschmid 33
#include "prefsfile.h"
34
#include "prefscontext.h"
35
#include "prefstable.h"
1578 tsoots 36
#include "fileunzip.h"
3934 cbradney 37
#include "selection.h"
544 fschmid 38
#include "serializer.h"
1436 tsoots 39
#include "undomanager.h"
1549 subik 40
#include "pluginmanager.h"
2529 craig 41
#include "util.h"
42
#include "scfontmetrics.h"
3207 craig 43
#include "stylestack.h"
3696 craig 44
#include "scraction.h"
45
#include "menumanager.h"
541 fschmid 46
 
47
using namespace std;
48
 
3207 craig 49
int oodrawimp_getPluginAPIVersion()
541 fschmid 50
{
3207 craig 51
        return PLUGIN_API_VERSION;
541 fschmid 52
}
53
 
3207 craig 54
ScPlugin* oodrawimp_getPlugin()
541 fschmid 55
{
3207 craig 56
        OODrawImportPlugin* plug = new OODrawImportPlugin();
57
        Q_CHECK_PTR(plug);
58
        return plug;
541 fschmid 59
}
60
 
3207 craig 61
void oodrawimp_freePlugin(ScPlugin* plugin)
541 fschmid 62
{
3207 craig 63
        OODrawImportPlugin* plug = dynamic_cast<OODrawImportPlugin*>(plugin);
64
        Q_ASSERT(plug);
65
        delete plug;
541 fschmid 66
}
67
 
3207 craig 68
OODrawImportPlugin::OODrawImportPlugin() :
3696 craig 69
        LoadSavePlugin(),
70
        importAction(new ScrAction(ScrAction::DLL, QIconSet(), "", QKeySequence(), this, "ImportOpenOfficeDraw"))
1208 cbradney 71
{
3207 craig 72
        // Set action info in languageChange, so we only have to do
3686 craig 73
        // it in one place. This includes registering file formats.
3207 craig 74
        languageChange();
3696 craig 75
 
76
        // Then hook up the action
77
        importAction->setEnabled(true);
78
        connect( importAction, SIGNAL(activated()), SLOT(import()) );
4026 craig 79
        ScMW->scrMenuMgr->addMenuItem(importAction, "FileImport");
1208 cbradney 80
}
81
 
3686 craig 82
OODrawImportPlugin::~OODrawImportPlugin()
83
{
84
        unregisterAll();
3696 craig 85
        // note: importAction is automatically deleted by Qt
3686 craig 86
};
3207 craig 87
 
88
void OODrawImportPlugin::languageChange()
1208 cbradney 89
{
7121 fschmid 90
        importAction->setMenuText( tr("Import &OpenOffice.org Draw..."));
3686 craig 91
        // (Re)register file formats
92
        unregisterAll();
93
        registerFormats();
1208 cbradney 94
}
95
 
3207 craig 96
const QString OODrawImportPlugin::fullTrName() const
1208 cbradney 97
{
3207 craig 98
        return QObject::tr("OpenOffice.org Draw Importer");
1208 cbradney 99
}
100
 
3207 craig 101
const ScActionPlugin::AboutData* OODrawImportPlugin::getAboutData() const
1208 cbradney 102
{
3241 craig 103
        AboutData* about = new AboutData;
3344 fschmid 104
        about->authors = "Franz Schmid <franz@scribus.info>";
3540 cbradney 105
        about->shortDescription = tr("Imports OpenOffice.org Draw Files");
106
        about->description = tr("Imports most OpenOffice.org Draw files into the current document, converting their vector data into Scribus objects.");
3344 fschmid 107
        about->license = "GPL";
3241 craig 108
        Q_CHECK_PTR(about);
109
        return about;
1208 cbradney 110
}
111
 
3241 craig 112
void OODrawImportPlugin::deleteAboutData(const AboutData* about) const
1208 cbradney 113
{
3241 craig 114
        Q_ASSERT(about);
115
        delete about;
1208 cbradney 116
}
117
 
3686 craig 118
void OODrawImportPlugin::registerFormats()
3487 craig 119
{
120
        QString odtName = tr("OpenDocument 1.0 Draw", "Import/export format name");
4024 craig 121
        FileFormat odtformat(this);
3643 craig 122
        odtformat.trName = odtName; // Human readable name
4024 craig 123
        odtformat.formatId = FORMATID_ODGIMPORT;
4309 craig 124
        odtformat.filter = odtName + " (*.odg *.ODG)"; // QFileDialog filter
3688 craig 125
        odtformat.nameMatch = QRegExp("\\.odg$", false);
3686 craig 126
        odtformat.load = true;
127
        odtformat.save = false;
3643 craig 128
        odtformat.mimeTypes = QStringList("application/vnd.oasis.opendocument.graphics"); // MIME types
129
        odtformat.priority = 64; // Priority
3686 craig 130
        registerFormat(odtformat);
131
 
3487 craig 132
        QString sxdName = tr("OpenOffice.org 1.x Draw", "Import/export format name");
4024 craig 133
        FileFormat sxdformat(this);
3643 craig 134
        sxdformat.trName = sxdName; // Human readable name
4024 craig 135
        sxdformat.formatId = FORMATID_SXDIMPORT;
4309 craig 136
        sxdformat.filter = sxdName + " (*.sxd *.SXD)"; // QFileDialog filter
3688 craig 137
        sxdformat.nameMatch = QRegExp("\\.sxd$", false);
3686 craig 138
        sxdformat.load = true;
139
        sxdformat.save = false;
3643 craig 140
        sxdformat.mimeTypes = QStringList("application/vnd.sun.xml.draw"); // MIME types
141
        sxdformat.priority = 64; // Priority
3686 craig 142
        registerFormat(sxdformat);
3487 craig 143
}
144
 
145
bool OODrawImportPlugin::fileSupported(QIODevice* /* file */) const
146
{
147
        // TODO: try to identify .sxd / .odt files
148
        return true;
149
}
150
 
5535 mrdocs 151
bool OODrawImportPlugin::loadFile(const QString & fileName, const FileFormat &, int flags, int /*index*/)
541 fschmid 152
{
3696 craig 153
        // For this plugin, right now "load" and "import" are the same thing
5535 mrdocs 154
        return import(fileName, flags);
3696 craig 155
}
156
 
5535 mrdocs 157
bool OODrawImportPlugin::import(QString fileName, int flags)
3696 craig 158
{
5535 mrdocs 159
        if (!checkFlags(flags))
160
                return false;
3207 craig 161
        if (fileName.isEmpty())
541 fschmid 162
        {
5535 mrdocs 163
                flags |= lfInteractive;
2856 cbradney 164
                PrefsContext* prefs = PrefsManager::instance()->prefsFile->getPluginContext("OODrawImport");
541 fschmid 165
                QString wdir = prefs->get("wdir", ".");
4590 cbradney 166
                CustomFDialog diaf(ScMW, wdir, QObject::tr("Open"), QObject::tr("OpenOffice.org Draw (*.sxd *.odg);;All Files (*)"));
541 fschmid 167
                if (diaf.exec())
168
                {
169
                        fileName = diaf.selectedFile();
170
                        prefs->set("wdir", fileName.left(fileName.findRev("/")));
171
                }
172
                else
3207 craig 173
                        return true;
541 fschmid 174
        }
4026 craig 175
        if (UndoManager::undoEnabled() && ScMW->HaveDoc)
1439 tsoots 176
        {
4026 craig 177
                UndoManager::instance()->beginTransaction(ScMW->doc->currentPage->getUName(),Um::IImageFrame,Um::ImportOOoDraw, fileName, Um::IImportOOoDraw);
1439 tsoots 178
        }
4026 craig 179
        else if (UndoManager::undoEnabled() && !ScMW->HaveDoc)
1439 tsoots 180
                UndoManager::instance()->setUndoEnabled(false);
4463 cbradney 181
        OODPlug dia;
5535 mrdocs 182
        bool importDone = dia.import(fileName, flags);
1436 tsoots 183
        if (UndoManager::undoEnabled())
184
                UndoManager::instance()->commit();
1439 tsoots 185
        else
186
                UndoManager::instance()->setUndoEnabled(true);
7270 jghali 187
        if (dia.unsupported)
188
                QMessageBox::warning(ScMW, CommonStrings::trWarning, tr("This file contains some unsupported features"), 1, 0, 0);
4463 cbradney 189
        return importDone;
541 fschmid 190
}
191
 
4463 cbradney 192
OODPlug::OODPlug()
541 fschmid 193
{
4463 cbradney 194
        interactive = false;
7270 jghali 195
        unsupported = false;
4463 cbradney 196
        Doku = NULL;
197
}
198
 
5535 mrdocs 199
bool OODPlug::import( QString fileName, int flags )
4463 cbradney 200
{
201
        bool importDone = false;
5535 mrdocs 202
        interactive = (flags & LoadSavePlugin::lfInteractive);
550 fschmid 203
        QString f, f2, f3;
4463 cbradney 204
        if ( !QFile::exists(fileName) )
205
                return false;
541 fschmid 206
        m_styles.setAutoDelete( true );
1578 tsoots 207
        FileUnzip* fun = new FileUnzip(fileName);
208
        stylePath   = fun->getFile("styles.xml");
209
        contentPath = fun->getFile("content.xml");
210
        metaPath = fun->getFile("meta.xml");
211
        delete fun;
541 fschmid 212
        if ((stylePath != NULL) && (contentPath != NULL))
213
        {
214
                QString docname = fileName.right(fileName.length() - fileName.findRev("/") - 1);
215
                docname = docname.left(docname.findRev("."));
216
                loadText(stylePath, &f);
217
                if(!inpStyles.setContent(f))
4463 cbradney 218
                        return false;
541 fschmid 219
                loadText(contentPath, &f2);
220
                if(!inpContents.setContent(f2))
4463 cbradney 221
                        return false;
541 fschmid 222
                QFile f1(stylePath);
223
                f1.remove();
224
                QFile f2(contentPath);
225
                f2.remove();
550 fschmid 226
                if (metaPath != NULL)
227
                {
228
                        HaveMeta = true;
229
                        loadText(metaPath, &f3);
230
                        if(!inpMeta.setContent(f3))
231
                                HaveMeta = false;
232
                        QFile f3(metaPath);
233
                        f3.remove();
234
                }
235
                else
236
                        HaveMeta = false;
541 fschmid 237
        }
238
        else if ((stylePath == NULL) && (contentPath != NULL))
239
        {
240
                QFile f2(contentPath);
241
                f2.remove();
242
        }
243
        else if ((stylePath != NULL) && (contentPath == NULL))
244
        {
245
                QFile f1(stylePath);
246
                f1.remove();
247
        }
248
        QString CurDirP = QDir::currentDirPath();
249
        QFileInfo efp(fileName);
250
        QDir::setCurrent(efp.dirPath());
5535 mrdocs 251
        importDone = convert(flags);
541 fschmid 252
        QDir::setCurrent(CurDirP);
4463 cbradney 253
        return importDone;
541 fschmid 254
}
255
 
5535 mrdocs 256
bool OODPlug::convert(int flags)
541 fschmid 257
{
258
        bool ret = false;
4590 cbradney 259
        bool isOODraw2 = false;
260
        QDomNode drawPagePNode;
544 fschmid 261
        int PageCounter = 0;
541 fschmid 262
        createStyleMap( inpStyles );
263
        QDomElement docElem = inpContents.documentElement();
264
        QDomNode automaticStyles = docElem.namedItem( "office:automatic-styles" );
265
        if( !automaticStyles.isNull() )
266
                insertStyles( automaticStyles.toElement() );
267
        QDomNode body = docElem.namedItem( "office:body" );
268
        QDomNode drawPage = body.namedItem( "draw:page" );
4590 cbradney 269
        if ( drawPage.isNull() )
4463 cbradney 270
        {
271
                QDomNode offDraw = body.namedItem( "office:drawing" );
272
                drawPage = offDraw.namedItem( "draw:page" );
273
                if (drawPage.isNull())
274
                {
275
                        QMessageBox::warning( ScMW, CommonStrings::trWarning, tr("This document does not seem to be an OpenOffice Draw file.") );
276
                        return false;
277
                }
278
                else
279
                {
4590 cbradney 280
                        isOODraw2 = true;
281
                        drawPagePNode = body.namedItem( "office:drawing" );
4463 cbradney 282
                }
283
        }
4590 cbradney 284
        else
285
                drawPagePNode = body;
286
        StyleStack::Mode mode = isOODraw2 ? StyleStack::OODraw2x : StyleStack::OODraw1x;
287
        m_styleStack.setMode( mode );
541 fschmid 288
        QDomElement dp = drawPage.toElement();
289
        QDomElement *master = m_styles[dp.attribute( "draw:master-page-name" )];
4590 cbradney 290
        QDomElement *style = NULL;
291
        QDomElement properties;
292
        if (isOODraw2)
293
        {
294
                style = m_styles[master->attribute( "style:page-layout-name" )];
295
                properties = style->namedItem( "style:page-layout-properties" ).toElement();
296
        }
297
        else
298
        {
299
                style = m_styles[master->attribute( "style:page-master-name" )];
300
                properties = style->namedItem( "style:properties" ).toElement();
301
        }
541 fschmid 302
        double width = !properties.attribute( "fo:page-width" ).isEmpty() ? parseUnit(properties.attribute( "fo:page-width" ) ) : 550.0;
303
        double height = !properties.attribute( "fo:page-height" ).isEmpty() ? parseUnit(properties.attribute( "fo:page-height" ) ) : 841.0;
5535 mrdocs 304
        if (!interactive || (flags & LoadSavePlugin::lfInsertPage))
4026 craig 305
                ScMW->doc->setPage(width, height, 0, 0, 0, 0, 0, 0, false, false);
541 fschmid 306
        else
307
        {
5535 mrdocs 308
                if (!ScMW->HaveDoc || (flags & LoadSavePlugin::lfCreateDoc))
541 fschmid 309
                {
4026 craig 310
                        ScMW->doFileNew(width, height, 0, 0, 0, 0, 0, 0, false, false, 0, false, 0, 1, "Custom");
4268 fschmid 311
                        ScMW->HaveNewDoc();
541 fschmid 312
                        ret = true;
313
                }
314
        }
3207 craig 315
        if ((ret) || (!interactive))
550 fschmid 316
        {
317
                if (width > height)
4026 craig 318
                        ScMW->doc->PageOri = 1;
550 fschmid 319
                else
4026 craig 320
                        ScMW->doc->PageOri = 0;
321
                ScMW->doc->PageSize = "Custom";
550 fschmid 322
                QDomNode mpg;
323
                QDomElement metaElem = inpMeta.documentElement();
324
                QDomElement mp = metaElem.namedItem( "office:meta" ).toElement();
325
                mpg = mp.namedItem( "dc:title" );
326
                if (!mpg.isNull())
4026 craig 327
                        ScMW->doc->documentInfo.setTitle(QString::fromUtf8(mpg.toElement().text()));
550 fschmid 328
                mpg = mp.namedItem( "meta:initial-creator" );
329
                if (!mpg.isNull())
4026 craig 330
                        ScMW->doc->documentInfo.setAuthor(QString::fromUtf8(mpg.toElement().text()));
550 fschmid 331
                mpg = mp.namedItem( "dc:description" );
332
                if (!mpg.isNull())
4026 craig 333
                        ScMW->doc->documentInfo.setComments(QString::fromUtf8(mpg.toElement().text()));
550 fschmid 334
                mpg = mp.namedItem( "dc:language" );
335
                if (!mpg.isNull())
4026 craig 336
                        ScMW->doc->documentInfo.setLangInfo(QString::fromUtf8(mpg.toElement().text()));
550 fschmid 337
                mpg = mp.namedItem( "meta:creation-date" );
338
                if (!mpg.isNull())
4026 craig 339
                        ScMW->doc->documentInfo.setDate(QString::fromUtf8(mpg.toElement().text()));
550 fschmid 340
                mpg = mp.namedItem( "dc:creator" );
341
                if (!mpg.isNull())
4026 craig 342
                        ScMW->doc->documentInfo.setContrib(QString::fromUtf8(mpg.toElement().text()));
550 fschmid 343
                mpg = mp.namedItem( "meta:keywords" );
344
                if (!mpg.isNull())
345
                {
346
                        QString Keys = "";
347
                        for( QDomNode n = mpg.firstChild(); !n.isNull(); n = n.nextSibling() )
348
                        {
349
                                Keys += QString::fromUtf8(n.toElement().text())+", ";
350
                        }
351
                        if (Keys.length() > 2)
4026 craig 352
                                ScMW->doc->documentInfo.setKeywords(Keys.left(Keys.length()-2));
550 fschmid 353
                }
354
        }
4026 craig 355
        Doku = ScMW->doc;
2880 fschmid 356
        FPoint minSize = Doku->minCanvasCoordinate;
357
        FPoint maxSize = Doku->maxCanvasCoordinate;
4026 craig 358
        ScMW->view->Deselect();
541 fschmid 359
        Elements.clear();
2891 cbradney 360
        Doku->setLoading(true);
541 fschmid 361
        Doku->DoDrawing = false;
4026 craig 362
        ScMW->view->setUpdatesEnabled(false);
363
        ScMW->ScriptRunning = true;
541 fschmid 364
        qApp->setOverrideCursor(QCursor(Qt::waitCursor), true);
9526 jghali 365
        Doku->PageColors.ensureBlackAndWhite();
4590 cbradney 366
        for( QDomNode drawPag = drawPagePNode.firstChild(); !drawPag.isNull(); drawPag = drawPag.nextSibling() )
541 fschmid 367
        {
368
                QDomElement dpg = drawPag.toElement();
3207 craig 369
                if (!interactive)
4025 cbradney 370
                {
4026 craig 371
                        ScMW->doc->addPage(PageCounter);
372
                        ScMW->view->addPage(PageCounter);
4025 cbradney 373
                }
545 fschmid 374
                PageCounter++;
541 fschmid 375
                m_styleStack.clear();
376
                fillStyleStack( dpg );
377
                parseGroup( dpg );
378
        }
4847 cbradney 379
        Doku->m_Selection->clear();
3207 craig 380
        if ((Elements.count() > 1) && (interactive))
541 fschmid 381
        {
382
                for (uint a = 0; a < Elements.count(); ++a)
383
                {
384
                        Elements.at(a)->Groups.push(Doku->GroupCounter);
385
                }
386
                Doku->GroupCounter++;
387
        }
388
        Doku->DoDrawing = true;
4026 craig 389
        ScMW->view->setUpdatesEnabled(true);
390
        ScMW->ScriptRunning = false;
3207 craig 391
        if (interactive)
2891 cbradney 392
                Doku->setLoading(false);
541 fschmid 393
        qApp->setOverrideCursor(QCursor(Qt::arrowCursor), true);
3207 craig 394
        if ((Elements.count() > 0) && (!ret) && (interactive))
541 fschmid 395
        {
396
                Doku->DragP = true;
397
                Doku->DraggedElem = 0;
398
                Doku->DragElements.clear();
399
                for (uint dre=0; dre<Elements.count(); ++dre)
400
                {
401
                        Doku->DragElements.append(Elements.at(dre)->ItemNr);
4847 cbradney 402
                        Doku->m_Selection->addItem(Elements.at(dre));
541 fschmid 403
                }
404
                ScriXmlDoc *ss = new ScriXmlDoc();
4026 craig 405
                ScMW->view->setGroupRect();
4847 cbradney 406
                QDragObject *dr = new QTextDrag(ss->WriteElem(Doku, ScMW->view, Doku->m_Selection), ScMW->view->viewport());
4302 avox 407
#ifndef QT_MAC
408
// see #2196, #2526
4707 cbradney 409
                Doku->itemSelection_DeleteItem();
4302 avox 410
#endif
4593 cbradney 411
                ScMW->view->resizeContents(qRound((maxSize.x() - minSize.x()) * ScMW->view->scale()), qRound((maxSize.y() - minSize.y()) * ScMW->view->scale()));
412
                ScMW->view->scrollBy(qRound((Doku->minCanvasCoordinate.x() - minSize.x()) * ScMW->view->scale()), qRound((Doku->minCanvasCoordinate.y() - minSize.y()) * ScMW->view->scale()));
2880 fschmid 413
                Doku->minCanvasCoordinate = minSize;
414
                Doku->maxCanvasCoordinate = maxSize;
541 fschmid 415
                dr->setPixmap(loadIcon("DragPix.xpm"));
4302 avox 416
                if (!dr->drag())
417
                        qDebug("oodraw import: couldn't start drag operation!");
541 fschmid 418
                delete ss;
419
                Doku->DragP = false;
420
                Doku->DraggedElem = 0;
421
                Doku->DragElements.clear();
422
        }
423
        else
424
        {
2891 cbradney 425
                Doku->setModified(false);
4026 craig 426
                ScMW->slotDocCh();
541 fschmid 427
        }
4463 cbradney 428
        return true;
541 fschmid 429
}
430
 
991 fschmid 431
QPtrList<PageItem> OODPlug::parseGroup(const QDomElement &e)
541 fschmid 432
{
433
        QPtrList<PageItem> GElements;
434
        FPointArray ImgClip;
435
        ImgClip.resize(0);
545 fschmid 436
        VGradient gradient;
795 fschmid 437
        double GradientAngle = 0;
438
        double xGoff = 0;
439
        double yGoff= 0;
545 fschmid 440
        bool HaveGradient = false;
441
        int GradientType = 0;
3200 cbradney 442
        double BaseX = Doku->currentPage->xOffset();
443
        double BaseY = Doku->currentPage->yOffset();
541 fschmid 444
        double lwidth = 0;
544 fschmid 445
        double x, y, w, h;
546 fschmid 446
        double FillTrans = 0;
547 fschmid 447
        double StrokeTrans = 0;
548 fschmid 448
        QValueList<double> dashes;
541 fschmid 449
        for (QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling())
450
        {
4546 subik 451
                QString StrokeColor = CommonStrings::None;
452
                QString FillColor = CommonStrings::None;
546 fschmid 453
                FillTrans = 0;
547 fschmid 454
                StrokeTrans = 0;
541 fschmid 455
                int z = -1;
548 fschmid 456
                dashes.clear();
541 fschmid 457
                QDomElement b = n.toElement();
458
                if( b.isNull() )
459
                        continue;
460
                QString STag = b.tagName();
547 fschmid 461
                QString drawID = b.attribute("draw:name");
541 fschmid 462
                storeObjectStyles(b);
4590 cbradney 463
                if( m_styleStack.hasAttribute("draw:stroke") )
541 fschmid 464
                {
544 fschmid 465
                        if( m_styleStack.attribute( "draw:stroke" ) == "none" )
466
                                lwidth = 0.0;
467
                        else
468
                        {
469
                                if( m_styleStack.hasAttribute("svg:stroke-width"))
470
                                {
471
                                        lwidth = parseUnit(m_styleStack.attribute("svg:stroke-width"));
472
                                        if (lwidth == 0)
473
                                                lwidth = 1;
474
                                }
475
                                if( m_styleStack.hasAttribute("svg:stroke-color"))
476
                                        StrokeColor = parseColor(m_styleStack.attribute("svg:stroke-color"));
547 fschmid 477
                                if( m_styleStack.hasAttribute( "svg:stroke-opacity" ) )
478
                                        StrokeTrans = m_styleStack.attribute( "svg:stroke-opacity" ).remove( '%' ).toDouble() / 100.0;
548 fschmid 479
                                if( m_styleStack.attribute( "draw:stroke" ) == "dash" )
480
                                {
481
                                        QString style = m_styleStack.attribute( "draw:stroke-dash" );
482
                                        if( style == "Ultrafine Dashed")
483
                                                dashes << 1.4 << 1.4;
484
                                        else if( style == "Fine Dashed" )
485
                                                dashes << 14.4 << 14.4;
486
                                        else if( style == "Fine Dotted")
487
                                                dashes << 13 << 13;
1549 subik 488
                                        else if( style == "Ultrafine 2 Dots 3 Dashes")
548 fschmid 489
                                                dashes << 1.45 << 3.6 << 1.45 << 3.6 << 7.2 << 3.6 << 7.2 << 3.6 << 7.2 << 3.6;
490
                                        else if( style == "Line with Fine Dots")
491
                                        {
492
                                                dashes << 56.9 << 4.31;
493
                                                for (int dd = 0; dd < 10; ++ dd)
494
                                                {
495
                                                        dashes << 8.6 << 4.31;
496
                                                }
497
                                        }
498
                                        else if( style == "2 Dots 1 Dash" )
499
                                                dashes << 2.8 << 5.75 << 2.8 << 5.75 << 5.75 << 5.75;
500
                                }
544 fschmid 501
                        }
541 fschmid 502
                }
503
                if( m_styleStack.hasAttribute( "draw:fill" ) )
504
                {
505
                        QString fill = m_styleStack.attribute( "draw:fill" );
506
                        if( fill == "solid" )
507
                        {
508
                                if( m_styleStack.hasAttribute( "draw:fill-color" ) )
509
                                        FillColor = parseColor( m_styleStack.attribute("draw:fill-color"));
546 fschmid 510
                                if( m_styleStack.hasAttribute( "draw:transparency" ) )
511
                                        FillTrans = m_styleStack.attribute( "draw:transparency" ).remove( '%' ).toDouble() / 100.0;
541 fschmid 512
                        }
545 fschmid 513
                        else if( fill == "gradient" )
514
                        {
515
                                HaveGradient = true;
592 fschmid 516
                                GradientAngle = 0;
545 fschmid 517
                                gradient.clearStops();
518
                                gradient.setRepeatMethod( VGradient::none );
519
                                QString style = m_styleStack.attribute( "draw:fill-gradient-name" );
520
                                QDomElement* draw = m_draws[style];
521
                                if( draw )
522
                                {
523
                                        double border = 0.0;
546 fschmid 524
                                        int shadeS = 100;
525
                                        int shadeE = 100;
545 fschmid 526
                                        if( draw->hasAttribute( "draw:border" ) )
527
                                                border += draw->attribute( "draw:border" ).remove( '%' ).toDouble() / 100.0;
546 fschmid 528
                                        if( draw->hasAttribute( "draw:start-intensity" ) )
529
                                                shadeS = draw->attribute( "draw:start-intensity" ).remove( '%' ).toInt();
530
                                        if( draw->hasAttribute( "draw:end-intensity" ) )
531
                                                shadeE = draw->attribute( "draw:end-intensity" ).remove( '%' ).toInt();
545 fschmid 532
                                        QString type = draw->attribute( "draw:style" );
533
                                        if( type == "linear" || type == "axial" )
534
                                        {
535
                                                gradient.setType( VGradient::linear );
536
                                                GradientAngle = draw->attribute( "draw:angle" ).toDouble() / 10;
537
                                                GradientType = 1;
538
                                        }
592 fschmid 539
                                        else if( type == "radial" || type == "ellipsoid" )
540
                                        {
541
                                                if( draw->hasAttribute( "draw:cx" ) )
542
                                                        xGoff = draw->attribute( "draw:cx" ).remove( '%' ).toDouble() / 100.0;
543
                                                else
544
                                                        xGoff = 0.5;
545
                                                if( draw->hasAttribute( "draw:cy" ) )
546
                                                        yGoff = draw->attribute( "draw:cy" ).remove( '%' ).toDouble() / 100.0;
547
                                                else
548
                                                        yGoff = 0.5;
549
                                                GradientType = 2;
550
                                        }
546 fschmid 551
                                        QString c, c2;
552
                                        c = parseColor( draw->attribute( "draw:start-color" ) );
553
                                        c2 = parseColor( draw->attribute( "draw:end-color" ) );
592 fschmid 554
                                        if (((GradientAngle > 90) && (GradientAngle < 271)) || (GradientType == 2))
546 fschmid 555
                                        {
556
                                                gradient.addStop( Doku->PageColors[c2].getRGBColor(), 0.0, 0.5, 1, c2, shadeE );
557
                                                gradient.addStop( Doku->PageColors[c].getRGBColor(), 1.0 - border, 0.5, 1, c, shadeS );
558
                                        }
559
                                        else
560
                                        {
561
                                                gradient.addStop( Doku->PageColors[c].getRGBColor(), border, 0.5, 1, c, shadeS );
562
                                                gradient.addStop( Doku->PageColors[c2].getRGBColor(), 1.0, 0.5, 1, c2, shadeE );
563
                                        }
545 fschmid 564
                                }
565
                        }
541 fschmid 566
                }
545 fschmid 567
                if( STag == "draw:g" )
541 fschmid 568
                {
991 fschmid 569
                        QPtrList<PageItem> gElements = parseGroup( b );
570
                        for (uint gr = 0; gr < gElements.count(); ++gr)
548 fschmid 571
                        {
991 fschmid 572
                                gElements.at(gr)->Groups.push(Doku->GroupCounter);
573
                                GElements.append(gElements.at(gr));
548 fschmid 574
                        }
575
                        Doku->GroupCounter++;
545 fschmid 576
                }
577
                else if( STag == "draw:rect" )
578
                {
544 fschmid 579
                        x = parseUnit(b.attribute("svg:x"));
580
                        y = parseUnit(b.attribute("svg:y")) ;
581
                        w = parseUnit(b.attribute("svg:width"));
582
                        h = parseUnit(b.attribute("svg:height"));
541 fschmid 583
                        double corner = parseUnit(b.attribute("draw:corner-radius"));
4704 cbradney 584
                        z = Doku->itemAdd(PageItem::Polygon, PageItem::Rectangle, BaseX+x, BaseY+y, w, h, lwidth, FillColor, StrokeColor, true);
3727 cbradney 585
                        PageItem* ite = Doku->Items->at(z);
541 fschmid 586
                        if (corner != 0)
587
                        {
3989 cbradney 588
                                ite->setCornerRadius(corner);
3242 cbradney 589
                                ite->SetFrameRound();
4672 cbradney 590
                                Doku->setRedrawBounding(ite);
541 fschmid 591
                        }
592
                }
544 fschmid 593
                else if( STag == "draw:circle" || STag == "draw:ellipse" )
594
                {
595
                        x = parseUnit(b.attribute("svg:x"));
596
                        y = parseUnit(b.attribute("svg:y")) ;
597
                        w = parseUnit(b.attribute("svg:width"));
598
                        h = parseUnit(b.attribute("svg:height"));
4704 cbradney 599
                        z = Doku->itemAdd(PageItem::Polygon, PageItem::Ellipse, BaseX+x, BaseY+y, w, h, lwidth, FillColor, StrokeColor, true);
544 fschmid 600
                }
601
                else if( STag == "draw:line" ) // line
602
                {
603
                        double x1 = b.attribute( "svg:x1" ).isEmpty() ? 0.0 : parseUnit( b.attribute( "svg:x1" ) );
604
                        double y1 = b.attribute( "svg:y1" ).isEmpty() ? 0.0 : parseUnit( b.attribute( "svg:y1" ) );
605
                        double x2 = b.attribute( "svg:x2" ).isEmpty() ? 0.0 : parseUnit( b.attribute( "svg:x2" ) );
606
                        double y2 = b.attribute( "svg:y2" ).isEmpty() ? 0.0 : parseUnit( b.attribute( "svg:y2" ) );
6384 fschmid 607
                        z = Doku->itemAdd(PageItem::PolyLine, PageItem::Unspecified, BaseX, BaseY, 10, 10, lwidth, CommonStrings::None, StrokeColor, true);
3727 cbradney 608
                        PageItem* ite = Doku->Items->at(z);
544 fschmid 609
                        ite->PoLine.resize(4);
610
                        ite->PoLine.setPoint(0, FPoint(x1, y1));
611
                        ite->PoLine.setPoint(1, FPoint(x1, y1));
612
                        ite->PoLine.setPoint(2, FPoint(x2, y2));
613
                        ite->PoLine.setPoint(3, FPoint(x2, y2));
1065 cbradney 614
                        FPoint wh = getMaxClipF(&ite->PoLine);
3934 cbradney 615
                        ite->setWidthHeight(wh.x(), wh.y());
550 fschmid 616
                        ite->ClipEdited = true;
617
                        ite->FrameType = 3;
6384 fschmid 618
                        HaveGradient = false;
548 fschmid 619
                        if (!b.hasAttribute("draw:transform"))
620
                        {
621
                                ite->Clip = FlattenPath(ite->PoLine, ite->Segments);
4026 craig 622
                                ScMW->view->AdjustItemSize(ite);
548 fschmid 623
                        }
1549 subik 624
                }
544 fschmid 625
                else if ( STag == "draw:polygon" )
626
                {
4704 cbradney 627
                        z = Doku->itemAdd(PageItem::Polygon, PageItem::Unspecified, BaseX, BaseY, 10, 10, lwidth, FillColor, StrokeColor, true);
3727 cbradney 628
                        PageItem* ite = Doku->Items->at(z);
544 fschmid 629
                        ite->PoLine.resize(0);
10417 jghali 630
                        appendPoints(&ite->PoLine, b, true);
1065 cbradney 631
                        FPoint wh = getMaxClipF(&ite->PoLine);
3934 cbradney 632
                        ite->setWidthHeight(wh.x(), wh.y());
550 fschmid 633
                        ite->ClipEdited = true;
634
                        ite->FrameType = 3;
548 fschmid 635
                        if (!b.hasAttribute("draw:transform"))
636
                        {
637
                                ite->Clip = FlattenPath(ite->PoLine, ite->Segments);
4026 craig 638
                                ScMW->view->AdjustItemSize(ite);
548 fschmid 639
                        }
544 fschmid 640
                }
641
                else if( STag == "draw:polyline" )
642
                {
4704 cbradney 643
                        z = Doku->itemAdd(PageItem::PolyLine, PageItem::Unspecified, BaseX, BaseY, 10, 10, lwidth, CommonStrings::None, StrokeColor, true);
3727 cbradney 644
                        PageItem* ite = Doku->Items->at(z);
544 fschmid 645
                        ite->PoLine.resize(0);
10417 jghali 646
                        appendPoints(&ite->PoLine, b, false);
1065 cbradney 647
                        FPoint wh = getMaxClipF(&ite->PoLine);
3934 cbradney 648
                        ite->setWidthHeight(wh.x(), wh.y());
550 fschmid 649
                        ite->ClipEdited = true;
650
                        ite->FrameType = 3;
548 fschmid 651
                        if (!b.hasAttribute("draw:transform"))
652
                        {
653
                                ite->Clip = FlattenPath(ite->PoLine, ite->Segments);
4026 craig 654
                                ScMW->view->AdjustItemSize(ite);
548 fschmid 655
                        }
544 fschmid 656
                }
657
                else if( STag == "draw:path" )
658
                {
7042 jghali 659
                        FPointArray pArray;
660
                        PageItem::ItemType itype = parseSVG(b.attribute("svg:d"), &pArray) ? PageItem::PolyLine : PageItem::Polygon;
661
                        z = Doku->itemAdd(itype, PageItem::Unspecified, BaseX, BaseY, 10, 10, lwidth, FillColor, StrokeColor, true);
3727 cbradney 662
                        PageItem* ite = Doku->Items->at(z);
544 fschmid 663
                        ite->PoLine.resize(0);
7042 jghali 664
                        ite->PoLine = pArray;
544 fschmid 665
                        if (ite->PoLine.size() < 4)
666
                        {
4847 cbradney 667
                                Doku->m_Selection->addItem(ite);
4707 cbradney 668
                                Doku->itemSelection_DeleteItem();
544 fschmid 669
                                z = -1;
670
                        }
671
                        else
672
                        {
10937 jghali 673
                                QWMatrix mat;
544 fschmid 674
                                x = parseUnit(b.attribute("svg:x"));
675
                                y = parseUnit(b.attribute("svg:y")) ;
676
                                w = parseUnit(b.attribute("svg:width"));
677
                                h = parseUnit(b.attribute("svg:height"));
678
                                double vx = 0;
679
                                double vy = 0;
680
                                double vw = 1;
681
                                double vh = 1;
682
                                parseViewBox(b, &vx, &vy, &vw, &vh);
10937 jghali 683
                                double sx = (vw != 0.0) ? (w / vw) : w;
684
                                double sy = (vh != 0.0) ? (h / vh) : h;
544 fschmid 685
                                mat.translate(x, y);
10937 jghali 686
                                mat.scale(sx, sy);
544 fschmid 687
                                ite->PoLine.map(mat);
1065 cbradney 688
                                FPoint wh = getMaxClipF(&ite->PoLine);
3934 cbradney 689
                                ite->setWidthHeight(wh.x(), wh.y());
550 fschmid 690
                                ite->ClipEdited = true;
691
                                ite->FrameType = 3;
548 fschmid 692
                                if (!b.hasAttribute("draw:transform"))
693
                                {
694
                                        ite->Clip = FlattenPath(ite->PoLine, ite->Segments);
4026 craig 695
                                        ScMW->view->AdjustItemSize(ite);
548 fschmid 696
                                }
544 fschmid 697
                        }
698
                }
699
                else if ( STag == "draw:text-box" )
700
                {
701
                        x = parseUnit(b.attribute("svg:x"));
702
                        y = parseUnit(b.attribute("svg:y")) ;
703
                        w = parseUnit(b.attribute("svg:width"));
704
                        h = parseUnit(b.attribute("svg:height"));
4704 cbradney 705
                        z = Doku->itemAdd(PageItem::TextFrame, PageItem::Unspecified, BaseX+x, BaseY+y, w, h+(h*0.1), lwidth, CommonStrings::None, StrokeColor, true);
592 fschmid 706
                }
707
                else
708
                {
7270 jghali 709
                        unsupported = true;
3211 craig 710
                        qDebug("Not supported yet: %s", STag.local8Bit().data());
592 fschmid 711
                        continue;
712
                }
713
                if (z != -1)
714
                {
3727 cbradney 715
                        PageItem* ite = Doku->Items->at(z);
3988 cbradney 716
                        ite->setTextToFrameDist(0.0, 0.0, 0.0, 0.0);
544 fschmid 717
                        bool firstPa = false;
718
                        for ( QDomNode n = b.firstChild(); !n.isNull(); n = n.nextSibling() )
719
                        {
4590 cbradney 720
                                if ( !n.hasAttributes() && !n.hasChildNodes() )
721
                                        continue;
4596 cbradney 722
                                QDomElement e = n.toElement();
723
                                if ( e.text().isEmpty() )
724
                                        continue;
1194 fschmid 725
                                int FontSize = Doku->toolSettings.defSize;
592 fschmid 726
                                int AbsStyle = 0;
727
                                if( m_styleStack.hasAttribute("fo:text-align"))
728
                                {
729
                                        if (m_styleStack.attribute("fo:text-align") == "left")
730
                                                AbsStyle = 0;
731
                                        if (m_styleStack.attribute("fo:text-align") == "center")
732
                                                AbsStyle = 1;
733
                                        if (m_styleStack.attribute("fo:text-align") == "right")
734
                                                AbsStyle = 2;
735
                                }
8281 jghali 736
                                if( m_styleStack.hasAttribute("fo:font-size"))
547 fschmid 737
                                {
8281 jghali 738
                                        FontSize = (int) (m_styleStack.attribute("fo:font-size").remove( "pt" ).toFloat() * 10);
547 fschmid 739
                                }
544 fschmid 740
/* ToDo: Add reading of Textstyles here */
8281 jghali 741
                                ite->setLineSpacing((FontSize + FontSize * 0.2) / 10.0);
544 fschmid 742
                                Serializer *ss = new Serializer("");
592 fschmid 743
                                ss->Objekt = QString::fromUtf8(e.text())+QChar(10);
8281 jghali 744
                                ss->GetText(ite, AbsStyle, Doku->toolSettings.defFont, FontSize, firstPa);
544 fschmid 745
                                delete ss;
746
                                firstPa = true;
3625 avox 747
                                if (! ite->asPolyLine())
1460 cbradney 748
                                        ite->convertTo(PageItem::TextFrame);
544 fschmid 749
                        }
1394 cbradney 750
                        ite->setFillTransparency(FillTrans);
751
                        ite->setLineTransparency(StrokeTrans);
548 fschmid 752
                        if (dashes.count() != 0)
753
                                ite->DashValues = dashes;
2877 cbradney 754
                        if (!drawID.isEmpty())
1361 tsoots 755
                                ite->setItemName(drawID);
541 fschmid 756
                        if (b.hasAttribute("draw:transform"))
757
                        {
546 fschmid 758
                                parseTransform(&ite->PoLine, b.attribute("draw:transform"));
545 fschmid 759
                                ite->ClipEdited = true;
760
                                ite->FrameType = 3;
1065 cbradney 761
                                FPoint wh = getMaxClipF(&ite->PoLine);
3934 cbradney 762
                                ite->setWidthHeight(wh.x(), wh.y());
545 fschmid 763
                                ite->Clip = FlattenPath(ite->PoLine, ite->Segments);
4026 craig 764
                                ScMW->view->AdjustItemSize(ite);
541 fschmid 765
                        }
545 fschmid 766
                        if (HaveGradient)
767
                        {
768
                                ite->GrType = 0;
7352 fschmid 769
                                if (gradient.Stops() > 1)
545 fschmid 770
                                {
7352 fschmid 771
                                        ite->fill_gradient = gradient;
772
                                        if (GradientType == 1)
546 fschmid 773
                                        {
7352 fschmid 774
                                                bool flipped = false;
775
                                                if ((GradientAngle == 0) || (GradientAngle == 180) || (GradientAngle == 90) || (GradientAngle == 270))
546 fschmid 776
                                                {
7352 fschmid 777
                                                        if ((GradientAngle == 0) || (GradientAngle == 180))
778
                                                        {
779
                                                                ite->GrType = 2;
780
                                                                //ScMW->view->updateGradientVectors(ite);
781
                                                                ite->updateGradientVectors();
782
                                                        }
783
                                                        else if ((GradientAngle == 90) || (GradientAngle == 270))
784
                                                        {
785
                                                                ite->GrType = 1;
786
                                                                //ScMW->view->updateGradientVectors(ite);
787
                                                                ite->updateGradientVectors();
788
                                                        }
546 fschmid 789
                                                }
7352 fschmid 790
                                                else
546 fschmid 791
                                                {
7352 fschmid 792
                                                        if ((GradientAngle > 90) && (GradientAngle < 270))
793
                                                                GradientAngle -= 180;
794
                                                        else if ((GradientAngle > 270) && (GradientAngle < 360))
546 fschmid 795
                                                        {
7352 fschmid 796
                                                                GradientAngle = 360 - GradientAngle;
797
                                                                flipped = true;
546 fschmid 798
                                                        }
7352 fschmid 799
                                                        double xpos;
800
                                                        xpos = (ite->width() / 2) * tan(GradientAngle* M_PI / 180.0) * (ite->height() / ite->width()) + (ite->width() / 2);
801
                                                        if ((xpos < 0) || (xpos > ite->width()))
802
                                                        {
803
                                                                xpos = (ite->height() / 2)- (ite->height() / 2) * tan(GradientAngle* M_PI / 180.0) * (ite->height() / ite->width());
804
                                                                if (flipped)
805
                                                                {
806
                                                                        ite->GrEndX = ite->width();
807
                                                                        ite->GrEndY = ite->height() - xpos;
808
                                                                        ite->GrStartX = 0;
809
                                                                        ite->GrStartY = xpos;
810
                                                                }
811
                                                                else
812
                                                                {
813
                                                                        ite->GrEndY = xpos;
814
                                                                        ite->GrEndX = ite->width();
815
                                                                        ite->GrStartX = 0;
816
                                                                        ite->GrStartY = ite->height() - xpos;
817
                                                                }
818
                                                        }
546 fschmid 819
                                                        else
820
                                                        {
7352 fschmid 821
                                                                ite->GrEndX = xpos;
822
                                                                ite->GrEndY = ite->height();
823
                                                                ite->GrStartX = ite->width() - xpos;
824
                                                                ite->GrStartY = 0;
546 fschmid 825
                                                        }
7352 fschmid 826
                                                        if (flipped)
827
                                                        {
828
                                                                ite->GrEndX = ite->width() - xpos;
829
                                                                ite->GrEndY = ite->height();
830
                                                                ite->GrStartX = xpos;
831
                                                                ite->GrStartY = 0;
832
                                                        }
833
                                                        ite->GrType = 6;
546 fschmid 834
                                                }
7352 fschmid 835
                                        }
836
                                        if (GradientType == 2)
837
                                        {
838
                                                ite->GrType = 7;
839
                                                ite->GrStartX = ite->width() * xGoff;
840
                                                ite->GrStartY = ite->height()* yGoff;
841
                                                if (ite->width() >= ite->height())
546 fschmid 842
                                                {
7352 fschmid 843
                                                        ite->GrEndX = ite->width();
844
                                                        ite->GrEndY = ite->height() / 2.0;
546 fschmid 845
                                                }
7352 fschmid 846
                                                else
546 fschmid 847
                                                {
7352 fschmid 848
                                                        ite->GrEndX = ite->width() / 2.0;
3934 cbradney 849
                                                        ite->GrEndY = ite->height();
546 fschmid 850
                                                }
7352 fschmid 851
                                                //ScMW->view->updateGradientVectors(ite);
852
                                                ite->updateGradientVectors();
546 fschmid 853
                                        }
545 fschmid 854
                                }
7352 fschmid 855
                                else
592 fschmid 856
                                {
7352 fschmid 857
                                        QPtrVector<VColorStop> cstops = gradient.colorStops();
858
                                        ite->setFillColor(cstops.at(0)->name);
859
                                        ite->setFillShade(cstops.at(0)->shade);
592 fschmid 860
                                }
545 fschmid 861
                                HaveGradient = false;
862
                        }
541 fschmid 863
                        GElements.append(ite);
864
                        Elements.append(ite);
865
                }
866
        }
991 fschmid 867
        return GElements;
541 fschmid 868
}
869
 
870
void OODPlug::createStyleMap( QDomDocument &docstyles )
871
{
872
        QDomElement styles = docstyles.documentElement();
873
        if( styles.isNull() )
874
                return;
875
 
876
        QDomNode fixedStyles = styles.namedItem( "office:styles" );
877
        if( !fixedStyles.isNull() )
878
        {
545 fschmid 879
                insertDraws( fixedStyles.toElement() );
541 fschmid 880
                insertStyles( fixedStyles.toElement() );
881
        }
882
        QDomNode automaticStyles = styles.namedItem( "office:automatic-styles" );
883
        if( !automaticStyles.isNull() )
884
                insertStyles( automaticStyles.toElement() );
885
 
886
        QDomNode masterStyles = styles.namedItem( "office:master-styles" );
887
        if( !masterStyles.isNull() )
888
                insertStyles( masterStyles.toElement() );
889
}
890
 
545 fschmid 891
void OODPlug::insertDraws( const QDomElement& styles )
892
{
893
        for( QDomNode n = styles.firstChild(); !n.isNull(); n = n.nextSibling() )
894
        {
895
                QDomElement e = n.toElement();
896
                if( !e.hasAttribute( "draw:name" ) )
897
                        continue;
898
                QString name = e.attribute( "draw:name" );
899
                m_draws.insert( name, new QDomElement( e ) );
900
        }
901
}
902
 
541 fschmid 903
void OODPlug::insertStyles( const QDomElement& styles )
904
{
905
        for ( QDomNode n = styles.firstChild(); !n.isNull(); n = n.nextSibling() )
906
        {
907
                QDomElement e = n.toElement();
908
                if( !e.hasAttribute( "style:name" ) )
909
                        continue;
910
                QString name = e.attribute( "style:name" );
911
                m_styles.insert( name, new QDomElement( e ) );
912
        }
913
}
914
 
915
void OODPlug::fillStyleStack( const QDomElement& object )
916
{
917
        if( object.hasAttribute( "presentation:style-name" ) )
918
                addStyles( m_styles[object.attribute( "presentation:style-name" )] );
919
        if( object.hasAttribute( "draw:style-name" ) )
920
                addStyles( m_styles[object.attribute( "draw:style-name" )] );
921
        if( object.hasAttribute( "draw:text-style-name" ) )
922
                addStyles( m_styles[object.attribute( "draw:text-style-name" )] );
923
        if( object.hasAttribute( "text:style-name" ) )
924
                addStyles( m_styles[object.attribute( "text:style-name" )] );
925
}
926
 
927
void OODPlug::addStyles( const QDomElement* style )
928
{
929
        if( style->hasAttribute( "style:parent-style-name" ) )
930
                addStyles( m_styles[style->attribute( "style:parent-style-name" )] );
931
        m_styleStack.push( *style );
932
}
933
 
934
void OODPlug::storeObjectStyles( const QDomElement& object )
935
{
936
        fillStyleStack( object );
937
}
938
 
939
double OODPlug::parseUnit(const QString &unit)
940
{
941
        QString unitval=unit;
2877 cbradney 942
        if (unit.isEmpty())
541 fschmid 943
                return 0.0;
944
        if( unit.right( 2 ) == "pt" )
945
                unitval.replace( "pt", "" );
946
        else if( unit.right( 2 ) == "cm" )
947
                unitval.replace( "cm", "" );
948
        else if( unit.right( 2 ) == "mm" )
949
                unitval.replace( "mm" , "" );
950
        else if( unit.right( 2 ) == "in" )
951
                unitval.replace( "in", "" );
952
        else if( unit.right( 2 ) == "px" )
953
                unitval.replace( "px", "" );
954
        double value = unitval.toDouble();
955
        if( unit.right( 2 ) == "pt" )
956
                value = value;
957
        else if( unit.right( 2 ) == "cm" )
958
                value = ( value / 2.54 ) * 72;
959
        else if( unit.right( 2 ) == "mm" )
960
                value = ( value / 25.4 ) * 72;
961
        else if( unit.right( 2 ) == "in" )
962
                value = value * 72;
963
        else if( unit.right( 2 ) == "px" )
964
                value = value;
965
        return value;
966
}
967
 
968
QColor OODPlug::parseColorN( const QString &rgbColor )
969
{
970
        int r, g, b;
971
        keywordToRGB( rgbColor, r, g, b );
972
        return QColor( r, g, b );
973
}
974
 
975
QString OODPlug::parseColor( const QString &s )
976
{
977
        QColor c;
4546 subik 978
        QString ret = CommonStrings::None;
541 fschmid 979
        if( s.startsWith( "rgb(" ) )
980
        {
981
                QString parse = s.stripWhiteSpace();
982
                QStringList colors = QStringList::split( ',', parse );
983
                QString r = colors[0].right( ( colors[0].length() - 4 ) );
984
                QString g = colors[1];
985
                QString b = colors[2].left( ( colors[2].length() - 1 ) );
986
                if( r.contains( "%" ) )
987
                {
988
                        r = r.left( r.length() - 1 );
989
                        r = QString::number( static_cast<int>( ( static_cast<double>( 255 * r.toDouble() ) / 100.0 ) ) );
990
                }
991
                if( g.contains( "%" ) )
992
                {
993
                        g = g.left( g.length() - 1 );
994
                        g = QString::number( static_cast<int>( ( static_cast<double>( 255 * g.toDouble() ) / 100.0 ) ) );
995
                }
996
                if( b.contains( "%" ) )
997
                {
998
                        b = b.left( b.length() - 1 );
999
                        b = QString::number( static_cast<int>( ( static_cast<double>( 255 * b.toDouble() ) / 100.0 ) ) );
1000
                }
1001
                c = QColor(r.toInt(), g.toInt(), b.toInt());
1002
        }
1003
        else
1004
        {
1005
                QString rgbColor = s.stripWhiteSpace();
1006
                if( rgbColor.startsWith( "#" ) )
1007
                        c.setNamedColor( rgbColor );
1008
                else
1009
                        c = parseColorN( rgbColor );
1010
        }
1065 cbradney 1011
        ColorList::Iterator it;
541 fschmid 1012
        bool found = false;
1488 fschmid 1013
        int r, g, b;
1014
        QColor tmpR;
541 fschmid 1015
        for (it = Doku->PageColors.begin(); it != Doku->PageColors.end(); ++it)
1016
        {
1488 fschmid 1017
                Doku->PageColors[it.key()].getRGB(&r, &g, &b);
1018
                tmpR.setRgb(r, g, b);
1019
                if (c == tmpR && Doku->PageColors[it.key()].getColorModel() == colorModelRGB)
541 fschmid 1020
                {
1021
                        ret = it.key();
1022
                        found = true;
1023
                }
1024
        }
1025
        if (!found)
1026
        {
2886 fschmid 1027
                ScColor tmp;
541 fschmid 1028
                tmp.fromQColor(c);
7490 fschmid 1029
                tmp.setSpotColor(false);
1030
                tmp.setRegistrationColor(false);
541 fschmid 1031
                Doku->PageColors.insert("FromOODraw"+c.name(), tmp);
4026 craig 1032
                ScMW->propertiesPalette->updateColorList();
541 fschmid 1033
                ret = "FromOODraw"+c.name();
1034
        }
1035
        return ret;
1036
}
1037
 
546 fschmid 1038
void OODPlug::parseTransform(FPointArray *composite, const QString &transform)
541 fschmid 1039
{
545 fschmid 1040
        double dx, dy;
1041
        QWMatrix result;
541 fschmid 1042
        QStringList subtransforms = QStringList::split(')', transform);
1043
        QStringList::ConstIterator it = subtransforms.begin();
1044
        QStringList::ConstIterator end = subtransforms.end();
546 fschmid 1045
        for (; it != end; ++it)
541 fschmid 1046
        {
1047
                QStringList subtransform = QStringList::split('(', (*it));
1048
                subtransform[0] = subtransform[0].stripWhiteSpace().lower();
1049
                subtransform[1] = subtransform[1].simplifyWhiteSpace();
1050
                QRegExp reg("[,( ]");
1051
                QStringList params = QStringList::split(reg, subtransform[1]);
1052
                if(subtransform[0].startsWith(";") || subtransform[0].startsWith(","))
1053
                        subtransform[0] = subtransform[0].right(subtransform[0].length() - 1);
1054
                if(subtransform[0] == "rotate")
546 fschmid 1055
                {
1056
                        result = QWMatrix();
1795 cbradney 1057
                        result.rotate(-parseUnit(params[0]) * 180 / M_PI);
546 fschmid 1058
                        composite->map(result);
1059
                }
541 fschmid 1060
                else if(subtransform[0] == "translate")
1061
                {
1062
                        if(params.count() == 2)
1063
                        {
545 fschmid 1064
                                dx = parseUnit(params[0]);
1065
                                dy = parseUnit(params[1]);
541 fschmid 1066
                        }
1067
                        else
1068
                        {
545 fschmid 1069
                                dx = parseUnit(params[0]);
1070
                                dy =0.0;
541 fschmid 1071
                        }
546 fschmid 1072
                        result = QWMatrix();
545 fschmid 1073
                        result.translate(dx, dy);
546 fschmid 1074
                        composite->map(result);
541 fschmid 1075
                }
545 fschmid 1076
                else if(subtransform[0] == "skewx")
546 fschmid 1077
                {
1078
                        result = QWMatrix();
5719 jghali 1079
                        result.shear(-tan(params[0].toDouble()), 0.0);
546 fschmid 1080
                        composite->map(result);
1081
                }
545 fschmid 1082
                else if(subtransform[0] == "skewy")
546 fschmid 1083
                {
1084
                        result = QWMatrix();
5719 jghali 1085
                        result.shear(0.0, -tan(params[0].toDouble()));
546 fschmid 1086
                        composite->map(result);
1087
                }
541 fschmid 1088
        }
1089
}
1090
 
544 fschmid 1091
void OODPlug::parseViewBox( const QDomElement& object, double *x, double *y, double *w, double *h )
541 fschmid 1092
{
544 fschmid 1093
        if( !object.attribute( "svg:viewBox" ).isEmpty() )
1094
        {
1095
                QString viewbox( object.attribute( "svg:viewBox" ) );
1096
                QStringList points = QStringList::split( ' ', viewbox.replace( QRegExp(","), " ").simplifyWhiteSpace() );
1097
                *x = points[0].toDouble();
1098
                *y = points[1].toDouble();
1099
                *w = points[2].toDouble();
1100
                *h = points[3].toDouble();
1101
        }
541 fschmid 1102
}
1103
 
10417 jghali 1104
void OODPlug::appendPoints(FPointArray *composite, const QDomElement& object, bool closePath)
541 fschmid 1105
{
544 fschmid 1106
        double x = parseUnit(object.attribute("svg:x"));
1107
        double y = parseUnit(object.attribute("svg:y")) ;
1108
        double w = parseUnit(object.attribute("svg:width"));
1109
        double h = parseUnit(object.attribute("svg:height"));
1110
        double vx = 0;
1111
        double vy = 0;
1112
        double vw = 1;
1113
        double vh = 1;
1114
        parseViewBox(object, &vx, &vy, &vw, &vh);
10937 jghali 1115
        double sx = (vw != 0.0) ? (w / vw) : w;
1116
        double sy = (vh != 0.0) ? (h / vh) : h;
544 fschmid 1117
        QStringList ptList = QStringList::split( ' ', object.attribute( "draw:points" ) );
1118
        FPoint point, firstP;
1119
        bool bFirst = true;
1120
        for( QStringList::Iterator it = ptList.begin(); it != ptList.end(); ++it )
1121
        {
1122
                point = FPoint((*it).section( ',', 0, 0 ).toDouble(), (*it).section( ',', 1, 1 ).toDouble());
1123
                if (bFirst)
1124
                {
1125
                        composite->addPoint(point);
1126
                        composite->addPoint(point);
1127
                        firstP = point;
1128
                        bFirst = false;
1129
                }
1130
                else
1131
                {
1132
                        composite->addPoint(point);
1133
                        composite->addPoint(point);
1134
                        composite->addPoint(point);
1135
                        composite->addPoint(point);
1136
                }
1137
    }
10417 jghali 1138
        if (closePath)
1139
        {
1140
                composite->addPoint(firstP);
1141
                composite->addPoint(firstP);
1142
        }
544 fschmid 1143
        QWMatrix mat;
1144
        mat.translate(x, y);
10937 jghali 1145
        mat.scale(sx, sy);
544 fschmid 1146
        composite->map(mat);
541 fschmid 1147
}
1148
 
544 fschmid 1149
const char * OODPlug::getCoord( const char *ptr, double &number )
541 fschmid 1150
{
1151
        int integer, exponent;
1152
        double decimal, frac;
1153
        int sign, expsign;
1154
 
1155
        exponent = 0;
1156
        integer = 0;
1157
        frac = 1.0;
1158
        decimal = 0;
1159
        sign = 1;
1160
        expsign = 1;
1161
 
544 fschmid 1162
        // read the sign
541 fschmid 1163
        if(*ptr == '+')
1164
                ptr++;
1165
        else if(*ptr == '-')
1166
        {
1167
                ptr++;
1168
                sign = -1;
1169
        }
1170
 
544 fschmid 1171
        // read the integer part
541 fschmid 1172
        while(*ptr != '\0' && *ptr >= '0' && *ptr <= '9')
1173
                integer = (integer * 10) + *(ptr++) - '0';
544 fschmid 1174
        if(*ptr == '.') // read the decimals
541 fschmid 1175
        {
1176
                ptr++;
1177
                while(*ptr != '\0' && *ptr >= '0' && *ptr <= '9')
1178
                        decimal += (*(ptr++) - '0') * (frac *= 0.1);
1179
        }
1180
 
544 fschmid 1181
        if(*ptr == 'e' || *ptr == 'E') // read the exponent part
541 fschmid 1182
        {
1183
                ptr++;
1184
 
544 fschmid 1185
                // read the sign of the exponent
541 fschmid 1186
                if(*ptr == '+')
1187
                        ptr++;
1188
                else if(*ptr == '-')
1189
                {
1190
                        ptr++;
1191
                        expsign = -1;
1192
                }
1193
 
1194
                exponent = 0;
1195
                while(*ptr != '\0' && *ptr >= '0' && *ptr <= '9')
1196
                {
1197
                        exponent *= 10;
1198
                        exponent += *ptr - '0';
1199
                        ptr++;
1200
                }
1201
        }
1202
        number = integer + decimal;
1203
        number *= sign * pow( static_cast<double>(10), static_cast<double>( expsign * exponent ) );
1204
 
544 fschmid 1205
        // skip the following space
541 fschmid 1206
        if(*ptr == ' ')
1207
                ptr++;
1208
 
1209
        return ptr;
1210
}
1211
 
544 fschmid 1212
bool OODPlug::parseSVG( const QString &s, FPointArray *ite )
541 fschmid 1213
{
1214
        QString d = s;
1215
        d = d.replace( QRegExp( "," ), " ");
1216
        bool ret = false;
1217
        if( !d.isEmpty() )
1218
        {
1219
                d = d.simplifyWhiteSpace();
1220
                const char *ptr = d.latin1();
1221
                const char *end = d.latin1() + d.length() + 1;
1222
                double contrlx, contrly, curx, cury, subpathx, subpathy, tox, toy, x1, y1, x2, y2, xc, yc;
1223
                double px1, py1, px2, py2, px3, py3;
1224
                bool relative;
1225
                FirstM = true;
1226
                char command = *(ptr++), lastCommand = ' ';
1227
                subpathx = subpathy = curx = cury = contrlx = contrly = 0.0;
1228
                while( ptr < end )
1229
                {
1230
                        if( *ptr == ' ' )
1231
                                ptr++;
1232
                        relative = false;
1233
                        switch( command )
1234
                        {
1235
                        case 'm':
1236
                                relative = true;
1237
                        case 'M':
1238
                                {
1239
                                        ptr = getCoord( ptr, tox );
1240
                                        ptr = getCoord( ptr, toy );
1241
                                        WasM = true;
1242
                                        subpathx = curx = relative ? curx + tox : tox;
1243
                                        subpathy = cury = relative ? cury + toy : toy;
1244
                                        svgMoveTo(curx, cury );
1245
                                        break;
1246
                                }
1247
                        case 'l':
1248
                                relative = true;
1249
                        case 'L':
1250
                                {
1251
                                        ptr = getCoord( ptr, tox );
1252
                                        ptr = getCoord( ptr, toy );
1253
                                        curx = relative ? curx + tox : tox;
1254
                                        cury = relative ? cury + toy : toy;
1255
                                        svgLineTo(ite, curx, cury );
1256
                                        break;
1257
                                }
1258
                        case 'h':
1259
                                {
1260
                                        ptr = getCoord( ptr, tox );
1261
                                        curx = curx + tox;
1262
                                        svgLineTo(ite, curx, cury );
1263
                                        break;
1264
                                }
1265
                        case 'H':
1266
                                {
1267
                                        ptr = getCoord( ptr, tox );
1268
                                        curx = tox;
1269
                                        svgLineTo(ite, curx, cury );
1270
                                        break;
1271
                                }
1272
                        case 'v':
1273
                                {
1274
                                        ptr = getCoord( ptr, toy );
1275
                                        cury = cury + toy;
1276
                                        svgLineTo(ite, curx, cury );
1277
                                        break;
1278
                                }
1279
                        case 'V':
1280
                                {
1281
                                        ptr = getCoord( ptr, toy );
1282
                                        cury = toy;
1283
                                        svgLineTo(ite,  curx, cury );
1284
                                        break;
1285
                                }
1286
                        case 'z':
1287
                        case 'Z':
1288
                                {
587 fschmid 1289
//                                      curx = subpathx;
1290
//                                      cury = subpathy;
541 fschmid 1291
                                        svgClosePath(ite);
1292
                                        break;
1293
                                }
1294
                        case 'c':
1295
                                relative = true;
1296
                        case 'C':
1297
                                {
1298
                                        ptr = getCoord( ptr, x1 );
1299
                                        ptr = getCoord( ptr, y1 );
1300
                                        ptr = getCoord( ptr, x2 );
1301
                                        ptr = getCoord( ptr, y2 );
1302
                                        ptr = getCoord( ptr, tox );
1303
                                        ptr = getCoord( ptr, toy );
1304
                                        px1 = relative ? curx + x1 : x1;
1305
                                        py1 = relative ? cury + y1 : y1;
1306
                                        px2 = relative ? curx + x2 : x2;
1307
                                        py2 = relative ? cury + y2 : y2;
1308
                                        px3 = relative ? curx + tox : tox;
1309
                                        py3 = relative ? cury + toy : toy;
1310
                                        svgCurveToCubic(ite, px1, py1, px2, py2, px3, py3 );
1311
                                        contrlx = relative ? curx + x2 : x2;
1312
                                        contrly = relative ? cury + y2 : y2;
1313
                                        curx = relative ? curx + tox : tox;
1314
                                        cury = relative ? cury + toy : toy;
1315
                                        break;
1316
                                }
1317
                        case 's':
1318
                                relative = true;
1319
                        case 'S':
1320
                                {
1321
                                        ptr = getCoord( ptr, x2 );
1322
                                        ptr = getCoord( ptr, y2 );
1323
                                        ptr = getCoord( ptr, tox );
1324
                                        ptr = getCoord( ptr, toy );
1325
                                        px1 = 2 * curx - contrlx;
1326
                                        py1 = 2 * cury - contrly;
1327
                                        px2 = relative ? curx + x2 : x2;
1328
                                        py2 = relative ? cury + y2 : y2;
1329
                                        px3 = relative ? curx + tox : tox;
1330
                                        py3 = relative ? cury + toy : toy;
1331
                                        svgCurveToCubic(ite, px1, py1, px2, py2, px3, py3 );
1332
                                        contrlx = relative ? curx + x2 : x2;
1333
                                        contrly = relative ? cury + y2 : y2;
1334
                                        curx = relative ? curx + tox : tox;
1335
                                        cury = relative ? cury + toy : toy;
1336
                                        break;
1337
                                }
1338
                        case 'q':
1339
                                relative = true;
1340
                        case 'Q':
1341
                                {
1342
                                        ptr = getCoord( ptr, x1 );
1343
                                        ptr = getCoord( ptr, y1 );
1344
                                        ptr = getCoord( ptr, tox );
1345
                                        ptr = getCoord( ptr, toy );
1346
                                        px1 = relative ? (curx + 2 * (x1 + curx)) * (1.0 / 3.0) : (curx + 2 * x1) * (1.0 / 3.0);
1347
                                        py1 = relative ? (cury + 2 * (y1 + cury)) * (1.0 / 3.0) : (cury + 2 * y1) * (1.0 / 3.0);
1348
                                        px2 = relative ? ((curx + tox) + 2 * (x1 + curx)) * (1.0 / 3.0) : (tox + 2 * x1) * (1.0 / 3.0);
1349
                                        py2 = relative ? ((cury + toy) + 2 * (y1 + cury)) * (1.0 / 3.0) : (toy + 2 * y1) * (1.0 / 3.0);
1350
                                        px3 = relative ? curx + tox : tox;
1351
                                        py3 = relative ? cury + toy : toy;
1352
                                        svgCurveToCubic(ite, px1, py1, px2, py2, px3, py3 );
1353
                                        contrlx = relative ? curx + x1 : (tox + 2 * x1) * (1.0 / 3.0);
1354
                                        contrly = relative ? cury + y1 : (toy + 2 * y1) * (1.0 / 3.0);
1355
                                        curx = relative ? curx + tox : tox;
1356
                                        cury = relative ? cury + toy : toy;
1357
                                        break;
1358
                                }
1359
                        case 't':
1360
                                relative = true;
1361
                        case 'T':
1362
                                {
1363
                                        ptr = getCoord(ptr, tox);
1364
                                        ptr = getCoord(ptr, toy);
1365
                                        xc = 2 * curx - contrlx;
1366
                                        yc = 2 * cury - contrly;
1367
                                        px1 = relative ? (curx + 2 * xc) * (1.0 / 3.0) : (curx + 2 * xc) * (1.0 / 3.0);
1368
                                        py1 = relative ? (cury + 2 * yc) * (1.0 / 3.0) : (cury + 2 * yc) * (1.0 / 3.0);
1369
                                        px2 = relative ? ((curx + tox) + 2 * xc) * (1.0 / 3.0) : (tox + 2 * xc) * (1.0 / 3.0);
1370
                                        py2 = relative ? ((cury + toy) + 2 * yc) * (1.0 / 3.0) : (toy + 2 * yc) * (1.0 / 3.0);
1371
                                        px3 = relative ? curx + tox : tox;
1372
                                        py3 = relative ? cury + toy : toy;
1373
                                        svgCurveToCubic(ite, px1, py1, px2, py2, px3, py3 );
1374
                                        contrlx = xc;
1375
                                        contrly = yc;
1376
                                        curx = relative ? curx + tox : tox;
1377
                                        cury = relative ? cury + toy : toy;
1378
                                        break;
1379
                                }
1380
                        case 'a':
1381
                                relative = true;
1382
                        case 'A':
1383
                                {
1384
                                        bool largeArc, sweep;
1385
                                        double angle, rx, ry;
1386
                                        ptr = getCoord( ptr, rx );
1387
                                        ptr = getCoord( ptr, ry );
1388
                                        ptr = getCoord( ptr, angle );
1389
                                        ptr = getCoord( ptr, tox );
1390
                                        largeArc = tox == 1;
1391
                                        ptr = getCoord( ptr, tox );
1392
                                        sweep = tox == 1;
1393
                                        ptr = getCoord( ptr, tox );
1394
                                        ptr = getCoord( ptr, toy );
1395
                                        calculateArc(ite, relative, curx, cury, angle, tox, toy, rx, ry, largeArc, sweep );
1396
                                }
1397
                        }
1398
                        lastCommand = command;
1399
                        if(*ptr == '+' || *ptr == '-' || (*ptr >= '0' && *ptr <= '9'))
1400
                        {
1401
                                // there are still coords in this command
1402
                                if(command == 'M')
1403
                                        command = 'L';
1404
                                else if(command == 'm')
1405
                                        command = 'l';
1406
                        }
1407
                        else
1408
                                command = *(ptr++);
1409
 
1410
                        if( lastCommand != 'C' && lastCommand != 'c' &&
1411
                                lastCommand != 'S' && lastCommand != 's' &&
1412
                                lastCommand != 'Q' && lastCommand != 'q' &&
1413
                                lastCommand != 'T' && lastCommand != 't')
1414
                        {
1415
                                contrlx = curx;
1416
                                contrly = cury;
1417
                        }
1418
                }
1419
                if ((lastCommand != 'z') && (lastCommand != 'Z'))
1420
                        ret = true;
1421
                if (ite->size() > 2)
1422
                {
1423
                        if ((ite->point(0).x() == ite->point(ite->size()-2).x()) && (ite->point(0).y() == ite->point(ite->size()-2).y()))
1424
                                ret = false;
1425
                }
1426
        }
1427
        return ret;
1428
}
1429
 
544 fschmid 1430
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 1431
{
1432
        double sin_th, cos_th;
1433
        double a00, a01, a10, a11;
1434
        double x0, y0, x1, y1, xc, yc;
1435
        double d, sfactor, sfactor_sq;
1436
        double th0, th1, th_arc;
1437
        int i, n_segs;
1438
        sin_th = sin(angle * (M_PI / 180.0));
1439
        cos_th = cos(angle * (M_PI / 180.0));
1440
        double dx;
1441
        if(!relative)
1442
                dx = (curx - x) / 2.0;
1443
        else
1444
                dx = -x / 2.0;
1445
        double dy;
1446
        if(!relative)
1447
                dy = (cury - y) / 2.0;
1448
        else
1449
                dy = -y / 2.0;
1450
        double _x1 =  cos_th * dx + sin_th * dy;
1451
        double _y1 = -sin_th * dx + cos_th * dy;
1452
        double Pr1 = r1 * r1;
1453
        double Pr2 = r2 * r2;
1454
        double Px = _x1 * _x1;
1455
        double Py = _y1 * _y1;
1456
        double check = Px / Pr1 + Py / Pr2;
1457
        if(check > 1)
1458
        {
1459
                r1 = r1 * sqrt(check);
1460
                r2 = r2 * sqrt(check);
1461
        }
1462
        a00 = cos_th / r1;
1463
        a01 = sin_th / r1;
1464
        a10 = -sin_th / r2;
1465
        a11 = cos_th / r2;
1466
        x0 = a00 * curx + a01 * cury;
1467
        y0 = a10 * curx + a11 * cury;
1468
        if(!relative)
1469
                x1 = a00 * x + a01 * y;
1470
        else
1471
                x1 = a00 * (curx + x) + a01 * (cury + y);
1472
        if(!relative)
1473
                y1 = a10 * x + a11 * y;
1474
        else
1475
                y1 = a10 * (curx + x) + a11 * (cury + y);
1476
        d = (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0);
1477
        sfactor_sq = 1.0 / d - 0.25;
1478
        if(sfactor_sq < 0)
1479
                sfactor_sq = 0;
1480
        sfactor = sqrt(sfactor_sq);
1481
        if(sweepFlag == largeArcFlag)
1482
                sfactor = -sfactor;
1483
        xc = 0.5 * (x0 + x1) - sfactor * (y1 - y0);
1484
        yc = 0.5 * (y0 + y1) + sfactor * (x1 - x0);
1485
 
1486
        th0 = atan2(y0 - yc, x0 - xc);
1487
        th1 = atan2(y1 - yc, x1 - xc);
1488
        th_arc = th1 - th0;
1489
        if(th_arc < 0 && sweepFlag)
1490
                th_arc += 2 * M_PI;
1491
        else if(th_arc > 0 && !sweepFlag)
1492
                th_arc -= 2 * M_PI;
1493
        n_segs = static_cast<int>(ceil(fabs(th_arc / (M_PI * 0.5 + 0.001))));
1494
        for(i = 0; i < n_segs; i++)
1495
        {
1496
                {
1497
                        double sin_th, cos_th;
1498
                        double a00, a01, a10, a11;
1499
                        double x1, y1, x2, y2, x3, y3;
1500
                        double t;
1501
                        double th_half;
1502
                        double _th0 = th0 + i * th_arc / n_segs;
1503
                        double _th1 = th0 + (i + 1) * th_arc / n_segs;
1504
                        sin_th = sin(angle * (M_PI / 180.0));
1505
                        cos_th = cos(angle * (M_PI / 180.0));
1506
                        a00 = cos_th * r1;
1507
                        a01 = -sin_th * r2;
1508
                        a10 = sin_th * r1;
1509
                        a11 = cos_th * r2;
1510
                        th_half = 0.5 * (_th1 - _th0);
1511
                        t = (8.0 / 3.0) * sin(th_half * 0.5) * sin(th_half * 0.5) / sin(th_half);
1512
                        x1 = xc + cos(_th0) - t * sin(_th0);
1513
                        y1 = yc + sin(_th0) + t * cos(_th0);
1514
                        x3 = xc + cos(_th1);
1515
                        y3 = yc + sin(_th1);
1516
                        x2 = x3 + t * sin(_th1);
1517
                        y2 = y3 - t * cos(_th1);
1518
                        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 );
1519
                }
1520
        }
1521
        if(!relative)
1522
                curx = x;
1523
        else
1524
                curx += x;
1525
        if(!relative)
1526
                cury = y;
1527
        else
1528
                cury += y;
1529
}
1530
 
544 fschmid 1531
void OODPlug::svgMoveTo(double x1, double y1)
541 fschmid 1532
{
1533
        CurrX = x1;
1534
        CurrY = y1;
1535
        StartX = x1;
1536
        StartY = y1;
1537
        PathLen = 0;
1538
}
1539
 
544 fschmid 1540
void OODPlug::svgLineTo(FPointArray *i, double x1, double y1)
541 fschmid 1541
{
1542
        if ((!FirstM) && (WasM))
1543
        {
1544
                i->setMarker();
1545
                PathLen += 4;
1546
        }
1547
        FirstM = false;
1548
        WasM = false;
1549
        if (i->size() > 3)
1550
        {
1551
                FPoint b1 = i->point(i->size()-4);
1552
                FPoint b2 = i->point(i->size()-3);
1553
                FPoint b3 = i->point(i->size()-2);
1554
                FPoint b4 = i->point(i->size()-1);
1555
                FPoint n1 = FPoint(CurrX, CurrY);
1556
                FPoint n2 = FPoint(x1, y1);
1557
                if ((b1 == n1) && (b2 == n1) && (b3 == n2) && (b4 == n2))
1558
                        return;
1559
        }
1560
        i->addPoint(FPoint(CurrX, CurrY));
1561
        i->addPoint(FPoint(CurrX, CurrY));
1562
        i->addPoint(FPoint(x1, y1));
1563
        i->addPoint(FPoint(x1, y1));
1564
        CurrX = x1;
1565
        CurrY = y1;
1566
        PathLen += 4;
1567
}
1568
 
544 fschmid 1569
void OODPlug::svgCurveToCubic(FPointArray *i, double x1, double y1, double x2, double y2, double x3, double y3)
541 fschmid 1570
{
1571
        if ((!FirstM) && (WasM))
1572
        {
1573
                i->setMarker();
1574
                PathLen += 4;
1575
        }
1576
        FirstM = false;
1577
        WasM = false;
1578
        if (PathLen > 3)
1579
        {
1580
                FPoint b1 = i->point(i->size()-4);
1581
                FPoint b2 = i->point(i->size()-3);
1582
                FPoint b3 = i->point(i->size()-2);
1583
                FPoint b4 = i->point(i->size()-1);
1584
                FPoint n1 = FPoint(CurrX, CurrY);
1585
                FPoint n2 = FPoint(x1, y1);
1586
                FPoint n3 = FPoint(x3, y3);
1587
                FPoint n4 = FPoint(x2, y2);
1588
                if ((b1 == n1) && (b2 == n2) && (b3 == n3) && (b4 == n4))
1589
                        return;
1590
        }
1591
        i->addPoint(FPoint(CurrX, CurrY));
1592
        i->addPoint(FPoint(x1, y1));
1593
        i->addPoint(FPoint(x3, y3));
1594
        i->addPoint(FPoint(x2, y2));
1595
        CurrX = x3;
1596
        CurrY = y3;
1597
        PathLen += 4;
1598
}
1599
 
544 fschmid 1600
void OODPlug::svgClosePath(FPointArray *i)
541 fschmid 1601
{
1602
        if (PathLen > 2)
1603
        {
1604
                if ((PathLen == 4) || (i->point(i->size()-2).x() != StartX) || (i->point(i->size()-2).y() != StartY))
1605
                {
1606
                        i->addPoint(i->point(i->size()-2));
1607
                        i->addPoint(i->point(i->size()-3));
1608
                        i->addPoint(FPoint(StartX, StartY));
1609
                        i->addPoint(FPoint(StartX, StartY));
1610
                }
1611
        }
1612
}
1613
 
544 fschmid 1614
OODPlug::~OODPlug()
1615
{}
541 fschmid 1616