Subversion Repositories Scribus

Rev

Rev 24719 | Rev 24868 | 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
 
17941 jghali 24
#include <QBuffer>
25
#include <QByteArray>
26
#include <QCheckBox>
27
#include <QDataStream>
10223 cbradney 28
#include <QFile>
9856 fschmid 29
#include <QList>
17941 jghali 30
#include <QMessageBox>
16238 fschmid 31
#include <QScopedPointer>
17941 jghali 32
#include <QTextStream>
766 cbradney 33
 
21 Franz 34
#include "svgexplugin.h"
512 fschmid 35
 
2688 craig 36
#include "scconfig.h"
10532 avox 37
#include "canvas.h"
5781 cbradney 38
#include "cmsettings.h"
4546 subik 39
#include "commonstrings.h"
17315 fschmid 40
#include "pageitem_table.h"
2856 cbradney 41
#include "prefsmanager.h"
3670 cbradney 42
#include "prefsfile.h"
43
#include "prefscontext.h"
18910 fschmid 44
#include "qtiocompressor.h"
16736 jghali 45
#include "scpage.h"
12623 fschmid 46
#include "scpattern.h"
14170 jghali 47
#include "scribuscore.h"
48
#include "sctextstruct.h"
17315 fschmid 49
#include "tableutils.h"
2533 craig 50
#include "util.h"
13552 cbradney 51
#include "ui/customfdialog.h"
13544 cbradney 52
#include "ui/guidemanager.h"
19605 jghali 53
#include "ui/scmessagebox.h"
7481 jghali 54
#include "sccolorengine.h"
10292 cbradney 55
#include "util_formats.h"
14170 jghali 56
#include "util_math.h"
21107 craig 57
#include "text/textlayout.h"
58
#include "text/textlayoutpainter.h"
59
#include "text/boxes.h"
1552 subik 60
 
3207 craig 61
int svgexplugin_getPluginAPIVersion()
21 Franz 62
{
3207 craig 63
        return PLUGIN_API_VERSION;
21 Franz 64
}
65
 
3207 craig 66
ScPlugin* svgexplugin_getPlugin()
21 Franz 67
{
3207 craig 68
        SVGExportPlugin* plug = new SVGExportPlugin();
69
        Q_CHECK_PTR(plug);
70
        return plug;
21 Franz 71
}
72
 
3207 craig 73
void svgexplugin_freePlugin(ScPlugin* plugin)
512 fschmid 74
{
24137 craig 75
        SVGExportPlugin* plug = qobject_cast<SVGExportPlugin*>(plugin);
3207 craig 76
        Q_ASSERT(plug);
77
        delete plug;
512 fschmid 78
}
79
 
17315 fschmid 80
using namespace TableUtils;
81
 
22639 craig 82
SVGExportPlugin::SVGExportPlugin()
1208 cbradney 83
{
3207 craig 84
        // Set action info in languageChange, so we only have to do
85
        // it in one place.
86
        languageChange();
1208 cbradney 87
}
88
 
3207 craig 89
SVGExportPlugin::~SVGExportPlugin() {};
90
 
91
void SVGExportPlugin::languageChange()
1208 cbradney 92
{
3207 craig 93
        // Note that we leave the unused members unset. They'll be initialised
94
        // with their default ctors during construction.
95
        // Action name
96
        m_actionInfo.name = "ExportAsSVG";
97
        // Action text for menu, including accel
5357 cbradney 98
        m_actionInfo.text = tr("Save as &SVG...");
3207 craig 99
        // Menu
100
        m_actionInfo.menu = "FileExport";
12566 cbradney 101
        m_actionInfo.enabledOnStartup = false;
10956 fschmid 102
        m_actionInfo.needsNumObjects = -1;
1208 cbradney 103
}
104
 
23705 craig 105
QString SVGExportPlugin::fullTrName() const
1208 cbradney 106
{
3207 craig 107
        return QObject::tr("SVG Export");
1208 cbradney 108
}
109
 
3207 craig 110
const ScActionPlugin::AboutData* SVGExportPlugin::getAboutData() const
1208 cbradney 111
{
3241 craig 112
        AboutData* about = new AboutData;
3344 fschmid 113
        about->authors = "Franz Schmid <franz@scribus.info>";
3355 cbradney 114
        about->shortDescription = tr("Exports SVG Files");
3357 cbradney 115
        about->description = tr("Exports the current page into an SVG file.");
3344 fschmid 116
        about->license = "GPL";
3241 craig 117
        Q_CHECK_PTR(about);
118
        return about;
1208 cbradney 119
}
120
 
3241 craig 121
void SVGExportPlugin::deleteAboutData(const AboutData* about) const
1208 cbradney 122
{
3241 craig 123
        Q_ASSERT(about);
124
        delete about;
1208 cbradney 125
}
126
 
22635 craig 127
bool SVGExportPlugin::run(ScribusDoc* doc, const QString& filename)
21 Franz 128
{
3207 craig 129
        Q_ASSERT(filename.isEmpty());
4182 subik 130
        QString fileName;
22600 craig 131
        if (doc!=nullptr)
2875 subik 132
        {
23060 craig 133
                PrefsContext* prefs = PrefsManager::instance().prefsFile->getPluginContext("svgex");
415 Franz 134
                QString wdir = prefs->get("wdir", ".");
16238 fschmid 135
                QScopedPointer<CustomFDialog> openDia( new CustomFDialog(doc->scMW(), wdir, QObject::tr("Save as"), QObject::tr("%1;;All Files (*)").arg(FormatsManager::instance()->extensionsForFormat(FormatsManager::SVG)), fdHidePreviewCheckBox) );
5781 cbradney 136
                openDia->setSelection(getFileNameByPage(doc, doc->currentPage()->pageNr(), "svg"));
4182 subik 137
                openDia->setExtension("svg");
138
                openDia->setZipExtension("svgz");
15224 jghali 139
                QCheckBox* compress = new QCheckBox(openDia.data());
12623 fschmid 140
                compress->setText( tr("Compress File"));
141
                compress->setChecked(false);
142
                openDia->addWidgets(compress);
15224 jghali 143
                QCheckBox* inlineImages = new QCheckBox(openDia.data());
12623 fschmid 144
                inlineImages->setText( tr("Save Images inline"));
145
                inlineImages->setToolTip( tr("Adds all Images on the Page inline to the SVG.\nCaution: this will increase the file size!"));
146
                inlineImages->setChecked(true);
147
                openDia->addWidgets(inlineImages);
15224 jghali 148
                QCheckBox* exportBack = new QCheckBox(openDia.data());
12623 fschmid 149
                exportBack->setText( tr("Export Page background"));
20272 craig 150
                exportBack->setToolTip( tr("Adds the Page itself as background to the SVG"));
12623 fschmid 151
                exportBack->setChecked(false);
152
                openDia->addWidgets(exportBack);
19104 jghali 153
 
15225 jghali 154
                if (!openDia->exec())
155
                        return true;
156
                fileName = openDia->selectedFile();
157
                QFileInfo fi(fileName);
23445 jghali 158
                QString m_baseDir = fi.absolutePath();
15225 jghali 159
                if (compress->isChecked())
23445 jghali 160
                        fileName = m_baseDir + "/" + fi.baseName() + ".svgz";
12623 fschmid 161
                else
23445 jghali 162
                        fileName = m_baseDir + "/" + fi.baseName() + ".svg";
15225 jghali 163
 
12623 fschmid 164
                SVGOptions Options;
165
                Options.inlineImages = inlineImages->isChecked();
166
                Options.exportPageBackground = exportBack->isChecked();
167
                Options.compressFile = compress->isChecked();
4182 subik 168
 
15225 jghali 169
                if (fileName.isEmpty())
170
                        return true;
171
                prefs->set("wdir", fileName.left(fileName.lastIndexOf("/")));
172
                QFile f(fileName);
173
                if (f.exists())
2875 subik 174
                {
19605 jghali 175
                        int exit = ScMessageBox::warning(doc->scMW(), CommonStrings::trWarning,
15225 jghali 176
                                QObject::tr("Do you really want to overwrite the file:\n%1 ?").arg(fileName),
19605 jghali 177
                                QMessageBox::Yes | QMessageBox::No,
178
                                QMessageBox::NoButton// GUI default
179
                                QMessageBox::Yes);      // batch default
15225 jghali 180
                        if (exit == QMessageBox::No)
181
                                return true;
2875 subik 182
                }
15225 jghali 183
                SVGExPlug *dia = new SVGExPlug(doc);
184
                dia->doExport(fileName, Options);
185
                delete dia;
2875 subik 186
        }
3207 craig 187
        return true;
21 Franz 188
}
189
 
8043 jghali 190
SVGExPlug::SVGExPlug( ScribusDoc* doc )
21 Franz 191
{
12623 fschmid 192
        m_Doc = doc;
193
        Options.inlineImages = true;
194
        Options.exportPageBackground = false;
195
        Options.compressFile = false;
23445 jghali 196
        m_glyphNames.clear();
8043 jghali 197
}
198
 
22600 craig 199
bool SVGExPlug::doExport( const QString& fName, SVGOptions &Opts )
8043 jghali 200
{
12623 fschmid 201
        Options = Opts;
202
        QFileInfo fiBase(fName);
23445 jghali 203
 
204
        m_baseDir = fiBase.absolutePath();
205
        m_gradCount = 0;
206
        m_clipCount = 0;
207
        m_pattCount = 0;
208
        m_maskCount = 0;
209
        m_filterCount = 0;
210
 
211
        m_domDoc = QDomDocument("svgdoc");
68 Franz 212
        QString vo = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
21 Franz 213
        QString st = "<svg></svg>";
23445 jghali 214
        m_domDoc.setContent(st);
215
 
216
        ScPage *page = m_Doc->currentPage();
13873 jghali 217
        double pageWidth  = page->width();
218
        double pageHeight = page->height();
23445 jghali 219
        m_domElem = m_domDoc.documentElement();
220
        m_domElem.setAttribute("width", FToStr(pageWidth) + "pt");
221
        m_domElem.setAttribute("height", FToStr(pageHeight) + "pt");
222
        m_domElem.setAttribute("viewBox", QString("0 0 %1 %2").arg(pageWidth).arg(pageHeight));
223
        m_domElem.setAttribute("xmlns", "http://www.w3.org/2000/svg");
224
        m_domElem.setAttribute("xmlns:inkscape","http://www.inkscape.org/namespaces/inkscape");
225
        m_domElem.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink");
226
        m_domElem.setAttribute("version","1.1");
15037 cbradney 227
        if (!m_Doc->documentInfo().title().isEmpty())
12623 fschmid 228
        {
23445 jghali 229
                QDomText title = m_domDoc.createTextNode(m_Doc->documentInfo().title());
230
                QDomElement titleElem = m_domDoc.createElement("title");
12623 fschmid 231
                titleElem.appendChild(title);
23445 jghali 232
                m_domElem.appendChild(titleElem);
12623 fschmid 233
        }
15037 cbradney 234
        if (!m_Doc->documentInfo().comments().isEmpty())
12623 fschmid 235
        {
23445 jghali 236
                QDomText desc = m_domDoc.createTextNode(m_Doc->documentInfo().comments());
237
                QDomElement descElem = m_domDoc.createElement("desc");
12623 fschmid 238
                descElem.appendChild(desc);
23445 jghali 239
                m_domElem.appendChild(descElem);
12623 fschmid 240
        }
23445 jghali 241
        m_globalDefs = m_domDoc.createElement("defs");
14169 fschmid 242
        writeBasePatterns();
15077 fschmid 243
        writeBaseSymbols();
23445 jghali 244
        m_domElem.appendChild(m_globalDefs);
12623 fschmid 245
        if (Options.exportPageBackground)
246
        {
23445 jghali 247
                QDomElement backG = m_domDoc.createElement("rect");
12623 fschmid 248
                backG.setAttribute("x", "0");
249
                backG.setAttribute("y", "0");
250
                backG.setAttribute("width", FToStr(pageWidth));
251
                backG.setAttribute("height", FToStr(pageHeight));
23445 jghali 252
                backG.setAttribute("style", "fill:" + m_Doc->paperColor().name() + ";" + "stroke:none;");
253
                m_domElem.appendChild(backG);
12623 fschmid 254
        }
13873 jghali 255
        ScLayer ll;
256
        ll.isPrintable = false;
257
        for (int la = 0; la < m_Doc->Layers.count(); la++)
258
        {
259
                m_Doc->Layers.levelToLayer(ll, la);
260
                if (ll.isPrintable)
261
                {
23129 craig 262
                        page = m_Doc->MasterPages.at(m_Doc->MasterNames[m_Doc->currentPage()->masterPageName()]);
23445 jghali 263
                        processPageLayer(page, ll);
13873 jghali 264
                        page = m_Doc->currentPage();
23445 jghali 265
                        processPageLayer(page, ll);
13873 jghali 266
                }
267
        }
12623 fschmid 268
        if(Options.compressFile)
6014 jghali 269
        {
8022 jghali 270
                // zipped saving
18910 fschmid 271
                QString wr = vo;
23445 jghali 272
                wr += m_domDoc.toString();
18910 fschmid 273
                QByteArray utf8wr = wr.toUtf8();
274
                QFile file(fName);
275
                QtIOCompressor compressor(&file);
276
                compressor.setStreamFormat(QtIOCompressor::GzipFormat);
277
                compressor.open(QIODevice::WriteOnly);
278
                compressor.write(utf8wr);
279
                compressor.close();
6014 jghali 280
        }
68 Franz 281
        else
6014 jghali 282
        {
68 Franz 283
                QFile f(fName);
8501 cbradney 284
                if(!f.open(QIODevice::WriteOnly))
8043 jghali 285
                        return false;
10004 fschmid 286
                QDataStream s(&f);
68 Franz 287
                QString wr = vo;
23445 jghali 288
                wr += m_domDoc.toString();
9535 fschmid 289
                QByteArray utf8wr = wr.toUtf8();
10004 fschmid 290
                s.writeRawData(utf8wr.data(), utf8wr.length());
68 Franz 291
                f.close();
6014 jghali 292
        }
8043 jghali 293
        return true;
21 Franz 294
}
295
 
