Subversion Repositories Scribus

Rev

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

Rev Author Line No. Line
4430 cbradney 1
/*
2
For general Scribus (>=1.3.2) copyright and licensing information please refer
3
to the COPYING file provided with the program. Following this notice may exist
4
a copyright and/or license notice that predates the release of Scribus 1.3.2
5
for which a new license (GPL+exception) is in place.
6
*/
21 Franz 7
/***************************************************************************
8
                          svgexplugin.cpp  -  description
9
                             -------------------
10
    begin                : Sun Aug 3 08:00:00 CEST 2002
11
    copyright            : (C) 2002 by Franz Schmid
12
    email                : Franz.Schmid@altmuehlnet.de
13
 ***************************************************************************/
14
 
15
/***************************************************************************
16
 *                                                                         *
17
 *   This program is free software; you can redistribute it and/or modify  *
18
 *   it under the terms of the GNU General Public License as published by  *
19
 *   the Free Software Foundation; either version 2 of the License, or     *
20
 *   (at your option) any later version.                                   *
21
 *                                                                         *
22
 ***************************************************************************/
766 cbradney 23
 
24
#include <qfile.h>
25
#include <qtextstream.h>
26
 
21 Franz 27
#include "svgexplugin.h"
512 fschmid 28
 
2688 craig 29
#include "scconfig.h"
4546 subik 30
#include "commonstrings.h"
21 Franz 31
#include "customfdialog.h"
766 cbradney 32
#include "scribus.h"
3670 cbradney 33
#include "page.h"
68 Franz 34
#ifdef HAVE_LIBZ
35
#include <zlib.h>
36
#endif
2856 cbradney 37
#include "prefsmanager.h"
3670 cbradney 38
#include "prefsfile.h"
39
#include "prefscontext.h"
3953 cbradney 40
#include "scmessagebox.h"
2533 craig 41
#include "util.h"
4182 subik 42
#include "customfdialog.h"
1552 subik 43
 
4182 subik 44
 
3207 craig 45
int svgexplugin_getPluginAPIVersion()
21 Franz 46
{
3207 craig 47
        return PLUGIN_API_VERSION;
21 Franz 48
}
49
 
3207 craig 50
ScPlugin* svgexplugin_getPlugin()
21 Franz 51
{
3207 craig 52
        SVGExportPlugin* plug = new SVGExportPlugin();
53
        Q_CHECK_PTR(plug);
54
        return plug;
21 Franz 55
}
56
 
3207 craig 57
void svgexplugin_freePlugin(ScPlugin* plugin)
512 fschmid 58
{
3207 craig 59
        SVGExportPlugin* plug = dynamic_cast<SVGExportPlugin*>(plugin);
60
        Q_ASSERT(plug);
61
        delete plug;
512 fschmid 62
}
63
 
3686 craig 64
SVGExportPlugin::SVGExportPlugin() : ScActionPlugin()
1208 cbradney 65
{
3207 craig 66
        // Set action info in languageChange, so we only have to do
67
        // it in one place.
68
        languageChange();
1208 cbradney 69
}
70
 
3207 craig 71
SVGExportPlugin::~SVGExportPlugin() {};
72
 
73
void SVGExportPlugin::languageChange()
1208 cbradney 74
{
3207 craig 75
        // Note that we leave the unused members unset. They'll be initialised
76
        // with their default ctors during construction.
77
        // Action name
78
        m_actionInfo.name = "ExportAsSVG";
79
        // Action text for menu, including accel
80
        m_actionInfo.text = tr("Save Page as &SVG...");
81
        // Menu
82
        m_actionInfo.menu = "FileExport";
83
        m_actionInfo.enabledOnStartup = true;
1208 cbradney 84
}
85
 
3207 craig 86
const QString SVGExportPlugin::fullTrName() const
1208 cbradney 87
{
3207 craig 88
        return QObject::tr("SVG Export");
1208 cbradney 89
}
90
 
3207 craig 91
const ScActionPlugin::AboutData* SVGExportPlugin::getAboutData() const
1208 cbradney 92
{
3241 craig 93
        AboutData* about = new AboutData;
3344 fschmid 94
        about->authors = "Franz Schmid <franz@scribus.info>";
3355 cbradney 95
        about->shortDescription = tr("Exports SVG Files");
3357 cbradney 96
        about->description = tr("Exports the current page into an SVG file.");
3344 fschmid 97
        about->license = "GPL";
3241 craig 98
        Q_CHECK_PTR(about);
99
        return about;
1208 cbradney 100
}
101
 
3241 craig 102
void SVGExportPlugin::deleteAboutData(const AboutData* about) const
1208 cbradney 103
{
3241 craig 104
        Q_ASSERT(about);
105
        delete about;
1208 cbradney 106
}
107
 
