Subversion Repositories Scribus

Rev

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

Rev Author Line No. Line
4430 cbradney 1
/*
2
For general Scribus (>=1.3.2) copyright and licensing information please refer
3
to the COPYING file provided with the program. Following this notice may exist
4
a copyright and/or license notice that predates the release of Scribus 1.3.2
5
for which a new license (GPL+exception) is in place.
6
*/
290 Franz 7
#include "importps.h"
8
#include "importps.moc"
2688 craig 9
 
10
#include "scconfig.h"
3207 craig 11
#include "scribus.h"
5243 cbradney 12
#include "scribuscore.h"
4546 subik 13
#include "commonstrings.h"
290 Franz 14
#include "customfdialog.h"
15
#include "mpalette.h"
415 Franz 16
#include "prefsfile.h"
2523 craig 17
#include "prefscontext.h"
5243 cbradney 18
#include "prefsmanager.h"
2523 craig 19
#include "prefstable.h"
290 Franz 20
#include "scribusXml.h"
21
#include <qfile.h>
22
#include <qtextstream.h>
23
#include <qcursor.h>
1525 cbradney 24
#include <qdragobject.h>
4167 fschmid 25
#include <qregexp.h>
290 Franz 26
#include <cmath>
27
#include <cstdlib>
4930 cbradney 28
 
29
#include "multiprogressdialog.h"
1693 craig 30
#include "scpaths.h"
2529 craig 31
#include "scfontmetrics.h"
3934 cbradney 32
#include "selection.h"
4930 cbradney 33
#include "prefsmanager.h"
34
#include "undomanager.h"
2529 craig 35
#include "util.h"
290 Franz 36
 
5346 mrdocs 37
extern SCRIBUS_API ScribusQApp * ScQApp;
4645 subik 38
 
