00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "util_ghostscript.h"
00026
00027 #include <QDebug>
00028 #include <QDir>
00029 #include <QFile>
00030 #include <QFileInfo>
00031 #include <QPainter>
00032 #include <QPixmap>
00033 #include <QProcess>
00034
00035 #include "scconfig.h"
00036
00037 #ifdef HAVE_UNISTD_H
00038 #include <unistd.h>
00039 #endif
00040
00041 #include "prefsfile.h"
00042 #include "prefsmanager.h"
00043 #include "scpaths.h"
00044 #include "scribuscore.h"
00045 #include "scribus.h"
00046 #include "util.h"
00047
00048 using namespace std;
00049
00050
00051 int callGS(const QStringList& args_in, const QString device)
00052 {
00053 QString cmd;
00054 QStringList args;
00055 PrefsManager* prefsManager = PrefsManager::instance();
00056 args.append( "-q" );
00057 args.append( "-dNOPAUSE" );
00058 args.append( "-dQUIET" );
00059 args.append( "-dPARANOIDSAFER" );
00060 args.append( "-dBATCH" );
00061
00062 if (!device.isEmpty())
00063 args.append( QString("-sDEVICE=%1").arg(device) );
00064 else if (!ScCore->havePNGAlpha())
00065 args.append( "-sDEVICE=png16m" );
00066 else
00067 args.append( "-sDEVICE=pngalpha" );
00068
00069 if (prefsManager->appPrefs.gs_AntiAliasText)
00070 args.append( "-dTextAlphaBits=4" );
00071 if (prefsManager->appPrefs.gs_AntiAliasGraphics)
00072 args.append( "-dGraphicsAlphaBits=4" );
00073
00074
00075 PrefsContext *pc = PrefsManager::instance()->prefsFile->getContext("Fonts");
00076 PrefsTable *extraFonts = pc->getTable("ExtraFontDirs");
00077 const char sep = ScPaths::envPathSeparator;
00078 if (extraFonts->getRowCount() >= 1)
00079 cmd = QString("-sFONTPATH=%1").arg(QDir::convertSeparators(extraFonts->get(0,0)));
00080 for (int i = 1; i < extraFonts->getRowCount(); ++i)
00081 cmd += QString("%1%2").arg(sep).arg(QDir::convertSeparators(extraFonts->get(i,0)));
00082 if( !cmd.isEmpty() )
00083 args.append( cmd );
00084
00085 args += args_in;
00086 args.append("-c");
00087 args.append("showpage");
00088
00089 return System( getShortPathName(prefsManager->ghostscriptExecutable()), args );
00090 }
00091
00092 int callGS(const QString& args_in, const QString device)
00093 {
00094 PrefsManager* prefsManager=PrefsManager::instance();
00095 QString cmd1 = getShortPathName(prefsManager->ghostscriptExecutable());
00096 cmd1 += " -q -dNOPAUSE -dQUIET -dPARANOIDSAFER -dBATCH";
00097
00098 if (!device.isEmpty())
00099
00100 cmd1 += " -sDEVICE="+device;
00101 else if (!ScCore->havePNGAlpha())
00102 cmd1 += " -sDEVICE=png16m";
00103 else
00104 cmd1 += " -sDEVICE=pngalpha";
00105
00106 if (prefsManager->appPrefs.gs_AntiAliasText)
00107 cmd1 += " -dTextAlphaBits=4";
00108 if (prefsManager->appPrefs.gs_AntiAliasGraphics)
00109 cmd1 += " -dGraphicsAlphaBits=4";
00110
00111
00112 PrefsContext *pc = PrefsManager::instance()->prefsFile->getContext("Fonts");
00113 PrefsTable *extraFonts = pc->getTable("ExtraFontDirs");
00114 #ifndef _WIN32
00115 if (extraFonts->getRowCount() >= 1)
00116 cmd1 += QString(" -sFONTPATH='%1'").arg(extraFonts->get(0,0));
00117 for (int i = 1; i < extraFonts->getRowCount(); ++i)
00118 cmd1 += QString(":'%1'").arg(extraFonts->get(i,0));
00119 #else
00120 if (extraFonts->getRowCount() >= 1)
00121 cmd1 += QString(" -sFONTPATH=\"%1\"").arg(extraFonts->get(0,0));
00122 for (int i = 1; i < extraFonts->getRowCount(); ++i)
00123 cmd1 += QString(";\"%1\"").arg(extraFonts->get(i,0));
00124 #endif
00125
00126
00127 cmd1 += " " + args_in + " -c showpage";
00128
00129 return system(cmd1.toLocal8Bit().constData());
00130 }
00131
00132 int convertPS2PS(QString in, QString out, const QStringList& opts, int level)
00133 {
00134 PrefsManager* prefsManager=PrefsManager::instance();
00135 QStringList args;
00136 args.append( "-q" );
00137 args.append( "-dQUIET" );
00138 args.append( "-dNOPAUSE" );
00139 args.append( "-dPARANOIDSAFER" );
00140 args.append( "-dBATCH" );
00141 if( level == 2 )
00142 {
00143 int major = 0, minor = 0;
00144
00145
00146 getNumericGSVersion(major, minor);
00147 if ((major >=8 && minor >= 53) || major > 8)
00148 args.append( "-sDEVICE=ps2write" );
00149 else
00150 {
00151 args.append( "-sDEVICE=pswrite" );
00152 args.append( QString("-dLanguageLevel=%1").arg(level) );
00153 }
00154
00155 }
00156 else
00157 {
00158 args.append( "-sDEVICE=pswrite" );
00159 if(level <= 3)
00160 args.append( QString("-dLanguageLevel=%1").arg(level) );
00161 }
00162 args += opts;
00163 args.append( QString("-sOutputFile=%1").arg(QDir::convertSeparators(out)) );
00164 args.append( QDir::convertSeparators(in) );
00165 int ret = System( getShortPathName(prefsManager->ghostscriptExecutable()), args );
00166 return ret;
00167 }
00168
00169 bool testGSAvailability( void )
00170 {
00171 QStringList args;
00172 PrefsManager* prefsManager = PrefsManager::instance();
00173 return testGSAvailability(prefsManager->ghostscriptExecutable());
00174 }
00175
00176 bool testGSAvailability( const QString& gsPath )
00177 {
00178 QStringList args;
00179 args.append( "-h" );
00180 QProcess proc;
00181 proc.start(getShortPathName(gsPath), args);
00182 if (!proc.waitForStarted(5000))
00183 return false;
00184 proc.waitForFinished(5000);
00185 return (proc.exitCode()==0);
00186 }
00187
00188 bool testGSDeviceAvailability( const QString& device )
00189 {
00190 QStringList args;
00191 PrefsManager* prefsManager = PrefsManager::instance();
00192 args.append( QString("-sDEVICE=%1").arg( device ) );
00193 args.append( "-c" );
00194 args.append( "quit" );
00195 QProcess proc;
00196 proc.start(getShortPathName(prefsManager->ghostscriptExecutable()), args);
00197 if (!proc.waitForStarted(5000))
00198 return false;
00199 proc.waitForFinished(5000);
00200 return (proc.exitCode()==0);
00201 }
00202
00203
00204 QString getGSVersion()
00205 {
00206 QStringList args;
00207 args.append(QString("--version").toLocal8Bit());
00208 QString gsExe = getShortPathName(PrefsManager::instance()->ghostscriptExecutable());
00209 QProcess proc;
00210 proc.start(gsExe.toLocal8Bit(), args);
00211 if (proc.waitForStarted(5000))
00212 while (!proc.waitForFinished(5000))
00213 qApp->processEvents();
00214 QString gsVer;
00215 if (proc.exitStatus()==QProcess::NormalExit)
00216 gsVer = proc.readAllStandardOutput();
00217 return gsVer;
00218 }
00219
00220
00221 bool getNumericGSVersion(int & major, int & minor)
00222 {
00223 QString gs_ver_string(getGSVersion());
00224 return getNumericGSVersion(gs_ver_string, major, minor);
00225 }
00226
00227 bool getNumericGSVersion(const QString& ver, int& major, int& minor)
00228 {
00229
00230
00231 bool success = false;
00232 major = ver.section('.', 0, 0).toInt(&success);
00233 if (!success)
00234 return false;
00235 minor = ver.section('.', 1, 1).toInt(&success);
00236 if (!success)
00237 return false;
00238 return true;
00239 }
00240
00241 QString getGSDefaultExeName(void)
00242 {
00243 QString gsName;
00244 #if defined _WIN32
00245
00246 gsName = "gswin32c.exe";
00247
00248 QMap<int, QString> gplGS = getGSExePaths("SOFTWARE\\GPL Ghostscript");
00249 QMap<int, QString> afplGS = getGSExePaths("SOFTWARE\\AFPL Ghostscript");
00250 QMap<int, QString> gsVersions = gplGS.unite(afplGS);
00251
00252 if (gsVersions.isEmpty())
00253 return gsName;
00254
00255 int currentVer = 0;
00256 QString gsPath;
00257 QMap<int, QString>::ConstIterator it, itEnd = gsVersions.constEnd();
00258 for (it = gsVersions.constBegin(); it != itEnd; ++it)
00259 {
00260 int version = it.key();
00261 if (version > currentVer)
00262 {
00263 gsPath = it.value();
00264 QFileInfo fInfo(gsPath);
00265 if (fInfo.exists())
00266 {
00267 gsName = gsPath;
00268 currentVer = version;
00269 }
00270 }
00271 }
00272 #else
00273 gsName = "gs";
00274 #endif
00275 return gsName;
00276 }
00277
00278 QMap<int, QString> SCRIBUS_API getGSExePaths(const QString& regKey)
00279 {
00280 QMap<int, QString> gsVersions;
00281 #if defined _WIN32
00282
00283 DWORD size;
00284 HKEY hKey1, hKey2;
00285 DWORD regType = REG_SZ;
00286 WCHAR regVersion[MAX_PATH];
00287 WCHAR regPath[MAX_PATH];
00288 WCHAR gsPath[MAX_PATH];
00289 QString gsVersion, gsName;
00290
00291 if( RegOpenKeyW(HKEY_LOCAL_MACHINE, (LPCWSTR) regKey.utf16(), &hKey1) == ERROR_SUCCESS )
00292 {
00293 size = sizeof(regVersion)/sizeof(WCHAR) - 1;
00294 DWORD keyIndex = 0;
00295 while ( RegEnumKeyExW(hKey1, keyIndex, regVersion, &size, NULL, NULL, NULL, NULL) == ERROR_SUCCESS )
00296 {
00297 int gsNumericVer, gsMajor, gsMinor;
00298 wcscpy(regPath, (const wchar_t*) regKey.utf16());
00299 wcscat(regPath, L"\\");
00300 wcscat(regPath, regVersion);
00301 if (RegOpenKeyW(HKEY_LOCAL_MACHINE, regPath, &hKey2) == ERROR_SUCCESS)
00302 {
00303 size = sizeof(gsPath) - 1;
00304 if (RegQueryValueExW(hKey2, L"GS_DLL", 0, ®Type, (LPBYTE) gsPath, &size) == ERROR_SUCCESS)
00305 {
00306
00307
00308 if ( getNumericGSVersion(QString::fromUtf16((const ushort*) regVersion), gsMajor, gsMinor) )
00309 {
00310 gsNumericVer = gsMajor * 1000 + gsMinor;
00311 gsName = QString::fromUtf16((const ushort*) gsPath);
00312 size = gsName.lastIndexOf("\\");
00313 if (size > 0)
00314 {
00315 gsName = gsName.left(size + 1);
00316 gsName += "gswin32c.exe";
00317 gsName.replace("\\", "/");
00318 gsVersions.insert(gsNumericVer, gsName);
00319 }
00320 }
00321 }
00322 RegCloseKey(hKey2);
00323 }
00324 keyIndex++;
00325 }
00326 RegCloseKey(hKey1);
00327 }
00328 #else
00329 int gsNumericVer, gsMajor, gsMinor;
00330 PrefsManager* prefsManager=PrefsManager::instance();
00331 if (getNumericGSVersion(gsMajor, gsMinor))
00332 {
00333 gsNumericVer = gsMajor * 1000 + gsMinor;
00334 gsVersions.insert(gsNumericVer, prefsManager->ghostscriptExecutable());
00335 }
00336 #endif
00337 return gsVersions;
00338 }
00339
00340 QPixmap LoadPDF(QString fn, int Page, int Size, int *w, int *h)
00341 {
00342 QString tmp, cmd1, cmd2;
00343 QString pdfFile = QDir::convertSeparators(fn);
00344 QString tmpFile = QDir::convertSeparators(ScPaths::getTempFileDir() + "sc.png");
00345 QPixmap pm;
00346 int ret = -1;
00347 tmp.setNum(Page);
00348 QStringList args;
00349 args.append("-r72");
00350
00351 args.append("-sOutputFile="+tmpFile);
00352 args.append("-dFirstPage="+tmp);
00353 args.append("-dLastPage="+tmp);
00354
00355 args.append(pdfFile);
00356 ret = callGS(args);
00357 if (ret == 0)
00358 {
00359 QImage image;
00360 image.load(tmpFile);
00361 QFile::remove(tmpFile);
00362 QImage im2;
00363 *h = image.height();
00364 *w = image.width();
00365 double sx = image.width() / static_cast<double>(Size);
00366 double sy = image.height() / static_cast<double>(Size);
00367 double t = (sy < sx ? sx : sy);
00368 im2 = image.scaled(static_cast<int>(image.width() / t), static_cast<int>(image.height() / t), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
00369 pm=QPixmap::fromImage(im2);
00370 QPainter p;
00371 p.begin(&pm);
00372 p.setBrush(Qt::NoBrush);
00373 p.setPen(Qt::black);
00374 p.drawRect(0, 0, pm.width(), pm.height());
00375 p.end();
00376 im2.detach();
00377 }
00378 return pm;
00379 }
00380
00381