3207 craig 108
bool SVGExportPlugin::run(QString filename)
21 Franz 109
{
3207 craig 110
        Q_ASSERT(filename.isEmpty());
4182 subik 111
        QString fileName;
112
 
4026 craig 113
        if (ScMW->HaveDoc)
2875 subik 114
        {
2856 cbradney 115
                PrefsContext* prefs = PrefsManager::instance()->prefsFile->getPluginContext("svgex");
415 Franz 116
                QString wdir = prefs->get("wdir", ".");
68 Franz 117
#ifdef HAVE_LIBZ
4182 subik 118
                CustomFDialog *openDia = new CustomFDialog(ScMW, wdir, QObject::tr("Save as"), QObject::tr("SVG-Images (*.svg *.svgz);;All Files (*)"), false, false, true, false, false);
68 Franz 119
#else
4182 subik 120
                CustomFDialog *openDia = new CustomFDialog(ScMW, wdir, QObject::tr("Save as"), QObject::tr("SVG-Images (*.svg);;All Files (*)"), false, false, false, false, false);
68 Franz 121
#endif
4182 subik 122
                openDia->setSelection(getFileNameByPage(ScMW->doc->currentPage->pageNr(), "svg"));
123
                openDia->setExtension("svg");
124
                openDia->setZipExtension("svgz");
125
                if (openDia->exec())
126
                        fileName = openDia->selectedFile();
127
                delete openDia;
128
 
21 Franz 129
                if (!fileName.isEmpty())
2875 subik 130
                {
131
                        prefs->set("wdir", fileName.left(fileName.findRev("/")));
132
                        QFile f(fileName);
133
                        if (f.exists())
21 Franz 134
                        {
4026 craig 135
                                int exit=ScMessageBox::warning(ScMW, QObject::tr("Warning"),
2875 subik 136
                                        QObject::tr("Do you really want to overwrite the File:\n%1 ?").arg(fileName),
137
                                        QObject::tr("Yes"),
138
                                        QObject::tr("No"),
139
                                        0, 0, 1);
140
                                if (exit != 0)
3207 craig 141
                                        return true;
21 Franz 142
                        }
3207 craig 143
                        SVGExPlug *dia = new SVGExPlug(fileName);
2875 subik 144
                        delete dia;
145
                }
21 Franz 146
                else
3207 craig 147
                        return true;
2875 subik 148
        }
3207 craig 149
        return true;
21 Franz 150
}
151
 
3207 craig 152
SVGExPlug::SVGExPlug( QString fName )
21 Franz 153
{
154
        QDomDocument docu("svgdoc");
68 Franz 155
        QString vo = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
21 Franz 156
        QString st = "<svg></svg>";
157
        docu.setContent(st);
158
        QDomElement elem = docu.documentElement();
4026 craig 159
        elem.setAttribute("width", FToStr(ScMW->doc->pageWidth)+"pt");
160
        elem.setAttribute("height", FToStr(ScMW->doc->pageHeight)+"pt");
68 Franz 161
        elem.setAttribute("xmlns", "http://www.w3.org/2000/svg");
1552 subik 162
        elem.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink");
21 Franz 163
        Page *Seite;
164
        GradCount = 0;
22 Franz 165
        ClipCount = 0;
4026 craig 166
        Seite = ScMW->doc->MasterPages.at(ScMW->doc->MasterNames[ScMW->doc->currentPage->MPageNam]);
3207 craig 167
        ProcessPage(Seite, &docu, &elem);
4026 craig 168
        Seite = ScMW->doc->currentPage;
3207 craig 169
        ProcessPage(Seite, &docu, &elem);
68 Franz 170
#ifdef HAVE_LIBZ
171
        if(fName.right(2) == "gz")
172
                {
173
// zipped saving
174
                gzFile gzDoc = gzopen(fName.latin1(),"wb");
175
                if(gzDoc == NULL)
176
                        return;
177
                gzputs(gzDoc, vo);
178
                gzputs(gzDoc, docu.toString().utf8());
179
                gzclose(gzDoc);
180
                }
181
        else
182
                {
183
                QFile f(fName);
184
                if(!f.open(IO_WriteOnly))
185
                        return;
186
                QTextStream s(&f);
187
                QString wr = vo;
188
                wr += docu.toString().utf8();
189
                s.writeRawBytes(wr, wr.length());
190
                f.close();
191
                }
192
#else
21 Franz 193
        QFile f(fName);
194
        if(!f.open(IO_WriteOnly))
195
                return;
196
        QTextStream s(&f);
68 Franz 197
        QString wr = vo;
198
        wr += docu.toString().utf8();
199
        s.writeRawBytes(wr, wr.length());
21 Franz 200
        f.close();
68 Franz 201
#endif
21 Franz 202
}
203
 
