Subversion Repositories Scribus

Rev

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