23445 jghali 296
void SVGExPlug::processPageLayer(ScPage *page, ScLayer& layer)
21 Franz 297
{
12623 fschmid 298
        QDomElement layerGroup;
23446 jghali 299
        PageItem *item;
300
        QList<PageItem*> items;
16729 fschmid 301
        ScPage* SavedAct = m_Doc->currentPage();
23129 craig 302
        if (page->pageNameEmpty())
23446 jghali 303
                items = m_Doc->DocItems;
456 fschmid 304
        else
23446 jghali 305
                items = m_Doc->MasterItems;
306
        if (items.count() == 0)
12623 fschmid 307
                return;
13873 jghali 308
        if (!layer.isPrintable)
309
                return;
310
        m_Doc->setCurrentPage(page);
311
 
23445 jghali 312
        layerGroup = m_domDoc.createElement("g");
13873 jghali 313
        layerGroup.setAttribute("id", layer.Name);
16238 fschmid 314
        layerGroup.setAttribute("inkscape:label", layer.Name);
315
        layerGroup.setAttribute("inkscape:groupmode", "layer");
13873 jghali 316
        if (layer.transparency != 1.0)
317
                layerGroup.setAttribute("opacity", FToStr(layer.transparency));
23446 jghali 318
        for (int j = 0; j < items.count(); ++j)
10895 jghali 319
        {
23446 jghali 320
                item = items.at(j);
321
                if (item->m_layerID != layer.ID)
13873 jghali 322
                        continue;
23446 jghali 323
                if (!item->printEnabled())
13873 jghali 324
                        continue;
325
                double x = page->xOffset();
326
                double y = page->yOffset();
327
                double w = page->width();
328
                double h = page->height();
23446 jghali 329
                double x2 = item->BoundingX;
330
                double y2 = item->BoundingY;
331
                double w2 = item->BoundingW;
332
                double h2 = item->BoundingH;
13873 jghali 333
                if (!( qMax( x, x2 ) <= qMin( x+w, x2+w2 ) && qMax( y, y2 ) <= qMin( y+h, y2+h2 )))
334
                        continue;
23446 jghali 335
                if ((!page->pageNameEmpty()) && (item->OwnPage != static_cast<int>(page->pageNr())) && (item->OwnPage != -1))
15049 jghali 336
                        continue;
23446 jghali 337
                processItemOnPage(item->xPos()-page->xOffset(), item->yPos()-page->yOffset(), item, &layerGroup);
12623 fschmid 338
        }
23445 jghali 339
        m_domElem.appendChild(layerGroup);
13873 jghali 340
 
12623 fschmid 341
        m_Doc->setCurrentPage(SavedAct);
342
}
343
 
