Subversion Repositories Scribus

Rev

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

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