Subversion Repositories Scribus

Rev

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

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