23446 jghali 344
void SVGExPlug::processItemOnPage(double xOffset, double yOffset, PageItem *item, QDomElement *parentElem)
12623 fschmid 345
{
346
        QDomElement ob;
23445 jghali 347
        QString trans = "translate(" + FToStr(xOffset) + ", " + FToStr(yOffset) + ")";
23446 jghali 348
        if (item->rotation() != 0)
349
                trans += " rotate(" + FToStr(item->rotation()) + ")";
350
        QString fill = getFillStyle(item);
351
        fill += processDropShadow(item);
12627 fschmid 352
        QString stroke = "stroke:none";
23446 jghali 353
        stroke = getStrokeStyle(item);
354
        switch (item->itemType())
12623 fschmid 355
        {
16215 fschmid 356
                case PageItem::Arc:
12623 fschmid 357
                case PageItem::Polygon:
358
                case PageItem::PolyLine:
16191 fschmid 359
                case PageItem::RegularPolygon:
16311 fschmid 360
                case PageItem::Spiral:
23446 jghali 361
                        ob = processPolyItem(item, trans, fill, stroke);
362
                        if ((item->lineColor() != CommonStrings::None) && ((item->startArrowIndex() != 0) || (item->endArrowIndex() != 0)))
363
                                ob = processArrows(item, ob, trans);
12623 fschmid 364
                        break;
365
                case PageItem::Line:
23446 jghali 366
                        ob = processLineItem(item, trans, stroke);
367
                        if ((item->lineColor() != CommonStrings::None) && ((item->startArrowIndex() != 0) || (item->endArrowIndex() != 0)))
368
                                ob = processArrows(item, ob, trans);
12623 fschmid 369
                        break;
370
                case PageItem::ImageFrame:
371
                case PageItem::LatexFrame:
23446 jghali 372
                        ob = processImageItem(item, trans, fill, stroke);
12623 fschmid 373
                        break;
374
                case PageItem::TextFrame:
21107 craig 375
                case PageItem::PathText:
23446 jghali 376
                        ob = processTextItem(item, trans, fill, stroke);
12623 fschmid 377
                        break;
15077 fschmid 378
                case PageItem::Symbol:
23446 jghali 379
                        ob = processSymbolItem(item, trans);
15077 fschmid 380
                        break;
16105 fschmid 381
                case PageItem::Group:
23446 jghali 382
                        if (item->groupItemList.count() > 0)
16105 fschmid 383
                        {
23445 jghali 384
                                ob = m_domDoc.createElement("g");
23446 jghali 385
                                if (!item->AutoName)
386
                                        ob.setAttribute("id", item->itemName());
387
                                if (item->GrMask > 0)
388
                                        ob.setAttribute("mask", handleMask(item, xOffset, yOffset));
16105 fschmid 389
                                else
390
                                {
23446 jghali 391
                                        if (item->fillTransparency() != 0)
392
                                                ob.setAttribute("opacity", FToStr(1.0 - item->fillTransparency()));
16105 fschmid 393
                                }
18743 jghali 394
                                QString tr = trans;
23446 jghali 395
                                if (item->imageFlippedH())
18743 jghali 396
                                {
23446 jghali 397
                                        tr += QString(" translate(%1, 0.0)").arg(item->width());
18743 jghali 398
                                        tr += QString(" scale(-1.0, 1.0)");
399
                                }
23446 jghali 400
                                if (item->imageFlippedV())
18743 jghali 401
                                {
23446 jghali 402
                                        tr += QString(" translate(0.0, %1)").arg(item->height());
18743 jghali 403
                                        tr += QString(" scale(1.0, -1.0)");
404
                                }
23446 jghali 405
                                tr += QString(" scale(%1, %2)").arg(item->width() / item->groupWidth).arg(item->height() / item->groupHeight);
16123 fschmid 406
                                ob.setAttribute("transform", tr);
16105 fschmid 407
                                ob.setAttribute("style", "fill:none; stroke:none");
23446 jghali 408
                                if (item->groupClipping())
18779 fschmid 409
                                {
23446 jghali 410
                                        FPointArray clipPath = item->PoLine;
18779 fschmid 411
                                        QTransform transform;
23446 jghali 412
                                        transform.scale(item->width() / item->groupWidth, item->height() / item->groupHeight);
18779 fschmid 413
                                        transform = transform.inverted();
414
                                        clipPath.map(transform);
415
                                        QDomElement obc = createClipPathElement(&clipPath);
416
                                        if (!obc.isNull())
23445 jghali 417
                                                ob.setAttribute("clip-path", "url(#" + obc.attribute("id") + ")");
23446 jghali 418
                                        if (item->fillRule)
18779 fschmid 419
                                                ob.setAttribute("clip-rule", "evenodd");
420
                                        else
421
                                                ob.setAttribute("clip-rule", "nonzero");
422
                                }
23446 jghali 423
                                for (int em = 0; em < item->groupItemList.count(); ++em)
16105 fschmid 424
                                {
23446 jghali 425
                                        PageItem* embed = item->groupItemList.at(em);
23445 jghali 426
                                        processItemOnPage(embed->gXpos, embed->gYpos, embed, &ob);
16105 fschmid 427
                                }
428
                        }
429
                        break;
17315 fschmid 430
                case PageItem::Table:
23445 jghali 431
                        ob = m_domDoc.createElement("g");
23446 jghali 432
                        ob.setAttribute("transform", trans + QString("translate(%1, %2)").arg(item->asTable()->gridOffset().x()).arg(item->asTable()->gridOffset().y()));
17315 fschmid 433
                        // Paint table fill.
23446 jghali 434
                        if (item->asTable()->fillColor() != CommonStrings::None)
17315 fschmid 435
                        {
23446 jghali 436
                                int lastCol = item->asTable()->columns() - 1;
437
                                int lastRow = item->asTable()->rows() - 1;
438
                                double x = item->asTable()->columnPosition(0);
439
                                double y = item->asTable()->rowPosition(0);
440
                                double width = item->asTable()->columnPosition(lastCol) + item->asTable()->columnWidth(lastCol) - x;
441
                                double height = item->asTable()->rowPosition(lastRow) + item->asTable()->rowHeight(lastRow) - y;
23445 jghali 442
                                QDomElement cl = m_domDoc.createElement("rect");
23446 jghali 443
                                cl.setAttribute("fill", setColor(item->asTable()->fillColor(), item->asTable()->fillShade()));
17315 fschmid 444
                                cl.setAttribute("x", "0");
445
                                cl.setAttribute("y", "0");
446
                                cl.setAttribute("width", FToStr(width));
447
                                cl.setAttribute("height", FToStr(height));
448
                                ob.appendChild(cl);
449
                        }
450
                        // Pass 1: Paint cell fills.
23446 jghali 451
                        for (int row = 0; row < item->asTable()->rows(); ++row)
17315 fschmid 452
                        {
453
                                int colSpan = 0;
23446 jghali 454
                                for (int col = 0; col < item->asTable()->columns(); col += colSpan)
17315 fschmid 455
                                {
23446 jghali 456
                                        TableCell cell = item->asTable()->cellAt(row, col);
17315 fschmid 457
                                        if (row == cell.row())
458
                                        {
459
                                                QString colorName = cell.fillColor();
460
                                                if (colorName != CommonStrings::None)
461
                                                {
462
                                                        int row = cell.row();
463
                                                        int col = cell.column();
464
                                                        int lastRow = row + cell.rowSpan() - 1;
465
                                                        int lastCol = col + cell.columnSpan() - 1;
23446 jghali 466
                                                        double x = item->asTable()->columnPosition(col);
467
                                                        double y = item->asTable()->rowPosition(row);
468
                                                        double width = item->asTable()->columnPosition(lastCol) + item->asTable()->columnWidth(lastCol) - x;
469
                                                        double height = item->asTable()->rowPosition(lastRow) + item->asTable()->rowHeight(lastRow) - y;
23445 jghali 470
                                                        QDomElement cl = m_domDoc.createElement("rect");
471
                                                        cl.setAttribute("fill", setColor(colorName, cell.fillShade()));
17315 fschmid 472
                                                        cl.setAttribute("x", FToStr(x));
473
                                                        cl.setAttribute("y", FToStr(y));
474
                                                        cl.setAttribute("width", FToStr(width));
475
                                                        cl.setAttribute("height", FToStr(height));
476
                                                        ob.appendChild(cl);
477
                                                }
478
                                        }
479
                                        colSpan = cell.columnSpan();
480
                                }
481
                        }
482
                        // Pass 2: Paint vertical borders.
23446 jghali 483
                        for (int row = 0; row < item->asTable()->rows(); ++row)
17315 fschmid 484
                        {
485
                                int colSpan = 0;
23446 jghali 486
                                for (int col = 0; col < item->asTable()->columns(); col += colSpan)
17315 fschmid 487
                                {
23446 jghali 488
                                        TableCell cell = item->asTable()->cellAt(row, col);
17315 fschmid 489
                                        if (row == cell.row())
490
                                        {
491
                                                const int lastRow = cell.row() + cell.rowSpan() - 1;
492
                                                const int lastCol = cell.column() + cell.columnSpan() - 1;
23446 jghali 493
                                                const double borderX = item->asTable()->columnPosition(lastCol) + item->asTable()->columnWidth(lastCol);
17315 fschmid 494
                                                QPointF start(borderX, 0.0);
495
                                                QPointF end(borderX, 0.0);
496
                                                QPointF startOffsetFactors, endOffsetFactors;
497
                                                int startRow, endRow;
498
                                                for (int row = cell.row(); row <= lastRow; row += endRow - startRow + 1)
499
                                                {
23446 jghali 500
                                                        TableCell rightCell = item->asTable()->cellAt(row, lastCol + 1);
17315 fschmid 501
                                                        startRow = qMax(cell.row(), rightCell.row());
502
                                                        endRow = qMin(lastRow, rightCell.isValid() ? rightCell.row() + rightCell.rowSpan() - 1 : lastRow);
23446 jghali 503
                                                        TableCell topLeftCell = item->asTable()->cellAt(startRow - 1, lastCol);
504
                                                        TableCell topRightCell = item->asTable()->cellAt(startRow - 1, lastCol + 1);
505
                                                        TableCell bottomRightCell = item->asTable()->cellAt(endRow + 1, lastCol + 1);
506
                                                        TableCell bottomLeftCell = item->asTable()->cellAt(endRow + 1, lastCol);
17315 fschmid 507
                                                        TableBorder topLeft, top, topRight, border, bottomLeft, bottom, bottomRight;
508
                                                        resolveBordersVertical(topLeftCell, topRightCell, cell, rightCell, bottomLeftCell, bottomRightCell,
23446 jghali 509
                                                                                                   &topLeft, &top, &topRight, &border, &bottomLeft, &bottom, &bottomRight, item->asTable());
17315 fschmid 510
                                                        if (border.isNull())
511
                                                                continue; // Quit early if the border to paint is null.
23446 jghali 512
                                                        start.setY(item->asTable()->rowPosition(startRow));
513
                                                        end.setY((item->asTable()->rowPosition(endRow) + item->asTable()->rowHeight(endRow)));
17315 fschmid 514
                                                        joinVertical(border, topLeft, top, topRight, bottomLeft, bottom, bottomRight, &start, &end, &startOffsetFactors, &endOffsetFactors);
515
                                                        paintBorder(border, start, end, startOffsetFactors, endOffsetFactors, ob);
516
                                                }
517
                                                if (col == 0)
518
                                                {
519
                                                        const int lastRow = cell.row() + cell.rowSpan() - 1;
520
                                                        const int firstCol = cell.column();
23446 jghali 521
                                                        const double borderX = item->asTable()->columnPosition(firstCol);
17315 fschmid 522
                                                        QPointF start(borderX, 0.0);
523
                                                        QPointF end(borderX, 0.0);
524
                                                        QPointF startOffsetFactors, endOffsetFactors;
525
                                                        int startRow, endRow;
526
                                                        for (int row = cell.row(); row <= lastRow; row += endRow - startRow + 1)
527
                                                        {
23446 jghali 528
                                                                TableCell leftCell = item->asTable()->cellAt(row, firstCol - 1);
17315 fschmid 529
                                                                startRow = qMax(cell.row(), leftCell.row());
530
                                                                endRow = qMin(lastRow, leftCell.isValid() ? leftCell.row() + leftCell.rowSpan() - 1 : lastRow);
23446 jghali 531
                                                                TableCell topLeftCell = item->asTable()->cellAt(startRow - 1, firstCol - 1);
532
                                                                TableCell topRightCell = item->asTable()->cellAt(startRow - 1, firstCol);
533
                                                                TableCell bottomRightCell = item->asTable()->cellAt(lastRow + 1, firstCol);
534
                                                                TableCell bottomLeftCell = item->asTable()->cellAt(lastRow + 1, firstCol - 1);
17315 fschmid 535
                                                                TableBorder topLeft, top, topRight, border, bottomLeft, bottom, bottomRight;
536
                                                                resolveBordersVertical(topLeftCell, topRightCell, leftCell, cell, bottomLeftCell, bottomRightCell,
23446 jghali 537
                                                                                                           &topLeft, &top, &topRight, &border, &bottomLeft, &bottom, &bottomRight, item->asTable());
17315 fschmid 538
                                                                if (border.isNull())
539
                                                                        continue; // Quit early if the border to paint is null.
23446 jghali 540
                                                                start.setY(item->asTable()->rowPosition(startRow));
541
                                                                end.setY((item->asTable()->rowPosition(endRow) + item->asTable()->rowHeight(endRow)));
17315 fschmid 542
                                                                joinVertical(border, topLeft, top, topRight, bottomLeft, bottom, bottomRight, &start, &end, &startOffsetFactors, &endOffsetFactors);
543
                                                                paintBorder(border, start, end, startOffsetFactors, endOffsetFactors, ob);
544
                                                        }
545
                                                }
546
                                        }
547
                                        colSpan = cell.columnSpan();
548
                                }
549
                        }
550
                        // Pass 3: Paint horizontal borders.
23446 jghali 551
                        for (int row = 0; row < item->asTable()->rows(); ++row)
17315 fschmid 552
                        {
553
                                int colSpan = 0;
23446 jghali 554
                                for (int col = 0; col < item->asTable()->columns(); col += colSpan)
17315 fschmid 555
                                {
23446 jghali 556
                                        TableCell cell = item->asTable()->cellAt(row, col);
17315 fschmid 557
                                        if (row == cell.row())
558
                                        {
559
                                                const int lastRow = cell.row() + cell.rowSpan() - 1;
560
                                                const int lastCol = cell.column() + cell.columnSpan() - 1;
23446 jghali 561
                                                const double borderY = (item->asTable()->rowPosition(lastRow) + item->asTable()->rowHeight(lastRow));
17315 fschmid 562
                                                QPointF start(0.0, borderY);
563
                                                QPointF end(0.0, borderY);
564
                                                QPointF startOffsetFactors, endOffsetFactors;
565
                                                int startCol, endCol;
566
                                                for (int col = cell.column(); col <= lastCol; col += endCol - startCol + 1)
567
                                                {
23446 jghali 568
                                                        TableCell bottomCell = item->asTable()->cellAt(lastRow + 1, col);
17315 fschmid 569
                                                        startCol = qMax(cell.column(), bottomCell.column());
570
                                                        endCol = qMin(lastCol, bottomCell.isValid() ? bottomCell.column() + bottomCell.columnSpan() - 1 : lastCol);
23446 jghali 571
                                                        TableCell topLeftCell = item->asTable()->cellAt(lastRow, startCol - 1);
572
                                                        TableCell topRightCell = item->asTable()->cellAt(lastRow, endCol + 1);
573
                                                        TableCell bottomRightCell = item->asTable()->cellAt(lastRow + 1, endCol + 1);
574
                                                        TableCell bottomLeftCell = item->asTable()->cellAt(lastRow + 1, startCol - 1);
17315 fschmid 575
                                                        TableBorder topLeft, left, bottomLeft, border, topRight, right, bottomRight;
576
                                                        resolveBordersHorizontal(topLeftCell, cell, topRightCell, bottomLeftCell, bottomCell,
23446 jghali 577
                                                                                                         bottomRightCell, &topLeft, &left, &bottomLeft, &border, &topRight, &right, &bottomRight, item->asTable());
17315 fschmid 578
                                                        if (border.isNull())
579
                                                                continue; // Quit early if the border is null.
23446 jghali 580
                                                        start.setX(item->asTable()->columnPosition(startCol));
581
                                                        end.setX(item->asTable()->columnPosition(endCol) + item->asTable()->columnWidth(endCol));
17315 fschmid 582
                                                        joinHorizontal(border, topLeft, left, bottomLeft, topRight, right, bottomRight, &start, &end, &startOffsetFactors, &endOffsetFactors);
583
                                                        paintBorder(border, start, end, startOffsetFactors, endOffsetFactors, ob);
584
                                                }
585
                                                if (row == 0)
586
                                                {
587
                                                        const int firstRow = cell.row();
588
                                                        const int lastCol = cell.column() + cell.columnSpan() - 1;
23446 jghali 589
                                                        const double borderY = item->asTable()->rowPosition(firstRow);
17315 fschmid 590
                                                        QPointF start(0.0, borderY);
591
                                                        QPointF end(0.0, borderY);
592
                                                        QPointF startOffsetFactors, endOffsetFactors;
593
                                                        int startCol, endCol;
594
                                                        for (int col = cell.column(); col <= lastCol; col += endCol - startCol + 1)
595
                                                        {
23446 jghali 596
                                                                TableCell topCell = item->asTable()->cellAt(firstRow - 1, col);
17315 fschmid 597
                                                                startCol = qMax(cell.column(), topCell.column());
598
                                                                endCol = qMin(lastCol, topCell.isValid() ? topCell.column() + topCell.columnSpan() - 1 : lastCol);
23446 jghali 599
                                                                TableCell topLeftCell = item->asTable()->cellAt(firstRow - 1, startCol - 1);
600
                                                                TableCell topRightCell = item->asTable()->cellAt(firstRow - 1, endCol + 1);
601
                                                                TableCell bottomRightCell = item->asTable()->cellAt(firstRow, endCol + 1);
602
                                                                TableCell bottomLeftCell = item->asTable()->cellAt(firstRow, startCol - 1);
17315 fschmid 603
                                                                TableBorder topLeft, left, bottomLeft, border, topRight, right, bottomRight;
604
                                                                resolveBordersHorizontal(topLeftCell, topCell, topRightCell, bottomLeftCell, cell,
23446 jghali 605
                                                                                                                 bottomRightCell, &topLeft, &left, &bottomLeft, &border, &topRight, &right, &bottomRight, item->asTable());
17315 fschmid 606
                                                                if (border.isNull())
607
                                                                        continue; // Quit early if the border is null.
23446 jghali 608
                                                                start.setX(item->asTable()->columnPosition(startCol));
609
                                                                end.setX(item->asTable()->columnPosition(endCol) + item->asTable()->columnWidth(endCol));
17315 fschmid 610
                                                                joinHorizontal(border, topLeft, left, bottomLeft, topRight, right, bottomRight, &start, &end, &startOffsetFactors, &endOffsetFactors);
611
                                                                paintBorder(border, start, end, startOffsetFactors, endOffsetFactors, ob);
612
                                                        }
613
                                                }
614
                                        }
615
                                        colSpan = cell.columnSpan();
616
                                }
617
                        }
618
                        // Pass 4: Paint cell content.
23446 jghali 619
                        for (int row = 0; row < item->asTable()->rows(); ++row)
17315 fschmid 620
                        {
23446 jghali 621
                                for (int col = 0; col < item->asTable()->columns(); col ++)
17315 fschmid 622
                                {
23446 jghali 623
                                        TableCell cell = item->asTable()->cellAt(row, col);
17315 fschmid 624
                                        if (cell.row() == row && cell.column() == col)
625
                                        {
626
                                                PageItem* textFrame = cell.textFrame();
23445 jghali 627
                                                processItemOnPage(cell.contentRect().x(), cell.contentRect().y(), textFrame, &ob);
17315 fschmid 628
                                        }
629
                                }
630
                        }
631
                        break;
12623 fschmid 632
                default:
633
                        break;
634
        }
23446 jghali 635
        if (item->GrMask > 0)
636
                ob.setAttribute("mask", handleMask(item, xOffset, yOffset));
637
        if (!item->AutoName)
638
                ob.setAttribute("id", item->itemName());
12623 fschmid 639
        parentElem->appendChild(ob);
640
}
641
 
