Subversion Repositories Scribus

Rev

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