4999 avox 39
EPSPlug::EPSPlug(QString fName, bool isInteractive, bool showProgress)
290 Franz 40
{
3207 craig 41
        interactive = isInteractive;
4923 avox 42
        cancel = false;
290 Franz 43
        double x, y, b, h, c, m, k;
44
        bool ret = false;
45
        bool found = false;
46
        CustColors.clear();
47
        QFileInfo fi = QFileInfo(fName);
48
        QString ext = fi.extension(false).lower();
5243 cbradney 49
        if ( !ScCore->usingGUI() ) {
4999 avox 50
                interactive = false;
51
                showProgress = false;
52
        }
53
        if ( showProgress ) {
54
                progressDialog = new MultiProgressDialog(tr("Importing PostScript"), CommonStrings::tr_Cancel, ScMW, "psexportprogress");
4923 avox 55
                QStringList barNames, barTexts;
56
                barNames << "GI";
4949 cbradney 57
                barTexts << tr("Analyzing PostScript:");
5370 cbradney 58
                QValueList<bool> barsNumeric;
59
                barsNumeric << false;
60
                progressDialog->addExtraProgressBars(barNames, barTexts, barsNumeric);
4923 avox 61
                progressDialog->setOverallTotalSteps(3);
62
                progressDialog->setOverallProgress(0);
63
                progressDialog->setProgress("GI", 0);
64
                progressDialog->show();
65
                connect(progressDialog->buttonCancel, SIGNAL(clicked()), this, SLOT(cancelRequested()));
5243 cbradney 66
                qApp->processEvents();
4923 avox 67
        }
4999 avox 68
        else {
69
                progressDialog = NULL;
70
        }
4923 avox 71
 
319 Franz 72
/* Set default Page to size defined in Preferences */
290 Franz 73
        x = 0.0;
74
        y = 0.0;
2834 cbradney 75
        b = PrefsManager::instance()->appPrefs.PageWidth;
76
        h = PrefsManager::instance()->appPrefs.PageHeight;
290 Franz 77
        if ((ext == "eps") || (ext == "ps"))
78
        {
4000 fschmid 79
                QString tmp, BBox, tmp2, FarNam;
2886 fschmid 80
                ScColor cc;
290 Franz 81
                QFile f(fName);
82
                if (f.open(IO_ReadOnly))
83
                {
84
/* Try to find Bounding Box */
85
                        QTextStream ts(&f);
86
                        while (!ts.atEnd())
87
                        {
4000 fschmid 88
                                tmp = ts.readLine();
290 Franz 89
                                if (tmp.startsWith("%%BoundingBox:"))
90
                                {
91
                                        found = true;
92
                                        BBox = tmp.remove("%%BoundingBox:");
93
                                }
94
                                if (!found)
95
                                {
96
                                        if (tmp.startsWith("%%BoundingBox"))
97
                                        {
98
                                                found = true;
99
                                                BBox = tmp.remove("%%BoundingBox");
100
                                        }
101
                                }
102
/* Read CustomColors if available */
103
                                if (tmp.startsWith("%%CMYKCustomColor"))
104
                                {
4170 fschmid 105
                                        tmp = tmp.remove(0,18);
290 Franz 106
                                        QTextStream ts2(&tmp, IO_ReadOnly);
4000 fschmid 107
                                        ts2 >> c >> m >> y >> k;
290 Franz 108
                                        FarNam = ts2.read();
109
                                        FarNam = FarNam.stripWhiteSpace();
110
                                        FarNam = FarNam.remove(0,1);
111
                                        FarNam = FarNam.remove(FarNam.length()-1,1);
4167 fschmid 112
                                        QRegExp badchars("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]");
113
                                        FarNam = FarNam.simplifyWhiteSpace().replace( badchars, "_" );
2886 fschmid 114
                                        cc = ScColor(static_cast<int>(255 * c), static_cast<int>(255 * m), static_cast<int>(255 * y), static_cast<int>(255 * k));
4000 fschmid 115
                                        cc.setSpotColor(true);
290 Franz 116
                                        CustColors.insert(FarNam, cc);
117
                                        while (!ts.atEnd())
118
                                        {
4000 fschmid 119
                                                tmp = ts.readLine();
290 Franz 120
                                                if (!tmp.startsWith("%%+"))
121
                                                        break;
4000 fschmid 122
                                                tmp = tmp.remove(0,3);
290 Franz 123
                                                QTextStream ts2(&tmp, IO_ReadOnly);
4000 fschmid 124
                                                ts2 >> c >> m >> y >> k;
290 Franz 125
                                                FarNam = ts2.read();
126
                                                FarNam = FarNam.stripWhiteSpace();
127
                                                FarNam = FarNam.remove(0,1);
128
                                                FarNam = FarNam.remove(FarNam.length()-1,1);
4170 fschmid 129
                                                QRegExp badchars("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]");
130
                                                FarNam = FarNam.simplifyWhiteSpace().replace( badchars, "_" );
2886 fschmid 131
                                                cc = ScColor(static_cast<int>(255 * c), static_cast<int>(255 * m), static_cast<int>(255 * y), static_cast<int>(255 * k));
4000 fschmid 132
                                                cc.setSpotColor(true);
290 Franz 133
                                                CustColors.insert(FarNam, cc);
134
                                        }
135
                                }
136
                                if (tmp.startsWith("%%EndComments"))
137
                                        break;
138
                        }
139
                        f.close();
140
                        if (found)
141
                        {
319 Franz 142
                                QStringList bb = QStringList::split(" ", BBox);
143
                                if (bb.count() == 4)
144
                                {
145
                                        QTextStream ts2(&BBox, IO_ReadOnly);
146
                                        ts2 >> x >> y >> b >> h;
147
                                }
290 Franz 148
                        }
149
                }
150
        }
3207 craig 151
        if (!interactive)
290 Franz 152
        {
4026 craig 153
                ScMW->doc->setPage(b-x, h-y, 0, 0, 0, 0, 0, 0, false, false);
154
                ScMW->doc->addPage(0);
155
                ScMW->view->addPage(0, true);
290 Franz 156
        }
506 fschmid 157
        else
158
        {
4026 craig 159
                if (!ScMW->HaveDoc)
506 fschmid 160
                {
4026 craig 161
                        ScMW->doFileNew(b-x, h-y, 0, 0, 0, 0, 0, 0, false, false, 0, false, 0, 1, "Custom");
4268 fschmid 162
                        ScMW->HaveNewDoc();
506 fschmid 163
                        ret = true;
164
                }
165
        }
3207 craig 166
        if ((ret) || (!interactive))
550 fschmid 167
        {
168
                if (b-x > h-y)
4026 craig 169
                        ScMW->doc->PageOri = 1;
550 fschmid 170
                else
4026 craig 171
                        ScMW->doc->PageOri = 0;
172
                ScMW->doc->PageSize = "Custom";
550 fschmid 173
        }
1065 cbradney 174
        ColorList::Iterator it;
4026 craig 175
        ScribusDoc* Doku = ScMW->doc;
290 Franz 176
        for (it = CustColors.begin(); it != CustColors.end(); ++it)
177
        {
178
                if (!Doku->PageColors.contains(it.key()))
179
                        Doku->PageColors.insert(it.key(), it.data());
180
        }
181
        Elements.clear();
2880 fschmid 182
        FPoint minSize = Doku->minCanvasCoordinate;
183
        FPoint maxSize = Doku->maxCanvasCoordinate;
2891 cbradney 184
        Doku->setLoading(true);
290 Franz 185
        Doku->DoDrawing = false;
4026 craig 186
        ScMW->view->setUpdatesEnabled(false);
187
        ScMW->ScriptRunning = true;
290 Franz 188
        qApp->setOverrideCursor(QCursor(waitCursor), true);
189
        QString CurDirP = QDir::currentDirPath();
190
        QDir::setCurrent(fi.dirPath());
191
        if (convert(fName, x, y, b, h))
192
        {
4847 cbradney 193
                Doku->m_Selection->clear();
290 Franz 194
                QDir::setCurrent(CurDirP);
3207 craig 195
                if ((Elements.count() > 1) && (interactive))
290 Franz 196
                {
197
                        for (uint a = 0; a < Elements.count(); ++a)
198
                        {
199
                                Elements.at(a)->Groups.push(Doku->GroupCounter);
200
                        }
201
                        Doku->GroupCounter++;
202
                }
203
                Doku->DoDrawing = true;
4026 craig 204
                ScMW->view->setUpdatesEnabled(true);
205
                ScMW->ScriptRunning = false;
2891 cbradney 206
                Doku->setLoading(false);
290 Franz 207
                qApp->setOverrideCursor(QCursor(arrowCursor), true);
3207 craig 208
                if ((Elements.count() > 0) && (!ret) && (interactive))
290 Franz 209
                {
210
                        Doku->DragP = true;
211
                        Doku->DraggedElem = 0;
212
                        Doku->DragElements.clear();
213
                        for (uint dre=0; dre<Elements.count(); ++dre)
214
                        {
215
                                Doku->DragElements.append(Elements.at(dre)->ItemNr);
4847 cbradney 216
                                Doku->m_Selection->addItem(Elements.at(dre));
290 Franz 217
                        }
4302 avox 218
                        ScMW->view->setGroupRect();
290 Franz 219
                        ScriXmlDoc *ss = new ScriXmlDoc();
4026 craig 220
                        //QDragObject *dr = new QTextDrag(ss->WriteElem(&ScMW->view->SelItem, Doku, ScMW->view), ScMW->view->viewport());
4847 cbradney 221
                        QDragObject *dr = new QTextDrag(ss->WriteElem(Doku, ScMW->view, Doku->m_Selection),ScMW->view->viewport());
4302 avox 222
#ifndef QT_MAC
4546 subik 223
// see #2196
4707 cbradney 224
                        Doku->itemSelection_DeleteItem();
4302 avox 225
#endif
4593 cbradney 226
                        ScMW->view->resizeContents(qRound((maxSize.x() - minSize.x()) * ScMW->view->scale()), qRound((maxSize.y() - minSize.y()) * ScMW->view->scale()));
227
                        ScMW->view->scrollBy(qRound((Doku->minCanvasCoordinate.x() - minSize.x()) * ScMW->view->scale()), qRound((Doku->minCanvasCoordinate.y() - minSize.y()) * ScMW->view->scale()));
2880 fschmid 228
                        Doku->minCanvasCoordinate = minSize;
229
                        Doku->maxCanvasCoordinate = maxSize;
4026 craig 230
                        ScMW->view->updateContents();
290 Franz 231
                        dr->setPixmap(loadIcon("DragPix.xpm"));
4302 avox 232
#if 0
233
                        qDebug("psimport: data");
234
                        QString data(dr->encodedData("text/plain"));
235
                        for (uint i=0; i <= data.length() / 4000; i++) {
236
                                qDebug(data.mid(i*4000, 4000));
237
                        }
238
                        qDebug("psimport: enddata");
239
                        qDebug(QString("psimport: drag type %1").arg(dr->format()));
240
#endif
241
                        if (!dr->drag())
242
                                qDebug("psimport: couldn't start dragging!");
290 Franz 243
                        delete ss;
244
                        Doku->DragP = false;
245
                        Doku->DraggedElem = 0;
246
                        Doku->DragElements.clear();
247
                }
248
                else
357 Franz 249
                {
2891 cbradney 250
                        Doku->setModified(false);
4026 craig 251
                        ScMW->slotDocCh();
357 Franz 252
                }
290 Franz 253
        }
254
        else
255
        {
256
                QDir::setCurrent(CurDirP);
257
                Doku->DoDrawing = true;
4026 craig 258
                ScMW->view->setUpdatesEnabled(true);
259
                ScMW->ScriptRunning = false;
290 Franz 260
                qApp->setOverrideCursor(QCursor(arrowCursor), true);
261
        }
3207 craig 262
        if (interactive)
2891 cbradney 263
                Doku->setLoading(false);
5004 cbradney 264
        //CB If we have a gui we must refresh it if we have used the progressbar
265
        if (showProgress)
266
                ScMW->view->DrawNew();
290 Franz 267
}
268
 