3207 craig 204
void SVGExPlug::ProcessPage(Page *Seite, QDomDocument *docu, QDomElement *elem)
21 Franz 205
{
55 Franz 206
        QString tmp, trans, fill, stroke, strokeW, strokeLC, strokeLJ, strokeDA, gradi, Clipi, chx;
21 Franz 207
        uint d;
1065 cbradney 208
        struct ScText *hl;
21 Franz 209
        int Lnr = 0;
210
        struct Layer ll;
1065 cbradney 211
        ll.isPrintable = false;
21 Franz 212
        ll.LNr = 0;
213
        QDomElement ob, gr, tp, tp2, defi, grad;
214
        QDomText tp1;
215
        PageItem *Item;
216
        gradi = "Grad";
22 Franz 217
        Clipi = "Clip";
456 fschmid 218
        QPtrList<PageItem> Items;
4026 craig 219
        Page* SavedAct = ScMW->doc->currentPage;
220
        ScMW->doc->currentPage = Seite;
2877 cbradney 221
        if (Seite->PageNam.isEmpty())
4026 craig 222
                Items = ScMW->doc->DocItems;
456 fschmid 223
        else
4026 craig 224
                Items = ScMW->doc->MasterItems;
225
        for (uint la = 0; la < ScMW->doc->Layers.count(); la++)
21 Franz 226
                {
4026 craig 227
                Level2Layer(ScMW->doc, &ll, Lnr);
1065 cbradney 228
                if (ll.isPrintable)
21 Franz 229
                        {
456 fschmid 230
                        for(uint j = 0; j < Items.count(); ++j)
231
                        {
232
                                Item = Items.at(j);
21 Franz 233
                                if (Item->LayerNr != ll.LNr)
234
                                        continue;
4726 fschmid 235
                                double x = Seite->xOffset();
236
                                double y = Seite->yOffset();
237
                                double w = Seite->width();
238
                                double h = Seite->height();
239
                                double x2 = Item->BoundingX;
240
                                double y2 = Item->BoundingY;
241
                                double w2 = Item->BoundingW;
242
                                double h2 = Item->BoundingH;
243
                                if (!( QMAX( x, x2 ) <= QMIN( x+w, x2+w2 ) && QMAX( y, y2 ) <= QMIN( y+h, y2+h2 )))
456 fschmid 244
                                        continue;
4546 subik 245
                                if ((Item->fillColor() != CommonStrings::None) || (Item->GrType != 0))
456 fschmid 246
                                {
3207 craig 247
                                        fill = "fill:"+SetFarbe(Item->fillColor(), Item->fillShade())+";";
21 Franz 248
                                        if (Item->GrType != 0)
456 fschmid 249
                                        {
21 Franz 250
                                                defi = docu->createElement("defs");
295 Franz 251
                                                if ((Item->GrType == 5) || (Item->GrType == 7))
21 Franz 252
                                                        grad = docu->createElement("radialGradient");
253
                                                else
254
                                                        grad = docu->createElement("linearGradient");
255
                                                grad.setAttribute("id", gradi+IToStr(GradCount));
22 Franz 256
                                                grad.setAttribute("gradientUnits", "userSpaceOnUse");
21 Franz 257
                                                switch (Item->GrType)
456 fschmid 258
                                                {
21 Franz 259
                                                        case 1:
260
                                                                grad.setAttribute("x1", "0");
3934 cbradney 261
                                                                grad.setAttribute("y1", FToStr(Item->height() / 2));
262
                                                                grad.setAttribute("x2", FToStr(Item->width()));
263
                                                                grad.setAttribute("y2", FToStr(Item->height() / 2));
21 Franz 264
                                                                break;
265
                                                        case 2:
3934 cbradney 266
                                                                grad.setAttribute("x1", FToStr(Item->width()/ 2));
21 Franz 267
                                                                grad.setAttribute("y1", "0");
3934 cbradney 268
                                                                grad.setAttribute("x2", FToStr(Item->width()/ 2));
269
                                                                grad.setAttribute("y2", FToStr(Item->height()));
21 Franz 270
                                                                break;
271
                                                        case 3:
272
                                                                grad.setAttribute("x1", "0");
273
                                                                grad.setAttribute("y1", "0");
3934 cbradney 274
                                                                grad.setAttribute("x2", FToStr(Item->width()));
275
                                                                grad.setAttribute("y2", FToStr(Item->height()));
21 Franz 276
                                                                break;
277
                                                        case 4:
295 Franz 278
                                                                grad.setAttribute("x1", "0");
3934 cbradney 279
                                                                grad.setAttribute("y1", FToStr(Item->height()));
280
                                                                grad.setAttribute("x2", FToStr(Item->width()));
295 Franz 281
                                                                grad.setAttribute("y2", "0");
21 Franz 282
                                                                break;
283
                                                        case 5:
3934 cbradney 284
                                                                grad.setAttribute("r", FToStr(QMAX(Item->width() / 2, Item->height() / 2)));
285
                                                                grad.setAttribute("cx", FToStr(Item->width() / 2));
286
                                                                grad.setAttribute("cy", FToStr(Item->height() / 2));
21 Franz 287
                                                                break;
292 Franz 288
                                                        case 6:
289
                                                                grad.setAttribute("x1", FToStr(Item->GrStartX));
290
                                                                grad.setAttribute("y1", FToStr(Item->GrStartY));
291
                                                                grad.setAttribute("x2", FToStr(Item->GrEndX));
292
                                                                grad.setAttribute("y2", FToStr(Item->GrEndY));
293
                                                                break;
295 Franz 294
                                                        case 7:
3934 cbradney 295
                                                                grad.setAttribute("r", FToStr(QMAX(Item->width() / 2, Item->height() / 2)));
295 Franz 296
                                                                grad.setAttribute("cx", FToStr(Item->GrStartX));
297
                                                                grad.setAttribute("cy", FToStr(Item->GrStartY));
298
                                                                break;
456 fschmid 299
                                                }
295 Franz 300
                                                QPtrVector<VColorStop> cstops = Item->fill_gradient.colorStops();
301
                                                for (uint cst = 0; cst < Item->fill_gradient.Stops(); ++cst)
302
                                                {
303
                                                        QDomElement itcl = docu->createElement("stop");
304
                                                        itcl.setAttribute("offset", FToStr(cstops.at(cst)->rampPoint*100)+"%");
305
                                                        itcl.setAttribute("stop-opacity", FToStr(cstops.at(cst)->opacity));
3207 craig 306
                                                        itcl.setAttribute("stop-color", SetFarbe(cstops.at(cst)->name, cstops.at(cst)->shade));
295 Franz 307
                                                        grad.appendChild(itcl);
308
                                                }
21 Franz 309
                                                defi.appendChild(grad);
310
                                                fill = "fill:url(#"+gradi+IToStr(GradCount)+");";
311
                                                GradCount++;
456 fschmid 312
                                        }
4477 fschmid 313
                                        if (Item->fillRule)
314
                                                fill += " fill-rule:evenodd;";
315
                                        else
316
                                                fill += " fill-rule:nonzero;";
1394 cbradney 317
                                        if (Item->fillTransparency() != 0)
1552 subik 318
                                                fill += " fill-opacity:"+FToStr(1.0 - Item->fillTransparency())+";";
456 fschmid 319
                                }
21 Franz 320
                                else
321
                                        fill = "fill:none;";
4546 subik 322
                                if (Item->lineColor() != CommonStrings::None)
456 fschmid 323
                                {
3207 craig 324
                                        stroke = "stroke:"+SetFarbe(Item->lineColor(), Item->lineShade())+";";
1394 cbradney 325
                                        if (Item->lineTransparency() != 0)
326
                                                stroke += " stroke-opacity:"+FToStr(1.0 - Item->lineTransparency())+";";
1552 subik 327
                                }
21 Franz 328
                                else
329
                                        stroke = "stroke:none;";
3903 cbradney 330
                                trans = "translate("+FToStr(Item->xPos()-Seite->xOffset())+", "+FToStr(Item->yPos()-Seite->yOffset())+")";
3934 cbradney 331
                                if (Item->rotation() != 0)
332
                                        trans += " rotate("+FToStr(Item->rotation())+")";
4580 cbradney 333
                                strokeW = "stroke-width:"+FToStr(Item->lineWidth())+"pt;";
21 Franz 334
                                strokeLC = "stroke-linecap:";
335
                                switch (Item->PLineEnd)
456 fschmid 336
                                {
21 Franz 337
                                        case Qt::FlatCap:
338
                                                strokeLC += "butt;";
339
                                                break;
340
                                        case Qt::SquareCap:
341
                                                strokeLC += "square;";
342
                                                break;
343
                                        case Qt::RoundCap:
344
                                                strokeLC += "round;";
345
                                                break;
346
                                        default:
347
                                                strokeLC += "butt;";
348
                                                break;
456 fschmid 349
                                }
21 Franz 350
                                strokeLJ = "stroke-linejoin:";
351
                                switch (Item->PLineJoin)
456 fschmid 352
                                {
21 Franz 353
                                        case Qt::MiterJoin:
354
                                                strokeLJ += "miter;";
355
                                                break;
356
                                        case Qt::BevelJoin:
357
                                                strokeLJ += "bevel;";
358
                                                break;
359
                                        case Qt::RoundJoin:
360
                                                strokeLJ += "round;";
361
                                                break;
362
                                        default:
363
                                                strokeLJ += "miter;";
364
                                                break;
456 fschmid 365
                                }
21 Franz 366
                                strokeDA = "stroke-dasharray:";
292 Franz 367
                                if (Item->DashValues.count() != 0)
368
                                {
369
                                        QValueList<double>::iterator it;
370
                                        for ( it = Item->DashValues.begin(); it != Item->DashValues.end(); ++it )
21 Franz 371
                                        {
292 Franz 372
                                                strokeDA += IToStr(static_cast<int>(*it))+" ";
21 Franz 373
                                        }
292 Franz 374
                                        strokeDA += "; stroke-dashoffset:"+IToStr(static_cast<int>(Item->DashOffset))+";";
375
                                }
376
                                else
377
                                {
4580 cbradney 378
                                        QString Dt = FToStr(QMAX(2*Item->lineWidth(), 1));
379
                                        QString Da = FToStr(QMAX(6*Item->lineWidth(), 1));
292 Franz 380
                                        switch (Item->PLineArt)
456 fschmid 381
                                        {
292 Franz 382
                                                case Qt::SolidLine:
383
                                                        strokeDA += "none;";
384
                                                        break;
385
                                                case Qt::DashLine:
386
                                                        strokeDA += Da+","+Dt+";";
387
                                                        break;
388
                                                case Qt::DotLine:
389
                                                        strokeDA += Dt+";";
390
                                                        break;
391
                                                case Qt::DashDotLine:
392
                                                        strokeDA += Da+","+Dt+","+Dt+","+Dt+";";
393
                                                        break;
394
                                                case Qt::DashDotDotLine:
395
                                                        strokeDA += Da+","+Dt+","+Dt+","+Dt+","+Dt+","+Dt+";";
396
                                                        break;
397
                                                default:
398
                                                        strokeDA += "none;";
399
                                                        break;
400
                                                }
401
                                }
21 Franz 402
                                gr = docu->createElement("g");
403
                                gr.setAttribute("transform", trans);
3625 avox 404
                                if (!Item->asTextFrame())
456 fschmid 405
                                {
2877 cbradney 406
                                        if (Item->NamedLStyle.isEmpty())
21 Franz 407
                                        {
3625 avox 408
                                                if ((Item->asLine()) || (Item->asPolyLine()) || (Item->asPathText()))
27 Franz 409
                                                        gr.setAttribute("style", "fill:none; "+stroke+" "+strokeW+" "+strokeLC+" "+strokeLJ+" "+strokeDA);
410
                                                else
411
                                                        gr.setAttribute("style", fill+" "+stroke+" "+strokeW+" "+strokeLC+" "+strokeLJ+" "+strokeDA);
21 Franz 412
                                        }
456 fschmid 413
                                }
1460 cbradney 414
                                switch (Item->itemType())
456 fschmid 415
                                {
1460 cbradney 416
                                /* Item types 3 and 1 are OBSOLETE: CR 2005-02-06
456 fschmid 417
                                case 1:
418
                                case 3:
1460 cbradney 419
                                */
420
                                case PageItem::Polygon:
2877 cbradney 421
                                                if (Item->NamedLStyle.isEmpty())
456 fschmid 422
                                                {
27 Franz 423
                                                        ob = docu->createElement("path");
424
                                                        ob.setAttribute("d", SetClipPath(Item)+"Z");
456 fschmid 425
                                                }
27 Franz 426
                                                else
456 fschmid 427
                                                {
27 Franz 428
                                                        ob = docu->createElement("path");
429
                                                        ob.setAttribute("d", SetClipPath(Item)+"Z");
430
                                                        ob.setAttribute("style", fill);
431
                                                        gr.appendChild(ob);
4026 craig 432
                                                        multiLine ml = ScMW->doc->MLineStyles[Item->NamedLStyle];
31 Franz 433
                                                        for (int it = ml.size()-1; it > -1; it--)
456 fschmid 434
                                                        {
27 Franz 435
                                                                ob = docu->createElement("path");
436
                                                                ob.setAttribute("d", SetClipPath(Item)+"Z");
3207 craig 437
                                                                ob.setAttribute("style", GetMultiStroke(&ml[it], Item));
27 Franz 438
                                                                gr.appendChild(ob);
439
                                                        }
456 fschmid 440
                                                }
441
                                        break;
1460 cbradney 442
                                case PageItem::ImageFrame:
4546 subik 443
                                                if ((Item->fillColor() != CommonStrings::None) || (Item->GrType != 0))
456 fschmid 444
                                                {
22 Franz 445
                                                        ob = docu->createElement("path");
446
                                                        ob.setAttribute("d", SetClipPath(Item)+"Z");
447
                                                        ob.setAttribute("style", fill);
448
                                                        gr.appendChild(ob);
456 fschmid 449
                                                }
2877 cbradney 450
                                                if ((Item->PicAvail) && (!Item->Pfile.isEmpty()))
456 fschmid 451
                                                {
23 Franz 452
                                                        ob = docu->createElement("clipPath");
22 Franz 453
                                                        ob.setAttribute("id", Clipi+IToStr(ClipCount));
454
                                                        ob.setAttribute("clipPathUnits", "userSpaceOnUse");
24 Franz 455
                                                        ob.setAttribute("clip-rule", "evenodd");
22 Franz 456
                                                        QDomElement cl = docu->createElement("path");
2040 fschmid 457
                                                        if (Item->imageClip.size() != 0)
458
                                                                cl.setAttribute("d", SetClipPathImage(Item)+"Z");
459
                                                        else
460
                                                                cl.setAttribute("d", SetClipPath(Item)+"Z");
22 Franz 461
                                                        ob.appendChild(cl);
462
                                                        gr.appendChild(ob);
2004 fschmid 463
                                                        ScImage img;
464
                                                        img.LoadPicture(Item->Pfile, Item->IProfile, Item->IRender, Item->UseEmbedded, true, 2, 72);
4084 cbradney 465
                                                        img.applyEffect(Item->effectsInUse, Item->document()->PageColors, true);
23 Franz 466
                                                        QFileInfo fi = QFileInfo(Item->Pfile);
467
                                                        img.save(fi.baseName()+".png", "PNG");
22 Franz 468
                                                        ob = docu->createElement("image");
469
                                                        ob.setAttribute("clip-path", "url(#"+Clipi+IToStr(ClipCount)+")");
23 Franz 470
                                                        ob.setAttribute("xlink:href", fi.baseName()+".png");
318 Franz 471
                                                        ob.setAttribute("x", "0pt");
472
                                                        ob.setAttribute("y", "0pt");
3934 cbradney 473
                                                        ob.setAttribute("width", FToStr(Item->width())+"pt");
474
                                                        ob.setAttribute("height", FToStr(Item->height())+"pt");
22 Franz 475
                                                        ClipCount++;
27 Franz 476
                                                        gr.appendChild(ob);
456 fschmid 477
                                                }
2877 cbradney 478
                                                if (Item->NamedLStyle.isEmpty())
456 fschmid 479
                                                {
27 Franz 480
                                                        ob = docu->createElement("path");
68 Franz 481
                                                        ob.setAttribute("d", SetClipPath(Item)+"Z");
482
                                                        ob.setAttribute("style", "fill:none; "+stroke+" "+strokeW+" "+strokeLC+" "+strokeLJ+" "+strokeDA);
456 fschmid 483
                                                }
27 Franz 484
                                                else
456 fschmid 485
                                                {
4026 craig 486
                                                        multiLine ml = ScMW->doc->MLineStyles[Item->NamedLStyle];
31 Franz 487
                                                        for (int it = ml.size()-1; it > -1; it--)
456 fschmid 488
                                                        {
27 Franz 489
                                                                ob = docu->createElement("path");
68 Franz 490
                                                                ob.setAttribute("d", SetClipPath(Item)+"Z");
3207 craig 491
                                                                ob.setAttribute("style", "fill:none; "+GetMultiStroke(&ml[it], Item));
27 Franz 492
                                                                gr.appendChild(ob);
493
                                                        }
456 fschmid 494
                                                }
495
                                        break;
1460 cbradney 496
                                case PageItem::PolyLine:
2877 cbradney 497
                                                if (Item->NamedLStyle.isEmpty())
456 fschmid 498
                                                {
27 Franz 499
                                                        ob = docu->createElement("path");
500
                                                        ob.setAttribute("d", SetClipPath(Item));
456 fschmid 501
                                                }
27 Franz 502
                                                else
456 fschmid 503
                                                {
4026 craig 504
                                                        multiLine ml = ScMW->doc->MLineStyles[Item->NamedLStyle];
31 Franz 505
                                                        for (int it = ml.size()-1; it > -1; it--)
456 fschmid 506
                                                        {
27 Franz 507
                                                                ob = docu->createElement("path");
508
                                                                ob.setAttribute("d", SetClipPath(Item));
3207 craig 509
                                                                ob.setAttribute("style", GetMultiStroke(&ml[it], Item));
27 Franz 510
                                                                gr.appendChild(ob);
511
                                                        }
456 fschmid 512
                                                }
513
                                        break;
1460 cbradney 514
                                case PageItem::TextFrame:
4546 subik 515
                                                if ((Item->fillColor() != CommonStrings::None) || (Item->GrType != 0))
456 fschmid 516
                                                {
21 Franz 517
                                                        ob = docu->createElement("path");
518
                                                        ob.setAttribute("d", SetClipPath(Item)+"Z");
519
                                                        ob.setAttribute("style", fill);
520
                                                        gr.appendChild(ob);
456 fschmid 521
                                                }
21 Franz 522
                                                ob = docu->createElement("text");
523
                                                for (d = 0; d < Item->MaxChars; d++)
456 fschmid 524
                                                {
1065 cbradney 525
                                                        hl = Item->itemText.at(d);
249 Franz 526
                                                        if ((hl->ch == QChar(13)) || (hl->ch == QChar(10)) || (hl->ch == QChar(9)) || (hl->ch == QChar(28)))
21 Franz 527
                                                                continue;
528
                                                        if (hl->yp == 0)
529
                                                                break;
55 Franz 530
                                                        if (hl->ch == QChar(29))
531
                                                                chx = " ";
532
                                                        else
533
                                                                chx = hl->ch;
21 Franz 534
                                                        tp = docu->createElement("tspan");
318 Franz 535
                                                        tp.setAttribute("x", FToStr(hl->xp)+"pt");
536
                                                        tp.setAttribute("y", FToStr(hl->yp)+"pt");
3207 craig 537
                                                        SetTextProps(&tp, hl);
55 Franz 538
                                                        tp1 = docu->createTextNode(chx);
21 Franz 539
                                                        tp.appendChild(tp1);
540
                                                        ob.appendChild(tp);
456 fschmid 541
                                                }
542
                                        break;
1460 cbradney 543
                                case PageItem::Line:
2877 cbradney 544
                                                if (Item->NamedLStyle.isEmpty())
456 fschmid 545
                                                {
27 Franz 546
                                                        ob = docu->createElement("path");
3934 cbradney 547
                                                        ob.setAttribute("d", "M 0 0 L "+FToStr(Item->width())+" 0");
456 fschmid 548
                                                }
27 Franz 549
                                                else
456 fschmid 550
                                                {
4026 craig 551
                                                        multiLine ml = ScMW->doc->MLineStyles[Item->NamedLStyle];
31 Franz 552
                                                        for (int it = ml.size()-1; it > -1; it--)
456 fschmid 553
                                                        {
27 Franz 554
                                                                ob = docu->createElement("path");
3934 cbradney 555
                                                                ob.setAttribute("d", "M 0 0 L "+FToStr(Item->width())+" 0");
3207 craig 556
                                                                ob.setAttribute("style", GetMultiStroke(&ml[it], Item));
27 Franz 557
                                                                gr.appendChild(ob);
558
                                                        }
456 fschmid 559
                                                }
560
                                        break;
1460 cbradney 561
                                case PageItem::PathText:
21 Franz 562
                                                if (Item->PoShow)
456 fschmid 563
                                                {
2877 cbradney 564
                                                        if (Item->NamedLStyle.isEmpty())
21 Franz 565
                                                        {
27 Franz 566
                                                                ob = docu->createElement("path");
567
                                                                ob.setAttribute("d", SetClipPath(Item));
568
                                                                gr.appendChild(ob);
456 fschmid 569
                                                        }
27 Franz 570
                                                        else
456 fschmid 571
                                                        {
4026 craig 572
                                                                multiLine ml = ScMW->doc->MLineStyles[Item->NamedLStyle];
31 Franz 573
                                                                for (int it = ml.size()-1; it > -1; it--)
456 fschmid 574
                                                                {
27 Franz 575
                                                                        ob = docu->createElement("path");
576
                                                                        ob.setAttribute("d", SetClipPath(Item));
3207 craig 577
                                                                        ob.setAttribute("style", GetMultiStroke(&ml[it], Item));
27 Franz 578
                                                                        gr.appendChild(ob);
579
                                                                }
21 Franz 580
                                                        }
456 fschmid 581
                                                }
21 Franz 582
                                                ob = docu->createElement("text");
583
                                                for (d = 0; d < Item->MaxChars; d++)
456 fschmid 584
                                                {
1065 cbradney 585
                                                        hl = Item->itemText.at(d);
2955 fschmid 586
                                                        if ((hl->ch == QChar(13)) || (hl->ch == QChar(10)) || (hl->ch == QChar(9)) || (hl->ch == QChar(25)) || (hl->ch == QChar(28)))
21 Franz 587
                                                                continue;
55 Franz 588
                                                        if (hl->ch == QChar(29))
589
                                                                chx = " ";
590
                                                        else
591
                                                                chx = hl->ch;
21 Franz 592
                                                        tp = docu->createElement("tspan");
318 Franz 593
                                                        tp.setAttribute("x", FToStr(hl->PtransX)+"pt");
594
                                                        tp.setAttribute("y", FToStr(hl->PtransY)+"pt");
21 Franz 595
                                                        tp.setAttribute("rotate", hl->PRot);
596
                                                        tp2 = docu->createElement("tspan");
318 Franz 597
                                                        tp2.setAttribute("dx", FToStr(hl->xp)+"pt");
598
                                                        tp2.setAttribute("dy", FToStr(hl->yp)+"pt");
3207 craig 599
                                                        SetTextProps(&tp2, hl);
55 Franz 600
                                                        tp1 = docu->createTextNode(chx);
21 Franz 601
                                                        tp2.appendChild(tp1);
602
                                                        tp.appendChild(tp2);
603
                                                        ob.appendChild(tp);
456 fschmid 604
                                                }
605
                                        break;
2004 fschmid 606
                                default:
607
                                        break;
456 fschmid 608
                                }
21 Franz 609
                                if (Item->GrType != 0)
610
                                        elem->appendChild(defi);
611
                                gr.appendChild(ob);
612
                                elem->appendChild(gr);
613
                        }
456 fschmid 614
                }
21 Franz 615
                Lnr++;
456 fschmid 616
        }
4026 craig 617
        ScMW->doc->currentPage = SavedAct;
21 Franz 618
}
619
 
