~ubuntu-branches/ubuntu/wily/scribus/wily-proposed

« back to all changes in this revision

Viewing changes to .pc/0001-qreal-double-fixes.patch/scribus/plugins/svgexplugin/svgexplugin.cpp

  • Committer: Package Import Robot
  • Author(s): Oleksandr Moskalenko
  • Date: 2012-02-09 21:50:56 UTC
  • mfrom: (1.1.6)
  • Revision ID: package-import@ubuntu.com-20120209215056-2wrx1ara0jbm7fi5
Tags: 1.4.0.dfsg+r17287-1
* New upstream stable release upload into Debian (Closes: #654703).
* Applied the Ubuntu armel patch.
* Removed non-free color swatches from resources.
* debian/control:
  - Moved icc-profiles from Recommends to Suggests (Closes: #655885).
  - Updated Standards-Version to 3.9.2.
  - Updated extended description per lintian warning.
* debian/rules:
  - Update mailcap (Closes: #630751). A request for mime.types update has
    been sent to the mime-support maintainer.
  - Added build-arch and build-indep targets per lintian warning.
* debian/patches:
  - top_cmakelists.patch - don't copy extra docs and changelogs.
  - scribus_cmakelists.patch - don't copy extra docs and changelogs.
  - scribus_cmakelists.patch - don't install the non-free "doc" dir.
  - profiles_cmakelists.patch - don't install non-free sRGB profile.
* debian/copyright: 
  - Converted to the DEP5 machine readable foramt.
  - Added licenses for free color swatches.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
*/
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
 
 ***************************************************************************/
23
 
 
24
 
#include <QFile>
25
 
#include <QTextStream>
26
 
#include <QDataStream>
27
 
#include <QByteArray>
28
 
#include <QBuffer>
29
 
#include <QList>
30
 
#include <QCheckBox>
31
 
#include <QScopedPointer>
32
 
 
33
 
#include "svgexplugin.h"
34
 
 
35
 
#include "scconfig.h"
36
 
#include "canvas.h"
37
 
#include "cmsettings.h"
38
 
#include "commonstrings.h"
39
 
#include "customfdialog.h"
40
 
#include "scribuscore.h"
41
 
#include "page.h"
42
 
#include "scgzfile.h"
43
 
#include "prefsmanager.h"
44
 
#include "prefsfile.h"
45
 
#include "prefscontext.h"
46
 
#include "scmessagebox.h"
47
 
#include "scpattern.h"
48
 
#include "util.h"
49
 
#include "util_math.h"
50
 
#include "customfdialog.h"
51
 
#include "sctextstruct.h"
52
 
#include "guidemanager.h"
53
 
#include "sccolorengine.h"
54
 
#include "util_formats.h"
55
 
 
56
 
int svgexplugin_getPluginAPIVersion()
57
 
{
58
 
        return PLUGIN_API_VERSION;
59
 
}
60
 
 
61
 
ScPlugin* svgexplugin_getPlugin()
62
 
{
63
 
        SVGExportPlugin* plug = new SVGExportPlugin();
64
 
        Q_CHECK_PTR(plug);
65
 
        return plug;
66
 
}
67
 
 
68
 
void svgexplugin_freePlugin(ScPlugin* plugin)
69
 
{
70
 
        SVGExportPlugin* plug = dynamic_cast<SVGExportPlugin*>(plugin);
71
 
        Q_ASSERT(plug);
72
 
        delete plug;
73
 
}
74
 
 
75
 
SVGExportPlugin::SVGExportPlugin() : ScActionPlugin()
76
 
{
77
 
        // Set action info in languageChange, so we only have to do
78
 
        // it in one place.
79
 
        languageChange();
80
 
}
81
 
 
82
 
SVGExportPlugin::~SVGExportPlugin() {};
83
 
 
84
 
void SVGExportPlugin::languageChange()
85
 
{
86
 
        // Note that we leave the unused members unset. They'll be initialised
87
 
        // with their default ctors during construction.
88
 
        // Action name
89
 
        m_actionInfo.name = "ExportAsSVG";
90
 
        // Action text for menu, including accel
91
 
        m_actionInfo.text = tr("Save as &SVG...");
92
 
        // Menu
93
 
        m_actionInfo.menu = "FileExport";
94
 
        m_actionInfo.enabledOnStartup = false;
95
 
        m_actionInfo.needsNumObjects = -1;
96
 
}
97
 
 
98
 
const QString SVGExportPlugin::fullTrName() const
99
 
{
100
 
        return QObject::tr("SVG Export");
101
 
}
102
 
 
103
 
const ScActionPlugin::AboutData* SVGExportPlugin::getAboutData() const
104
 
{
105
 
        AboutData* about = new AboutData;
106
 
        about->authors = "Franz Schmid <franz@scribus.info>";
107
 
        about->shortDescription = tr("Exports SVG Files");
108
 
        about->description = tr("Exports the current page into an SVG file.");
109
 
        about->license = "GPL";
110
 
        Q_CHECK_PTR(about);
111
 
        return about;
112
 
}
113
 
 
114
 
void SVGExportPlugin::deleteAboutData(const AboutData* about) const
115
 
{
116
 
        Q_ASSERT(about);
117
 
        delete about;
118
 
}
119
 
 
120
 
bool SVGExportPlugin::run(ScribusDoc* doc, QString filename)
121
 
{
122
 
        Q_ASSERT(filename.isEmpty());
123
 
        QString fileName;
124
 
        if (doc!=0)
125
 
        {
126
 
                PrefsContext* prefs = PrefsManager::instance()->prefsFile->getPluginContext("svgex");
127
 
                QString wdir = prefs->get("wdir", ".");
128
 
                QScopedPointer<CustomFDialog> openDia( new CustomFDialog(doc->scMW(), wdir, QObject::tr("Save as"), QObject::tr("%1;;All Files (*)").arg(FormatsManager::instance()->extensionsForFormat(FormatsManager::SVG)), fdHidePreviewCheckBox) );
129
 
                openDia->setSelection(getFileNameByPage(doc, doc->currentPage()->pageNr(), "svg"));
130
 
                openDia->setExtension("svg");
131
 
                openDia->setZipExtension("svgz");
132
 
                QCheckBox* compress = new QCheckBox(openDia.data());
133
 
                compress->setText( tr("Compress File"));
134
 
                compress->setChecked(false);
135
 
                openDia->addWidgets(compress);
136
 
                QCheckBox* inlineImages = new QCheckBox(openDia.data());
137
 
                inlineImages->setText( tr("Save Images inline"));
138
 
                inlineImages->setToolTip( tr("Adds all Images on the Page inline to the SVG.\nCaution: this will increase the file size!"));
139
 
                inlineImages->setChecked(true);
140
 
                openDia->addWidgets(inlineImages);
141
 
                QCheckBox* exportBack = new QCheckBox(openDia.data());
142
 
                exportBack->setText( tr("Export Page background"));
143
 
                exportBack->setToolTip( tr("Adds the Page itself as background to the SVG."));
144
 
                exportBack->setChecked(false);
145
 
                openDia->addWidgets(exportBack);
146
 
                
147
 
                if (!openDia->exec())
148
 
                        return true;
149
 
                fileName = openDia->selectedFile();
150
 
                QFileInfo fi(fileName);
151
 
                QString baseDir = fi.absolutePath();
152
 
                if (compress->isChecked())
153
 
                        fileName = baseDir + "/" + fi.baseName() + ".svgz";
154
 
                else
155
 
                        fileName = baseDir + "/" + fi.baseName() + ".svg";
156
 
 
157
 
                SVGOptions Options;
158
 
                Options.inlineImages = inlineImages->isChecked();
159
 
                Options.exportPageBackground = exportBack->isChecked();
160
 
                Options.compressFile = compress->isChecked();
161
 
 
162
 
                if (fileName.isEmpty())
163
 
                        return true;
164
 
                prefs->set("wdir", fileName.left(fileName.lastIndexOf("/")));
165
 
                QFile f(fileName);
166
 
                if (f.exists())
167
 
                {
168
 
                        int exit = QMessageBox::warning(doc->scMW(), CommonStrings::trWarning,
169
 
                                QObject::tr("Do you really want to overwrite the file:\n%1 ?").arg(fileName),
170
 
                                QMessageBox::Yes | QMessageBox::No);
171
 
                        if (exit == QMessageBox::No)
172
 
                                return true;
173
 
                }
174
 
                SVGExPlug *dia = new SVGExPlug(doc);
175
 
                dia->doExport(fileName, Options);
176
 
                delete dia;
177
 
        }
178
 
        return true;
179
 
}
180
 
 
181
 
SVGExPlug::SVGExPlug( ScribusDoc* doc )
182
 
{
183
 
        m_Doc = doc;
184
 
        Options.inlineImages = true;
185
 
        Options.exportPageBackground = false;
186
 
        Options.compressFile = false;
187
 
        glyphNames.clear();
188
 
}
189
 
 
190
 
bool SVGExPlug::doExport( QString fName, SVGOptions &Opts )
191
 
{
192
 
        Options = Opts;
193
 
        QFileInfo fiBase(fName);
194
 
        baseDir = fiBase.absolutePath();
195
 
        Page *page;
196
 
        GradCount = 0;
197
 
        ClipCount = 0;
198
 
        PattCount = 0;
199
 
        docu = QDomDocument("svgdoc");
200
 
        QString vo = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
201
 
        QString st = "<svg></svg>";
202
 
        docu.setContent(st);
203
 
        page = m_Doc->currentPage();
204
 
        double pageWidth  = page->width();
205
 
        double pageHeight = page->height();
206
 
        docElement = docu.documentElement();
207
 
        docElement.setAttribute("width", FToStr(pageWidth)+"pt");
208
 
        docElement.setAttribute("height", FToStr(pageHeight)+"pt");
209
 
        docElement.setAttribute("viewBox", QString("0 0 %1 %2").arg(pageWidth).arg(pageHeight));
210
 
        docElement.setAttribute("xmlns", "http://www.w3.org/2000/svg");
211
 
        docElement.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink");
212
 
        docElement.setAttribute("version","1.1");
213
 
        if (!m_Doc->documentInfo.getTitle().isEmpty())
214
 
        {
215
 
                QDomText title = docu.createTextNode(m_Doc->documentInfo.getTitle());
216
 
                QDomElement titleElem = docu.createElement("title");
217
 
                titleElem.appendChild(title);
218
 
                docElement.appendChild(titleElem);
219
 
        }
220
 
        if (!m_Doc->documentInfo.getComments().isEmpty())
221
 
        {
222
 
                QDomText desc = docu.createTextNode(m_Doc->documentInfo.getComments());
223
 
                QDomElement descElem = docu.createElement("desc");
224
 
                descElem.appendChild(desc);
225
 
                docElement.appendChild(descElem);
226
 
        }
227
 
        globalDefs = docu.createElement("defs");
228
 
        docElement.appendChild(globalDefs);
229
 
        if (Options.exportPageBackground)
230
 
        {
231
 
                QDomElement backG = docu.createElement("rect");
232
 
                backG.setAttribute("x", "0");
233
 
                backG.setAttribute("y", "0");
234
 
                backG.setAttribute("width", FToStr(pageWidth));
235
 
                backG.setAttribute("height", FToStr(pageHeight));
236
 
                backG.setAttribute("style", "fill:"+m_Doc->papColor.name()+";" + "stroke:none;");
237
 
                docElement.appendChild(backG);
238
 
        }
239
 
        page = m_Doc->MasterPages.at(m_Doc->MasterNames[m_Doc->currentPage()->MPageNam]);
240
 
        ProcessPage(page);
241
 
        page = m_Doc->currentPage();
242
 
        ProcessPage(page);
243
 
        if(Options.compressFile)
244
 
        {
245
 
                // zipped saving
246
 
                QByteArray array(docu.toString().toUtf8());
247
 
                if (!ScGzFile::writeToFile(fName, array, vo.toUtf8().data()))
248
 
                        return false;
249
 
        }
250
 
        else
251
 
        {
252
 
                QFile f(fName);
253
 
                if(!f.open(QIODevice::WriteOnly))
254
 
                        return false;
255
 
                QDataStream s(&f);
256
 
                QString wr = vo;
257
 
                wr += docu.toString();
258
 
                QByteArray utf8wr = wr.toUtf8();
259
 
                s.writeRawData(utf8wr.data(), utf8wr.length());
260
 
                f.close();
261
 
        }
262
 
        return true;
263
 
}
264
 
 
265
 
void SVGExPlug::ProcessPage(Page *page)
266
 
{
267
 
        int Lnr = 0;
268
 
        ScLayer ll;
269
 
        ll.isPrintable = false;
270
 
        ll.LNr = 0;
271
 
        QDomElement layerGroup;
272
 
        PageItem *Item;
273
 
        QList<PageItem*> Items;
274
 
        QStack<PageItem*> groupStack;
275
 
        QStack<QDomElement> groupStack2;
276
 
        Page* SavedAct = m_Doc->currentPage();
277
 
        if (page->pageName().isEmpty())
278
 
                Items = m_Doc->DocItems;
279
 
        else
280
 
                Items = m_Doc->MasterItems;
281
 
        if (Items.count() == 0)
282
 
                return;
283
 
        m_Doc->setCurrentPage(page);
284
 
        for (int la = 0; la < m_Doc->Layers.count(); la++)
285
 
        {
286
 
                m_Doc->Layers.levelToLayer(ll, Lnr);
287
 
                if (ll.isPrintable)
288
 
                {
289
 
                        layerGroup = docu.createElement("g");
290
 
                        layerGroup.setAttribute("id", ll.Name);
291
 
                        if (ll.transparency != 1.0)
292
 
                                layerGroup.setAttribute("opacity", FToStr(ll.transparency));
293
 
                        for(int j = 0; j < Items.count(); ++j)
294
 
                        {
295
 
                                Item = Items.at(j);
296
 
                                if (Item->LayerNr != ll.LNr)
297
 
                                        continue;
298
 
                                if (!Item->printEnabled())
299
 
                                        continue;
300
 
                                double x = page->xOffset();
301
 
                                double y = page->yOffset();
302
 
                                double w = page->width();
303
 
                                double h = page->height();
304
 
                                double x2 = Item->BoundingX;
305
 
                                double y2 = Item->BoundingY;
306
 
                                double w2 = Item->BoundingW;
307
 
                                double h2 = Item->BoundingH;
308
 
                                if (!( qMax( x, x2 ) <= qMin( x+w, x2+w2 ) && qMax( y, y2 ) <= qMin( y+h, y2+h2 )))
309
 
                                        continue;
310
 
                                if ((!page->pageName().isEmpty()) && (Item->OwnPage != static_cast<int>(page->pageNr())) && (Item->OwnPage != -1))
311
 
                                        continue;
312
 
                                if (Item->isGroupControl)
313
 
                                {
314
 
                                        groupStack.push(Item->groupsLastItem);
315
 
                                        groupStack2.push(layerGroup);
316
 
                                        layerGroup = docu.createElement("g");
317
 
                                        if (!Item->AutoName)
318
 
                                                layerGroup.setAttribute("id", Item->itemName());
319
 
                                        if (Item->fillTransparency() != 0)
320
 
                                                layerGroup.setAttribute("opacity", FToStr(1.0 - Item->fillTransparency()));
321
 
                                        QDomElement ob = docu.createElement("clipPath");
322
 
                                        ob.setAttribute("id", "Clip"+IToStr(ClipCount));
323
 
                                        QDomElement cl = docu.createElement("path");
324
 
                                        cl.setAttribute("d", SetClipPath(&Item->PoLine, true));
325
 
                                        QString trans = "translate("+FToStr(Item->xPos()-page->xOffset())+", "+FToStr(Item->yPos()-page->yOffset())+")";
326
 
                                        if (Item->rotation() != 0)
327
 
                                                trans += " rotate("+FToStr(Item->rotation())+")";
328
 
                                        cl.setAttribute("transform", trans);
329
 
                                        ob.appendChild(cl);
330
 
                                        globalDefs.appendChild(ob);
331
 
                                        layerGroup.setAttribute("clip-path", "url(#Clip"+IToStr(ClipCount)+")");
332
 
                                        ClipCount++;
333
 
                                        continue;
334
 
                                }
335
 
                                ProcessItemOnPage(Item->xPos()-page->xOffset(), Item->yPos()-page->yOffset(), Item, &layerGroup);
336
 
                                if (groupStack.count() != 0)
337
 
                                {
338
 
                                        while (Item == groupStack.top())
339
 
                                        {
340
 
                                                groupStack.pop();
341
 
                                                groupStack2.top().appendChild(layerGroup);
342
 
                                                layerGroup = groupStack2.pop();
343
 
                                                if (groupStack.count() == 0)
344
 
                                                        break;
345
 
                                        }
346
 
                                }
347
 
                        }
348
 
                        for(int j = 0; j < Items.count(); ++j)
349
 
                        {
350
 
                                Item = Items.at(j);
351
 
                                if (Item->LayerNr != ll.LNr)
352
 
                                        continue;
353
 
                                if (!Item->printEnabled())
354
 
                                        continue;
355
 
                                double x = page->xOffset();
356
 
                                double y = page->yOffset();
357
 
                                double w = page->width();
358
 
                                double h = page->height();
359
 
                                double x2 = Item->BoundingX;
360
 
                                double y2 = Item->BoundingY;
361
 
                                double w2 = Item->BoundingW;
362
 
                                double h2 = Item->BoundingH;
363
 
                                if (!( qMax( x, x2 ) <= qMin( x+w, x2+w2 ) && qMax( y, y2 ) <= qMin( y+h, y2+h2 )))
364
 
                                        continue;
365
 
                                if (!Item->isTableItem)
366
 
                                        continue;
367
 
                                if ((Item->lineColor() == CommonStrings::None) || (Item->lineWidth() == 0.0))
368
 
                                        continue;
369
 
                                if ((Item->TopLine) || (Item->RightLine) || (Item->BottomLine) || (Item->LeftLine))
370
 
                                {
371
 
                                        QString trans = "translate("+FToStr(Item->xPos()-page->xOffset())+", "+FToStr(Item->yPos()-page->yOffset())+")";
372
 
                                        if (Item->rotation() != 0)
373
 
                                                trans += " rotate("+FToStr(Item->rotation())+")";
374
 
                                        QString stroke = getStrokeStyle(Item);
375
 
                                        QDomElement ob = docu.createElement("path");
376
 
                                        ob.setAttribute("transform", trans);
377
 
                                        ob.setAttribute("style", "fill:none; " + stroke);
378
 
                                        QString pathAttr = "";
379
 
                                        if (Item->TopLine)
380
 
                                                pathAttr += "M 0 0 L "+FToStr(Item->width())+" 0";
381
 
                                        if (Item->RightLine)
382
 
                                                pathAttr += " M " + FToStr(Item->width()) + "0 L "+FToStr(Item->width())+" "+FToStr(Item->height());
383
 
                                        if (Item->BottomLine)
384
 
                                                pathAttr += " M 0 " + FToStr(Item->height()) + " L "+FToStr(Item->width())+" "+FToStr(Item->height());
385
 
                                        if (Item->LeftLine)
386
 
                                                pathAttr += " M 0 0 L 0 "+FToStr(Item->height());
387
 
                                        ob.setAttribute("d", pathAttr);
388
 
                                        layerGroup.appendChild(ob);
389
 
                                }
390
 
                        }
391
 
                        docElement.appendChild(layerGroup);
392
 
                }
393
 
                Lnr++;
394
 
        }
395
 
        m_Doc->setCurrentPage(SavedAct);
396
 
}
397
 
 
398
 
void SVGExPlug::ProcessItemOnPage(double xOffset, double yOffset, PageItem *Item, QDomElement *parentElem)
399
 
{
400
 
        QDomElement ob;
401
 
        QString trans = "translate("+FToStr(xOffset)+", "+FToStr(yOffset)+")";
402
 
        if (Item->rotation() != 0)
403
 
                trans += " rotate("+FToStr(Item->rotation())+")";
404
 
        QString fill = getFillStyle(Item);
405
 
        QString stroke = "stroke:none";
406
 
        if (!Item->isTableItem)
407
 
                stroke = getStrokeStyle(Item);
408
 
        switch (Item->itemType())
409
 
        {
410
 
                case PageItem::Polygon:
411
 
                case PageItem::PolyLine:
412
 
                        ob = processPolyItem(Item, trans, fill, stroke);
413
 
                        if ((Item->lineColor() != CommonStrings::None) && ((Item->startArrowIndex() != 0) || (Item->endArrowIndex() != 0)))
414
 
                                ob = processArrows(Item, ob, trans);
415
 
                        break;
416
 
                case PageItem::Line:
417
 
                        ob = processLineItem(Item, trans, stroke);
418
 
                        if ((Item->lineColor() != CommonStrings::None) && ((Item->startArrowIndex() != 0) || (Item->endArrowIndex() != 0)))
419
 
                                ob = processArrows(Item, ob, trans);
420
 
                        break;
421
 
                case PageItem::ImageFrame:
422
 
                case PageItem::LatexFrame:
423
 
                        ob = processImageItem(Item, trans, fill, stroke);
424
 
                        break;
425
 
                case PageItem::TextFrame:
426
 
                        ob = processTextItem(Item, trans, fill, stroke);
427
 
                        break;
428
 
                case PageItem::PathText:
429
 
                        ob = processPathTextItem(Item, trans, stroke);
430
 
                        break;
431
 
                default:
432
 
                        break;
433
 
        }
434
 
        if (!Item->AutoName)
435
 
                ob.setAttribute("id", Item->itemName());
436
 
        parentElem->appendChild(ob);
437
 
}
438
 
 
439
 
QDomElement SVGExPlug::processPolyItem(PageItem *Item, QString trans, QString fill, QString stroke)
440
 
{
441
 
        bool closedPath;
442
 
        QDomElement ob;
443
 
        if (Item->itemType() == PageItem::Polygon)
444
 
                closedPath = true;
445
 
        else
446
 
                closedPath = false;
447
 
        if (Item->NamedLStyle.isEmpty())
448
 
        {
449
 
                ob = docu.createElement("path");
450
 
                ob.setAttribute("d", SetClipPath(&Item->PoLine, closedPath));
451
 
                ob.setAttribute("transform", trans);
452
 
                ob.setAttribute("style", fill + stroke);
453
 
        }
454
 
        else
455
 
        {
456
 
                ob = docu.createElement("g");
457
 
                ob.setAttribute("transform", trans);
458
 
                QDomElement ob2 = docu.createElement("path");
459
 
                ob2.setAttribute("d", SetClipPath(&Item->PoLine, closedPath));
460
 
                ob2.setAttribute("style", fill);
461
 
                ob.appendChild(ob2);
462
 
                multiLine ml = m_Doc->MLineStyles[Item->NamedLStyle];
463
 
                for (int it = ml.size()-1; it > -1; it--)
464
 
                {
465
 
                        if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
466
 
                        {
467
 
                                QDomElement ob3 = docu.createElement("path");
468
 
                                ob3.setAttribute("d", SetClipPath(&Item->PoLine, closedPath));
469
 
                                ob3.setAttribute("style", GetMultiStroke(&ml[it], Item));
470
 
                                ob.appendChild(ob3);
471
 
                        }
472
 
                }
473
 
        }
474
 
        return ob;
475
 
}
476
 
 
477
 
QDomElement SVGExPlug::processLineItem(PageItem *Item, QString trans, QString stroke)
478
 
{
479
 
        QDomElement ob;
480
 
        if (Item->NamedLStyle.isEmpty())
481
 
        {
482
 
                ob = docu.createElement("path");
483
 
                ob.setAttribute("d", "M 0 0 L "+FToStr(Item->width())+" 0");
484
 
                ob.setAttribute("transform", trans);
485
 
                ob.setAttribute("style", stroke);
486
 
        }
487
 
        else
488
 
        {
489
 
                ob = docu.createElement("g");
490
 
                ob.setAttribute("transform", trans);
491
 
                multiLine ml = m_Doc->MLineStyles[Item->NamedLStyle];
492
 
                for (int it = ml.size()-1; it > -1; it--)
493
 
                {
494
 
                        if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
495
 
                        {
496
 
                                QDomElement ob2 = docu.createElement("path");
497
 
                                ob2.setAttribute("d", "M 0 0 L "+FToStr(Item->width())+" 0");
498
 
                                ob2.setAttribute("style", GetMultiStroke(&ml[it], Item));
499
 
                                ob.appendChild(ob2);
500
 
                        }
501
 
                }
502
 
        }
503
 
        return ob;
504
 
}
505
 
 
506
 
QDomElement SVGExPlug::processImageItem(PageItem *Item, QString trans, QString fill, QString stroke)
507
 
{
508
 
        QDomElement ob;
509
 
        ob = docu.createElement("g");
510
 
        ob.setAttribute("transform", trans);
511
 
        if ((Item->fillColor() != CommonStrings::None) || (Item->GrType != 0))
512
 
        {
513
 
                QDomElement ob1 = docu.createElement("path");
514
 
                ob1.setAttribute("d", SetClipPath(&Item->PoLine, true));
515
 
                ob1.setAttribute("style", fill);
516
 
                ob.appendChild(ob1);
517
 
        }
518
 
        if ((Item->PictureIsAvailable) && (!Item->Pfile.isEmpty()))
519
 
        {
520
 
                QDomElement ob2 = docu.createElement("clipPath");
521
 
                ob2.setAttribute("id", "Clip"+IToStr(ClipCount));
522
 
                ob2.setAttribute("clipPathUnits", "userSpaceOnUse");
523
 
                ob2.setAttribute("clip-rule", "evenodd");
524
 
                QDomElement cl = docu.createElement("path");
525
 
                if (Item->imageClip.size() != 0)
526
 
                        cl.setAttribute("d", SetClipPath(&Item->imageClip, true));
527
 
                else
528
 
                        cl.setAttribute("d", SetClipPath(&Item->PoLine, true));
529
 
                ob2.appendChild(cl);
530
 
                globalDefs.appendChild(ob2);
531
 
                QDomElement ob3 = docu.createElement("image");
532
 
                ob3.setAttribute("clip-path", "url(#Clip"+IToStr(ClipCount)+")");
533
 
                ScImage img;
534
 
                CMSettings cms(m_Doc, Item->IProfile, Item->IRender);
535
 
                img.LoadPicture(Item->Pfile, Item->pixm.imgInfo.actualPageNumber, cms, Item->UseEmbedded, true, ScImage::RGBProof, 72);
536
 
                img.applyEffect(Item->effectsInUse, m_Doc->PageColors, true);
537
 
                if (Options.inlineImages)
538
 
                {
539
 
                        QBuffer buffer;
540
 
                        buffer.open(QIODevice::WriteOnly);
541
 
                        img.qImage().save(&buffer, "PNG");
542
 
                        QByteArray ba = buffer.buffer().toBase64();
543
 
                        buffer.close();
544
 
                        ob3.setAttribute("xlink:href", "data:image/png;base64,"+QString(ba));
545
 
                }
546
 
                else
547
 
                {
548
 
                        QFileInfo fi = QFileInfo(Item->Pfile);
549
 
                        QString imgFileName = baseDir + "/" + fi.baseName()+".png";
550
 
                        QFileInfo im = QFileInfo(imgFileName);
551
 
                        if (im.exists())
552
 
                                imgFileName = baseDir + "/" + fi.baseName()+"_copy.png";
553
 
                        img.qImage().save(imgFileName, "PNG");
554
 
                        QFileInfo fi2 = QFileInfo(imgFileName);
555
 
                        ob3.setAttribute("xlink:href", fi2.baseName()+".png");
556
 
                }
557
 
                ob3.setAttribute("x", FToStr(Item->imageXOffset() * Item->imageXScale()));
558
 
                ob3.setAttribute("y", FToStr(Item->imageYOffset() * Item->imageYScale()));
559
 
                ob3.setAttribute("width", FToStr(img.width() * Item->imageXScale()));
560
 
                ob3.setAttribute("height", FToStr(img.height() * Item->imageYScale()));
561
 
                QMatrix mpa;
562
 
                if (Item->imageFlippedH())
563
 
                {
564
 
                        mpa.translate(Item->width(), 0);
565
 
                        mpa.scale(-1, 1);
566
 
                }
567
 
                if (Item->imageFlippedV())
568
 
                {
569
 
                        mpa.translate(0, Item->height());
570
 
                        mpa.scale(1, -1);
571
 
                }
572
 
                ob3.setAttribute("transform", MatrixToStr(mpa));
573
 
                ClipCount++;
574
 
                ob.appendChild(ob3);
575
 
        }
576
 
        if (Item->NamedLStyle.isEmpty())
577
 
        {
578
 
                QDomElement ob4 = docu.createElement("path");
579
 
                ob4.setAttribute("d", SetClipPath(&Item->PoLine, true));
580
 
                ob4.setAttribute("style", "fill:none; "+stroke);
581
 
                ob.appendChild(ob4);
582
 
        }
583
 
        else
584
 
        {
585
 
                multiLine ml = m_Doc->MLineStyles[Item->NamedLStyle];
586
 
                for (int it = ml.size()-1; it > -1; it--)
587
 
                {
588
 
                        if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
589
 
                        {
590
 
                                QDomElement ob5 = docu.createElement("path");
591
 
                                ob5.setAttribute("d", SetClipPath(&Item->PoLine, true));
592
 
                                ob5.setAttribute("style", "fill:none; "+GetMultiStroke(&ml[it], Item));
593
 
                                ob.appendChild(ob5);
594
 
                        }
595
 
                }
596
 
        }
597
 
        return ob;
598
 
}
599
 
 
600
 
QDomElement SVGExPlug::processTextItem(PageItem *Item, QString trans, QString fill, QString stroke)
601
 
{
602
 
        QDomElement ob;
603
 
        ob = docu.createElement("g");
604
 
        ob.setAttribute("transform", trans);
605
 
        if ((Item->fillColor() != CommonStrings::None) || (Item->GrType != 0))
606
 
        {
607
 
                QDomElement ob1 = docu.createElement("path");
608
 
                ob1.setAttribute("d", SetClipPath(&Item->PoLine, true));
609
 
                ob1.setAttribute("style", fill);
610
 
                ob.appendChild(ob1);
611
 
        }
612
 
        double x, y, wide;
613
 
        QString chstr;
614
 
        for (uint ll=0; ll < Item->itemText.lines(); ++ll)
615
 
        {
616
 
                LineSpec ls = Item->itemText.line(ll);
617
 
                double CurX = ls.x;
618
 
                for (int a = ls.firstItem; a <= ls.lastItem; ++a)
619
 
                {
620
 
                        x = 0.0;
621
 
                        y = 0.0;
622
 
                        ScText * hl = Item->itemText.item(a);
623
 
                        const CharStyle& charStyle(Item->itemText.charStyle(a));
624
 
                        chstr = Item->itemText.text(a,1);
625
 
                        if ((chstr == QChar(13)) || (chstr == QChar(29)))
626
 
                        {
627
 
                                if (chstr == QChar(29))
628
 
                                        CurX += hl->glyph.wide();
629
 
                                continue;
630
 
                        }
631
 
                        if (chstr == QChar(30))
632
 
                        {
633
 
                                chstr = Item->ExpandToken(a);
634
 
                                if (chstr == QChar(32))
635
 
                                {
636
 
                                        CurX += hl->glyph.wide();
637
 
                                        continue;
638
 
                                }
639
 
                        }
640
 
                        double chs = charStyle.fontSize();
641
 
                        if (hl->effects() & ScStyle_SmallCaps)
642
 
                        {
643
 
                                if (chstr.toUpper() != chstr)
644
 
                                {
645
 
                                        chs = qMax(static_cast<int>(hl->fontSize() * m_Doc->typographicSettings.valueSmallCaps / 100), 1);
646
 
                                        chstr = chstr.toUpper();
647
 
                                }
648
 
                        }
649
 
                        else if (hl->effects() & ScStyle_AllCaps)
650
 
                                chstr = chstr.toUpper();
651
 
                        uint chr = chstr[0].unicode();
652
 
                        QMatrix chma, chma2, chma3, chma4, chma6;
653
 
                        QMatrix trafo = QMatrix( 1, 0, 0, 1, CurX, ls.y );
654
 
                        if (Item->rotation() != 0)
655
 
                        {
656
 
                                QMatrix sca;
657
 
                                sca.translate(-Item->xPos(), -Item->yPos());
658
 
                                trafo *= sca;
659
 
                        }
660
 
                        chma.scale(hl->glyph.scaleH * charStyle.fontSize() / 100.00, hl->glyph.scaleV * charStyle.fontSize() / 100.0);
661
 
                        if (Item->reversed())
662
 
                        {
663
 
                                if (a < Item->itemText.length()-1)
664
 
                                        wide = hl->font().charWidth(chstr[0], hl->fontSize(), Item->itemText.text(a+1));
665
 
                                else
666
 
                                        wide = hl->font().charWidth(chstr[0], hl->fontSize());
667
 
                                chma3.scale(-1, 1);
668
 
                                chma3.translate(-wide, 0);
669
 
                        }
670
 
                        chma4.translate(0, Item->BaseOffs - (charStyle.fontSize() / 10.0) * hl->glyph.scaleV);
671
 
                        if (charStyle.effects() & (ScStyle_Subscript | ScStyle_Superscript | ScStyle_DropCap))
672
 
                                chma6.translate(0, hl->glyph.yoffset);
673
 
                        if (hl->baselineOffset() != 0)
674
 
                                chma6.translate(0, (-charStyle.fontSize() / 10.0) * (charStyle.baselineOffset() / 1000.0));
675
 
                        QMatrix finalMat = QMatrix(chma * chma2 * chma3 * chma4 * chma6 * trafo);
676
 
                        if (Item->rotation() != 0)
677
 
                        {
678
 
                                QMatrix sca;
679
 
                                sca.translate(Item->xPos(), Item->yPos());
680
 
                                finalMat *= sca;
681
 
                        }
682
 
                        if ((hl->ch == SpecialChars::OBJECT) && (hl->embedded.hasItem()))
683
 
                        {
684
 
                                ob.appendChild(processInlineItem(CurX + hl->glyph.xoffset, ls.y + hl->glyph.yoffset, finalMat, hl, false, trans));
685
 
                                InlineFrame& embedded(const_cast<InlineFrame&>(hl->embedded));
686
 
                                CurX += (embedded.getItem()->gWidth + embedded.getItem()->lineWidth()) * hl->glyph.scaleH;
687
 
                        }
688
 
                        else
689
 
                        {
690
 
                                QString glName;
691
 
                                if (chstr > QChar(32))
692
 
                                        glName = handleGlyph(chr, hl);
693
 
                                if ((charStyle.effects() & ScStyle_Shadowed) && (charStyle.strokeColor() != CommonStrings::None) && (chstr > QChar(32)))
694
 
                                {
695
 
                                        QMatrix sha = finalMat;
696
 
                                        QMatrix shad;
697
 
                                        shad.translate(charStyle.fontSize() * charStyle.shadowXOffset() / 10000.0, -charStyle.fontSize() * charStyle.shadowYOffset() / 10000.0);
698
 
                                        sha *= shad;
699
 
                                        QDomElement ob2 = docu.createElement("use");
700
 
                                        ob2.setAttribute("xlink:href", "#" + glName);
701
 
                                        ob2.setAttribute("transform", MatrixToStr(sha));
702
 
                                        ob2.setAttribute("style", "fill:"+SetColor(hl->strokeColor(), hl->strokeShade())+";" + "stroke:none;");
703
 
                                        ob.appendChild(ob2);
704
 
                                }
705
 
                                QChar chstc = hl->ch;
706
 
                                if (((charStyle.effects() & ScStyle_Underline) && !SpecialChars::isBreak(chstc))
707
 
                                        || ((charStyle.effects() & ScStyle_UnderlineWords) && !chstc.isSpace() && !SpecialChars::isBreak(chstc)))
708
 
                                {
709
 
                                        x = CurX;
710
 
                                        y = ls.y;
711
 
                                        double Ulen = hl->glyph.xadvance;
712
 
                                        double Upos, lw, kern;
713
 
                                        if (charStyle.effects() & ScStyle_StartOfLine)
714
 
                                                kern = 0;
715
 
                                        else
716
 
                                                kern = charStyle.fontSize() * charStyle.tracking() / 10000.0;
717
 
                                        if ((charStyle.underlineOffset() != -1) || (charStyle.underlineWidth() != -1))
718
 
                                        {
719
 
                                                if (charStyle.underlineOffset() != -1)
720
 
                                                        Upos = (charStyle.underlineOffset() / 1000.0) * (charStyle.font().descent(charStyle.fontSize() / 10.0));
721
 
                                                else
722
 
                                                        Upos = charStyle.font().underlinePos(charStyle.fontSize() / 10.0);
723
 
                                                if (charStyle.underlineWidth() != -1)
724
 
                                                        lw = (charStyle.underlineWidth() / 1000.0) * (charStyle.fontSize() / 10.0);
725
 
                                                else
726
 
                                                        lw = qMax(charStyle.font().strokeWidth(charStyle.fontSize() / 10.0), 1.0);
727
 
                                        }
728
 
                                        else
729
 
                                        {
730
 
                                                Upos = charStyle.font().underlinePos(charStyle.fontSize() / 10.0);
731
 
                                                lw = qMax(charStyle.font().strokeWidth(charStyle.fontSize() / 10.0), 1.0);
732
 
                                        }
733
 
                                        if (charStyle.baselineOffset() != 0)
734
 
                                                Upos += (charStyle.fontSize() / 10.0) * (charStyle.baselineOffset() / 1000.0);
735
 
                                        QDomElement ob6 = docu.createElement("path");
736
 
                                        if (charStyle.effects() & ScStyle_Subscript)
737
 
                                                ob6.setAttribute("d", QString("M %1 %2 L%3 %4").arg(x + hl->glyph.xoffset-kern).arg(y + hl->glyph.yoffset - Upos).arg(x + hl->glyph.xoffset+Ulen).arg(y + hl->glyph.yoffset - Upos));
738
 
                                        else
739
 
                                                ob6.setAttribute("d", QString("M %1 %2 L%3 %4").arg(x + hl->glyph.xoffset-kern).arg(y - Upos).arg(x + hl->glyph.xoffset+Ulen).arg(y - Upos));
740
 
                                        QString sT = "stroke:none;";
741
 
                                        if (charStyle.fillColor() != CommonStrings::None)
742
 
                                        {
743
 
                                                sT = "stroke:"+SetColor(charStyle.fillColor(), charStyle.fillShade())+";";
744
 
                                                sT += " stroke-width:"+FToStr(lw)+";";
745
 
                                        }
746
 
                                        ob6.setAttribute("style", "fill:none;" + sT);
747
 
                                        ob.appendChild(ob6);
748
 
                                }
749
 
                                if (chstr > QChar(32))
750
 
                                {
751
 
                                        QDomElement ob3 = docu.createElement("use");
752
 
                                        ob3.setAttribute("xlink:href", "#" + glName);
753
 
                                        ob3.setAttribute("transform", MatrixToStr(finalMat));
754
 
                                        QString fT = "fill:"+SetColor(hl->fillColor(), hl->fillShade())+";";
755
 
                                        QString sT = "stroke:none;";
756
 
                                        if (charStyle.effects() & ScStyle_Outline)
757
 
                                        {
758
 
                                                sT = "stroke:"+SetColor(hl->strokeColor(), hl->strokeShade())+";";
759
 
                                                sT += " stroke-width:"+FToStr(chs * hl->outlineWidth() / 10000.0)+";";
760
 
                                        }
761
 
                                        ob3.setAttribute("style", fT + sT);
762
 
                                        ob.appendChild(ob3);
763
 
                                }
764
 
                                if (charStyle.effects() & ScStyle_Strikethrough)
765
 
                                {
766
 
                                        x = CurX;
767
 
                                        y = ls.y;
768
 
                                        double Ulen = hl->glyph.xadvance;
769
 
                                        double Upos, lw, kern;
770
 
                                        if (charStyle.effects() & ScStyle_StartOfLine)
771
 
                                                kern = 0;
772
 
                                        else
773
 
                                                kern = charStyle.fontSize() * charStyle.tracking() / 10000.0;
774
 
                                        if ((charStyle.strikethruOffset() != -1) || (charStyle.strikethruWidth() != -1))
775
 
                                        {
776
 
                                                if (charStyle.strikethruOffset() != -1)
777
 
                                                        Upos = (charStyle.strikethruOffset() / 1000.0) * (charStyle.font().ascent(charStyle.fontSize() / 10.0));
778
 
                                                else
779
 
                                                        Upos = charStyle.font().strikeoutPos(charStyle.fontSize() / 10.0);
780
 
                                                if (charStyle.strikethruWidth() != -1)
781
 
                                                        lw = (charStyle.strikethruWidth() / 1000.0) * (charStyle.fontSize() / 10.0);
782
 
                                                else
783
 
                                                        lw = qMax(charStyle.font().strokeWidth(charStyle.fontSize() / 10.0), 1.0);
784
 
                                        }
785
 
                                        else
786
 
                                        {
787
 
                                                Upos = charStyle.font().strikeoutPos(charStyle.fontSize() / 10.0);
788
 
                                                lw = qMax(charStyle.font().strokeWidth(charStyle.fontSize() / 10.0), 1.0);
789
 
                                        }
790
 
                                        if (charStyle.baselineOffset() != 0)
791
 
                                                Upos += (charStyle.fontSize() / 10.0) * hl->glyph.scaleV * (charStyle.baselineOffset() / 1000.0);
792
 
                                        QDomElement ob7 = docu.createElement("path");
793
 
                                        ob7.setAttribute("d", QString("M %1 %2 L%3 %4").arg(x + hl->glyph.xoffset-kern).arg(y + hl->glyph.yoffset - Upos).arg(x + hl->glyph.xoffset+Ulen).arg(y + hl->glyph.yoffset - Upos));
794
 
                                        QString sT = "stroke:none;";
795
 
                                        if (charStyle.fillColor() != CommonStrings::None)
796
 
                                        {
797
 
                                                sT = "stroke:"+SetColor(charStyle.fillColor(), charStyle.fillShade())+";";
798
 
                                                sT += " stroke-width:"+FToStr(lw)+";";
799
 
                                        }
800
 
                                        ob7.setAttribute("style", "fill:none;" + sT);
801
 
                                        ob.appendChild(ob7);
802
 
                                }
803
 
                                CurX += hl->glyph.wide();
804
 
                        }
805
 
                }
806
 
        }
807
 
        if (Item->NamedLStyle.isEmpty())
808
 
        {
809
 
                QDomElement ob4 = docu.createElement("path");
810
 
                ob4.setAttribute("d", SetClipPath(&Item->PoLine, true));
811
 
                ob4.setAttribute("style", "fill:none; "+stroke);
812
 
                ob.appendChild(ob4);
813
 
        }
814
 
        else
815
 
        {
816
 
                multiLine ml = m_Doc->MLineStyles[Item->NamedLStyle];
817
 
                for (int it = ml.size()-1; it > -1; it--)
818
 
                {
819
 
                        if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
820
 
                        {
821
 
                                QDomElement ob5 = docu.createElement("path");
822
 
                                ob5.setAttribute("d", SetClipPath(&Item->PoLine, true));
823
 
                                ob5.setAttribute("style", "fill:none; "+GetMultiStroke(&ml[it], Item));
824
 
                                ob.appendChild(ob5);
825
 
                        }
826
 
                }
827
 
        }
828
 
        return ob;
829
 
}
830
 
 
831
 
QDomElement SVGExPlug::processPathTextItem(PageItem *Item, QString trans, QString stroke)
832
 
{
833
 
        QDomElement ob;
834
 
        ob = docu.createElement("g");
835
 
        ob.setAttribute("transform", trans);
836
 
        if (Item->PoShow)
837
 
        {
838
 
                if (Item->NamedLStyle.isEmpty())
839
 
                {
840
 
                        QDomElement ob4 = docu.createElement("path");
841
 
                        ob4.setAttribute("d", SetClipPath(&Item->PoLine, false));
842
 
                        ob4.setAttribute("style", "fill:none; "+stroke);
843
 
                        ob.appendChild(ob4);
844
 
                }
845
 
                else
846
 
                {
847
 
                        multiLine ml = m_Doc->MLineStyles[Item->NamedLStyle];
848
 
                        for (int it = ml.size()-1; it > -1; it--)
849
 
                        {
850
 
                                if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
851
 
                                {
852
 
                                        QDomElement ob5 = docu.createElement("path");
853
 
                                        ob5.setAttribute("d", SetClipPath(&Item->PoLine, false));
854
 
                                        ob5.setAttribute("style", "fill:none; "+GetMultiStroke(&ml[it], Item));
855
 
                                        ob.appendChild(ob5);
856
 
                                }
857
 
                        }
858
 
                }
859
 
        }
860
 
        double x, y, wide;
861
 
        QString chstr;
862
 
        for (int a = 0; a < Item->itemText.length(); ++a)
863
 
        {
864
 
                x = 0.0;
865
 
                y = 0.0;
866
 
                ScText *hl = Item->itemText.item(a);
867
 
                const CharStyle& charStyle(Item->itemText.charStyle(a));
868
 
                chstr = Item->itemText.text(a,1);
869
 
                if ((chstr == QChar(13)) || (chstr == QChar(29)))
870
 
                        continue;
871
 
                if (chstr == QChar(30))
872
 
                {
873
 
                        chstr = Item->ExpandToken(a);
874
 
                        if (chstr == QChar(32))
875
 
                                continue;
876
 
                }
877
 
                double chs = charStyle.fontSize();
878
 
                if (hl->effects() & ScStyle_SmallCaps)
879
 
                {
880
 
                        if (chstr.toUpper() != chstr)
881
 
                        {
882
 
                                chs = qMax(static_cast<int>(hl->fontSize() * m_Doc->typographicSettings.valueSmallCaps / 100), 1);
883
 
                                chstr = chstr.toUpper();
884
 
                        }
885
 
                }
886
 
                else if (hl->effects() & ScStyle_AllCaps)
887
 
                        chstr = chstr.toUpper();
888
 
                uint chr = chstr[0].unicode();
889
 
                QPointF tangt = QPointF( cos(hl->PRot), sin(hl->PRot) );
890
 
                QMatrix chma, chma2, chma3, chma4, chma6;
891
 
                QMatrix trafo = QMatrix( 1, 0, 0, -1, -hl->PDx, 0 );
892
 
                if (Item->textPathFlipped)
893
 
                        trafo *= QMatrix(1, 0, 0, -1, 0, 0);
894
 
                if (Item->textPathType == 0)
895
 
                        trafo *= QMatrix( tangt.x(), tangt.y(), tangt.y(), -tangt.x(), hl->PtransX, hl->PtransY );
896
 
                else if (Item->textPathType == 1)
897
 
                        trafo *= QMatrix(1, 0, 0, -1, hl->PtransX, hl->PtransY );
898
 
                else if (Item->textPathType == 2)
899
 
                {
900
 
                        double a = 1;
901
 
                        double b = -1;
902
 
                        if (tangt.x() < 0)
903
 
                        {
904
 
                                a = -1;
905
 
                                b = 1;
906
 
                        }
907
 
                        if (fabs(tangt.x()) > 0.1)
908
 
                                trafo *= QMatrix( a, (tangt.y() / tangt.x()) * b, 0, -1, hl->PtransX, hl->PtransY ); // ID's Skew mode
909
 
                        else
910
 
                                trafo *= QMatrix( a, 6 * b, 0, -1, hl->PtransX, hl->PtransY );
911
 
                }
912
 
                if ((hl->ch == SpecialChars::OBJECT) && (hl->embedded.hasItem()))
913
 
                {
914
 
                        QMatrix finalMat = QMatrix(chma * chma2 * chma3 * chma4 * chma6 * trafo);
915
 
                        ob.appendChild(processInlineItem(0, 0, finalMat, hl, true, trans));
916
 
                }
917
 
                else
918
 
                {
919
 
                        if (Item->rotation() != 0)
920
 
                        {
921
 
                                QMatrix sca;
922
 
                                sca.translate(-Item->xPos(), -Item->yPos());
923
 
                                trafo *= sca;
924
 
                        }
925
 
                        chma.scale(hl->glyph.scaleH * charStyle.fontSize() / 100.00, hl->glyph.scaleV * charStyle.fontSize() / 100.0);
926
 
                        if (Item->reversed())
927
 
                        {
928
 
                                if (a < Item->itemText.length()-1)
929
 
                                        wide = hl->font().charWidth(chstr[0], hl->fontSize(), Item->itemText.text(a+1));
930
 
                                else
931
 
                                        wide = hl->font().charWidth(chstr[0], hl->fontSize());
932
 
                                chma3.scale(-1, 1);
933
 
                                chma3.translate(-wide, 0);
934
 
                        }
935
 
                        chma4.translate(0, Item->BaseOffs - (charStyle.fontSize() / 10.0) * hl->glyph.scaleV);
936
 
                        if (charStyle.effects() & (ScStyle_Subscript | ScStyle_Superscript | ScStyle_DropCap))
937
 
                                chma6.translate(0, hl->glyph.yoffset);
938
 
                        if (hl->baselineOffset() != 0)
939
 
                                chma6.translate(0, (-charStyle.fontSize() / 10.0) * (charStyle.baselineOffset() / 1000.0));
940
 
                        QMatrix finalMat = QMatrix(chma * chma2 * chma3 * chma4 * chma6 * trafo);
941
 
                        if (Item->rotation() != 0)
942
 
                        {
943
 
                                QMatrix sca;
944
 
                                sca.translate(Item->xPos(), Item->yPos());
945
 
                                finalMat *= sca;
946
 
                        }
947
 
                        QChar chstc = hl->ch;
948
 
                        if (((charStyle.effects() & ScStyle_Underline) && !SpecialChars::isBreak(chstc))
949
 
                                || ((charStyle.effects() & ScStyle_UnderlineWords) && !chstc.isSpace() && !SpecialChars::isBreak(chstc)))
950
 
                        {
951
 
                                QMatrix stro = QMatrix(chma2 * chma3 * chma6 * trafo);
952
 
                                if (Item->rotation() != 0)
953
 
                                {
954
 
                                        QMatrix sca;
955
 
                                        sca.translate(Item->xPos(), Item->yPos());
956
 
                                        stro *= sca;
957
 
                                }
958
 
                                double Ulen = hl->glyph.xadvance;
959
 
                                double Upos, Uwid, kern;
960
 
                                if (hl->effects() & ScStyle_StartOfLine)
961
 
                                        kern = 0;
962
 
                                else
963
 
                                        kern = charStyle.fontSize() * charStyle.tracking() / 10000.0;
964
 
                                if ((charStyle.underlineOffset() != -1) || (charStyle.underlineWidth() != -1))
965
 
                                {
966
 
                                        if (charStyle.underlineOffset() != -1)
967
 
                                                Upos = (charStyle.underlineOffset() / 1000.0) * (charStyle.font().descent(charStyle.fontSize() / 10.0));
968
 
                                        else
969
 
                                                Upos = charStyle.font().underlinePos(charStyle.fontSize() / 10.0);
970
 
                                        if (charStyle.underlineWidth() != -1)
971
 
                                                Uwid = (charStyle.underlineWidth() / 1000.0) * (charStyle.fontSize() / 10.0);
972
 
                                        else
973
 
                                                Uwid = qMax(charStyle.font().strokeWidth(charStyle.fontSize() / 10.0), 1.0);
974
 
                                }
975
 
                                else
976
 
                                {
977
 
                                        Upos = charStyle.font().underlinePos(charStyle.fontSize() / 10.0);
978
 
                                        Uwid = qMax(charStyle.font().strokeWidth(charStyle.fontSize() / 10.0), 1.0);
979
 
                                }
980
 
                                if (charStyle.baselineOffset() != 0)
981
 
                                        Upos += (charStyle.fontSize() / 10.0) * (charStyle.baselineOffset() / 1000.0);
982
 
                                QDomElement ob8 = docu.createElement("path");
983
 
                                ob8.setAttribute("transform", MatrixToStr(stro));
984
 
                                if (charStyle.effects() & ScStyle_Subscript)
985
 
                                        ob8.setAttribute("d", QString("M %1 %2 L%3 %4").arg(hl->glyph.xoffset-kern).arg(-Upos).arg(hl->glyph.xoffset+Ulen).arg(-Upos));
986
 
                                else
987
 
                                        ob8.setAttribute("d", QString("M %1 %2 L%3 %4").arg(hl->glyph.xoffset-kern).arg(-(Upos + hl->glyph.yoffset)).arg(hl->glyph.xoffset+Ulen).arg(-(Upos + hl->glyph.yoffset)));
988
 
                                QString sT = "stroke:none;";
989
 
                                if (charStyle.fillColor() != CommonStrings::None)
990
 
                                {
991
 
                                        sT = "stroke:"+SetColor(charStyle.fillColor(), charStyle.fillShade())+";";
992
 
                                        sT += " stroke-width:"+FToStr(Uwid)+";";
993
 
                                }
994
 
                                ob8.setAttribute("style", "fill:none;" + sT);
995
 
                                ob.appendChild(ob8);
996
 
                        }
997
 
                        if (chstr > QChar(32))
998
 
                        {
999
 
                                QString glName = handleGlyph(chr, hl);
1000
 
                                if ((charStyle.effects() & ScStyle_Shadowed) && (charStyle.strokeColor() != CommonStrings::None))
1001
 
                                {
1002
 
                                        QMatrix sha = finalMat;
1003
 
                                        QMatrix shad;
1004
 
                                        shad.translate(charStyle.fontSize() * charStyle.shadowXOffset() / 10000.0, -charStyle.fontSize() * charStyle.shadowYOffset() / 10000.0);
1005
 
                                        sha *= shad;
1006
 
                                        QDomElement ob2 = docu.createElement("use");
1007
 
                                        ob2.setAttribute("xlink:href", "#" + glName);
1008
 
                                        ob2.setAttribute("transform", MatrixToStr(sha));
1009
 
                                        ob2.setAttribute("style", "fill:"+SetColor(hl->strokeColor(), hl->strokeShade())+";" + "stroke:none;");
1010
 
                                        ob.appendChild(ob2);
1011
 
                                }
1012
 
                                QDomElement ob1 = docu.createElement("use");
1013
 
                                ob1.setAttribute("xlink:href", "#" + glName);
1014
 
                                ob1.setAttribute("transform", MatrixToStr(finalMat));
1015
 
                                QString fT = "fill:"+SetColor(hl->fillColor(), hl->fillShade())+";";
1016
 
                                QString sT = "stroke:none;";
1017
 
                                if (charStyle.effects() & ScStyle_Outline)
1018
 
                                {
1019
 
                                        sT = "stroke:"+SetColor(hl->strokeColor(), hl->strokeShade())+";";
1020
 
                                        sT += " stroke-width:"+FToStr(chs * hl->outlineWidth() / 10000.0)+";";
1021
 
                                }
1022
 
                                ob1.setAttribute("style", fT + sT);
1023
 
                                ob.appendChild(ob1);
1024
 
                        }
1025
 
                        if (charStyle.effects() & ScStyle_Strikethrough)
1026
 
                        {
1027
 
                                QMatrix stro = QMatrix(chma2 * chma3 * chma6 * trafo);
1028
 
                                if (Item->rotation() != 0)
1029
 
                                {
1030
 
                                        QMatrix sca;
1031
 
                                        sca.translate(Item->xPos(), Item->yPos());
1032
 
                                        stro *= sca;
1033
 
                                }
1034
 
                                double Ulen = hl->glyph.xadvance;
1035
 
                                double Upos, Uwid, kern;
1036
 
                                if (hl->effects() & ScStyle_StartOfLine)
1037
 
                                        kern = 0;
1038
 
                                else
1039
 
                                        kern = charStyle.fontSize() * charStyle.tracking() / 10000.0;
1040
 
                                if ((charStyle.strikethruOffset() != -1) || (charStyle.strikethruWidth() != -1))
1041
 
                                {
1042
 
                                        if (charStyle.strikethruOffset() != -1)
1043
 
                                                Upos = (charStyle.strikethruOffset() / 1000.0) * (charStyle.font().ascent(charStyle.fontSize() / 10.0));
1044
 
                                        else
1045
 
                                                Upos = charStyle.font().strikeoutPos(charStyle.fontSize() / 10.0);
1046
 
                                        if (charStyle.strikethruWidth() != -1)
1047
 
                                                Uwid = (charStyle.strikethruWidth() / 1000.0) * (charStyle.fontSize() / 10.0);
1048
 
                                        else
1049
 
                                                Uwid = qMax(charStyle.font().strokeWidth(charStyle.fontSize() / 10.0), 1.0);
1050
 
                                }
1051
 
                                else
1052
 
                                {
1053
 
                                        Upos = charStyle.font().strikeoutPos(charStyle.fontSize() / 10.0);
1054
 
                                        Uwid = qMax(charStyle.font().strokeWidth(charStyle.fontSize() / 10.0), 1.0);
1055
 
                                }
1056
 
                                if (charStyle.baselineOffset() != 0)
1057
 
                                        Upos += (charStyle.fontSize() / 10.0) * (charStyle.baselineOffset() / 1000.0);
1058
 
                                QDomElement ob7 = docu.createElement("path");
1059
 
                                ob7.setAttribute("transform", MatrixToStr(stro));
1060
 
                                ob7.setAttribute("d", QString("M %1 %2 L%3 %4").arg(hl->glyph.xoffset-kern).arg(-Upos).arg(hl->glyph.xoffset+Ulen).arg(-Upos));
1061
 
                                QString sT = "stroke:none;";
1062
 
                                if (charStyle.fillColor() != CommonStrings::None)
1063
 
                                {
1064
 
                                        sT = "stroke:"+SetColor(charStyle.fillColor(), charStyle.fillShade())+";";
1065
 
                                        sT += " stroke-width:"+FToStr(Uwid)+";";
1066
 
                                }
1067
 
                                ob7.setAttribute("style", "fill:none;" + sT);
1068
 
                                ob.appendChild(ob7);
1069
 
                        }
1070
 
                }
1071
 
        }
1072
 
        return ob;
1073
 
}
1074
 
 
1075
 
QDomElement SVGExPlug::processInlineItem(double xpos, double ypos, QMatrix &finalMat, ScText *hl, bool pathT, QString trans)
1076
 
{
1077
 
        const CharStyle & charStyle(*hl);
1078
 
        QList<PageItem*> emG = hl->embedded.getGroupedItems();
1079
 
        QStack<PageItem*> groupStack;
1080
 
        QStack<QDomElement> groupStack2;
1081
 
        QDomElement layerGroup = docu.createElement("g");
1082
 
        if (pathT)
1083
 
                layerGroup.setAttribute("transform", MatrixToStr(finalMat));
1084
 
        for (int em = 0; em < emG.count(); ++em)
1085
 
        {
1086
 
                PageItem* embedded = emG.at(em);
1087
 
                if (embedded->isGroupControl)
1088
 
                {
1089
 
                        groupStack.push(embedded->groupsLastItem);
1090
 
                        groupStack2.push(layerGroup);
1091
 
                        layerGroup = docu.createElement("g");
1092
 
                        if (embedded->fillTransparency() != 0)
1093
 
                                layerGroup.setAttribute("opacity", FToStr(1.0 - embedded->fillTransparency()));
1094
 
                        QDomElement ob = docu.createElement("clipPath");
1095
 
                        ob.setAttribute("id", "Clip"+IToStr(ClipCount));
1096
 
                        QDomElement cl = docu.createElement("path");
1097
 
                        cl.setAttribute("d", SetClipPath(&embedded->PoLine, true));
1098
 
                        QMatrix mm;
1099
 
                        mm.translate(xpos + embedded->gXpos * (charStyle.scaleH() / 1000.0), (ypos - (embedded->gHeight * (charStyle.scaleV() / 1000.0)) + embedded->gYpos * (charStyle.scaleV() / 1000.0)));
1100
 
                        if (charStyle.baselineOffset() != 0)
1101
 
                                mm.translate(0, embedded->gHeight * (charStyle.baselineOffset() / 1000.0));
1102
 
                        if (charStyle.scaleH() != 1000)
1103
 
                                mm.scale(charStyle.scaleH() / 1000.0, 1);
1104
 
                        if (charStyle.scaleV() != 1000)
1105
 
                                mm.scale(1, charStyle.scaleV() / 1000.0);
1106
 
                        mm.rotate(embedded->rotation());
1107
 
                        cl.setAttribute("transform", MatrixToStr(mm));
1108
 
                        ob.appendChild(cl);
1109
 
                        globalDefs.appendChild(ob);
1110
 
                        layerGroup.setAttribute("clip-path", "url(#Clip"+IToStr(ClipCount)+")");
1111
 
                        ClipCount++;
1112
 
                        continue;
1113
 
                }
1114
 
                QDomElement obE;
1115
 
                QString fill = getFillStyle(embedded);
1116
 
                QString stroke = "stroke:none";
1117
 
                if (!embedded->isTableItem)
1118
 
                        stroke = getStrokeStyle(embedded);
1119
 
                switch (embedded->itemType())
1120
 
                {
1121
 
                        case PageItem::Polygon:
1122
 
                        case PageItem::PolyLine:
1123
 
                                obE = processPolyItem(embedded, trans, fill, stroke);
1124
 
                                if ((embedded->lineColor() != CommonStrings::None) && ((embedded->startArrowIndex() != 0) || (embedded->endArrowIndex() != 0)))
1125
 
                                        obE = processArrows(embedded, obE, trans);
1126
 
                                break;
1127
 
                        case PageItem::Line:
1128
 
                                obE = processLineItem(embedded, trans, stroke);
1129
 
                                if ((embedded->lineColor() != CommonStrings::None) && ((embedded->startArrowIndex() != 0) || (embedded->endArrowIndex() != 0)))
1130
 
                                        obE = processArrows(embedded, obE, trans);
1131
 
                                break;
1132
 
                        case PageItem::ImageFrame:
1133
 
                        case PageItem::LatexFrame:
1134
 
                                obE = processImageItem(embedded, trans, fill, stroke);
1135
 
                                break;
1136
 
                        case PageItem::TextFrame:
1137
 
                                obE = processTextItem(embedded, trans, fill, stroke);
1138
 
                                break;
1139
 
                        case PageItem::PathText:
1140
 
                                obE = processPathTextItem(embedded, trans, stroke);
1141
 
                                break;
1142
 
                        default:
1143
 
                                break;
1144
 
                }
1145
 
                QMatrix mm;
1146
 
                mm.translate(xpos + embedded->gXpos * (charStyle.scaleH() / 1000.0), (ypos - (embedded->gHeight * (charStyle.scaleV() / 1000.0)) + embedded->gYpos * (charStyle.scaleV() / 1000.0)));
1147
 
                if (charStyle.baselineOffset() != 0)
1148
 
                        mm.translate(0, embedded->gHeight * (charStyle.baselineOffset() / 1000.0));
1149
 
                if (charStyle.scaleH() != 1000)
1150
 
                        mm.scale(charStyle.scaleH() / 1000.0, 1);
1151
 
                if (charStyle.scaleV() != 1000)
1152
 
                        mm.scale(1, charStyle.scaleV() / 1000.0);
1153
 
                mm.rotate(embedded->rotation());
1154
 
                obE.setAttribute("transform", MatrixToStr(mm));
1155
 
                layerGroup.appendChild(obE);
1156
 
                if (groupStack.count() != 0)
1157
 
                {
1158
 
                        while (embedded == groupStack.top())
1159
 
                        {
1160
 
                                groupStack.pop();
1161
 
                                groupStack2.top().appendChild(layerGroup);
1162
 
                                layerGroup = groupStack2.pop();
1163
 
                                if (groupStack.count() == 0)
1164
 
                                        break;
1165
 
                        }
1166
 
                }
1167
 
        }
1168
 
        for (int em = 0; em < emG.count(); ++em)
1169
 
        {
1170
 
                PageItem* embedded = emG.at(em);
1171
 
                if (!embedded->isTableItem)
1172
 
                        continue;
1173
 
                if ((embedded->lineColor() == CommonStrings::None) || (embedded->lineWidth() == 0.0))
1174
 
                        continue;
1175
 
                if ((embedded->TopLine) || (embedded->RightLine) || (embedded->BottomLine) || (embedded->LeftLine))
1176
 
                {
1177
 
                        QMatrix mm;
1178
 
                        mm.translate(xpos + embedded->gXpos * (charStyle.scaleH() / 1000.0), (ypos - (embedded->gHeight * (charStyle.scaleV() / 1000.0)) + embedded->gYpos * (charStyle.scaleV() / 1000.0)));
1179
 
                        if (charStyle.baselineOffset() != 0)
1180
 
                                mm.translate(0, embedded->gHeight * (charStyle.baselineOffset() / 1000.0));
1181
 
                        if (charStyle.scaleH() != 1000)
1182
 
                                mm.scale(charStyle.scaleH() / 1000.0, 1);
1183
 
                        if (charStyle.scaleV() != 1000)
1184
 
                                mm.scale(1, charStyle.scaleV() / 1000.0);
1185
 
                        mm.rotate(embedded->rotation());
1186
 
                        QString stroke = getStrokeStyle(embedded);
1187
 
                        QDomElement obL = docu.createElement("path");
1188
 
                        obL.setAttribute("transform", MatrixToStr(mm));
1189
 
                        obL.setAttribute("style", "fill:none; " + stroke);
1190
 
                        QString pathAttr = "";
1191
 
                        if (embedded->TopLine)
1192
 
                                pathAttr += "M 0 0 L "+FToStr(embedded->width())+" 0";
1193
 
                        if (embedded->RightLine)
1194
 
                                pathAttr += " M " + FToStr(embedded->width()) + "0 L "+FToStr(embedded->width())+" "+FToStr(embedded->height());
1195
 
                        if (embedded->BottomLine)
1196
 
                                pathAttr += " M 0 " + FToStr(embedded->height()) + " L "+FToStr(embedded->width())+" "+FToStr(embedded->height());
1197
 
                        if (embedded->LeftLine)
1198
 
                                pathAttr += " M 0 0 L 0 "+FToStr(embedded->height());
1199
 
                        obL.setAttribute("d", pathAttr);
1200
 
                        layerGroup.appendChild(obL);
1201
 
                }
1202
 
        }
1203
 
        return layerGroup;
1204
 
}
1205
 
 
1206
 
QString SVGExPlug::handleGlyph(uint chr, ScText *hl)
1207
 
{
1208
 
        if (chr == 32)
1209
 
                return "SPACE";
1210
 
        QString glName = QString("Gl%1%2").arg(hl->font().psName().simplified().replace(QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" )).arg(chr);
1211
 
        if (glyphNames.contains(glName))
1212
 
                return glName;
1213
 
        uint gl = hl->font().char2CMap(chr);
1214
 
        FPointArray pts = hl->font().glyphOutline(gl);
1215
 
        QDomElement ob = docu.createElement("path");
1216
 
        ob.setAttribute("d", SetClipPath(&pts, true));
1217
 
        ob.setAttribute("id", glName);
1218
 
        globalDefs.appendChild(ob);
1219
 
        glyphNames.append(glName);
1220
 
        return glName;
1221
 
}
1222
 
 
1223
 
QDomElement SVGExPlug::processArrows(PageItem *Item, QDomElement line, QString trans)
1224
 
{
1225
 
        QDomElement ob, gr;
1226
 
        gr = docu.createElement("g");
1227
 
        gr.appendChild(line);
1228
 
        if (Item->startArrowIndex() != 0)
1229
 
        {
1230
 
                QMatrix arrowTrans;
1231
 
                FPointArray arrow = m_Doc->arrowStyles.at(Item->startArrowIndex()-1).points.copy();
1232
 
                if (Item->itemType() == PageItem::Line)
1233
 
                {
1234
 
                        arrowTrans.translate(0, 0);
1235
 
                        if (Item->NamedLStyle.isEmpty())
1236
 
                        {
1237
 
                                if (Item->lineWidth() != 0.0)
1238
 
                                        arrowTrans.scale(Item->lineWidth(), Item->lineWidth());
1239
 
                        }
1240
 
                        else
1241
 
                        {
1242
 
                                multiLine ml = m_Doc->MLineStyles[Item->NamedLStyle];
1243
 
                                if (ml[ml.size()-1].Width != 0.0)
1244
 
                                        arrowTrans.scale(ml[ml.size()-1].Width, ml[ml.size()-1].Width);
1245
 
                        }
1246
 
                        arrowTrans.scale(-1,1);
1247
 
                }
1248
 
                else
1249
 
                {
1250
 
                        FPoint Start = Item->PoLine.point(0);
1251
 
                        for (uint xx = 1; xx < Item->PoLine.size(); xx += 2)
1252
 
                        {
1253
 
                                FPoint Vector = Item->PoLine.point(xx);
1254
 
                                if ((Start.x() != Vector.x()) || (Start.y() != Vector.y()))
1255
 
                                {
1256
 
                                        double r = atan2(Start.y()-Vector.y(),Start.x()-Vector.x())*(180.0/M_PI);
1257
 
                                        arrowTrans.translate(Start.x(), Start.y());
1258
 
                                        arrowTrans.rotate(r);
1259
 
                                        if (Item->NamedLStyle.isEmpty())
1260
 
                                        {
1261
 
                                                if (Item->lineWidth() != 0.0)
1262
 
                                                        arrowTrans.scale(Item->lineWidth(), Item->lineWidth());
1263
 
                                        }
1264
 
                                        else
1265
 
                                        {
1266
 
                                                multiLine ml = m_Doc->MLineStyles[Item->NamedLStyle];
1267
 
                                                if (ml[ml.size()-1].Width != 0.0)
1268
 
                                                        arrowTrans.scale(ml[ml.size()-1].Width, ml[ml.size()-1].Width);
1269
 
                                        }
1270
 
                                        break;
1271
 
                                }
1272
 
                        }
1273
 
                }
1274
 
                arrow.map(arrowTrans);
1275
 
                if (Item->NamedLStyle.isEmpty())
1276
 
                {
1277
 
                        ob = docu.createElement("path");
1278
 
                        ob.setAttribute("d", SetClipPath(&arrow, true));
1279
 
                        ob.setAttribute("transform", trans);
1280
 
                        QString aFill = "fill:"+SetColor(Item->lineColor(), Item->lineShade())+";";
1281
 
                        if (Item->lineTransparency() != 0)
1282
 
                                aFill += " fill-opacity:"+FToStr(1.0 - Item->lineTransparency())+";";
1283
 
                        ob.setAttribute("style", aFill + " stroke:none;");
1284
 
                        gr.appendChild(ob);
1285
 
                }
1286
 
                else
1287
 
                {
1288
 
                        multiLine ml = m_Doc->MLineStyles[Item->NamedLStyle];
1289
 
                        if (ml[0].Color != CommonStrings::None)
1290
 
                        {
1291
 
                                ob = docu.createElement("path");
1292
 
                                ob.setAttribute("d", SetClipPath(&arrow, true));
1293
 
                                ob.setAttribute("transform", trans);
1294
 
                                QString aFill = "fill:"+SetColor(ml[0].Color, ml[0].Shade)+";";
1295
 
                                ob.setAttribute("style", aFill + " stroke:none;");
1296
 
                                gr.appendChild(ob);
1297
 
                        }
1298
 
                        for (int it = ml.size()-1; it > 0; it--)
1299
 
                        {
1300
 
                                if (ml[it].Color != CommonStrings::None)
1301
 
                                {
1302
 
                                        QDomElement ob5 = docu.createElement("path");
1303
 
                                        ob5.setAttribute("d", SetClipPath(&arrow, true));
1304
 
                                        ob5.setAttribute("transform", trans);
1305
 
                                        QString stroke = "fill:none; stroke:"+SetColor(ml[it].Color, ml[it].Shade)+"; stroke-linecap:butt; stroke-linejoin:miter; stroke-dasharray:none;";
1306
 
                                        if (ml[it].Width != 0.0)
1307
 
                                                stroke += " stroke-width:"+FToStr(ml[it].Width)+";";
1308
 
                                        else
1309
 
                                                stroke += " stroke-width:1px;";
1310
 
                                        ob5.setAttribute("style", stroke);
1311
 
                                        gr.appendChild(ob5);
1312
 
                                }
1313
 
                        }
1314
 
                }
1315
 
        }
1316
 
        if (Item->endArrowIndex() != 0)
1317
 
        {
1318
 
                QMatrix arrowTrans;
1319
 
                FPointArray arrow = m_Doc->arrowStyles.at(Item->endArrowIndex()-1).points.copy();
1320
 
                if (Item->itemType() == PageItem::Line)
1321
 
                {
1322
 
                        arrowTrans.translate(Item->width(), 0);
1323
 
                        if (Item->NamedLStyle.isEmpty())
1324
 
                        {
1325
 
                                if (Item->lineWidth() != 0.0)
1326
 
                                        arrowTrans.scale(Item->lineWidth(), Item->lineWidth());
1327
 
                        }
1328
 
                        else
1329
 
                        {
1330
 
                                multiLine ml = m_Doc->MLineStyles[Item->NamedLStyle];
1331
 
                                if (ml[ml.size()-1].Width != 0.0)
1332
 
                                        arrowTrans.scale(ml[ml.size()-1].Width, ml[ml.size()-1].Width);
1333
 
                        }
1334
 
                }
1335
 
                else
1336
 
                {
1337
 
                        FPoint End = Item->PoLine.point(Item->PoLine.size()-2);
1338
 
                        for (uint xx = Item->PoLine.size()-1; xx > 0; xx -= 2)
1339
 
                        {
1340
 
                                FPoint Vector = Item->PoLine.point(xx);
1341
 
                                if ((End.x() != Vector.x()) || (End.y() != Vector.y()))
1342
 
                                {
1343
 
                                        double r = atan2(End.y()-Vector.y(),End.x()-Vector.x())*(180.0/M_PI);
1344
 
                                        arrowTrans.translate(End.x(), End.y());
1345
 
                                        arrowTrans.rotate(r);
1346
 
                                        if (Item->NamedLStyle.isEmpty())
1347
 
                                        {
1348
 
                                                if (Item->lineWidth() != 0.0)
1349
 
                                                        arrowTrans.scale(Item->lineWidth(), Item->lineWidth());
1350
 
                                        }
1351
 
                                        else
1352
 
                                        {
1353
 
                                                multiLine ml = m_Doc->MLineStyles[Item->NamedLStyle];
1354
 
                                                if (ml[ml.size()-1].Width != 0.0)
1355
 
                                                        arrowTrans.scale(ml[ml.size()-1].Width, ml[ml.size()-1].Width);
1356
 
                                        }
1357
 
                                        break;
1358
 
                                }
1359
 
                        }
1360
 
                }
1361
 
                arrow.map(arrowTrans);
1362
 
                if (Item->NamedLStyle.isEmpty())
1363
 
                {
1364
 
                        ob = docu.createElement("path");
1365
 
                        ob.setAttribute("d", SetClipPath(&arrow, true));
1366
 
                        ob.setAttribute("transform", trans);
1367
 
                        QString aFill = "fill:"+SetColor(Item->lineColor(), Item->lineShade())+";";
1368
 
                        if (Item->lineTransparency() != 0)
1369
 
                                aFill += " fill-opacity:"+FToStr(1.0 - Item->lineTransparency())+";";
1370
 
                        ob.setAttribute("style", aFill + " stroke:none;");
1371
 
                        gr.appendChild(ob);
1372
 
                }
1373
 
                else
1374
 
                {
1375
 
                        multiLine ml = m_Doc->MLineStyles[Item->NamedLStyle];
1376
 
                        if (ml[0].Color != CommonStrings::None)
1377
 
                        {
1378
 
                                ob = docu.createElement("path");
1379
 
                                ob.setAttribute("d", SetClipPath(&arrow, true));
1380
 
                                ob.setAttribute("transform", trans);
1381
 
                                QString aFill = "fill:"+SetColor(ml[0].Color, ml[0].Shade)+";";
1382
 
                                ob.setAttribute("style", aFill + " stroke:none;");
1383
 
                                gr.appendChild(ob);
1384
 
                        }
1385
 
                        for (int it = ml.size()-1; it > 0; it--)
1386
 
                        {
1387
 
                                if (ml[it].Color != CommonStrings::None)
1388
 
                                {
1389
 
                                        QDomElement ob5 = docu.createElement("path");
1390
 
                                        ob5.setAttribute("d", SetClipPath(&arrow, true));
1391
 
                                        ob5.setAttribute("transform", trans);
1392
 
                                        QString stroke = "fill:none; stroke:"+SetColor(ml[it].Color, ml[it].Shade)+"; stroke-linecap:butt; stroke-linejoin:miter; stroke-dasharray:none;";
1393
 
                                        if (ml[it].Width != 0.0)
1394
 
                                                stroke += " stroke-width:"+FToStr(ml[it].Width)+";";
1395
 
                                        else
1396
 
                                                stroke += " stroke-width:1px;";
1397
 
                                        ob5.setAttribute("style", stroke);
1398
 
                                        gr.appendChild(ob5);
1399
 
                                }
1400
 
                        }
1401
 
                }
1402
 
        }
1403
 
        return gr;
1404
 
}
1405
 
 
1406
 
QString SVGExPlug::getFillStyle(PageItem *Item)
1407
 
{
1408
 
        QDomElement grad;
1409
 
        QString fill;
1410
 
        if (Item->asPathText())
1411
 
                return "fill:none;";
1412
 
        if ((Item->fillColor() != CommonStrings::None) || (Item->GrType != 0))
1413
 
        {
1414
 
                fill = "fill:"+SetColor(Item->fillColor(), Item->fillShade())+";";
1415
 
                if (Item->GrType != 0)
1416
 
                {
1417
 
                        if (Item->GrType == 8)
1418
 
                        {
1419
 
                                QStack<PageItem*> groupStack;
1420
 
                                QStack<QDomElement> groupStack2;
1421
 
                                QString pattID = Item->pattern()+IToStr(PattCount);
1422
 
                                PattCount++;
1423
 
                                ScPattern pa = m_Doc->docPatterns[Item->pattern()];
1424
 
                                QDomElement patt = docu.createElement("pattern");
1425
 
                                patt.setAttribute("id", pattID);
1426
 
                                patt.setAttribute("height", pa.height);
1427
 
                                patt.setAttribute("width", pa.width);
1428
 
                                patt.setAttribute("patternUnits", "userSpaceOnUse");
1429
 
                                double patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation;
1430
 
                                Item->patternTransform(patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation);
1431
 
                                QMatrix mpa;
1432
 
                                mpa.translate(patternOffsetX, patternOffsetY);
1433
 
                                mpa.rotate(patternRotation);
1434
 
                                mpa.scale(pa.scaleX, pa.scaleY);
1435
 
                                mpa.scale(patternScaleX / 100.0 , patternScaleY / 100.0);
1436
 
                                patt.setAttribute("patternTransform", MatrixToStr(mpa));
1437
 
                                for (int em = 0; em < pa.items.count(); ++em)
1438
 
                                {
1439
 
                                        PageItem* Item = pa.items.at(em);
1440
 
                                        if (Item->isGroupControl)
1441
 
                                        {
1442
 
                                                groupStack.push(Item->groupsLastItem);
1443
 
                                                groupStack2.push(patt);
1444
 
                                                patt = docu.createElement("g");
1445
 
                                                if (Item->fillTransparency() != 0)
1446
 
                                                        patt.setAttribute("opacity", FToStr(1.0 - Item->fillTransparency()));
1447
 
                                                QDomElement ob = docu.createElement("clipPath");
1448
 
                                                ob.setAttribute("id", "Clip"+IToStr(ClipCount));
1449
 
                                                QDomElement cl = docu.createElement("path");
1450
 
                                                cl.setAttribute("d", SetClipPath(&Item->PoLine, true));
1451
 
                                                QString trans = "translate("+FToStr(Item->gXpos)+", "+FToStr(Item->gYpos)+")";
1452
 
                                                if (Item->rotation() != 0)
1453
 
                                                        trans += " rotate("+FToStr(Item->rotation())+")";
1454
 
                                                cl.setAttribute("transform", trans);
1455
 
                                                ob.appendChild(cl);
1456
 
                                                globalDefs.appendChild(ob);
1457
 
                                                patt.setAttribute("clip-path", "url(#Clip"+IToStr(ClipCount)+")");
1458
 
                                                ClipCount++;
1459
 
                                                continue;
1460
 
                                        }
1461
 
                                        ProcessItemOnPage(Item->gXpos, Item->gYpos, Item, &patt);
1462
 
                                        if (groupStack.count() != 0)
1463
 
                                        {
1464
 
                                                while (Item == groupStack.top())
1465
 
                                                {
1466
 
                                                        groupStack.pop();
1467
 
                                                        groupStack2.top().appendChild(patt);
1468
 
                                                        patt = groupStack2.pop();
1469
 
                                                        if (groupStack.count() == 0)
1470
 
                                                                break;
1471
 
                                                }
1472
 
                                        }
1473
 
                                }
1474
 
                                for (int em = 0; em < pa.items.count(); ++em)
1475
 
                                {
1476
 
                                        PageItem* embedded = pa.items.at(em);
1477
 
                                        QString trans = "translate("+FToStr(embedded->gXpos)+", "+FToStr(embedded->gYpos)+")";
1478
 
                                        if (embedded->rotation() != 0)
1479
 
                                                trans += " rotate("+FToStr(embedded->rotation())+")";
1480
 
                                        if (!embedded->isTableItem)
1481
 
                                                continue;
1482
 
                                        if ((embedded->lineColor() == CommonStrings::None) || (embedded->lineWidth() == 0.0))
1483
 
                                                continue;
1484
 
                                        if ((embedded->TopLine) || (embedded->RightLine) || (embedded->BottomLine) || (embedded->LeftLine))
1485
 
                                        {
1486
 
                                                QString stroke = getStrokeStyle(embedded);
1487
 
                                                QDomElement obL = docu.createElement("path");
1488
 
                                                obL.setAttribute("transform", trans);
1489
 
                                                obL.setAttribute("style", "fill:none; " + stroke);
1490
 
                                                QString pathAttr = "";
1491
 
                                                if (embedded->TopLine)
1492
 
                                                        pathAttr += "M 0 0 L "+FToStr(embedded->width())+" 0";
1493
 
                                                if (embedded->RightLine)
1494
 
                                                        pathAttr += " M " + FToStr(embedded->width()) + "0 L "+FToStr(embedded->width())+" "+FToStr(embedded->height());
1495
 
                                                if (embedded->BottomLine)
1496
 
                                                        pathAttr += " M 0 " + FToStr(embedded->height()) + " L "+FToStr(embedded->width())+" "+FToStr(embedded->height());
1497
 
                                                if (embedded->LeftLine)
1498
 
                                                        pathAttr += " M 0 0 L 0 "+FToStr(embedded->height());
1499
 
                                                obL.setAttribute("d", pathAttr);
1500
 
                                                patt.appendChild(obL);
1501
 
                                        }
1502
 
                                }
1503
 
                                globalDefs.appendChild(patt);
1504
 
                                fill = "fill:url(#"+pattID+");";
1505
 
                        }
1506
 
                        else
1507
 
                        {
1508
 
                                if ((Item->GrType == 5) || (Item->GrType == 7))
1509
 
                                        grad = docu.createElement("radialGradient");
1510
 
                                else
1511
 
                                        grad = docu.createElement("linearGradient");
1512
 
                                grad.setAttribute("id", "Grad"+IToStr(GradCount));
1513
 
                                grad.setAttribute("gradientUnits", "userSpaceOnUse");
1514
 
                                switch (Item->GrType)
1515
 
                                {
1516
 
                                        case 1:
1517
 
                                                grad.setAttribute("x1", "0");
1518
 
                                                grad.setAttribute("y1", FToStr(Item->height() / 2.0));
1519
 
                                                grad.setAttribute("x2", FToStr(Item->width()));
1520
 
                                                grad.setAttribute("y2", FToStr(Item->height() / 2.0));
1521
 
                                                break;
1522
 
                                        case 2:
1523
 
                                                grad.setAttribute("x1", FToStr(Item->width()/ 2.0));
1524
 
                                                grad.setAttribute("y1", "0");
1525
 
                                                grad.setAttribute("x2", FToStr(Item->width()/ 2.0));
1526
 
                                                grad.setAttribute("y2", FToStr(Item->height()));
1527
 
                                                break;
1528
 
                                        case 3:
1529
 
                                                grad.setAttribute("x1", "0");
1530
 
                                                grad.setAttribute("y1", "0");
1531
 
                                                grad.setAttribute("x2", FToStr(Item->width()));
1532
 
                                                grad.setAttribute("y2", FToStr(Item->height()));
1533
 
                                                break;
1534
 
                                        case 4:
1535
 
                                                grad.setAttribute("x1", "0");
1536
 
                                                grad.setAttribute("y1", FToStr(Item->height()));
1537
 
                                                grad.setAttribute("x2", FToStr(Item->width()));
1538
 
                                                grad.setAttribute("y2", "0");
1539
 
                                                break;
1540
 
                                        case 5:
1541
 
                                                grad.setAttribute("r", FToStr(qMax(Item->width() / 2.0, Item->height() / 2.0)));
1542
 
                                                grad.setAttribute("cx", FToStr(Item->width() / 2.0));
1543
 
                                                grad.setAttribute("cy", FToStr(Item->height() / 2.0));
1544
 
                                                break;
1545
 
                                        case 6:
1546
 
                                                grad.setAttribute("x1", FToStr(Item->GrStartX));
1547
 
                                                grad.setAttribute("y1", FToStr(Item->GrStartY));
1548
 
                                                grad.setAttribute("x2", FToStr(Item->GrEndX));
1549
 
                                                grad.setAttribute("y2", FToStr(Item->GrEndY));
1550
 
                                                break;
1551
 
                                        case 7:
1552
 
                                                grad.setAttribute("r", FToStr(qMax(Item->width() / 2.0, Item->height() / 2.0)));
1553
 
                                                grad.setAttribute("cx", FToStr(Item->GrStartX));
1554
 
                                                grad.setAttribute("cy", FToStr(Item->GrStartY));
1555
 
                                                break;
1556
 
                                }
1557
 
                                bool   isFirst = true;
1558
 
                                double actualStop = 0.0, lastStop = 0.0;
1559
 
                                QList<VColorStop*> cstops = Item->fill_gradient.colorStops();
1560
 
                                for (uint cst = 0; cst < Item->fill_gradient.Stops(); ++cst)
1561
 
                                {
1562
 
                                        actualStop = cstops.at(cst)->rampPoint;
1563
 
                                        if ((actualStop != lastStop) || (isFirst))
1564
 
                                        {
1565
 
                                                QDomElement itcl = docu.createElement("stop");
1566
 
                                                itcl.setAttribute("offset", FToStr(cstops.at(cst)->rampPoint*100)+"%");
1567
 
                                                itcl.setAttribute("stop-opacity", FToStr(cstops.at(cst)->opacity));
1568
 
                                                itcl.setAttribute("stop-color", SetColor(cstops.at(cst)->name, cstops.at(cst)->shade));
1569
 
                                                grad.appendChild(itcl);
1570
 
                                                lastStop = actualStop;
1571
 
                                                isFirst  = false;
1572
 
                                        }
1573
 
                                }
1574
 
                                globalDefs.appendChild(grad);
1575
 
                                fill = "fill:url(#Grad"+IToStr(GradCount)+");";
1576
 
                                GradCount++;
1577
 
                        }
1578
 
                }
1579
 
                if (Item->fillRule)
1580
 
                        fill += " fill-rule:evenodd;";
1581
 
                else
1582
 
                        fill += " fill-rule:nonzero;";
1583
 
                if (Item->fillTransparency() != 0)
1584
 
                        fill += " fill-opacity:"+FToStr(1.0 - Item->fillTransparency())+";";
1585
 
        }
1586
 
        else
1587
 
                fill = "fill:none;";
1588
 
        return fill;
1589
 
}
1590
 
 
1591
 
QString SVGExPlug::getStrokeStyle(PageItem *Item)
1592
 
{
1593
 
        QString stroke = "";
1594
 
        if (Item->lineColor() != CommonStrings::None)
1595
 
        {
1596
 
                stroke = "stroke:"+SetColor(Item->lineColor(), Item->lineShade())+";";
1597
 
                if (Item->lineTransparency() != 0)
1598
 
                        stroke += " stroke-opacity:"+FToStr(1.0 - Item->lineTransparency())+";";
1599
 
                if (Item->lineWidth() != 0.0)
1600
 
                        stroke += " stroke-width:"+FToStr(Item->lineWidth())+";";
1601
 
                else
1602
 
                        stroke += " stroke-width:1px;";
1603
 
                stroke += " stroke-linecap:";
1604
 
                switch (Item->PLineEnd)
1605
 
                {
1606
 
                        case Qt::FlatCap:
1607
 
                                stroke += "butt;";
1608
 
                                break;
1609
 
                        case Qt::SquareCap:
1610
 
                                stroke += "square;";
1611
 
                                break;
1612
 
                        case Qt::RoundCap:
1613
 
                                stroke += "round;";
1614
 
                                break;
1615
 
                        default:
1616
 
                                stroke += "butt;";
1617
 
                                break;
1618
 
                }
1619
 
                stroke += " stroke-linejoin:";
1620
 
                switch (Item->PLineJoin)
1621
 
                {
1622
 
                        case Qt::MiterJoin:
1623
 
                                stroke += "miter;";
1624
 
                                break;
1625
 
                        case Qt::BevelJoin:
1626
 
                                stroke += "bevel;";
1627
 
                                break;
1628
 
                        case Qt::RoundJoin:
1629
 
                                stroke += "round;";
1630
 
                                break;
1631
 
                        default:
1632
 
                                stroke += "miter;";
1633
 
                                break;
1634
 
                }
1635
 
                stroke += " stroke-dasharray:";
1636
 
                if (Item->DashValues.count() != 0)
1637
 
                {
1638
 
                        QVector<double>::iterator it;
1639
 
                        for ( it = Item->DashValues.begin(); it != Item->DashValues.end(); ++it )
1640
 
                        {
1641
 
                                stroke += IToStr(static_cast<int>(*it))+" ";
1642
 
                        }
1643
 
                        stroke += "; stroke-dashoffset:"+IToStr(static_cast<int>(Item->DashOffset))+";";
1644
 
                }
1645
 
                else
1646
 
                {
1647
 
                        if (Item->PLineArt == Qt::SolidLine)
1648
 
                                stroke += "none;";
1649
 
                        else
1650
 
                        {
1651
 
                                QString Da = getDashString(Item->PLineArt, Item->lineWidth());
1652
 
                                if (Da.isEmpty())
1653
 
                                        stroke += "none;";
1654
 
                                else
1655
 
                                        stroke += Da.replace(" ", ", ")+";";
1656
 
                        }
1657
 
                }
1658
 
        }
1659
 
        else
1660
 
                stroke = "stroke:none;";
1661
 
        return stroke;
1662
 
}
1663
 
 
1664
 
QString SVGExPlug::SetClipPath(FPointArray *ite, bool closed)
1665
 
{
1666
 
        QString tmp = "";
1667
 
        FPoint np, np1, np2, np3;
1668
 
        bool nPath = true;
1669
 
        if (ite->size() > 3)
1670
 
        {
1671
 
                for (uint poi=0; poi<ite->size()-3; poi += 4)
1672
 
                {
1673
 
                        if (ite->point(poi).x() > 900000)
1674
 
                        {
1675
 
                                tmp += "Z ";
1676
 
                                nPath = true;
1677
 
                                continue;
1678
 
                        }
1679
 
                        if (nPath)
1680
 
                        {
1681
 
                                np = ite->point(poi);
1682
 
                                tmp += QString("M%1 %2 ").arg(np.x()).arg(np.y());
1683
 
                                nPath = false;
1684
 
                        }
1685
 
                        np = ite->point(poi);
1686
 
                        np1 = ite->point(poi+1);
1687
 
                        np2 = ite->point(poi+3);
1688
 
                        np3 = ite->point(poi+2);
1689
 
                        if ((np == np1) && (np2 == np3))
1690
 
                                tmp += QString("L%1 %2 ").arg(np3.x()).arg(np3.y());
1691
 
                        else
1692
 
                                tmp += QString("C%1 %2 %3 %4 %5 %6 ").arg(np1.x()).arg(np1.y()).arg(np2.x()).arg(np2.y()).arg(np3.x()).arg(np3.y());
1693
 
                }
1694
 
        }
1695
 
        if (closed)
1696
 
                tmp += "Z";
1697
 
        return tmp;
1698
 
}
1699
 
 
1700
 
QString SVGExPlug::FToStr(double c)
1701
 
{
1702
 
        QString cc;
1703
 
        return cc.setNum(c);
1704
 
}
1705
 
 
1706
 
QString SVGExPlug::IToStr(int c)
1707
 
{
1708
 
        QString cc;
1709
 
        return cc.setNum(c);
1710
 
}
1711
 
 
1712
 
QString SVGExPlug::MatrixToStr(QMatrix &mat)
1713
 
{
1714
 
        QString cc("matrix(%1 %2 %3 %4 %5 %6)");
1715
 
        return  cc.arg(mat.m11()).arg(mat.m12()).arg(mat.m21()).arg(mat.m22()).arg(mat.dx()).arg(mat.dy());
1716
 
}
1717
 
 
1718
 
QString SVGExPlug::SetColor(QString farbe, int shad)
1719
 
{
1720
 
        const ScColor& col = m_Doc->PageColors[farbe];
1721
 
        return ScColorEngine::getShadeColorProof(col, m_Doc, shad).name();
1722
 
}
1723
 
 
1724
 
QString SVGExPlug::GetMultiStroke(struct SingleLine *sl, PageItem *Item)
1725
 
{
1726
 
        QString tmp = "fill:none; ";
1727
 
        tmp += "stroke:"+SetColor(sl->Color, sl->Shade)+"; ";
1728
 
        if (Item->fillTransparency() != 0)
1729
 
                tmp += QString(" stroke-opacity:%1; ").arg(1.0 - Item->fillTransparency());
1730
 
        tmp += QString("stroke-width:%1; ").arg(sl->Width);
1731
 
        tmp += "stroke-linecap:";
1732
 
        switch (static_cast<Qt::PenCapStyle>(sl->LineEnd))
1733
 
                {
1734
 
                case Qt::FlatCap:
1735
 
                        tmp += "butt;";
1736
 
                        break;
1737
 
                case Qt::SquareCap:
1738
 
                        tmp += "square;";
1739
 
                        break;
1740
 
                case Qt::RoundCap:
1741
 
                        tmp += "round;";
1742
 
                        break;
1743
 
                default:
1744
 
                        tmp += "butt;";
1745
 
                        break;
1746
 
                }
1747
 
        tmp += " stroke-linejoin:";
1748
 
        switch (static_cast<Qt::PenJoinStyle>(sl->LineJoin))
1749
 
                {
1750
 
                case Qt::MiterJoin:
1751
 
                        tmp += "miter;";
1752
 
                        break;
1753
 
                case Qt::BevelJoin:
1754
 
                        tmp += "bevel;";
1755
 
                        break;
1756
 
                case Qt::RoundJoin:
1757
 
                        tmp += "round;";
1758
 
                        break;
1759
 
                default:
1760
 
                        tmp += "miter;";
1761
 
                        break;
1762
 
                }
1763
 
        tmp += " stroke-dasharray:";
1764
 
        if (static_cast<Qt::PenStyle>(sl->Dash) == Qt::SolidLine)
1765
 
                tmp += "none;";
1766
 
        else
1767
 
        {
1768
 
                QString Da = getDashString(sl->Dash, sl->Width);
1769
 
                if (Da.isEmpty())
1770
 
                        tmp += "none;";
1771
 
                else
1772
 
                        tmp += Da.replace(" ", ", ")+";";
1773
 
        }
1774
 
        return tmp;
1775
 
}
1776
 
 
1777
 
SVGExPlug::~SVGExPlug()
1778
 
{
1779
 
}