17315 fschmid 642
void SVGExPlug::paintBorder(const TableBorder& border, const QPointF& start, const QPointF& end, const QPointF& startOffsetFactors, const QPointF& endOffsetFactors, QDomElement &ob)
643
{
644
        QPointF lineStart, lineEnd;
22506 jghali 645
        for (const TableBorderLine& line : border.borderLines())
17315 fschmid 646
        {
647
                lineStart.setX(start.x() + line.width() * startOffsetFactors.x());
648
                lineStart.setY(start.y() + line.width() * startOffsetFactors.y());
649
                lineEnd.setX(end.x() + line.width() * endOffsetFactors.x());
650
                lineEnd.setY(end.y() + line.width() * endOffsetFactors.y());
23445 jghali 651
                QDomElement cl = m_domDoc.createElement("path");
652
                cl.setAttribute("d", "M " + FToStr(lineStart.x()) + " " + FToStr(lineStart.y()) + " L " + FToStr(lineEnd.x()) + " " + FToStr(lineEnd.y()));
17315 fschmid 653
                QString stroke = "";
654
                if (line.color() != CommonStrings::None)
23445 jghali 655
                        cl.setAttribute("stroke", setColor(line.color(), line.shade()));
17315 fschmid 656
                if (line.width() != 0.0)
23445 jghali 657
                        stroke = "stroke-width:" + FToStr(line.width()) + ";";
17315 fschmid 658
                else
659
                        stroke = "stroke-width:1px;";
660
                stroke += " stroke-linecap:butt;";
661
                stroke += " stroke-linejoin:miter;";
662
                stroke += " stroke-dasharray:";
663
                if (line.style() == Qt::SolidLine)
664
                        stroke += "none;";
665
                else
666
                {
667
                        QString Da = getDashString(line.style(), qMax(line.width(), 1.0));
668
                        if (Da.isEmpty())
669
                                stroke += "none;";
670
                        else
23445 jghali 671
                                stroke += Da.replace(" ", ", ") + ";";
17315 fschmid 672
                }
673
                cl.setAttribute("style", stroke);
674
                ob.appendChild(cl);
675
        }
676
}
677
 
23446 jghali 678
QString SVGExPlug::processDropShadow(PageItem *item)
18787 fschmid 679
{
23446 jghali 680
        if (!item->hasSoftShadow())
18790 fschmid 681
                return "";
23445 jghali 682
        QString ID = "Filter" + IToStr(m_filterCount);
683
        QDomElement filter = m_domDoc.createElement("filter");
18787 fschmid 684
        filter.setAttribute("id", ID);
18790 fschmid 685
        filter.setAttribute("inkscape:label", "Drop shadow");
23445 jghali 686
        QDomElement ob = m_domDoc.createElement("feGaussianBlur");
687
        ob.setAttribute("id", "feGaussianBlur" + IToStr(m_filterCount));
18790 fschmid 688
        ob.setAttribute("in", "SourceAlpha");
23446 jghali 689
        ob.setAttribute("stdDeviation", FToStr(item->softShadowBlurRadius()));
18790 fschmid 690
        ob.setAttribute("result", "blur");
691
        filter.appendChild(ob);
23445 jghali 692
        QDomElement ob2 = m_domDoc.createElement("feColorMatrix");
693
        ob2.setAttribute("id", "feColorMatrix" + IToStr(m_filterCount));
23446 jghali 694
        const ScColor& col = m_Doc->PageColors[item->softShadowColor()];
695
        QColor color = ScColorEngine::getShadeColorProof(col, m_Doc, item->softShadowShade());
18790 fschmid 696
        ob2.setAttribute("type", "matrix");
23446 jghali 697
        ob2.setAttribute("values", QString("1 0 0 %1 0 0 1 0 %2 0 0 0 1 %3 0 0 0 0 %4 0").arg(color.redF()).arg(color.greenF()).arg(color.blueF()).arg(1.0 - item->softShadowOpacity()));
18790 fschmid 698
        ob2.setAttribute("result", "bluralpha");
18787 fschmid 699
        filter.appendChild(ob2);
23445 jghali 700
        QDomElement ob3 = m_domDoc.createElement("feOffset");
701
        ob3.setAttribute("id", "feOffset" + IToStr(m_filterCount));
18790 fschmid 702
        ob3.setAttribute("in", "bluralpha");
23446 jghali 703
        ob3.setAttribute("dx", FToStr(item->softShadowXOffset()));
704
        ob3.setAttribute("dy", FToStr(item->softShadowYOffset()));
18790 fschmid 705
        ob3.setAttribute("result", "offsetBlur");
706
        filter.appendChild(ob3);
23445 jghali 707
        QDomElement ob4 = m_domDoc.createElement("feMerge");
708
        ob4.setAttribute("id", "feMerge" + IToStr(m_filterCount));
709
        QDomElement ob5 = m_domDoc.createElement("feMergeNode");
710
        ob5.setAttribute("id", "feMergeNode1" + IToStr(m_filterCount));
18790 fschmid 711
        ob5.setAttribute("in", "offsetBlur");
712
        ob4.appendChild(ob5);
23445 jghali 713
        QDomElement ob6 = m_domDoc.createElement("feMergeNode");
714
        ob6.setAttribute("id", "feMergeNode2" + IToStr(m_filterCount));
18790 fschmid 715
        ob6.setAttribute("in", "SourceGraphic");
716
        ob4.appendChild(ob6);
717
        filter.appendChild(ob4);
23445 jghali 718
        m_globalDefs.appendChild(filter);
719
        m_filterCount++;
720
        return "filter:url(#" + ID + ");";
18787 fschmid 721
}
722
 
23446 jghali 723
QDomElement SVGExPlug::processHatchFill(PageItem *item, const QString& transl)
18935 fschmid 724
{
725
        QDomElement ob;
23445 jghali 726
        ob = m_domDoc.createElement("g");
18935 fschmid 727
        if (!transl.isEmpty())
728
                ob.setAttribute("transform", transl);
23446 jghali 729
        QDomElement obc = createClipPathElement(&item->PoLine);
18935 fschmid 730
        if (!obc.isNull())
23445 jghali 731
                ob.setAttribute("clip-path", "url(#" + obc.attribute("id") + ")");
23446 jghali 732
        if (item->fillRule)
18935 fschmid 733
                ob.setAttribute("clip-rule", "evenodd");
734
        else
735
                ob.setAttribute("clip-rule", "nonzero");
23446 jghali 736
        if (item->hatchUseBackground)
18935 fschmid 737
        {
23445 jghali 738
                QDomElement ob2 = m_domDoc.createElement("path");
23446 jghali 739
                ob2.setAttribute("d", setClipPath(&item->PoLine, true));
740
                ob2.setAttribute("fill", setColor(item->hatchBackground, 100));
18935 fschmid 741
                ob.appendChild(ob2);
742
        }
743
        QString stroke = "";
744
        stroke += "stroke-width:1;";
745
        stroke += " stroke-linecap:butt;";
746
        stroke += " stroke-linejoin:miter;";
23446 jghali 747
        double lineLen = sqrt((item->width() / 2.0) * (item->width() / 2.0) + (item->height() / 2.0) * (item->height() / 2.0));
18935 fschmid 748
        double dist = 0.0;
749
        while (dist < lineLen)
750
        {
751
                QTransform mpx;
23446 jghali 752
                mpx.translate(item->width() / 2.0, item->height() / 2.0);
753
                if (item->hatchAngle != 0.0)
754
                        mpx.rotate(-item->hatchAngle);
23445 jghali 755
                QDomElement ob3 = m_domDoc.createElement("path");
756
                ob3.setAttribute("transform", matrixToStr(mpx));
18935 fschmid 757
                ob3.setAttribute("d", QString("M %1, %2 L %3, %4").arg(-lineLen).arg(dist).arg(lineLen).arg(dist));
23446 jghali 758
                ob3.setAttribute("stroke", setColor(item->hatchForeground, 100));
18935 fschmid 759
                ob3.setAttribute("style", stroke);
760
                ob.appendChild(ob3);
761
                if (dist > 0)
762
                {
23445 jghali 763
                        QDomElement ob4 = m_domDoc.createElement("path");
764
                        ob4.setAttribute("transform", matrixToStr(mpx));
18935 fschmid 765
                        ob4.setAttribute("d", QString("M %1, %2 L %3, %4").arg(-lineLen).arg(-dist).arg(lineLen).arg(-dist));
23446 jghali 766
                        ob4.setAttribute("stroke", setColor(item->hatchForeground, 100));
18935 fschmid 767
                        ob4.setAttribute("style", stroke);
768
                        ob.appendChild(ob4);
769
                }
23446 jghali 770
                dist += item->hatchDistance;
18935 fschmid 771
        }
23446 jghali 772
        if ((item->hatchType == 1) || (item->hatchType == 2))
18935 fschmid 773
        {
774
                dist = 0.0;
775
                while (dist < lineLen)
776
                {
777
                        QTransform mpx;
23446 jghali 778
                        mpx.translate(item->width() / 2.0, item->height() / 2.0);
779
                        if (item->hatchAngle != 0.0)
780
                                mpx.rotate(-item->hatchAngle + 90);
23445 jghali 781
                        QDomElement ob3 = m_domDoc.createElement("path");
782
                        ob3.setAttribute("transform", matrixToStr(mpx));
18935 fschmid 783
                        ob3.setAttribute("d", QString("M %1, %2 L %3, %4").arg(-lineLen).arg(dist).arg(lineLen).arg(dist));
23446 jghali 784
                        ob3.setAttribute("stroke", setColor(item->hatchForeground, 100));
18935 fschmid 785
                        ob3.setAttribute("style", stroke);
786
                        ob.appendChild(ob3);
787
                        if (dist > 0)
788
                        {
23445 jghali 789
                                QDomElement ob4 = m_domDoc.createElement("path");
790
                                ob4.setAttribute("transform", matrixToStr(mpx));
18935 fschmid 791
                                ob4.setAttribute("d", QString("M %1, %2 L %3, %4").arg(-lineLen).arg(-dist).arg(lineLen).arg(-dist));
23446 jghali 792
                                ob4.setAttribute("stroke", setColor(item->hatchForeground, 100));
18935 fschmid 793
                                ob4.setAttribute("style", stroke);
794
                                ob.appendChild(ob4);
795
                        }
23446 jghali 796
                        dist += item->hatchDistance;
18935 fschmid 797
                }
798
        }
23446 jghali 799
        if (item->hatchType == 2)
18935 fschmid 800
        {
801
                dist = 0.0;
802
                while (dist < lineLen)
803
                {
804
                        double dDist = dist * sqrt(2.0);
805
                        QTransform mpx;
23446 jghali 806
                        mpx.translate(item->width() / 2.0, item->height() / 2.0);
807
                        if (item->hatchAngle != 0.0)
808
                                mpx.rotate(-item->hatchAngle + 45);
23445 jghali 809
                        QDomElement ob3 = m_domDoc.createElement("path");
810
                        ob3.setAttribute("transform", matrixToStr(mpx));
18935 fschmid 811
                        ob3.setAttribute("d", QString("M %1, %2 L %3, %4").arg(-lineLen).arg(dDist).arg(lineLen).arg(dDist));
23446 jghali 812
                        ob3.setAttribute("stroke", setColor(item->hatchForeground, 100));
18935 fschmid 813
                        ob3.setAttribute("style", stroke);
814
                        ob.appendChild(ob3);
815
                        if (dist > 0)
816
                        {
23445 jghali 817
                                QDomElement ob4 = m_domDoc.createElement("path");
818
                                ob4.setAttribute("transform", matrixToStr(mpx));
18935 fschmid 819
                                ob4.setAttribute("d", QString("M %1, %2 L %3, %4").arg(-lineLen).arg(-dDist).arg(lineLen).arg(-dDist));
23446 jghali 820
                                ob4.setAttribute("stroke", setColor(item->hatchForeground, 100));
18935 fschmid 821
                                ob4.setAttribute("style", stroke);
822
                                ob.appendChild(ob4);
823
                        }
23446 jghali 824
                        dist += item->hatchDistance;
18935 fschmid 825
                }
826
        }
827
        return ob;
828
}
829
 