269
bool EPSPlug::convert(QString fn, double x, double y, double b, double h)
270
{
4194 fschmid 271
        QStringList args;
272
        QString cmd, cmd1, cmd2, cmd3, tmp, tmp2, tmp3, tmp4;
3120 fschmid 273
        // import.prolog do not cope with filenames containing blank spaces
274
        // so take care that output filename does not (win32 compatibility)
5243 cbradney 275
        QString tmpFile = getShortPathName(PrefsManager::instance()->preferencesLocation())+ "/ps.out";
276
        QString errFile = getShortPathName(PrefsManager::instance()->preferencesLocation())+ "/ps.err";
1693 craig 277
        QString pfad = ScPaths::instance().libDir();
3120 fschmid 278
        QString pfad2 = QDir::convertSeparators(pfad + "import.prolog");
1735 fschmid 279
        QFileInfo fi = QFileInfo(fn);
280
        QString ext = fi.extension(false).lower();
4923 avox 281
 
282
        if (progressDialog) {
283
                progressDialog->setOverallProgress(1);
5243 cbradney 284
                qApp->processEvents();
4923 avox 285
        }
4194 fschmid 286
        args.append( getShortPathName(PrefsManager::instance()->ghostscriptExecutable()) );
287
        args.append( "-q" );
288
        args.append( "-dNOPAUSE" );
4745 avox 289
        args.append( "-sDEVICE=nullpage" );
4194 fschmid 290
        args.append( "-dBATCH" );
4978 avox 291
        args.append( "-dDELAYBIND" );
2523 craig 292
        // Add any extra font paths being used by Scribus to gs's font search
293
        // path We have to use Scribus's prefs context, not a plugin context, to
294
        // get to the required information.
2856 cbradney 295
        PrefsContext *pc = PrefsManager::instance()->prefsFile->getContext("Fonts");
2523 craig 296
        PrefsTable *extraFonts = pc->getTable("ExtraFontDirs");
4194 fschmid 297
        const char sep = ScPaths::envPathSeparator;
2523 craig 298
        if (extraFonts->getRowCount() >= 1)
4194 fschmid 299
                cmd = QString("-sFONTPATH=%1").arg(extraFonts->get(0,0));
2523 craig 300
        for (int i = 1; i < extraFonts->getRowCount(); ++i)
4194 fschmid 301
                cmd += QString("%1%2").arg(sep).arg(extraFonts->get(i,0));
302
        if( !cmd.isEmpty() )
303
                args.append( cmd );
2523 craig 304
        // then finish building the command and call gs
4788 avox 305
        args.append( QString("-g%1x%2").arg(tmp2.setNum(qRound((b-x)*4))).arg(tmp3.setNum(qRound((h-y)*4))) );
306
        args.append( "-r288");
307
        args.append( "-dTextAlphaBits=4" );
308
        args.append( "-dGraphicsAlphaBits=4" );
4194 fschmid 309
        args.append( "-c" );
310
        args.append( tmp.setNum(-x) );
311
        args.append( tmp.setNum(-y) );
312
        args.append( "translate" );
4740 avox 313
        args.append( QString("-sTraceFile=%1").arg(QDir::convertSeparators(tmpFile)) );
4801 avox 314
        QString exportPath = ScMW->doc->DocName + "-" + fi.baseName();
315
        QFileInfo exportFi(exportPath);
316
        if ( !exportFi.isWritable() ) {
317
                PrefsContext* docContext = PrefsManager::instance()->prefsFile->getContext("docdirs", false);
318
                QString docDir = ".";
319
                QString prefsDocDir=PrefsManager::instance()->documentDir();
320
                if (!prefsDocDir.isEmpty())
321
                        docDir = docContext->get("docsopen", prefsDocDir);
322
                else
323
                        docDir = docContext->get("docsopen", ".");             
324
                exportFi.setFile(docDir + "/" + exportFi.baseName());
325
        }
4867 cbradney 326
        //qDebug(QString("using export path %1").arg(exportFi.absFilePath()));
4801 avox 327
        args.append( QString("-sExportFiles=%1").arg(QDir::convertSeparators(exportFi.absFilePath())) );
4194 fschmid 328
        args.append( pfad2 );
329
        args.append( QDir::convertSeparators(fn) );
330
        args.append( "-c" );
331
        args.append( "flush" );
332
        args.append( "cfile" );
333
        args.append( "closefile" );
334
        args.append( "quit" );
335
        QCString finalCmd = args.join(" ").local8Bit();
4801 avox 336
        int ret = System(args, errFile, errFile);
290 Franz 337
        if (ret != 0)
338
        {
2791 craig 339
                qDebug("PostScript import failed when calling gs as: \n%s\n", finalCmd.data());
4725 avox 340
                qDebug("Ghostscript diagnostics:\n");
4801 avox 341
                QFile diag(errFile);
342
                if (diag.open(IO_ReadOnly) && !diag.atEnd() ) {
4725 avox 343
                        QString line;
4801 avox 344
                        while (diag.readLine(line, 120) > 0) {
345
                                qDebug("\t%s", line.ascii());
4725 avox 346
                        }
347
                        diag.close();
348
                }
349
                else {
350
                        qDebug("-- no output --");
351
                }
290 Franz 352
                QString mess = tr("Importing File:\n%1\nfailed!").arg(fn);
353
                QMessageBox::critical(0, tr("Fatal Error"), mess, 1, 0, 0);
354
                return false;
355
        }
4923 avox 356
        if(progressDialog) {
357
                progressDialog->setOverallProgress(2);
358
                progressDialog->setLabel("GI", tr("Generating Items"));
5243 cbradney 359
                qApp->processEvents();
4923 avox 360
        }
361
        if (!cancel) {
362
                parseOutput(tmpFile, ext == "eps");
363
        }
2921 fschmid 364
        QFile::remove(tmpFile);
4923 avox 365
        if (progressDialog)
366
                progressDialog->close();
290 Franz 367
        return true;
368
}
369
 