620
QString SVGExPlug::SetClipPath(PageItem *ite)
621
{
622
        QString tmp = "";
623
        FPoint np, np1, np2;
624
        bool nPath = true;
625
        if (ite->PoLine.size() > 3)
626
                {
627
                for (uint poi=0; poi<ite->PoLine.size()-3; poi += 4)
628
                        {
629
                        if (ite->PoLine.point(poi).x() > 900000)
630
                                {
631
                                tmp += "Z ";
632
                                nPath = true;
633
                                continue;
634
                                }
635
                        if (nPath)
636
                                {
637
                                np = ite->PoLine.point(poi);
638
                                tmp += "M"+FToStr(np.x())+" "+FToStr(np.y())+" ";
639
                                nPath = false;
640
                                }
641
                        np = ite->PoLine.point(poi+1);
642
                        tmp += "C"+FToStr(np.x())+" "+FToStr(np.y())+" ";
643
                        np1 = ite->PoLine.point(poi+3);
644
                        tmp += FToStr(np1.x())+" "+FToStr(np1.y())+" ";
645
                        np2 = ite->PoLine.point(poi+2);
646
                        tmp += FToStr(np2.x())+" "+FToStr(np2.y())+" ";
647
                        }
648
                }
649
        return tmp;
1552 subik 650
}
21 Franz 651
 