23446 jghali 830
QDomElement SVGExPlug::processSymbolStroke(PageItem *item, const QString& trans)
15077 fschmid 831
{
832
        QDomElement ob;
23445 jghali 833
        ob = m_domDoc.createElement("g");
15077 fschmid 834
        ob.setAttribute("transform", trans);
23446 jghali 835
        QPainterPath path = item->PoLine.toQPainterPath(false);
836
        ScPattern pat = m_Doc->docPatterns[item->strokePattern()];
837
        double pLen = path.length() - ((pat.width / 2.0) * (item->patternStrokeScaleX / 100.0));
838
        double adv = pat.width * item->patternStrokeScaleX / 100.0 * item->patternStrokeSpace;
839
        double xpos = item->patternStrokeOffsetX * item->patternStrokeScaleX / 100.0;
15077 fschmid 840
        while (xpos < pLen)
841
        {
842
                double currPerc = path.percentAtLength(xpos);
843
                double currAngle = path.angleAtPercent(currPerc);
844
                if (currAngle <= 180.0)
845
                        currAngle *= -1.0;
846
                else
847
                        currAngle = 360.0 - currAngle;
848
                QPointF currPoint = path.pointAtPercent(currPerc);
849
                QTransform trans;
850
                trans.translate(currPoint.x(), currPoint.y());
851
                trans.rotate(-currAngle);
23446 jghali 852
                trans.translate(0.0, item->patternStrokeOffsetY);
853
                trans.rotate(-item->patternStrokeRotation);
854
                trans.shear(item->patternStrokeSkewX, -item->patternStrokeSkewY);
855
                trans.scale(item->patternStrokeScaleX / 100.0, item->patternStrokeScaleY / 100.0);
15077 fschmid 856
                trans.translate(-pat.width / 2.0, -pat.height / 2.0);
857
                QDomElement obS;
23445 jghali 858
                obS = m_domDoc.createElement("use");
859
                obS.setAttribute("transform", matrixToStr(trans));
23446 jghali 860
                if (item->patternStrokeMirrorX)
15077 fschmid 861
                {
862
                        trans.translate(pat.width, 0);
863
                        trans.scale(-1, 1);
864
                }
23446 jghali 865
                if (item->patternStrokeMirrorY)
15077 fschmid 866
                {
867
                        trans.translate(0, pat.height);
868
                        trans.scale(1, -1);
869
                }
870
                obS.setAttribute("x", "0");
871
                obS.setAttribute("y", "0");
872
                obS.setAttribute("width", FToStr(pat.width));
873
                obS.setAttribute("height", FToStr(pat.height));
23446 jghali 874
                obS.setAttribute("xlink:href", "#S" + item->strokePattern());
15077 fschmid 875
                ob.appendChild(obS);
876
                xpos += adv;
877
        }
878
        return ob;
879
}
880
 
23446 jghali 881
QDomElement SVGExPlug::processSymbolItem(PageItem *item, const QString& trans)
15077 fschmid 882
{
883
        QDomElement ob;
23446 jghali 884
        ScPattern pat = m_Doc->docPatterns[item->pattern()];
23445 jghali 885
        ob = m_domDoc.createElement("use");
15077 fschmid 886
        ob.setAttribute("x", "0");
887
        ob.setAttribute("y", "0");
18745 jghali 888
        ob.setAttribute("width", FToStr(pat.width));
889
        ob.setAttribute("height", FToStr(pat.height));
23446 jghali 890
        ob.setAttribute("xlink:href", "#S" + item->pattern());
891
        QString tr = trans + QString(" scale(%1, %2)").arg(item->width() / pat.width).arg(item->height() / pat.height);
15077 fschmid 892
        ob.setAttribute("transform", tr);
893
        return ob;
894
}
895
 
23446 jghali 896
QDomElement SVGExPlug::processPolyItem(PageItem *item, const QString& trans, const QString& fill, const QString& stroke)
12623 fschmid 897
{
898
        bool closedPath;
899
        QDomElement ob;
23446 jghali 900
        closedPath = (item->itemType() == PageItem::Polygon) || (item->itemType() == PageItem::RegularPolygon) || (item->itemType() == PageItem::Arc);
901
        if (item->NamedLStyle.isEmpty())
12623 fschmid 902
        {
23446 jghali 903
                if ((!item->strokePattern().isEmpty()) && (item->patternStrokePath))
15077 fschmid 904
                {
23445 jghali 905
                        ob = m_domDoc.createElement("g");
23904 jghali 906
                        if (item->GrType == Gradient_Hatch)
18935 fschmid 907
                        {
23446 jghali 908
                                QDomElement ob1 = processHatchFill(item, trans);
18935 fschmid 909
                                ob.appendChild(ob1);
910
                        }
23445 jghali 911
                        QDomElement ob2 = m_domDoc.createElement("path");
23446 jghali 912
                        ob2.setAttribute("d", setClipPath(&item->PoLine, closedPath));
15077 fschmid 913
                        ob2.setAttribute("transform", trans);
23904 jghali 914
                        if (item->GrType != Gradient_Hatch)
18935 fschmid 915
                                ob2.setAttribute("style", fill);
916
                        else
917
                        {
23446 jghali 918
                                QString drS = processDropShadow(item);
18935 fschmid 919
                                if (!drS.isEmpty())
920
                                        ob2.setAttribute("style", "fill:none;" + drS);
921
                        }
15077 fschmid 922
                        ob.appendChild(ob2);
23446 jghali 923
                        ob.appendChild(processSymbolStroke(item, trans));
15077 fschmid 924
                }
925
                else
926
                {
23904 jghali 927
                        if (item->GrType == Gradient_Hatch)
18935 fschmid 928
                        {
23445 jghali 929
                                ob = m_domDoc.createElement("g");
18935 fschmid 930
                                ob.setAttribute("transform", trans);
23446 jghali 931
                                QDomElement ob1 = processHatchFill(item);
18935 fschmid 932
                                ob.appendChild(ob1);
23445 jghali 933
                                QDomElement ob2 = m_domDoc.createElement("path");
23446 jghali 934
                                ob2.setAttribute("d", setClipPath(&item->PoLine, closedPath));
935
                                ob2.setAttribute("style", stroke + "fill:none;" + processDropShadow(item));
18935 fschmid 936
                                ob.appendChild(ob2);
937
                        }
938
                        else
939
                        {
23445 jghali 940
                                ob = m_domDoc.createElement("path");
23446 jghali 941
                                ob.setAttribute("d", setClipPath(&item->PoLine, closedPath));
18935 fschmid 942
                                ob.setAttribute("transform", trans);
943
                                ob.setAttribute("style", fill + stroke);
944
                        }
15077 fschmid 945
                }
12623 fschmid 946
        }
947
        else
948
        {
23445 jghali 949
                ob = m_domDoc.createElement("g");
12623 fschmid 950
                ob.setAttribute("transform", trans);
23904 jghali 951
                if (item->GrType == Gradient_Hatch)
18935 fschmid 952
                {
23446 jghali 953
                        QDomElement ob1 = processHatchFill(item);
18935 fschmid 954
                        ob.appendChild(ob1);
955
                }
23445 jghali 956
                QDomElement ob2 = m_domDoc.createElement("path");
23446 jghali 957
                ob2.setAttribute("d", setClipPath(&item->PoLine, closedPath));
23904 jghali 958
                if (item->GrType != Gradient_Hatch)
18935 fschmid 959
                        ob2.setAttribute("style", fill);
960
                else
961
                {
23446 jghali 962
                        QString drS = processDropShadow(item);
18935 fschmid 963
                        if (!drS.isEmpty())
964
                                ob2.setAttribute("style", "fill:none;" + drS);
965
                }
12623 fschmid 966
                ob.appendChild(ob2);
23707 jghali 967
                multiLine ml = m_Doc->docLineStyles[item->NamedLStyle];
12623 fschmid 968
                for (int it = ml.size()-1; it > -1; it--)
969
                {
970
                        if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
971
                        {
23445 jghali 972
                                QDomElement ob3 = m_domDoc.createElement("path");
23446 jghali 973
                                ob3.setAttribute("d", setClipPath(&item->PoLine, closedPath));
974
                                ob3.setAttribute("style", getMultiStroke(&ml[it], item));
12623 fschmid 975
                                ob.appendChild(ob3);
976
                        }
977
                }
978
        }
979
        return ob;
980
}
981
 
23446 jghali 982
QDomElement SVGExPlug::processLineItem(PageItem *item, const QString& trans, const QString& stroke)
12623 fschmid 983
{
984
        QDomElement ob;
23446 jghali 985
        if (item->NamedLStyle.isEmpty())
12623 fschmid 986
        {
23445 jghali 987
                ob = m_domDoc.createElement("path");
23446 jghali 988
                ob.setAttribute("d", "M 0 0 L " + FToStr(item->width()) + " 0");
12623 fschmid 989
                ob.setAttribute("transform", trans);
990
                ob.setAttribute("style", stroke);
991
        }
992
        else
993
        {
23445 jghali 994
                ob = m_domDoc.createElement("g");
12623 fschmid 995
                ob.setAttribute("transform", trans);
23707 jghali 996
                multiLine ml = m_Doc->docLineStyles[item->NamedLStyle];
22600 craig 997
                for (int i = ml.size()-1; i > -1; i--)
12623 fschmid 998
                {
22600 craig 999
                        if ((ml[i].Color != CommonStrings::None) && (ml[i].Width != 0))
12623 fschmid 1000
                        {
23445 jghali 1001
                                QDomElement ob2 = m_domDoc.createElement("path");
23446 jghali 1002
                                ob2.setAttribute("d", "M 0 0 L " + FToStr(item->width()) + " 0");
1003
                                ob2.setAttribute("style", getMultiStroke(&ml[i], item));
12623 fschmid 1004
                                ob.appendChild(ob2);
1005
                        }
1006
                }
1007
        }
1008
        return ob;
1009
}
1010
 