1735 fschmid 370
void EPSPlug::parseOutput(QString fn, bool eps)
290 Franz 371
{
372
        QString tmp, token, params, lasttoken, lastPath, currPath;
537 fschmid 373
        int z, lcap, ljoin, dc, pagecount;
4962 avox 374
        int failedImages = 0;
319 Franz 375
        double dcp;
4770 avox 376
        bool fillRuleEvenOdd = true;
290 Franz 377
        PageItem* ite;
378
        QFile f(fn);
379
        lasttoken = "";
537 fschmid 380
        pagecount = 1;
290 Franz 381
        if (f.open(IO_ReadOnly))
382
        {
4923 avox 383
                if (progressDialog) {
384
                        progressDialog->setTotalSteps("GI", (int) f.size());
5243 cbradney 385
                        qApp->processEvents();
4923 avox 386
                }
290 Franz 387
                lastPath = "";
388
                currPath = "";
389
                LineW = 0;
390
                Opacity = 1;
4546 subik 391
                CurrColor = CommonStrings::None;
292 Franz 392
                JoinStyle = MiterJoin;
393
                CapStyle = FlatCap;
394
                DashPattern.clear();
290 Franz 395
                QTextStream ts(&f);
4923 avox 396
                int line_cnt = 0;
397
                while (!ts.atEnd() && !cancel)
290 Franz 398
                {
399
                        tmp = "";
400
                        tmp = ts.readLine();
4923 avox 401
                        if (progressDialog && (++line_cnt % 100 == 0)) {
402
                                progressDialog->setProgress("GI", (int) f.at());
5243 cbradney 403
                                qApp->processEvents();
4923 avox 404
                        }
4801 avox 405
                        token = tmp.section(' ', 0, 0);
406
                        params = tmp.section(' ', 1, -1, QString::SectionIncludeTrailingSep);
5006 avox 407
                        if (lasttoken == "sp"  && !eps && token != "sp" ) //av: messes up anyway: && (!interactive))
537 fschmid 408
                        {
4026 craig 409
                                ScMW->doc->addPage(pagecount);
410
                                ScMW->view->addPage(pagecount, true);
537 fschmid 411
                                pagecount++;
412
                        }
290 Franz 413
                        if (token == "n")
414
                        {
415
                                Coords.resize(0);
416
                                FirstM = true;
417
                                WasM = false;
418
                                ClosedPath = false;
419
                        }
420
                        else if (token == "m")
421
                                WasM = true;
422
                        else if (token == "c")
423
                        {
424
                                Curve(&Coords, params);
425
                                currPath += params;
426
                        }
427
                        else if (token == "l")
428
                        {
429
                                LineTo(&Coords, params);
430
                                currPath += params;
431
                        }
4770 avox 432
                        else if (token == "fill-winding")
433
                        {
434
                                fillRuleEvenOdd = false;
435
                        }
436
                        else if (token == "fill-evenodd")
437
                        {
438
                                fillRuleEvenOdd = true;
439
                        }
290 Franz 440
                        else if (token == "f")
441
                        {
4770 avox 442
                                //TODO: pattern -> Imageframe + Clip
290 Franz 443
                                if (Coords.size() != 0)
444
                                {
445
                                        if ((Elements.count() != 0) && (lastPath == currPath))
446
                                        {
447
                                                ite = Elements.at(Elements.count()-1);
1394 cbradney 448
                                                ite->setFillColor(CurrColor);
449
                                                ite->setFillTransparency(1.0 - Opacity);
290 Franz 450
                                        }
451
                                        else
452
                                        {
453
                                                if (ClosedPath)
4546 subik 454
                                                        z = ScMW->doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, 0, 0, 10, 10, LineW, CurrColor, CommonStrings::None, true);
290 Franz 455
                                                else
4546 subik 456
                                                        z = ScMW->doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, 0, 0, 10, 10, LineW, CurrColor, CommonStrings::None, true);
4026 craig 457
                                                ite = ScMW->doc->Items->at(z);
4801 avox 458
                                                ite->PoLine = Coords.copy();  //FIXME: try to avoid copy if FPointArray when properly shared
5087 subik 459
                                                ite->PoLine.translate(ScMW->doc->currentPage()->xOffset(), ScMW->doc->currentPage()->yOffset());
290 Franz 460
                                                ite->ClipEdited = true;
461
                                                ite->FrameType = 3;
4770 avox 462
                                                ite->fillRule = (fillRuleEvenOdd);
1065 cbradney 463
                                                FPoint wh = getMaxClipF(&ite->PoLine);
3934 cbradney 464
                                                ite->setWidthHeight(wh.x(),wh.y());
290 Franz 465
                                                ite->Clip = FlattenPath(ite->PoLine, ite->Segments);
1394 cbradney 466
                                                ite->setFillTransparency(1.0 - Opacity);
4026 craig 467
                                                ScMW->view->AdjustItemSize(ite);
290 Franz 468
                                                Elements.append(ite);
469
                                        }
470
                                        lastPath = currPath;
471
                                        currPath = "";
472
                                }
473
                        }
474
                        else if (token == "s")
475
                        {
476
                                if (Coords.size() != 0)
477
                                {
478
                                        LineW = QMAX(LineW, 0.1); // Set Linewidth to be a least 0.1 pts, a Stroke without a Linewidth makes no sense
479
                                        if ((Elements.count() != 0) && (lastPath == currPath))
480
                                        {
481
                                                ite = Elements.at(Elements.count()-1);
1394 cbradney 482
                                                ite->setLineColor(CurrColor);
4580 cbradney 483
                                                ite->setLineWidth(LineW);
292 Franz 484
                                                ite->PLineEnd = CapStyle;
485
                                                ite->PLineJoin = JoinStyle;
1394 cbradney 486
                                                ite->setLineTransparency(1.0 - Opacity);
292 Franz 487
                                                ite->DashOffset = DashOffset;
488
                                                ite->DashValues = DashPattern;
290 Franz 489
                                        }
490
                                        else
491
                                        {
4026 craig 492
                                                ScribusDoc* Doku = ScMW->doc;
290 Franz 493
                                                if (ClosedPath)
4546 subik 494
                                                        z = Doku->itemAdd(PageItem::Polygon, PageItem::Unspecified, 0, 0, 10, 10, LineW, CommonStrings::None, CurrColor, true);
290 Franz 495
                                                else
4546 subik 496
                                                        z = Doku->itemAdd(PageItem::PolyLine, PageItem::Unspecified, 0, 0, 10, 10, LineW, CommonStrings::None, CurrColor, true);
3727 cbradney 497
                                                ite = Doku->Items->at(z);
4801 avox 498
                                                ite->PoLine = Coords.copy(); //FIXME: try to avoid copy when FPointArray is properly shared
5087 subik 499
                                                ite->PoLine.translate(Doku->currentPage()->xOffset(), Doku->currentPage()->yOffset());
290 Franz 500
                                                ite->ClipEdited = true;
501
                                                ite->FrameType = 3;
292 Franz 502
                                                ite->PLineEnd = CapStyle;
503
                                                ite->PLineJoin = JoinStyle;
504
                                                ite->DashOffset = DashOffset;
505
                                                ite->DashValues = DashPattern;
1065 cbradney 506
                                                FPoint wh = getMaxClipF(&ite->PoLine);
3934 cbradney 507
                                                ite->setWidthHeight(wh.x(), wh.y());
290 Franz 508
                                                ite->Clip = FlattenPath(ite->PoLine, ite->Segments);
1394 cbradney 509
                                                ite->setLineTransparency(1.0 - Opacity);
4026 craig 510
                                                ScMW->view->AdjustItemSize(ite);
290 Franz 511
                                                Elements.append(ite);
512
                                        }
513
                                        lastPath = currPath;
514
                                        currPath = "";
515
                                }
516
                        }
517
                        else if (token == "co")
518
                                CurrColor = parseColor(params);
1488 fschmid 519
                        else if (token == "corgb")
520
                                CurrColor = parseColor(params, colorModelRGB);
290 Franz 521
                        else if (token == "ci")
522
                        {
4923 avox 523
                                clipCoords = Coords;
524
                                Coords   = FPointArray(0);
290 Franz 525
                                lastPath = "";
526
                                currPath = "";
527
                        }
528
                        else if (token == "w")
529
                        {
530
                                QTextStream Lw(&params, IO_ReadOnly);
531
                                Lw >> LineW;
532
                                currPath += params;
533
                        }
292 Franz 534
                        else if (token == "ld")
535
                        {
536
                                QTextStream Lw(&params, IO_ReadOnly);
537
                                Lw >> dc;
538
                                Lw >> DashOffset;
539
                                DashPattern.clear();
540
                                if (dc != 0)
541
                                {
542
                                        for (int dcc = 0; dcc < dc; ++dcc)
543
                                        {
544
                                                Lw >> dcp;
545
                                                DashPattern.append(dcp);
546
                                        }
547
                                }
548
                                currPath += params;
549
                        }
550
                        else if (token == "lc")
551
                        {
552
                                QTextStream Lw(&params, IO_ReadOnly);
553
                                Lw >> lcap;
554
                                switch (lcap)
555
                                {
556
                                        case 0:
557
                                                CapStyle = Qt::FlatCap;
558
                                                break;
559
                                        case 1:
560
                                                CapStyle = Qt::RoundCap;
561
                                                break;
562
                                        case 2:
563
                                                CapStyle = Qt::SquareCap;
564
                                                break;
565
                                        default:
566
                                                CapStyle = Qt::FlatCap;
567
                                                break;
568
                                }
569
                                currPath += params;
570
                        }
571
                        else if (token == "lj")
572
                        {
573
                                QTextStream Lw(&params, IO_ReadOnly);
574
                                Lw >> ljoin;
575
                                switch (ljoin)
576
                                {
577
                                        case 0:
578
                                                JoinStyle = Qt::MiterJoin;
579
                                                break;
580
                                        case 1:
581
                                                JoinStyle = Qt::RoundJoin;
582
                                                break;
583
                                        case 2:
584
                                                JoinStyle = Qt::BevelJoin;
585
                                                break;
586
                                        default:
587
                                                JoinStyle = Qt::MiterJoin;
588
                                                break;
589
                                }
590
                                currPath += params;
591
                        }
4717 avox 592
                        else if (token == "cp") {
290 Franz 593
                                ClosedPath = true;
4717 avox 594
                        }
595
                        else if (token == "im") {
4962 avox 596
                                if ( !Image(params) )
597
                                        ++failedImages;
4717 avox 598
                        }
290 Franz 599
                        lasttoken = token;
600
                }
