~ubuntu-branches/ubuntu/maverick/scribus-ng/maverick-backports

« back to all changes in this revision

Viewing changes to scribus/plugins/svgexplugin/svgexplugin.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Oleksandr Moskalenko
  • Date: 2009-02-09 09:25:18 UTC
  • mfrom: (5.1.4 sid)
  • Revision ID: james.westby@ubuntu.com-20090209092518-iqsxmh3pjspgrdyd
Tags: 1.3.5.dfsg~svn20090208-2
debian/control: Use "type-handling -n arm,armel,armeb any" to generate the
list of architectures to build on.

Show diffs side-by-side

added added

removed removed

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