23446 jghali 1011
QDomElement SVGExPlug::processImageItem(PageItem *item, const QString& trans, const QString& fill, const QString& stroke)
12623 fschmid 1012
{
1013
        QDomElement ob;
23445 jghali 1014
        ob = m_domDoc.createElement("g");
12623 fschmid 1015
        ob.setAttribute("transform", trans);
23446 jghali 1016
        if ((item->fillColor() != CommonStrings::None) || (item->GrType != 0))
12623 fschmid 1017
        {
23904 jghali 1018
                if (item->GrType == Gradient_Hatch)
18935 fschmid 1019
                {
23446 jghali 1020
                        QDomElement ob1 = processHatchFill(item);
18935 fschmid 1021
                        ob.appendChild(ob1);
23446 jghali 1022
                        QString drS = processDropShadow(item);
18935 fschmid 1023
                        if (!drS.isEmpty())
1024
                                ob.setAttribute("style", "fill:none;" + drS);
1025
                }
1026
                else
1027
                {
23445 jghali 1028
                        QDomElement ob1 = m_domDoc.createElement("path");
23446 jghali 1029
                        ob1.setAttribute("d", setClipPath(&item->PoLine, true));
18935 fschmid 1030
                        ob1.setAttribute("style", fill);
1031
                        ob.appendChild(ob1);
1032
                }
12623 fschmid 1033
        }
23446 jghali 1034
        if ((item->imageIsAvailable) && (!item->Pfile.isEmpty()))
12623 fschmid 1035
        {
18735 jghali 1036
                QDomElement cl, ob2;
23446 jghali 1037
                if (!item->imageClip.empty())
1038
                        ob2 = createClipPathElement(&item->imageClip, &cl);
12623 fschmid 1039
                else
23446 jghali 1040
                        ob2 = createClipPathElement(&item->PoLine, &cl);
18735 jghali 1041
                if (!ob2.isNull())
17042 fschmid 1042
                {
18735 jghali 1043
                        ob2.setAttribute("clipPathUnits", "userSpaceOnUse");
1044
                        ob2.setAttribute("clip-rule", "evenodd");
1045
                        QTransform mpc;
23446 jghali 1046
                        if (item->imageFlippedH())
18735 jghali 1047
                        {
23446 jghali 1048
                                mpc.translate(item->width(), 0);
18735 jghali 1049
                                mpc.scale(-1, 1);
1050
                        }
23446 jghali 1051
                        if (item->imageFlippedV())
18735 jghali 1052
                        {
23446 jghali 1053
                                mpc.translate(0, item->height());
18735 jghali 1054
                                mpc.scale(1, -1);
1055
                        }
23445 jghali 1056
                        cl.setAttribute("transform", matrixToStr(mpc));
17042 fschmid 1057
                }
23445 jghali 1058
                QDomElement ob6 = m_domDoc.createElement("g");
18735 jghali 1059
                if (!ob2.isNull())
1060
                        ob6.setAttribute("clip-path", "url(#" + ob2.attribute("id") + ")");
23445 jghali 1061
                QDomElement ob3 = m_domDoc.createElement("image");
12623 fschmid 1062
                ScImage img;
23488 jghali 1063
                CMSettings cms(m_Doc, item->ImageProfile, item->ImageIntent);
23446 jghali 1064
                cms.setUseEmbeddedProfile(item->UseEmbedded);
14467 jghali 1065
                cms.allowSoftProofing(true);
23446 jghali 1066
                img.loadPicture(item->Pfile, item->pixm.imgInfo.actualPageNumber, cms, ScImage::RGBData, 72);
1067
                img.applyEffect(item->effectsInUse, m_Doc->PageColors, true);
12623 fschmid 1068
                if (Options.inlineImages)
1069
                {
1070
                        QBuffer buffer;
1071
                        buffer.open(QIODevice::WriteOnly);
1072
                        img.qImage().save(&buffer, "PNG");
1073
                        QByteArray ba = buffer.buffer().toBase64();
1074
                        buffer.close();
23445 jghali 1075
                        ob3.setAttribute("xlink:href", "data:image/png;base64," + QString(ba));
12623 fschmid 1076
                }
1077
                else
1078
                {
23446 jghali 1079
                        QFileInfo fi = QFileInfo(item->Pfile);
23445 jghali 1080
                        QString imgFileName = m_baseDir + "/" + fi.baseName() + ".png";
12623 fschmid 1081
                        QFileInfo im = QFileInfo(imgFileName);
1082
                        if (im.exists())
23445 jghali 1083
                                imgFileName = m_baseDir + "/" + fi.baseName() + "_copy.png";
12623 fschmid 1084
                        img.qImage().save(imgFileName, "PNG");
1085
                        QFileInfo fi2 = QFileInfo(imgFileName);
23445 jghali 1086
                        ob3.setAttribute("xlink:href", fi2.baseName() + ".png");
12623 fschmid 1087
                }
23446 jghali 1088
                ob3.setAttribute("x", FToStr(item->imageXOffset() * item->imageXScale()));
1089
                ob3.setAttribute("y", FToStr(item->imageYOffset() * item->imageYScale()));
1090
                ob3.setAttribute("width", FToStr(img.width() * item->imageXScale()));
1091
                ob3.setAttribute("height", FToStr(img.height() * item->imageYScale()));
13951 fschmid 1092
                QTransform mpa;
23446 jghali 1093
                if (item->imageFlippedH())
12623 fschmid 1094
                {
23446 jghali 1095
                        mpa.translate(item->width(), 0);
12623 fschmid 1096
                        mpa.scale(-1, 1);
1097
                }
23446 jghali 1098
                if (item->imageFlippedV())
12623 fschmid 1099
                {
23446 jghali 1100
                        mpa.translate(0, item->height());
12623 fschmid 1101
                        mpa.scale(1, -1);
1102
                }
23446 jghali 1103
                mpa.rotate(item->imageRotation());
23445 jghali 1104
                ob3.setAttribute("transform", matrixToStr(mpa));
14864 fschmid 1105
                ob6.appendChild(ob3);
1106
                ob.appendChild(ob6);
12623 fschmid 1107
        }
23446 jghali 1108
        if (item->NamedLStyle.isEmpty())
12623 fschmid 1109
        {
23446 jghali 1110
                if ((!item->strokePattern().isEmpty()) && (item->patternStrokePath))
15077 fschmid 1111
                {
23445 jghali 1112
                        QDomElement ob4 = m_domDoc.createElement("g");
1113
                        QDomElement ob2 = m_domDoc.createElement("path");
23446 jghali 1114
                        ob2.setAttribute("d", setClipPath(&item->PoLine, true));
15077 fschmid 1115
                        ob2.setAttribute("transform", trans);
1116
                        ob2.setAttribute("style", fill);
1117
                        ob4.appendChild(ob2);
23446 jghali 1118
                        ob4.appendChild(processSymbolStroke(item, trans));
15077 fschmid 1119
                        ob.appendChild(ob4);
1120
                }
1121
                else
1122
                {
23445 jghali 1123
                        QDomElement ob4 = m_domDoc.createElement("path");
23446 jghali 1124
                        ob4.setAttribute("d", setClipPath(&item->PoLine, true));
23445 jghali 1125
                        ob4.setAttribute("style", "fill:none; " + stroke);
15077 fschmid 1126
                        ob.appendChild(ob4);
1127
                }
12623 fschmid 1128
        }
1129
        else
1130
        {
23707 jghali 1131
                multiLine ml = m_Doc->docLineStyles[item->NamedLStyle];
12623 fschmid 1132
                for (int it = ml.size()-1; it > -1; it--)
1133
                {
1134
                        if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
1135
                        {
23445 jghali 1136
                                QDomElement ob5 = m_domDoc.createElement("path");
23446 jghali 1137
                                ob5.setAttribute("d", setClipPath(&item->PoLine, true));
1138
                                ob5.setAttribute("style", "fill:none; " + getMultiStroke(&ml[it], item));
12623 fschmid 1139
                                ob.appendChild(ob5);
1140
                        }
1141
                }
1142
        }
1143
        return ob;
1144
}
1145
 
21107 craig 1146
class SvgPainter: public TextLayoutPainter
1147
{
1148
        QDomElement m_elem;
1149
        SVGExPlug *m_svg;
1150
        QString m_trans;
1151
 
1152
public:
22600 craig 1153
        SvgPainter(const QString& trans, SVGExPlug *svg, QDomElement &elem)
21107 craig 1154
                : m_elem(elem)
1155
                , m_svg(svg)
1156
                , m_trans(trans)
1157
        {}
1158
 
23073 jghali 1159
        void drawGlyph(const GlyphCluster& gc) override
21107 craig 1160
        {
22780 jghali 1161
                if (gc.isControlGlyphs() || gc.isEmpty())
21107 craig 1162
                        return;
21563 jghali 1163
                double current_x = 0.0;
22506 jghali 1164
                for (const GlyphLayout& gl : gc.glyphs())
1165
                {
22780 jghali 1166
                        if (gl.glyph >= ScFace::CONTROL_GLYPHS)
1167
                        {
23072 jghali 1168
                                current_x += gl.xadvance * gl.scaleH;
22780 jghali 1169
                                continue;
1170
                        }
1171
 
21563 jghali 1172
                        QTransform transform = matrix();
1173
                        transform.translate(x() + gl.xoffset + current_x, y() - (fontSize() * gc.scaleV()) + gl.yoffset);
1174
                        transform.scale(gc.scaleH() * fontSize() / 10.0, gc.scaleV() * fontSize() / 10.0);
23445 jghali 1175
                        QDomElement glyph = m_svg->m_domDoc.createElement("use");
21563 jghali 1176
                        glyph.setAttribute("xlink:href", "#" + m_svg->handleGlyph(gl.glyph, font()));
23445 jghali 1177
                        glyph.setAttribute("transform", m_svg->matrixToStr(transform));
1178
                        QString fill = "fill:" + m_svg->setColor(fillColor().color, fillColor().shade) + ";";
21563 jghali 1179
                        QString stroke = "stroke:none;";
1180
                        glyph.setAttribute("style", fill + stroke);
1181
                        m_elem.appendChild(glyph);
22780 jghali 1182
 
23072 jghali 1183
                        current_x += gl.xadvance * gl.scaleH;
21563 jghali 1184
                }
22780 jghali 1185
        }
21107 craig 1186
 
23073 jghali 1187
        void drawGlyphOutline(const GlyphCluster& gc, bool hasFill) override
21107 craig 1188
        {
24736 jghali 1189
                if (gc.isControlGlyphs() || gc.isEmpty())
21107 craig 1190
                        return;
22780 jghali 1191
 
21563 jghali 1192
                double current_x = 0.0;
22506 jghali 1193
                for (const GlyphLayout& gl : gc.glyphs())
1194
                {
22780 jghali 1195
                        if (gl.glyph >= ScFace::CONTROL_GLYPHS)
1196
                        {
23072 jghali 1197
                                current_x += gl.xadvance * gl.scaleH;
22780 jghali 1198
                                continue;
1199
                        }
1200
 
21563 jghali 1201
                        QTransform transform = matrix();
1202
                        transform.translate(x() + gl.xoffset + current_x, y() - (fontSize() * gc.scaleV()) + gl.yoffset);
1203
                        transform.scale(gc.scaleH() * fontSize() / 10.0, gc.scaleV() * fontSize() / 10.0);
23445 jghali 1204
                        QDomElement glyph = m_svg->m_domDoc.createElement("use");
21563 jghali 1205
                        glyph.setAttribute("xlink:href", "#" + m_svg->handleGlyph(gl.glyph, font()));
23445 jghali 1206
                        glyph.setAttribute("transform", m_svg->matrixToStr(transform));
21563 jghali 1207
                        QString fill = "fill:none;";
1208
                        if (hasFill)
23445 jghali 1209
                                fill = "fill:" + m_svg->setColor(fillColor().color, fillColor().shade) + ";";
1210
                        QString stroke ="stroke:" + m_svg->setColor(strokeColor().color, strokeColor().shade) + ";";
21563 jghali 1211
                        stroke += " stroke-width:" + m_svg->FToStr(strokeWidth() / (gc.scaleV() * fontSize() / 10.0)) + ";";
1212
                        glyph.setAttribute("style", fill + stroke);
1213
                        m_elem.appendChild(glyph);
22780 jghali 1214
 
23072 jghali 1215
                        current_x += gl.xadvance * gl.scaleH;
21563 jghali 1216
                }
22780 jghali 1217
        }
21107 craig 1218
 
23073 jghali 1219
        void drawLine(QPointF start, QPointF end) override
21107 craig 1220
        {
1221
                QTransform transform = matrix();
1222
                transform.translate(x(), y());
23445 jghali 1223
                QDomElement path = m_svg-> m_domDoc.createElement("path");
21107 craig 1224
                path.setAttribute("d", QString("M %1 %2 L%3 %4").arg(start.x()).arg(start.y()).arg(end.x()).arg(end.y()));
1225
                QString stroke = "stroke:none;";
1226
                if (fillColor().color != CommonStrings::None)
1227
                {
23445 jghali 1228
                        stroke = "stroke:" + m_svg->setColor(fillColor().color, fillColor().shade) + ";";
21107 craig 1229
                        stroke += " stroke-width:" + m_svg->FToStr(strokeWidth()) + ";";
1230
                }
1231
                path.setAttribute("style", "fill:none;" + stroke);
23445 jghali 1232
                path.setAttribute("transform", m_svg->matrixToStr(transform));
21107 craig 1233
                m_elem.appendChild(path);
1234
        }
1235
 
24719 jghali 1236
        void drawRect(const QRectF& rect) override
21107 craig 1237
        {
1238
                QTransform transform = matrix();
1239
                transform.translate(x(), y());
1240
                QString paS = QString("M %1 %2 ").arg(rect.x()).arg(rect.y());
1241
                paS += QString("L %1 %2 ").arg(rect.x() + rect.width()).arg(rect.y());
1242
                paS += QString("L %1 %2 ").arg(rect.x() + rect.width()).arg(rect.y() + rect.height());
1243
                paS += QString("L %1 %2 ").arg(rect.x()).arg(rect.y() + rect.height());
1244
                paS += "Z";
23445 jghali 1245
                QDomElement path = m_svg->m_domDoc.createElement("path");
21107 craig 1246
                path.setAttribute("d", paS);
23445 jghali 1247
                path.setAttribute("transform", m_svg->matrixToStr(transform));
1248
                path.setAttribute("style", "fill:" + m_svg->setColor(fillColor().color, fillColor().shade) + ";" + "stroke:none;");
21107 craig 1249
                m_elem.appendChild(path);
1250
        }
1251
 
23073 jghali 1252
        void drawObject(PageItem* item) override
21107 craig 1253
        {
21312 fschmid 1254
                QTransform transform = matrix();
1255
                transform.translate(x() + item->gXpos, y() + item->gYpos);
1256
                transform.rotate(item->rotation());
1257
                transform.scale(scaleH(), scaleV());
23445 jghali 1258
                QDomElement Group = m_svg->m_domDoc.createElement("g");
21107 craig 1259
                QDomElement layerGroup = m_svg->processInlineItem(item, m_trans, scaleH(), scaleV());
21312 fschmid 1260
                Group.appendChild(layerGroup);
23445 jghali 1261
                Group.setAttribute("transform", m_svg->matrixToStr(transform));
21312 fschmid 1262
                m_elem.appendChild(Group);
21107 craig 1263
        }
1264
};
1265
 