601
                f.close();
602
        }
4962 avox 603
        if (failedImages > 0)
604
        {
605
                QString mess = tr("Converting of %1 images failed!").arg(failedImages);
606
                QMessageBox::critical(0, tr("Error"), mess, 1, 0, 0);
607
        }
290 Franz 608
}
609
 
4962 avox 610
bool EPSPlug::Image(QString vals)
4717 avox 611
{
612
        double x, y, w, h, angle;
613
        int horpix, verpix;
614
        QString filename, device;
615
        QTextStream Code(&vals, IO_ReadOnly);
616
        Code >> x;
617
        Code >> y;
618
        Code >> w;
619
        Code >> h;
620
        Code >> angle;
621
        Code >> horpix;
622
        Code >> verpix;
623
        Code >> device;
4788 avox 624
        filename = Code.read().stripWhiteSpace();
4999 avox 625
        if (device.startsWith("psd")) {
626
                filename = filename.mid(0, filename.length()-3) + "psd";
627
        }
628
 
4717 avox 629
        qDebug(QString("import %6 image %1: %2x%3 @ (%4,%5) °%5").arg(filename).arg(w).arg(h).arg(x).arg(y).arg(angle).arg(device));
630
        QString rawfile = filename.mid(0, filename.length()-3) + "dat";
631
        QStringList args;
632
        args.append( getShortPathName(PrefsManager::instance()->ghostscriptExecutable()) );
633
        args.append( "-q" );
634
        args.append( "-dNOPAUSE" );
635
        args.append( QString("-sDEVICE=%1").arg(device) );    
636
        args.append( "-dBATCH" );
637
        args.append( QString("-g%1x%2").arg(horpix).arg(verpix) );
638
        args.append( QString("-sOutputFile=%1").arg(QDir::convertSeparators(filename)) );
639
        args.append( QDir::convertSeparators(rawfile) );
640
        args.append( "-c" );
641
        args.append( "showpage" );
642
        args.append( "quit" );
643
        QCString finalCmd = args.join(" ").local8Bit();
644
        int ret = System(args);
645
        if (ret != 0)
646
        {
647
                qDebug("PostScript image conversion failed when calling gs as: \n%s\n", finalCmd.data());
4986 avox 648
                qDebug("Ghostscript diagnostics: %d\n", ret);
4725 avox 649
                QFile diag(filename);
650
                if (diag.open(IO_ReadOnly)) {
651
                        QString line;
4740 avox 652
                        long int len;
653
                        bool gs_error = false;
654
                        do {
655
                                len = diag.readLine(line, 120);
656
                                gs_error |= line.contains("Error");
657
                                if (gs_error)
658
                                        qDebug("\t%s", line.ascii());
4725 avox 659
                        }
4740 avox 660
                        while (len > 0);
4725 avox 661
                        diag.close();
4983 avox 662
                        }
4725 avox 663
                else {
664
                        qDebug("-- no output --");
665
                }
4983 avox 666
                qDebug("Failed file was:\n");
667
                QFile dat(rawfile);
668
                if (dat.open(IO_ReadOnly)) {
669
                        QString line;
670
                        long int len;
671
                        do {
672
                                len = dat.readLine(line, 120);
673
                                qDebug("\t%s", line.ascii());
674
                        }
4986 avox 675
                        while ( len > 0 && !line.contains("image") );
4983 avox 676
                        dat.close();
677
                }
678
                else {
679
                        qDebug("-- empty --");
680
                }
4717 avox 681
        }
4923 avox 682
        QFile::remove(rawfile);
4717 avox 683
        int z = ScMW->doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, 0, 0, w, h, LineW, CommonStrings::None, CurrColor, true);
