Scribus Developer Documentation - API
logo-pen

Scribus Developer Documentation - API

importps.cpp

Go to the documentation of this file.
00001 /*
00002 For general Scribus (>=1.3.2) copyright and licensing information please refer
00003 to the COPYING file provided with the program. Following this notice may exist
00004 a copyright and/or license notice that predates the release of Scribus 1.3.2
00005 for which a new license (GPL+exception) is in place.
00006 */
00007 
00008 #include <QByteArray>
00009 #include <QCursor>
00010 #include <QDrag>
00011 #include <QFile>
00012 #include <QList>
00013 #include <QMimeData>
00014 #include <QRegExp>
00015 #include <QStack>
00016 #include <QStack>
00017 #include <QTextStream>
00018 
00019 #include <cmath>
00020 #include <cstdlib>
00021 
00022 
00023 #include "commonstrings.h"
00024 #include "customfdialog.h"
00025 #include "importps.h"
00026 #include "loadsaveplugin.h"
00027 #include "multiprogressdialog.h"
00028 #include "prefscontext.h"
00029 #include "prefsfile.h"
00030 #include "prefsmanager.h"
00031 #include "prefsmanager.h"
00032 #include "prefstable.h"
00033 #include "propertiespalette.h"
00034 #include "scconfig.h"
00035 #include "scpaths.h"
00036 #include "scribus.h"
00037 #include "scribusXml.h"
00038 #include "scribuscore.h"
00039 #include "selection.h"
00040 #include "undomanager.h"
00041 #include "util.h"
00042 #include "util_formats.h"
00043 #include "util_icon.h"
00044 #include "util_math.h"
00045 
00046 
00047 extern SCRIBUS_API ScribusQApp * ScQApp;
00048 
00049 EPSPlug::EPSPlug(ScribusDoc* doc, int flags)
00050 {
00051     tmpSel=new Selection(this, false);
00052     m_Doc=doc;
00053     interactive = (flags & LoadSavePlugin::lfInteractive);
00054 }
00055 
00056 bool EPSPlug::import(QString fName, int flags, bool showProgress)
00057 {
00058     bool success = false;
00059     interactive = (flags & LoadSavePlugin::lfInteractive);
00060     cancel = false;
00061     double x, y, b, h, c, m, k;
00062     bool ret = false;
00063     bool found = false;
00064     CustColors.clear();
00065     QFileInfo fi = QFileInfo(fName);
00066     QString ext = fi.suffix().toLower();
00067     if ( !ScCore->usingGUI() ) {
00068         interactive = false;
00069         showProgress = false;
00070     }
00071     if ( showProgress ) 
00072     {
00073         ScribusMainWindow* mw=(m_Doc==0) ? ScCore->primaryMainWindow() : m_Doc->scMW();
00074         progressDialog = new MultiProgressDialog( tr("Importing: %1").arg(fi.fileName()), CommonStrings::tr_Cancel, mw);
00075         QStringList barNames, barTexts;
00076         barNames << "GI";
00077         barTexts << tr("Analyzing PostScript:");
00078         QList<bool> barsNumeric;
00079         barsNumeric << false;
00080         progressDialog->addExtraProgressBars(barNames, barTexts, barsNumeric);
00081         progressDialog->setOverallTotalSteps(3);
00082         progressDialog->setOverallProgress(0);
00083         progressDialog->setProgress("GI", 0);
00084         progressDialog->show();
00085         connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelRequested()));
00086         qApp->processEvents();
00087     }
00088     else {
00089         progressDialog = NULL;
00090     }
00091     
00092 /* Set default Page to size defined in Preferences */
00093     x = 0.0;
00094     y = 0.0;
00095     b = PrefsManager::instance()->appPrefs.PageWidth;
00096     h = PrefsManager::instance()->appPrefs.PageHeight;
00097     if (extensionIndicatesEPSorPS(ext))
00098     {
00099         QString tmp, BBox, tmp2, FarNam;
00100         ScColor cc;
00101         QFile f(fName);
00102         if (f.open(QIODevice::ReadOnly))
00103         {
00104 /* Try to find Bounding Box */
00105             QDataStream ts(&f);
00106             while (!ts.atEnd())
00107             {
00108                 tmp = readLinefromDataStream(ts);
00109                 if (tmp.startsWith("%%BoundingBox:"))
00110                 {
00111                     found = true;
00112                     BBox = tmp.remove("%%BoundingBox:");
00113                 }
00114                 if (!found)
00115                 {
00116                     if (tmp.startsWith("%%BoundingBox"))
00117                     {
00118                         found = true;
00119                         BBox = tmp.remove("%%BoundingBox");
00120                     }
00121                 }
00122 /* Read CustomColors if available */
00123                 if (tmp.startsWith("%%CMYKCustomColor"))
00124                 {
00125                     tmp = tmp.remove(0,18);
00126                     QTextStream ts2(&tmp, QIODevice::ReadOnly);
00127                     ts2 >> c >> m >> y >> k;
00128                     FarNam = ts2.readAll();
00129                     FarNam = FarNam.trimmed();
00130                     FarNam = FarNam.remove(0,1);
00131                     FarNam = FarNam.remove(FarNam.length()-1,1);
00132 //                  QRegExp badchars("[\\s\\/\\{\\[\\]\\}\<\>\\(\\)\\%]");
00133 //                  FarNam = FarNam.simplified().replace( badchars, "_" );
00134                     cc = ScColor(qRound(255 * c), qRound(255 * m), qRound(255 * y), qRound(255 * k));
00135                     cc.setSpotColor(true);
00136                     CustColors.insert(FarNam, cc);
00137                     importedColors.append(FarNam);
00138                     while (!ts.atEnd())
00139                     {
00140                         uint oldPos = ts.device()->pos();
00141                         tmp = readLinefromDataStream(ts);
00142                         if (!tmp.startsWith("%%+"))
00143                         {
00144                             ts.device()->seek(oldPos);
00145                             break;
00146                         }
00147                         tmp = tmp.remove(0,3);
00148                         QTextStream ts2(&tmp, QIODevice::ReadOnly);
00149                         ts2 >> c >> m >> y >> k;
00150                         FarNam = ts2.readAll();
00151                         FarNam = FarNam.trimmed();
00152                         FarNam = FarNam.remove(0,1);
00153                         FarNam = FarNam.remove(FarNam.length()-1,1);
00154 //                      QRegExp badchars("[\\s\\/\\{\\[\\]\\}\<\>\\(\\)\\%]");
00155 //                      FarNam = FarNam.simplified().replace( badchars, "_" );
00156                         cc = ScColor(qRound(255 * c), qRound(255 * m), qRound(255 * y), qRound(255 * k));
00157                         cc.setSpotColor(true);
00158                         CustColors.insert(FarNam, cc);
00159                         importedColors.append(FarNam);
00160                     }
00161                 }
00162                 if (tmp.startsWith("%%EndComments"))
00163                     break;
00164             }
00165             f.close();
00166             if (found)
00167             {
00168                 QStringList bb = BBox.split(" ", QString::SkipEmptyParts);
00169                 if (bb.count() == 4)
00170                 {
00171                     QTextStream ts2(&BBox, QIODevice::ReadOnly);
00172                     ts2 >> x >> y >> b >> h;
00173                 }
00174             }
00175         }
00176     }
00177     baseX = 0;
00178     baseY = 0;
00179     if (!interactive || (flags & LoadSavePlugin::lfInsertPage))
00180     {
00181         m_Doc->setPage(b-x, h-y, 0, 0, 0, 0, 0, 0, false, false);
00182         m_Doc->addPage(0);
00183         m_Doc->view()->addPage(0, true);
00184         baseX = 0;
00185         baseY = 0;
00186     }
00187     else
00188     {
00189         if (!m_Doc || (flags & LoadSavePlugin::lfCreateDoc))
00190         {
00191             m_Doc=ScCore->primaryMainWindow()->doFileNew(b-x, h-y, 0, 0, 0, 0, 0, 0, false, false, 0, false, 0, 1, "Custom", true);
00192             ScCore->primaryMainWindow()->HaveNewDoc();
00193             ret = true;
00194             baseX = 0;
00195             baseY = 0;
00196         }
00197     }
00198     if ((!ret) && (interactive))
00199     {
00200         baseX = m_Doc->currentPage()->xOffset();
00201         baseY = m_Doc->currentPage()->yOffset();
00202     }
00203     if ((ret) || (!interactive))
00204     {
00205         if (b-x > h-y)
00206             m_Doc->PageOri = 1;
00207         else
00208             m_Doc->PageOri = 0;
00209         m_Doc->m_pageSize = "Custom";
00210     }
00211     ColorList::Iterator it;
00212     for (it = CustColors.begin(); it != CustColors.end(); ++it)
00213     {
00214         if (!m_Doc->PageColors.contains(it.key()))
00215             m_Doc->PageColors.insert(it.key(), it.value());
00216     }
00217     Elements.clear();
00218     FPoint minSize = m_Doc->minCanvasCoordinate;
00219     FPoint maxSize = m_Doc->maxCanvasCoordinate;
00220     FPoint cOrigin = m_Doc->view()->canvasOrigin();
00221     m_Doc->setLoading(true);
00222     m_Doc->DoDrawing = false;
00223     m_Doc->view()->updatesOn(false);
00224     m_Doc->scMW()->ScriptRunning = true;
00225     qApp->changeOverrideCursor(QCursor(Qt::WaitCursor));
00226     QString CurDirP = QDir::currentPath();
00227     QDir::setCurrent(fi.path());
00228     if (convert(fName, x, y, b, h))
00229     {
00230 //      m_Doc->m_Selection->clear();
00231         tmpSel->clear();
00232         QDir::setCurrent(CurDirP);
00233 //      if ((Elements.count() > 1) && (interactive))
00234         if (Elements.count() > 1)
00235         {
00236             bool isGroup = true;
00237             int firstElem = -1;
00238             if (Elements.at(0)->Groups.count() != 0)
00239                 firstElem = Elements.at(0)->Groups.top();
00240             for (int bx = 0; bx < Elements.count(); ++bx)
00241             {
00242                 PageItem* bxi = Elements.at(bx);
00243                 if (bxi->Groups.count() != 0)
00244                 {
00245                     if (bxi->Groups.top() != firstElem)
00246                         isGroup = false;
00247                 }
00248                 else
00249                     isGroup = false;
00250             }
00251             if (!isGroup)
00252             {
00253                 double minx = 99999.9;
00254                 double miny = 99999.9;
00255                 double maxx = -99999.9;
00256                 double maxy = -99999.9;
00257                 uint lowestItem = 999999;
00258                 uint highestItem = 0;
00259                 for (int a = 0; a < Elements.count(); ++a)
00260                 {
00261                     Elements.at(a)->Groups.push(m_Doc->GroupCounter);
00262                     PageItem* currItem = Elements.at(a);
00263                     lowestItem = qMin(lowestItem, currItem->ItemNr);
00264                     highestItem = qMax(highestItem, currItem->ItemNr);
00265                     double lw = currItem->lineWidth() / 2.0;
00266                     if (currItem->rotation() != 0)
00267                     {
00268                         FPointArray pb;
00269                         pb.resize(0);
00270                         pb.addPoint(FPoint(currItem->xPos()-lw, currItem->yPos()-lw));
00271                         pb.addPoint(FPoint(currItem->width()+lw*2.0, -lw, currItem->xPos()-lw, currItem->yPos()-lw, currItem->rotation(), 1.0, 1.0));
00272                         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));
00273                         pb.addPoint(FPoint(-lw, currItem->height()+lw*2.0, currItem->xPos()-lw, currItem->yPos()-lw, currItem->rotation(), 1.0, 1.0));
00274                         for (uint pc = 0; pc < 4; ++pc)
00275                         {
00276                             minx = qMin(minx, pb.point(pc).x());
00277                             miny = qMin(miny, pb.point(pc).y());
00278                             maxx = qMax(maxx, pb.point(pc).x());
00279                             maxy = qMax(maxy, pb.point(pc).y());
00280                         }
00281                     }
00282                     else
00283                     {
00284                         minx = qMin(minx, currItem->xPos()-lw);
00285                         miny = qMin(miny, currItem->yPos()-lw);
00286                         maxx = qMax(maxx, currItem->xPos()-lw + currItem->width()+lw*2.0);
00287                         maxy = qMax(maxy, currItem->yPos()-lw + currItem->height()+lw*2.0);
00288                     }
00289                 }
00290                 double gx = minx;
00291                 double gy = miny;
00292                 double gw = maxx - minx;
00293                 double gh = maxy - miny;
00294                 PageItem *high = m_Doc->Items->at(highestItem);
00295                 int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, gx, gy, gw, gh, 0, m_Doc->toolSettings.dBrush, m_Doc->toolSettings.dPen, true);
00296                 PageItem *neu = m_Doc->Items->takeAt(z);
00297                 m_Doc->Items->insert(lowestItem, neu);
00298                 neu->Groups.push(m_Doc->GroupCounter);
00299                 neu->setItemName( tr("Group%1").arg(neu->Groups.top()));
00300                 neu->isGroupControl = true;
00301                 neu->groupsLastItem = high;
00302                 neu->setTextFlowMode(PageItem::TextFlowUsesFrameShape);
00303                 for (int a = 0; a < m_Doc->Items->count(); ++a)
00304                 {
00305                     m_Doc->Items->at(a)->ItemNr = a;
00306                 }
00307                 Elements.prepend(neu);
00308                 m_Doc->GroupCounter++;
00309             }
00310         }
00311         m_Doc->DoDrawing = true;
00312         m_Doc->scMW()->ScriptRunning = false;
00313         m_Doc->setLoading(false);
00314         qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
00315         if ((Elements.count() > 0) && (!ret) && (interactive))
00316         {
00317             if (flags & LoadSavePlugin::lfScripted)
00318             {
00319                 bool loadF = m_Doc->isLoading();
00320                 m_Doc->setLoading(false);
00321                 m_Doc->changed();
00322                 m_Doc->setLoading(loadF);
00323                 for (int dre=0; dre<Elements.count(); ++dre)
00324                 {
00325                     m_Doc->m_Selection->addItem(Elements.at(dre), true);
00326                 }
00327                 m_Doc->m_Selection->setGroupRect();
00328                 m_Doc->view()->updatesOn(true);
00329             }
00330             else
00331             {
00332                 m_Doc->DragP = true;
00333                 m_Doc->DraggedElem = 0;
00334                 m_Doc->DragElements.clear();
00335                 for (int dre=0; dre<Elements.count(); ++dre)
00336                 {
00337                     m_Doc->DragElements.append(Elements.at(dre)->ItemNr);
00338                     tmpSel->addItem(Elements.at(dre), true);
00339                 }
00340                 tmpSel->setGroupRect();
00341                 ScriXmlDoc *ss = new ScriXmlDoc();
00342                 QMimeData* md = new QMimeData();
00343                 md->setText(ss->WriteElem(m_Doc, m_Doc->view(), tmpSel));
00344                 QDrag* dr = new QDrag(m_Doc->view()->viewport());
00345                 dr->setMimeData(md);
00346 #ifndef Q_WS_MAC
00347 // see #2196
00348                 m_Doc->itemSelection_DeleteItem(tmpSel);
00349 #else
00350                 qDebug("psimport: leaving items on page");
00351 #endif
00352 //              m_Doc->view()->resizeContents(qRound((maxSize.x() - minSize.x()) * m_Doc->view()->scale()), qRound((maxSize.y() - minSize.y()) * m_Doc->view()->scale()));
00353 //              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()));
00354                 m_Doc->minCanvasCoordinate = minSize;
00355                 m_Doc->maxCanvasCoordinate = maxSize;
00356                 m_Doc->view()->adjustCanvas(qRound((maxSize.x() - minSize.x()) * m_Doc->view()->scale()), qRound((maxSize.y() - minSize.y()) * m_Doc->view()->scale()), 0, 0);
00357                 m_Doc->view()->setCanvasOrigin(cOrigin.x(), cOrigin.y());
00358                 m_Doc->view()->updatesOn(true);
00359                 m_Doc->view()->updateCanvas();
00360                 const QPixmap& dragCursor = loadIcon("DragPix.xpm");
00361                 dr->setDragCursor(dragCursor, Qt::CopyAction);
00362                 dr->setDragCursor(dragCursor, Qt::MoveAction);
00363                 dr->setDragCursor(dragCursor, Qt::LinkAction);
00364                 dr->exec();
00365 #if 0
00366             qDebug("psimport: data");
00367             QString data(dr->encodedData("text/plain"));
00368             for (uint i=0; i <= data.length() / 4000; i++) {
00369                 qDebug(data.mid(i*4000, 4000));
00370             }
00371             qDebug("psimport: enddata");
00372             qDebug(QString("psimport: drag type %1").arg(dr->format()));
00373 #endif
00374                 /* JG : incorrect, see the Qt Reference: "The function returns TRUE if the caller should 
00375                 delete the original copy of the dragged data */
00376                 /*if (!dr->drag())
00377                 {
00378                     if (importedColors.count() != 0)
00379                     {
00380                         for (int cd = 0; cd < importedColors.count(); cd++)
00381                         {
00382                             m_Doc->PageColors.remove(importedColors[cd]);
00383                         }
00384                     }
00385                 }*/
00386                 delete ss;
00387                 m_Doc->DragP = false;
00388                 m_Doc->DraggedElem = 0;
00389                 m_Doc->DragElements.clear();
00390             }
00391         }
00392         else
00393         {
00394             m_Doc->changed();
00395             m_Doc->reformPages();
00396             m_Doc->view()->updatesOn(true);
00397         }
00398         success = true;
00399     }
00400     else
00401     {
00402         QDir::setCurrent(CurDirP);
00403         m_Doc->DoDrawing = true;
00404         m_Doc->scMW()->ScriptRunning = false;
00405         m_Doc->view()->updatesOn(true);
00406         qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
00407     }
00408     if (interactive)
00409         m_Doc->setLoading(false);
00410     //CB If we have a gui we must refresh it if we have used the progressbar
00411     if ((showProgress) && (!interactive))
00412         m_Doc->view()->DrawNew();
00413     return success;
00414 }
00415 
00416 EPSPlug::~EPSPlug()
00417 {
00418     delete tmpSel;
00419 }
00420     
00421 
00422 bool EPSPlug::convert(QString fn, double x, double y, double b, double h)
00423 {
00424     QStringList args;
00425     QString cmd, cmd1, cmd2, cmd3, tmp, tmp2, tmp3, tmp4;
00426     // import.prolog do not cope with filenames containing blank spaces
00427     // so take care that output filename does not (win32 compatibility)
00428     QString tmpFile = getShortPathName(ScPaths::getTempFileDir())+ "/ps.out";
00429     QString errFile = getShortPathName(ScPaths::getTempFileDir())+ "/ps.err";
00430     QString pfad = ScPaths::instance().libDir();
00431     QString pfad2 = QDir::convertSeparators(pfad + "import.prolog");
00432     QFileInfo fi = QFileInfo(fn);
00433     QString ext = fi.suffix().toLower();
00434     
00435     if (progressDialog) {
00436         progressDialog->setOverallProgress(1);
00437         qApp->processEvents();
00438     }
00439     args.append( "-q" );
00440     args.append( "-dNOPAUSE" );
00441     args.append( "-sDEVICE=nullpage" );
00442     args.append( "-dBATCH" );
00443     args.append( "-dDELAYBIND" );
00444     // Add any extra font paths being used by Scribus to gs's font search
00445     // path We have to use Scribus's prefs context, not a plugin context, to
00446     // get to the required information.
00447     PrefsContext *pc = PrefsManager::instance()->prefsFile->getContext("Fonts");
00448     PrefsTable *extraFonts = pc->getTable("ExtraFontDirs");
00449     const char sep = ScPaths::envPathSeparator;
00450     if (extraFonts->getRowCount() >= 1)
00451         cmd = QString("-sFONTPATH=%1").arg(extraFonts->get(0,0));
00452     for (int i = 1; i < extraFonts->getRowCount(); ++i)
00453         cmd += QString("%1%2").arg(sep).arg(extraFonts->get(i,0));
00454     if( !cmd.isEmpty() )
00455         args.append( cmd );
00456     // then finish building the command and call gs
00457     args.append( QString("-g%1x%2").arg(tmp2.setNum(qRound((b-x)))).arg(tmp3.setNum(qRound((h-y)))) );
00458     args.append( "-r72");
00459     args.append( "-dTextAlphaBits=4" );
00460     args.append( "-dGraphicsAlphaBits=4" );
00461     args.append( "-c" );
00462     args.append( tmp.setNum(-x) );
00463     args.append( tmp.setNum(-y) );
00464     args.append( "translate" );
00465     args.append( QString("-sTraceFile=%1").arg(QDir::convertSeparators(tmpFile)) );
00466     QString exportPath = m_Doc->DocName + "-" + fi.baseName();
00467     QFileInfo exportFi(exportPath);
00468     if ( !exportFi.isWritable() ) {
00469         PrefsContext* docContext = PrefsManager::instance()->prefsFile->getContext("docdirs", false);
00470         QString docDir = ".";
00471         QString prefsDocDir=PrefsManager::instance()->documentDir();
00472         if (!prefsDocDir.isEmpty())
00473             docDir = docContext->get("docsopen", prefsDocDir);
00474         else
00475             docDir = docContext->get("docsopen", ".");      
00476         exportFi.setFile(docDir + "/" + exportFi.baseName());
00477     }
00478     //qDebug(QString("using export path %1").arg(exportFi.absFilePath()));
00479     args.append( QString("-sExportFiles=%1").arg(QDir::convertSeparators(exportFi.absoluteFilePath())) );
00480     args.append( pfad2 );
00481     args.append( QDir::convertSeparators(fn) );
00482     args.append( "-c" );
00483     args.append( "flush" );
00484     args.append( "cfile" );
00485     args.append( "closefile" );
00486     args.append( "quit" );
00487     QByteArray finalCmd = args.join(" ").toLocal8Bit();
00488     int ret = System(getShortPathName(PrefsManager::instance()->ghostscriptExecutable()), args, errFile, errFile);
00489     if (ret != 0)
00490     {
00491         qDebug("PostScript import failed when calling gs as: \n%s\n", finalCmd.data());
00492         qDebug("Ghostscript diagnostics:\n");
00493         QFile diag(errFile);
00494         if (diag.open(QIODevice::ReadOnly) && !diag.atEnd() ) {
00495             char buf[121];
00496             while (diag.readLine(buf, 120) > 0) {
00497                 qDebug("\t%s", buf);
00498             }
00499             diag.close();
00500         }
00501         else {
00502             qDebug("-- no output --");
00503         }
00504         if (progressDialog)
00505             progressDialog->close();
00506         QString mess = tr("Importing File:\n%1\nfailed!").arg(fn);
00507         QMessageBox::critical(0, tr("Fatal Error"), mess, 1, 0, 0);
00508         return false;
00509     }
00510     if(progressDialog) {
00511         progressDialog->setOverallProgress(2);
00512         progressDialog->setLabel("GI", tr("Generating Items"));
00513         qApp->processEvents();
00514     }
00515     if (!cancel) {
00516         parseOutput(tmpFile, extensionIndicatesEPSorPS(ext));
00517     }
00518     QFile::remove(tmpFile);
00519     if (progressDialog)
00520         progressDialog->close();
00521     return true;
00522 }
00523 
00524 void EPSPlug::parseOutput(QString fn, bool eps)
00525 {
00526     QString tmp, token, params, lasttoken, lastPath, currPath;
00527     int z, lcap, ljoin, dc, pagecount;
00528     int failedImages = 0;
00529     double dcp;
00530     bool fillRuleEvenOdd = true;
00531     PageItem* ite;
00532     QStack<PageItem*> groupStack;
00533     QStack<int>  gsStack;
00534     QStack<uint> elemCount;
00535     QStack<uint> gsStackMarks;
00536     QFile f(fn);
00537     lasttoken = "";
00538     pagecount = 1;
00539     if (f.open(QIODevice::ReadOnly))
00540     {
00541         int fProgress = 0;
00542         int fSize = (int) f.size();
00543         if (progressDialog) {
00544             progressDialog->setTotalSteps("GI", fSize);
00545             qApp->processEvents();
00546         }
00547         lastPath = "";
00548         currPath = "";
00549         LineW = 0;
00550         Opacity = 1;
00551         CurrColor = CommonStrings::None;
00552         JoinStyle = Qt::MiterJoin;
00553         CapStyle = Qt::FlatCap;
00554         DashPattern.clear();
00555         QTextStream ts(&f);
00556         int line_cnt = 0;
00557         while (!ts.atEnd() && !cancel)
00558         {
00559             tmp = "";
00560             tmp = ts.readLine();
00561             if (progressDialog && (++line_cnt % 100 == 0)) {
00562                 int fPos = f.pos();
00563                 int progress = static_cast<int>(ceil(fPos / (double) fSize * 100));
00564                 if (progress > fProgress)
00565                 {
00566                     progressDialog->setProgress("GI", fPos);
00567                     qApp->processEvents();
00568                     fProgress = progress;
00569                 }
00570             }
00571             token = tmp.section(' ', 0, 0);
00572             params = tmp.section(' ', 1, -1, QString::SectionIncludeTrailingSep);
00573             if (lasttoken == "sp"  && !eps && token != "sp" ) //av: messes up anyway: && (!interactive))
00574             {
00575                 m_Doc->addPage(pagecount);
00576                 m_Doc->view()->addPage(pagecount, true);
00577                 pagecount++;
00578             }
00579             if (token == "n")
00580             {
00581                 Coords.resize(0);
00582                 FirstM = true;
00583                 WasM = false;
00584                 ClosedPath = false;
00585             }
00586             else if (token == "m")
00587                 WasM = true;
00588             else if (token == "c")
00589             {
00590                 Curve(&Coords, params);
00591                 currPath += params;
00592             }
00593             else if (token == "l")
00594             {
00595                 LineTo(&Coords, params);
00596                 currPath += params;
00597             }
00598             else if (token == "fill-winding")
00599             {
00600                 fillRuleEvenOdd = false;
00601             }
00602             else if (token == "fill-evenodd")
00603             {
00604                 fillRuleEvenOdd = true;
00605             }
00606             else if (token == "f")
00607             {
00608                 //TODO: pattern -> Imageframe + Clip
00609                 if (Coords.size() != 0)
00610                 {
00611                     if ((Elements.count() != 0) && (lastPath == currPath))
00612                     {
00613                         ite = Elements.at(Elements.count()-1);
00614                         ite->setFillColor(CurrColor);
00615                         ite->setFillTransparency(1.0 - Opacity);
00616                         lastPath = "";
00617                     }
00618                     else
00619                     {
00620                         if (ClosedPath)
00621                             z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColor, CommonStrings::None, true);
00622                         else
00623                             z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColor, CommonStrings::None, true);
00624                         ite = m_Doc->Items->at(z);
00625                         ite->PoLine = Coords.copy();  //FIXME: try to avoid copy if FPointArray when properly shared
00626                         ite->PoLine.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
00627                         ite->ClipEdited = true;
00628                         ite->FrameType = 3;
00629                         ite->fillRule = (fillRuleEvenOdd);
00630                         FPoint wh = getMaxClipF(&ite->PoLine);
00631                         ite->setWidthHeight(wh.x(),wh.y());
00632                         ite->Clip = FlattenPath(ite->PoLine, ite->Segments);
00633                         ite->setFillTransparency(1.0 - Opacity);
00634                         ite->setTextFlowMode(PageItem::TextFlowUsesFrameShape);
00635                         m_Doc->AdjustItemSize(ite);
00636                         if (groupStack.count() != 0)
00637                         {
00638                             QStack<int> groupOld = groupStack.top()->Groups;
00639                             for (int gg = 0; gg < groupOld.count(); gg++)
00640                             {
00641                                 ite->Groups.push(groupOld[gg]);
00642                             }
00643                         }
00644                         Elements.append(ite);
00645                         lastPath = currPath;
00646                     }
00647                     currPath = "";
00648                 }
00649             }
00650             else if (token == "s")
00651             {
00652                 if (Coords.size() != 0)
00653                 {
00654                     LineW = qMax(LineW, 0.1); // Set Linewidth to be a least 0.1 pts, a Stroke without a Linewidth makes no sense
00655                     if ((Elements.count() != 0) && (lastPath == currPath))
00656                     {
00657                         ite = Elements.at(Elements.count()-1);
00658                         ite->setLineColor(CurrColor);
00659                         ite->setLineWidth(LineW);
00660                         ite->PLineEnd = CapStyle;
00661                         ite->PLineJoin = JoinStyle;
00662                         ite->setLineTransparency(1.0 - Opacity);
00663                         ite->DashOffset = DashOffset;
00664                         ite->DashValues = DashPattern;
00665                     }
00666                     else
00667                     {
00668                         if (ClosedPath)
00669                             z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CommonStrings::None, CurrColor, true);
00670                         else
00671                             z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CommonStrings::None, CurrColor, true);
00672                         ite = m_Doc->Items->at(z);
00673                         ite->PoLine = Coords.copy(); //FIXME: try to avoid copy when FPointArray is properly shared
00674                         ite->PoLine.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
00675                         ite->ClipEdited = true;
00676                         ite->FrameType = 3;
00677                         ite->PLineEnd = CapStyle;
00678                         ite->PLineJoin = JoinStyle;
00679                         ite->DashOffset = DashOffset;
00680                         ite->DashValues = DashPattern;
00681                         FPoint wh = getMaxClipF(&ite->PoLine);
00682                         ite->setWidthHeight(wh.x(), wh.y());
00683                         ite->Clip = FlattenPath(ite->PoLine, ite->Segments);
00684                         ite->setLineTransparency(1.0 - Opacity);
00685                         m_Doc->AdjustItemSize(ite);
00686                         ite->setTextFlowMode(PageItem::TextFlowUsesFrameShape);
00687                         if (groupStack.count() != 0)
00688                         {
00689                             QStack<int> groupOld = groupStack.top()->Groups;
00690                             for (int gg = 0; gg < groupOld.count(); gg++)
00691                             {
00692                                 ite->Groups.push(groupOld[gg]);
00693                             }
00694                         }
00695                         Elements.append(ite);
00696                     }
00697                     lastPath = "";
00698                     currPath = "";
00699                 }
00700             }
00701             else if (token == "co")
00702                 CurrColor = parseColor(params, eps);
00703             else if (token == "corgb")
00704                 CurrColor = parseColor(params, eps, colorModelRGB);
00705             else if (token == "ci")
00706             {
00707                 clipCoords = Coords;
00708                 if (Coords.size() != 0)
00709                 {
00710                     z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, baseX, baseY, 10, 10, 0, CommonStrings::None, CommonStrings::None, true);
00711                     ite = m_Doc->Items->at(z);
00712                     ite->PoLine = Coords.copy();  //FIXME: try to avoid copy if FPointArray when properly shared
00713                     ite->PoLine.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
00714                     ite->ClipEdited = true;
00715                     ite->FrameType = 3;
00716 //                  ite->fillRule = (fillRuleEvenOdd);
00717                     FPoint wh = getMaxClipF(&ite->PoLine);
00718                     ite->setWidthHeight(wh.x(),wh.y());
00719                     ite->Clip = FlattenPath(ite->PoLine, ite->Segments);
00720 //                  ite->setFillTransparency(1.0 - Opacity);
00721                     m_Doc->AdjustItemSize(ite);
00722                     ite->Groups.push(m_Doc->GroupCounter);
00723                     if (groupStack.count() != 0)
00724                     {
00725                         QStack<int> groupOld = groupStack.top()->Groups;
00726                         for (int gg = 0; gg < groupOld.count(); gg++)
00727                         {
00728                             ite->Groups.push(groupOld[gg]);
00729                         }
00730                     }
00731                     ite->isGroupControl = true;
00732                     ite->setItemName( tr("Group%1").arg(m_Doc->GroupCounter));
00733                     ite->AutoName = false;
00734                     ite->setTextFlowMode(PageItem::TextFlowUsesFrameShape);
00735                     Elements.append(ite);
00736                     groupStack.push(ite);
00737                     elemCount.push(Elements.count());
00738                     gsStackMarks.push(gsStack.count());
00739                     m_Doc->GroupCounter++;
00740                 }
00741                 Coords   = FPointArray(0);
00742                 lastPath = "";
00743                 currPath = "";
00744             }
00745             else if (token == "gs")
00746             {
00747                 gsStack.push(1);
00748             }
00749             else if (token == "gr")
00750             {
00751                 gsStack.pop();
00752                 if (groupStack.count() != 0)
00753                 {
00754                     if (gsStack.count() < static_cast<int>(gsStackMarks.top()))
00755                     {
00756                         PageItem *ite = groupStack.pop();
00757                         int count = elemCount.pop();
00758                         if (count == Elements.count())
00759                         {
00760                             m_Doc->Items->removeLast();
00761                             Elements.removeLast();
00762                         }
00763                         else
00764                             ite->groupsLastItem = Elements.at(Elements.count()-1);
00765                         gsStackMarks.pop();
00766                     }
00767                 }
00768             }
00769             else if (token == "w")
00770             {
00771                 QTextStream Lw(&params, QIODevice::ReadOnly);
00772                 Lw >> LineW;
00773 //              currPath += params;
00774             }
00775             else if (token == "ld")
00776             {
00777                 QTextStream Lw(&params, QIODevice::ReadOnly);
00778                 Lw >> dc;
00779                 Lw >> DashOffset;
00780                 DashPattern.clear();
00781                 if (dc != 0)
00782                 {
00783                     for (int dcc = 0; dcc < dc; ++dcc)
00784                     {
00785                         Lw >> dcp;
00786                         DashPattern.append(dcp);
00787                     }
00788                 }
00789 //              currPath += params;
00790             }
00791             else if (token == "lc")
00792             {
00793                 QTextStream Lw(&params, QIODevice::ReadOnly);
00794                 Lw >> lcap;
00795                 switch (lcap)
00796                 {
00797                     case 0:
00798                         CapStyle = Qt::FlatCap;
00799                         break;
00800                     case 1:
00801                         CapStyle = Qt::RoundCap;
00802                         break;
00803                     case 2:
00804                         CapStyle = Qt::SquareCap;
00805                         break;
00806                     default:
00807                         CapStyle = Qt::FlatCap;
00808                         break;
00809                 }
00810 //              currPath += params;
00811             }
00812             else if (token == "lj")
00813             {
00814                 QTextStream Lw(&params, QIODevice::ReadOnly);
00815                 Lw >> ljoin;
00816                 switch (ljoin)
00817                 {
00818                     case 0:
00819                         JoinStyle = Qt::MiterJoin;
00820                         break