23446 jghali 1266
QDomElement SVGExPlug::processTextItem(PageItem *item, const QString& trans, const QString& fill, const QString& stroke)
12623 fschmid 1267
{
1268
        QDomElement ob;
23445 jghali 1269
        ob = m_domDoc.createElement("g");
12623 fschmid 1270
        ob.setAttribute("transform", trans);
23446 jghali 1271
        if ((item->fillColor() != CommonStrings::None) || (item->GrType != 0))
12623 fschmid 1272
        {
23904 jghali 1273
                if (item->GrType == Gradient_Hatch)
18935 fschmid 1274
                {
23446 jghali 1275
                        QDomElement ob1 = processHatchFill(item);
18935 fschmid 1276
                        ob.appendChild(ob1);
23446 jghali 1277
                        QString drS = processDropShadow(item);
18935 fschmid 1278
                        if (!drS.isEmpty())
1279
                                ob.setAttribute("style", "fill:none;" + drS);
1280
                }
1281
                else
1282
                {
23445 jghali 1283
                        QDomElement ob1 = m_domDoc.createElement("path");
23446 jghali 1284
                        ob1.setAttribute("d", setClipPath(&item->PoLine, true));
18935 fschmid 1285
                        ob1.setAttribute("style", fill);
1286
                        ob.appendChild(ob1);
1287
                }
12623 fschmid 1288
        }
21113 craig 1289
 
23446 jghali 1290
        if (item->itemText.length() != 0)
21321 fschmid 1291
        {
1292
                SvgPainter p(trans, this, ob);
23446 jghali 1293
                item->textLayout.renderBackground(&p);
1294
                item->textLayout.render(&p);
21321 fschmid 1295
        }
23446 jghali 1296
        if (item->isTextFrame())
21128 fschmid 1297
        {
23446 jghali 1298
                if (item->NamedLStyle.isEmpty())
21128 fschmid 1299
                {
23446 jghali 1300
                        if ((!item->strokePattern().isEmpty()) && (item->patternStrokePath))
21128 fschmid 1301
                        {
23445 jghali 1302
                                QDomElement ob4 = m_domDoc.createElement("g");
1303
                                QDomElement ob2 = m_domDoc.createElement("path");
23446 jghali 1304
                                ob2.setAttribute("d", setClipPath(&item->PoLine, true));
21128 fschmid 1305
                                ob2.setAttribute("transform", trans);
1306
                                ob2.setAttribute("style", fill);
1307
                                ob4.appendChild(ob2);
23446 jghali 1308
                                ob4.appendChild(processSymbolStroke(item, trans));
21128 fschmid 1309
                                ob.appendChild(ob4);
1310
                        }
1311
                        else
1312
                        {
23445 jghali 1313
                                QDomElement ob4 = m_domDoc.createElement("path");
23446 jghali 1314
                                ob4.setAttribute("d", setClipPath(&item->PoLine, true));
23445 jghali 1315
                                ob4.setAttribute("style", "fill:none; " + stroke);
21128 fschmid 1316
                                ob.appendChild(ob4);
1317
                        }
1318
                }
1319
                else
1320
                {
23707 jghali 1321
                        multiLine ml = m_Doc->docLineStyles[item->NamedLStyle];
21128 fschmid 1322
                        for (int it = ml.size()-1; it > -1; it--)
1323
                        {
1324
                                if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
1325
                                {
23445 jghali 1326
                                        QDomElement ob5 = m_domDoc.createElement("path");
23446 jghali 1327
                                        ob5.setAttribute("d", setClipPath(&item->PoLine, true));
1328
                                        ob5.setAttribute("style", "fill:none; " + getMultiStroke(&ml[it], item));
21128 fschmid 1329
                                        ob.appendChild(ob5);
1330
                                }
1331
                        }
1332
                }
1333
        }
23446 jghali 1334
        else if (item->isPathText() && item->PoShow)
21128 fschmid 1335
        {
23446 jghali 1336
                if (item->NamedLStyle.isEmpty())
21128 fschmid 1337
                {
23446 jghali 1338
                        if ((!item->strokePattern().isEmpty()) && (item->patternStrokePath))
21128 fschmid 1339
                        {
23445 jghali 1340
                                QDomElement ob4 = m_domDoc.createElement("g");
1341
                                QDomElement ob2 = m_domDoc.createElement("path");
23446 jghali 1342
                                ob2.setAttribute("d", setClipPath(&item->PoLine, false));
21128 fschmid 1343
                                ob2.setAttribute("transform", trans);
1344
                                ob2.setAttribute("style", fill);
1345
                                ob4.appendChild(ob2);
23446 jghali 1346
                                ob4.appendChild(processSymbolStroke(item, trans));
21128 fschmid 1347
                                ob.appendChild(ob4);
1348
                        }
1349
                        else
1350
                        {
23445 jghali 1351
                                QDomElement ob4 = m_domDoc.createElement("path");
23446 jghali 1352
                                ob4.setAttribute("d", setClipPath(&item->PoLine, false));
23445 jghali 1353
                                ob4.setAttribute("style", "fill:none; " + stroke);
21128 fschmid 1354
                                ob.appendChild(ob4);
1355
                        }
1356
                }
1357
                else
1358
                {
23707 jghali 1359
                        multiLine ml = m_Doc->docLineStyles[item->NamedLStyle];
21128 fschmid 1360
                        for (int it = ml.size()-1; it > -1; it--)
1361
                        {
1362
                                if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
1363
                                {
23445 jghali 1364
                                        QDomElement ob5 = m_domDoc.createElement("path");
23446 jghali 1365
                                        ob5.setAttribute("d", setClipPath(&item->PoLine, false));
1366
                                        ob5.setAttribute("style", "fill:none; " + getMultiStroke(&ml[it], item));
21128 fschmid 1367
                                        ob.appendChild(ob5);
1368
                                }
1369
                        }
1370
                }
1371
        }
12623 fschmid 1372
        return ob;
1373
}
1374
 
22600 craig 1375
QDomElement SVGExPlug::processInlineItem(PageItem* embItem, const QString& trans, double scaleH, double scaleV)
12623 fschmid 1376
{
18987 avox 1377
        QList<PageItem*> emG;
19104 jghali 1378
        if (embItem->isGroup())
21312 fschmid 1379
                emG = embItem->groupItemList;
19104 jghali 1380
        else
1381
                emG.append(embItem);
1382
 
23445 jghali 1383
        QDomElement layerGroup = m_domDoc.createElement("g");
12627 fschmid 1384
        for (int em = 0; em < emG.count(); ++em)
1385
        {
1386
                PageItem* embedded = emG.at(em);
1387
                QDomElement obE;
1388
                QString fill = getFillStyle(embedded);
1389
                QString stroke = "stroke:none";
17418 fschmid 1390
                stroke = getStrokeStyle(embedded);
21312 fschmid 1391
                QString transE = "";
1392
                if (embItem->isGroup())
1393
                {
23445 jghali 1394
                        transE = "translate(" + FToStr(embedded->gXpos) + ", " + FToStr(embedded->gYpos) + ")";
21312 fschmid 1395
                        if (embedded->rotation() != 0)
23445 jghali 1396
                                transE += " rotate(" + FToStr(embedded->rotation()) + ")";
21312 fschmid 1397
                }
12627 fschmid 1398
                switch (embedded->itemType())
1399
                {
16215 fschmid 1400
                        case PageItem::Arc:
12627 fschmid 1401
                        case PageItem::Polygon:
1402
                        case PageItem::PolyLine:
16191 fschmid 1403
                        case PageItem::RegularPolygon:
16311 fschmid 1404
                        case PageItem::Spiral:
21312 fschmid 1405
                                obE = processPolyItem(embedded, transE, fill, stroke);
13013 fschmid 1406
                                if ((embedded->lineColor() != CommonStrings::None) && ((embedded->startArrowIndex() != 0) || (embedded->endArrowIndex() != 0)))
21312 fschmid 1407
                                        obE = processArrows(embedded, obE, transE);
12627 fschmid 1408
                                break;
1409
                        case PageItem::Line:
21312 fschmid 1410
                                obE = processLineItem(embedded, transE, stroke);
13013 fschmid 1411
                                if ((embedded->lineColor() != CommonStrings::None) && ((embedded->startArrowIndex() != 0) || (embedded->endArrowIndex() != 0)))
21312 fschmid 1412
                                        obE = processArrows(embedded, obE, transE);
12627 fschmid 1413
                                break;
1414
                        case PageItem::ImageFrame:
1415
                        case PageItem::LatexFrame:
21312 fschmid 1416
                                obE = processImageItem(embedded, transE, fill, stroke);
12627 fschmid 1417
                                break;
1418
                        case PageItem::TextFrame:
21107 craig 1419
                        case PageItem::PathText:
21312 fschmid 1420
                                obE = processTextItem(embedded, transE, fill, stroke);
12627 fschmid 1421
                                break;
15077 fschmid 1422
                        case PageItem::Symbol:
21312 fschmid 1423
                                obE = processSymbolItem(embedded, transE);
15077 fschmid 1424
                                break;
21312 fschmid 1425
                        case PageItem::Group:
1426
                                if (embedded->groupItemList.count() > 0)
1427
                                {
23445 jghali 1428
                                        obE = m_domDoc.createElement("g");
21312 fschmid 1429
                                        if (!embedded->AutoName)
1430
                                                obE.setAttribute("id", embedded->itemName());
1431
                                        if (embedded->GrMask > 0)
1432
                                                obE.setAttribute("mask", handleMask(embedded, embedded->xPos() - m_Doc->currentPage()->xOffset(), embedded->yPos() - m_Doc->currentPage()->yOffset()));
1433
                                        else
1434
                                        {
1435
                                                if (embedded->fillTransparency() != 0)
1436
                                                        obE.setAttribute("opacity", FToStr(1.0 - embedded->fillTransparency()));
1437
                                        }
1438
                                        QString tr = trans;
1439
                                        if (embedded->imageFlippedH())
1440
                                        {
1441
                                                tr += QString(" translate(%1, 0.0)").arg(embedded->width());
1442
                                                tr += QString(" scale(-1.0, 1.0)");
1443
                                        }
1444
                                        if (embedded->imageFlippedV())
1445
                                        {
1446
                                                tr += QString(" translate(0.0, %1)").arg(embedded->height());
1447
                                                tr += QString(" scale(1.0, -1.0)");
1448
                                        }
1449
                                        tr += QString(" scale(%1, %2)").arg(embedded->width() / embedded->groupWidth).arg(embedded->height() / embedded->groupHeight);
1450
                                        obE.setAttribute("transform", tr);
1451
                                        obE.setAttribute("style", "fill:none; stroke:none");
1452
                                        if (embedded->groupClipping())
1453
                                        {
1454
                                                FPointArray clipPath = embedded->PoLine;
1455
                                                QTransform transform;
1456
                                                transform.scale(embedded->width() / embedded->groupWidth, embedded->height() / embedded->groupHeight);
1457
                                                transform = transform.inverted();
1458
                                                clipPath.map(transform);
1459
                                                QDomElement obc = createClipPathElement(&clipPath);
1460
                                                if (!obc.isNull())
23445 jghali 1461
                                                        obE.setAttribute("clip-path", "url(#" + obc.attribute("id") + ")");
21312 fschmid 1462
                                                if (embedded->fillRule)
1463
                                                        obE.setAttribute("clip-rule", "evenodd");
1464
                                                else
1465
                                                        obE.setAttribute("clip-rule", "nonzero");
1466
                                        }
1467
                                        for (int em = 0; em < embedded->groupItemList.count(); ++em)
1468
                                        {
1469
                                                PageItem* embed = embedded->groupItemList.at(em);
23445 jghali 1470
                                                processItemOnPage(embed->gXpos, embed->gYpos, embed, &obE);
21312 fschmid 1471
                                        }
1472
                                }
1473
                                break;
12627 fschmid 1474
                        default:
1475
                                break;
1476
                }
1477
                layerGroup.appendChild(obE);
1478
        }
21312 fschmid 1479
        QTransform mm;
1480
        if (embItem->isGroup())
1481
                mm.scale(embItem->width() / embItem->groupWidth, embItem->height() / embItem->groupHeight);
23445 jghali 1482
        layerGroup.setAttribute("transform", matrixToStr(mm));
12627 fschmid 1483
        return layerGroup;
1484
}
1485
 