684
        PageItem * ite = ScMW->doc->Items->at(z);
5087 subik 685
        ite->setXYPos(ScMW->doc->currentPage()->xOffset() + x, ScMW->doc->currentPage()->yOffset() + y);
4717 avox 686
        ite->setWidthHeight(w, h);
687
        ite->clearContents();
688
/*      FPoint a(x, y);
689
        FPoint b(x+w, y);
690
        FPoint c(x+w, y-h);
691
        FPoint d(x, y-h);
692
        ite->PoLine.resize(0);
693
        ite->PoLine.addQuadPoint(a, a, b, b);
694
        ite->PoLine.addQuadPoint(b, b, c, c);
695
        ite->PoLine.addQuadPoint(c, c, d, d);
696
        ite->PoLine.addQuadPoint(d, d, a, a);
4976 avox 697
        ite->PoLine.translate(ScMW->doc->currentPage->xOffset() - x, ScMW->doc->currentPage->yOffset() - y);
4717 avox 698
        ite->ClipEdited = true;
699
        ite->Clip = FlattenPath(ite->PoLine, ite->Segments);
4976 avox 700
*/
701
        ScMW->doc->loadPict(filename, ite, -1);
4717 avox 702
        ite->setRotation(angle);
703
        ite->setImageScalingMode(false, true); // fit to frame, keep ratio