2040 fschmid 652
QString SVGExPlug::SetClipPathImage(PageItem *ite)
653
{
654
        QString tmp = "";
655
        FPoint np, np1, np2;
656
        bool nPath = true;
657
        if (ite->imageClip.size() > 3)
658
                {
659
                for (uint poi=0; poi<ite->imageClip.size()-3; poi += 4)
660
                        {
661
                        if (ite->imageClip.point(poi).x() > 900000)
662
                                {
663
                                tmp += "Z ";
664
                                nPath = true;
665
                                continue;
666
                                }
667
                        if (nPath)
668
                                {
669
                                np = ite->imageClip.point(poi);
670
                                tmp += "M"+FToStr(np.x())+" "+FToStr(np.y())+" ";
671
                                nPath = false;
672
                                }
673
                        np = ite->imageClip.point(poi+1);
674
                        tmp += "C"+FToStr(np.x())+" "+FToStr(np.y())+" ";
675
                        np1 = ite->imageClip.point(poi+3);
676
                        tmp += FToStr(np1.x())+" "+FToStr(np1.y())+" ";
677
                        np2 = ite->imageClip.point(poi+2);
678
                        tmp += FToStr(np2.x())+" "+FToStr(np2.y())+" ";
679
                        }
680
                }
681
        return tmp;
682
}
683
 
