Subversion Repositories Scribus

Rev

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