704
//      ScMW->view->AdjustItemSize(ite);
4962 avox 705
        Elements.append(ite);
706
        return ret == 0;
4717 avox 707
}
708
 
709
 
290 Franz 710
void EPSPlug::LineTo(FPointArray *i, QString vals)
711
{
2877 cbradney 712
        if (vals.isEmpty())
290 Franz 713
                return;
714
        double x1, x2, y1, y2;
4801 avox 715
        x1 = vals.section(' ', 0, 0, QString::SectionSkipEmpty).toDouble();
716
        y1 = vals.section(' ', 1, 1, QString::SectionSkipEmpty).toDouble();
717
        x2 = vals.section(' ', 2, 2, QString::SectionSkipEmpty).toDouble();
718
        y2 = vals.section(' ', 3, 3, QString::SectionSkipEmpty).toDouble();
290 Franz 719
        if ((!FirstM) && (WasM))
720
                i->setMarker();
721
        FirstM = false;
722
        WasM = false;
723
        i->addPoint(FPoint(x1, y1));
724
        i->addPoint(FPoint(x1, y1));
725
        i->addPoint(FPoint(x2, y2));
726
        i->addPoint(FPoint(x2, y2));
727
}
728
 
729
void EPSPlug::Curve(FPointArray *i, QString vals)
730
{
2877 cbradney 731
        if (vals.isEmpty())
290 Franz 732
                return;
733
        double x1, x2, y1, y2, x3, y3, x4, y4;
4801 avox 734
        x1 = vals.section(' ', 0, 0, QString::SectionSkipEmpty).toDouble();
735
        y1 = vals.section(' ', 1, 1, QString::SectionSkipEmpty).toDouble();
736
        x2 = vals.section(' ', 2, 2, QString::SectionSkipEmpty).toDouble();
737
        y2 = vals.section(' ', 3, 3, QString::SectionSkipEmpty).toDouble();
738
        x3 = vals.section(' ', 4, 4, QString::SectionSkipEmpty).toDouble();
739
        y3 = vals.section(' ', 5, 5, QString::SectionSkipEmpty).toDouble();
740
        x4 = vals.section(' ', 6, 6, QString::SectionSkipEmpty).toDouble();
741
        y4 = vals.section(' ', 7, 7, QString::SectionSkipEmpty).toDouble();
290 Franz 742
        if ((!FirstM) && (WasM))
743
                i->setMarker();
744
        FirstM = false;
745
        WasM = false;
746
        i->addPoint(FPoint(x1, y1));
747
        i->addPoint(FPoint(x2, y2));
748
        i->addPoint(FPoint(x4, y4));
749
        i->addPoint(FPoint(x3, y3));
750
}
751
 