80 Franz 684
QString SVGExPlug::FToStr(double c)
21 Franz 685
{
686
        QString cc;
687
        return cc.setNum(c);
688
}
689
 
690
QString SVGExPlug::IToStr(int c)
691
{
692
        QString cc;
693
        return cc.setNum(c);
694
}
695
 
3207 craig 696
void SVGExPlug::SetTextProps(QDomElement *tp, struct ScText *hl)
21 Franz 697
{
68 Franz 698
        int chst = hl->cstyle & 127;
4546 subik 699
        if (hl->ccolor != CommonStrings::None)
3207 craig 700
                tp->setAttribute("fill", SetFarbe(hl->ccolor, hl->cshade));
21 Franz 701
        else
702
                tp->setAttribute("fill", "none");
4546 subik 703
        if ((hl->cstroke != CommonStrings::None) && (chst & 4))
68 Franz 704
                {
3207 craig 705
                tp->setAttribute("stroke", SetFarbe(hl->cstroke, hl->cshade2));
4026 craig 706
                tp->setAttribute("stroke-width", FToStr((*ScMW->doc->AllFonts)[hl->cfont->scName()]->strokeWidth * (hl->csize / 10.0))+"pt");
68 Franz 707
                }
708
        else
709
                tp->setAttribute("stroke", "none");
111 Franz 710
        tp->setAttribute("font-size", (hl->csize / 10.0));
4026 craig 711
        tp->setAttribute("font-family", (*ScMW->doc->AllFonts)[hl->cfont->scName()]->family());
21 Franz 712
        if (chst != 0)
713
                {
714
                if (chst & 64)
715
                        tp->setAttribute("font-variant", "small-caps");
716
                if (chst & 32)
717
                        tp->setAttribute("font-weight", "bold");
718
                if (chst & 16)
719
                        tp->setAttribute("text-decoration", "line-through");
720
                if (chst & 8)
721
                        tp->setAttribute("text-decoration", "underline");
722
                }
723
}
724
 