22600 craig 1486
QString SVGExPlug::handleGlyph(uint gid, const ScFace& font)
12627 fschmid 1487
{
21107 craig 1488
        QString glName = QString("Gl%1%2").arg(font.psName().simplified().replace(QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" )).arg(gid);
23445 jghali 1489
        if (m_glyphNames.contains(glName))
12623 fschmid 1490
                return glName;
21107 craig 1491
        FPointArray pts = font.glyphOutline(gid);
23445 jghali 1492
        QDomElement ob = m_domDoc.createElement("path");
1493
        ob.setAttribute("d", setClipPath(&pts, true));
12623 fschmid 1494
        ob.setAttribute("id", glName);
23445 jghali 1495
        m_globalDefs.appendChild(ob);
1496
        m_glyphNames.append(glName);
12623 fschmid 1497
        return glName;
1498
}
1499
 
23446 jghali 1500
QDomElement SVGExPlug::processArrows(PageItem *item, const QDomElement& line, const QString& trans)
12623 fschmid 1501
{
1502
        QDomElement ob, gr;
23445 jghali 1503
        gr = m_domDoc.createElement("g");
12623 fschmid 1504
        gr.appendChild(line);
23446 jghali 1505
        if (item->startArrowIndex() != 0)
12623 fschmid 1506
        {
13951 fschmid 1507
                QTransform arrowTrans;
23446 jghali 1508
                FPointArray arrow = m_Doc->arrowStyles().at(item->startArrowIndex()-1).points.copy();
1509
                if (item->itemType() == PageItem::Line)
12623 fschmid 1510
                {
1511
                        arrowTrans.translate(0, 0);
23446 jghali 1512
                        arrowTrans.scale(item->startArrowScale() / 100.0, item->startArrowScale() / 100.0);
1513
                        if (item->NamedLStyle.isEmpty())
13302 fschmid 1514
                        {
23446 jghali 1515
                                if (item->lineWidth() != 0.0)
1516
                                        arrowTrans.scale(item->lineWidth(), item->lineWidth());
13302 fschmid 1517
                        }
1518
                        else
1519
                        {
23707 jghali 1520
                                multiLine ml = m_Doc->docLineStyles[item->NamedLStyle];
13302 fschmid 1521
                                if (ml[ml.size()-1].Width != 0.0)
1522
                                        arrowTrans.scale(ml[ml.size()-1].Width, ml[ml.size()-1].Width);
1523
                        }
12623 fschmid 1524
                        arrowTrans.scale(-1,1);
1525
                }
1526
                else
1527
                {
23446 jghali 1528
                        FPoint Start = item->PoLine.point(0);
1529
                        for (int xx = 1; xx < item->PoLine.size(); xx += 2)
12623 fschmid 1530
                        {
23446 jghali 1531
                                FPoint Vector = item->PoLine.point(xx);
12623 fschmid 1532
                                if ((Start.x() != Vector.x()) || (Start.y() != Vector.y()))
1533
                                {
1534
                                        double r = atan2(Start.y()-Vector.y(),Start.x()-Vector.x())*(180.0/M_PI);
1535
                                        arrowTrans.translate(Start.x(), Start.y());
1536
                                        arrowTrans.rotate(r);
23446 jghali 1537
                                        arrowTrans.scale(item->startArrowScale() / 100.0, item->startArrowScale() / 100.0);
1538
                                        if (item->NamedLStyle.isEmpty())
13302 fschmid 1539
                                        {
23446 jghali 1540
                                                if (item->lineWidth() != 0.0)
1541
                                                        arrowTrans.scale(item->lineWidth(), item->lineWidth());
13302 fschmid 1542
                                        }
1543
                                        else
1544
                                        {
23707 jghali 1545
                                                multiLine ml = m_Doc->docLineStyles[item->NamedLStyle];
13302 fschmid 1546
                                                if (ml[ml.size()-1].Width != 0.0)
1547
                                                        arrowTrans.scale(ml[ml.size()-1].Width, ml[ml.size()-1].Width);
1548
                                        }
456 fschmid 1549
                                        break;
12623 fschmid 1550
                                }
1551
                        }
1552
                }
1553
                arrow.map(arrowTrans);
23446 jghali 1554
                if (item->NamedLStyle.isEmpty())
13302 fschmid 1555
                {
23445 jghali 1556
                        ob = m_domDoc.createElement("path");
1557
                        ob.setAttribute("d", setClipPath(&arrow, true));
13302 fschmid 1558
                        ob.setAttribute("transform", trans);
14169 fschmid 1559
                        QString aFill;
23446 jghali 1560
                        if (!item->strokePattern().isEmpty())
14169 fschmid 1561
                        {
23446 jghali 1562
                                QString pattID = item->strokePattern()+IToStr(m_pattCount);
23445 jghali 1563
                                m_pattCount++;
23446 jghali 1564
                                ScPattern pa = m_Doc->docPatterns[item->strokePattern()];
23445 jghali 1565
                                QDomElement patt = m_domDoc.createElement("pattern");
14169 fschmid 1566
                                patt.setAttribute("id", pattID);
1567
                                patt.setAttribute("height", pa.height);
1568
                                patt.setAttribute("width", pa.width);
1569
                                patt.setAttribute("patternUnits", "userSpaceOnUse");
14398 fschmid 1570
                                double patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY, patternSpace;
23446 jghali 1571
                                item->strokePatternTransform(patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY, patternSpace);
14276 fschmid 1572
                                bool mirrorX, mirrorY;
23446 jghali 1573
                                item->strokePatternFlip(mirrorX, mirrorY);
14169 fschmid 1574
                                QTransform mpa;
23446 jghali 1575
                                mpa.translate(-item->lineWidth() / 2.0, -item->lineWidth() / 2.0);
14169 fschmid 1576
                                mpa.translate(patternOffsetX, patternOffsetY);
1577
                                mpa.rotate(patternRotation);
14260 fschmid 1578
                                mpa.shear(-patternSkewX, patternSkewY);
14169 fschmid 1579
                                mpa.scale(pa.scaleX, pa.scaleY);
1580
                                mpa.scale(patternScaleX / 100.0 , patternScaleY / 100.0);
14276 fschmid 1581
                                if (mirrorX)
1582
                                        mpa.scale(-1, 1);
1583
                                if (mirrorY)
1584
                                        mpa.scale(1, -1);
23445 jghali 1585
                                patt.setAttribute("patternTransform", matrixToStr(mpa));
23446 jghali 1586
                                patt.setAttribute("xlink:href", "#" + item->strokePattern());
23445 jghali 1587
                                m_globalDefs.appendChild(patt);
1588
                                aFill += "fill:url(#" + pattID + ");";
14169 fschmid 1589
                        }
23446 jghali 1590
                        else if (item->GrTypeStroke > 0)
14220 fschmid 1591
                        {
1592
                                QDomElement grad;
23904 jghali 1593
                                if (item->GrTypeStroke == Gradient_Radial)
14220 fschmid 1594
                                {
23445 jghali 1595
                                        grad = m_domDoc.createElement("radialGradient");
23446 jghali 1596
                                        grad.setAttribute("r", FToStr(sqrt(pow(item->GrStrokeEndX - item->GrStrokeStartX, 2) + pow(item->GrStrokeEndY - item->GrStrokeStartY,2))));
1597
                                        grad.setAttribute("cx", FToStr(item->GrStrokeStartX));
1598
                                        grad.setAttribute("cy", FToStr(item->GrStrokeStartY));
14220 fschmid 1599
                                }
1600
                                else
1601
                                {
23445 jghali 1602
                                        grad = m_domDoc.createElement("linearGradient");
23446 jghali 1603
                                        grad.setAttribute("x1", FToStr(item->GrStrokeStartX));
1604
                                        grad.setAttribute("y1", FToStr(item->GrStrokeStartY));
1605
                                        grad.setAttribute("x2", FToStr(item->GrStrokeEndX));
1606
                                        grad.setAttribute("y2", FToStr(item->GrStrokeEndY));
14220 fschmid 1607
                                }
15202 jghali 1608
                                bool   isFirst = true;
1609
                                double actualStop = 0.0, lastStop = 0.0;
23446 jghali 1610
                                QList<VColorStop*> cstops = item->stroke_gradient.colorStops();
1611
                                for (int cst = 0; cst < item->stroke_gradient.stops(); ++cst)
14220 fschmid 1612
                                {
15202 jghali 1613
                                        actualStop = cstops.at(cst)->rampPoint;
1614
                                        if ((actualStop != lastStop) || (isFirst))
1615
                                        {
23445 jghali 1616
                                                QDomElement itcl = m_domDoc.createElement("stop");
1617
                                                itcl.setAttribute("offset", FToStr(cstops.at(cst)->rampPoint*100) + "%");
15202 jghali 1618
                                                if (cstops.at(cst)->name == CommonStrings::None)
1619
                                                        itcl.setAttribute("stop-opacity", FToStr(0));
1620
                                                else
1621
                                                        itcl.setAttribute("stop-opacity", FToStr(cstops.at(cst)->opacity));
23445 jghali 1622
                                                itcl.setAttribute("stop-color", setColor(cstops.at(cst)->name, cstops.at(cst)->shade));
15202 jghali 1623
                                                grad.appendChild(itcl);
1624
                                                lastStop = actualStop;
1625
                                                isFirst  = false;
1626
                                        }
14220 fschmid 1627
                                }
23445 jghali 1628
                                grad.setAttribute("id", "Grad" + IToStr(m_gradCount));
14220 fschmid 1629
                                grad.setAttribute("gradientUnits", "userSpaceOnUse");
23445 jghali 1630
                                m_globalDefs.appendChild(grad);
1631
                                aFill = " fill:url(#Grad" + IToStr(m_gradCount) + ");";
1632
                                m_gradCount++;
14220 fschmid 1633
                        }
14169 fschmid 1634
                        else
23446 jghali 1635
                                aFill = "fill:" + setColor(item->lineColor(), item->lineShade()) + ";";
1636
                        if (item->lineTransparency() != 0)
1637
                                aFill += " fill-opacity:" + FToStr(1.0 - item->lineTransparency()) + ";";
13302 fschmid 1638
                        ob.setAttribute("style", aFill + " stroke:none;");
1639
                        gr.appendChild(ob);
1640
                }
1641
                else
1642
                {
23707 jghali 1643
                        multiLine ml = m_Doc->docLineStyles[item->NamedLStyle];
13302 fschmid 1644
                        if (ml[0].Color != CommonStrings::None)
1645
                        {
23445 jghali 1646
                                ob = m_domDoc.createElement("path");
1647
                                ob.setAttribute("d", setClipPath(&arrow, true));
13302 fschmid 1648
                                ob.setAttribute("transform", trans);
23445 jghali 1649
                                QString aFill = "fill:" + setColor(ml[0].Color, ml[0].Shade) + ";";
13302 fschmid 1650
                                ob.setAttribute("style", aFill + " stroke:none;");
1651
                                gr.appendChild(ob);
1652
                        }
1653
                        for (int it = ml.size()-1; it > 0; it--)
1654
                        {
1655
                                if (ml[it].Color != CommonStrings::None)
1656
                                {
23445 jghali 1657
                                        QDomElement ob5 = m_domDoc.createElement("path");
1658
                                        ob5.setAttribute("d", setClipPath(&arrow, true));
13302 fschmid 1659
                                        ob5.setAttribute("transform", trans);
23445 jghali 1660
                                        QString stroke = "fill:none; stroke:" + setColor(ml[it].Color, ml[it].Shade) + "; stroke-linecap:butt; stroke-linejoin:miter; stroke-dasharray:none;";
13302 fschmid 1661
                                        if (ml[it].Width != 0.0)
23445 jghali 1662
                                                stroke += " stroke-width:" + FToStr(ml[it].Width) + ";";
13302 fschmid 1663
                                        else
1664
                                                stroke += " stroke-width:1px;";
1665
                                        ob5.setAttribute("style", stroke);
1666
                                        gr.appendChild(ob5);
1667
                                }
1668
                        }
1669
                }
12623 fschmid 1670
        }
23446 jghali 1671
        if (item->endArrowIndex() != 0)
12623 fschmid 1672
        {
13951 fschmid 1673
                QTransform arrowTrans;
23446 jghali 1674
                FPointArray arrow = m_Doc->arrowStyles().at(item->endArrowIndex()-1).points.copy();
1675
                if (item->itemType() == PageItem::Line)