1488 fschmid 752
QString EPSPlug::parseColor(QString vals, colorModel model)
290 Franz 753
{
4026 craig 754
        ScribusDoc* Doku = ScMW->doc;
4546 subik 755
        QString ret = CommonStrings::None;
2877 cbradney 756
        if (vals.isEmpty())
290 Franz 757
                return ret;
1488 fschmid 758
        double c, m, y, k, r, g, b;
2886 fschmid 759
        ScColor tmp;
1488 fschmid 760
        ColorList::Iterator it;
290 Franz 761
        QTextStream Code(&vals, IO_ReadOnly);
762
        bool found = false;
1488 fschmid 763
        if (model == colorModelRGB)
290 Franz 764
        {
1488 fschmid 765
                Code >> r;
766
                Code >> g;
767
                Code >> b;
768
                Code >> Opacity;
769
                int Rc = static_cast<int>(r * 255 + 0.5);
770
                int Gc = static_cast<int>(g * 255 + 0.5);
771
                int Bc = static_cast<int>(b * 255 + 0.5);
772
                int hR, hG, hB;
773
                tmp.setColorRGB(Rc, Gc, Bc);
774
                for (it = Doku->PageColors.begin(); it != Doku->PageColors.end(); ++it)
290 Franz 775
                {
1488 fschmid 776
                        Doku->PageColors[it.key()].getRGB(&hR, &hG, &hB);
777
                        if ((Rc == hR) && (Gc == hG) && (Bc == hB))
778
                        {
779
                                if (Doku->PageColors[it.key()].getColorModel() == colorModelRGB)
780
                                {
781
                                        ret = it.key();
782
                                        found = true;
783
                                }
784
                        }
290 Franz 785
                }
786
        }
1488 fschmid 787
        else
788
        {
789
                Code >> c;
790
                Code >> m;
791
                Code >> y;
792
                Code >> k;
793
                Code >> Opacity;
794
                int Cc = static_cast<int>(c * 255 + 0.5);
795
                int Mc = static_cast<int>(m * 255 + 0.5);
796
                int Yc = static_cast<int>(y * 255 + 0.5);
797
                int Kc = static_cast<int>(k * 255 + 0.5);
798
                int hC, hM, hY, hK;
799
                tmp.setColor(Cc, Mc, Yc, Kc);
800
                for (it = Doku->PageColors.begin(); it != Doku->PageColors.end(); ++it)
801
                {
802
                        Doku->PageColors[it.key()].getCMYK(&hC, &hM, &hY, &hK);
803
                        if ((Cc == hC) && (Mc == hM) && (Yc == hY) && (Kc == hK))
804
                        {
805
                                if (Doku->PageColors[it.key()].getColorModel() == colorModelCMYK)
806
                                {
807
                                        ret = it.key();
808
                                        found = true;
809
                                }
810
                        }
811
                }
812
        }
290 Franz 813
        if (!found)
814
        {
815
                Doku->PageColors.insert("FromEPS"+tmp.name(), tmp);
4026 craig 816
                ScMW->propertiesPalette->updateColorList();
290 Franz 817
                ret = "FromEPS"+tmp.name();
818
        }
819
        return ret;
820
}