3207 craig 725
QString SVGExPlug::SetFarbe(QString farbe, int shad)
21 Franz 726
{
4026 craig 727
        return ScMW->doc->PageColors[farbe].getShadeColorProof(shad).name();
21 Franz 728
}
729
 
3207 craig 730
QString SVGExPlug::GetMultiStroke(struct SingleLine *sl, PageItem *Item)
27 Franz 731
{
732
        QString tmp = "fill:none; ";
3207 craig 733
        tmp += "stroke:"+SetFarbe(sl->Color, sl->Shade)+"; ";
1394 cbradney 734
        if (Item->fillTransparency() != 0)
735
                tmp += " stroke-opacity:"+FToStr(1.0 - Item->fillTransparency())+"; ";
318 Franz 736
        tmp += "stroke-width:"+FToStr(sl->Width)+"pt; ";
27 Franz 737
        tmp += "stroke-linecap:";
738
        switch (static_cast<PenCapStyle>(sl->LineEnd))
739
                {
740
                case Qt::FlatCap:
741
                        tmp += "butt;";
742
                        break;
743
                case Qt::SquareCap:
744
                        tmp += "square;";
745
                        break;
746
                case Qt::RoundCap:
747
                        tmp += "round;";
748
                        break;
749
                default:
750
                        tmp += "butt;";
751
                        break;
752
                }
753
        tmp += " stroke-linejoin:";
754
        switch (static_cast<PenJoinStyle>(sl->LineJoin))
755
                {
756
                case Qt::MiterJoin:
757
                        tmp += "miter;";
758
                        break;
759
                case Qt::BevelJoin:
760
                        tmp += "bevel;";
761
                        break;
762
                case Qt::RoundJoin:
763
                        tmp += "round;";
764
                        break;
765
                default:
766
                        tmp += "miter;";
767
                        break;
768
                }
769
        tmp += " stroke-dasharray:";
292 Franz 770
        QString Dt = FToStr(QMAX(2*sl->Width, 1));
771
        QString Da = FToStr(QMAX(6*sl->Width, 1));
27 Franz 772
        switch (static_cast<PenStyle>(sl->Dash))
773
                {
774
                case Qt::SolidLine:
775
                        tmp += "none;";
776
                        break;
777
                case Qt::DashLine:
778
                        tmp += Da+","+Dt+";";
779
                        break;
780
                case Qt::DotLine:
781
                        tmp += Dt+";";
782
                        break;
783
                case Qt::DashDotLine:
784
                        tmp += Da+","+Dt+","+Dt+","+Dt+";";
785
                        break;
786
                case Qt::DashDotDotLine:
787
                        tmp += Da+","+Dt+","+Dt+","+Dt+","+Dt+","+Dt+";";
788
                        break;
789
                default:
790
                        tmp += "none;";
791
                        break;
792
                }
793
        return tmp;
794
}
795
 
21 Franz 796
SVGExPlug::~SVGExPlug()
797
{
798
}
3207 craig 799
 
800
#include "svgexplugin.moc"