Subversion Repositories Scribus

Rev

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