Subversion Repositories Scribus

Rev

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

Rev Author Line No. Line
4507 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
*/
7
/***************************************************************************
8
                          gsutil.cpp  -  description
9
                             -------------------
10
    begin                : Fri Sep 14 2001
11
    copyright            : (C) 2001 by Franz Schmid
12
    copyright            : (C) 2006- Scribus Team (code moved from util.cpp)
13
    email                : Franz.Schmid@altmuehlnet.de
14
 ***************************************************************************/
15
 
16
/***************************************************************************
17
 *                                                                         *
18
 *   This program is free software; you can redistribute it and/or modify  *
19
 *   it under the terms of the GNU General Public License as published by  *
20
 *   the Free Software Foundation; either version 2 of the License, or     *
21
 *   (at your option) any later version.                                   *
22
 *                                                                         *
23
 ***************************************************************************/
24
 
25
#include "gsutil.h"
26
 
27
#include <qdir.h>
28
#include <qfile.h>
29
#include <qfileinfo.h>
30
#include <qpainter.h>
31
#include <qprocess.h>
32
 
33
/* CB old includes from util.cpp.
34
#include <algorithm>
35
#include <cstdlib>
36
#include <cmath>
37
*/
38
#include "scconfig.h"
39
 
40
#ifdef HAVE_UNISTD_H
41
#include <unistd.h>
42
#endif
43
/*
44
#include <setjmp.h>
45
#include "pagestructs.h"
46
*/
47
#include "prefsfile.h"
48
/*
49
#include "prefscontext.h"
50
#include "prefstable.h"
51
*/
52
#include "prefsmanager.h"
53
#include "scpaths.h"
54
 
55
/*
56
extern "C"
57
{
58
#define XMD_H           // shut JPEGlib up
59
#if defined(Q_OS_UNIXWARE)
60
#  define HAVE_BOOLEAN  // libjpeg under Unixware seems to need this
61
#endif
62
#include <jpeglib.h>
63
#include <jerror.h>
64
#undef HAVE_STDLIB_H
65
#ifdef const
66
#  undef const          // remove crazy C hackery in jconfig.h
67
#endif
68
}
69
*/
70
#include "scribus.h"
71
/*
72
#include <ft2build.h>
73
#include FT_FREETYPE_H
74
#include FT_OUTLINE_H
75
#include FT_GLYPH_H
76
#ifdef HAVE_TIFF
77
        #include <tiffio.h>
78
#endif
79
#ifdef HAVE_CMS
80
        #include CMS_INC
81
extern cmsHPROFILE CMSoutputProf;
82
extern cmsHPROFILE CMSprinterProf;
83
extern cmsHTRANSFORM stdTransG;
84
extern cmsHTRANSFORM stdProofG;
85
extern cmsHTRANSFORM stdTransImgG;
86
extern cmsHTRANSFORM stdProofImgG;
87
extern bool BlackPoint;
88
extern bool SoftProofing;
89
extern bool Gamut;
90
extern bool CMSuse;
91
extern int IntentMonitor;
92
extern int IntentPrinter;
93
#endif
94
*/
95
 
96
#include "util.h"
97
 
98
using namespace std;
99
 
100
 
101
int callGS(const QStringList& args_in, const QString device)
102
{
103
        QString cmd;
104
        QStringList args;
105
        PrefsManager* prefsManager = PrefsManager::instance();
106
        args.append( getShortPathName(prefsManager->ghostscriptExecutable()) );
107
        args.append( "-q" );
108
        args.append( "-dNOPAUSE" );
109
        args.append( "-dQUIET" );
110
        args.append( "-dPARANOIDSAFER" );
111
        args.append( "-dBATCH" );
112
        // Choose rendering device
113
        if (!device.isEmpty())
114
                args.append( QString("-sDEVICE=%1").arg(device) ); // user specified device
115
        else if (ScMW->HavePngAlpha != 0)
116
                args.append( "-sDEVICE=png16m" );
117
        else
118
                args.append( "-sDEVICE=pngalpha" );
119
        // and antialiasing
120
        if (prefsManager->appPrefs.gs_AntiAliasText)
121
                args.append( "-dTextAlphaBits=4" );
122
        if (prefsManager->appPrefs.gs_AntiAliasGraphics)
123
                args.append( "-dGraphicsAlphaBits=4" );
124
 
125
        // Add any extra font paths being used by Scribus to gs's font search path
126
        PrefsContext *pc = PrefsManager::instance()->prefsFile->getContext("Fonts");
127
        PrefsTable *extraFonts = pc->getTable("ExtraFontDirs");
128
        const char sep = ScPaths::envPathSeparator;
129
        if (extraFonts->getRowCount() >= 1)
5118 cbradney 130
                cmd = QString("-sFONTPATH=%1").arg(QDir::convertSeparators(extraFonts->get(0,0)));
4507 cbradney 131
        for (int i = 1; i < extraFonts->getRowCount(); ++i)
5118 cbradney 132
                cmd += QString("%1%2").arg(sep).arg(QDir::convertSeparators(extraFonts->get(i,0)));
4507 cbradney 133
        if( !cmd.isEmpty() )
134
                args.append( cmd );
135
 
136
        args += args_in;
137
        args.append("-c");
138
        args.append("showpage");
139
        return System( args );
140
}
141
 
142
int callGS(const QString& args_in, const QString device)
143
{
144
        PrefsManager* prefsManager=PrefsManager::instance();
145
        QString cmd1 = getShortPathName(prefsManager->ghostscriptExecutable());
146
        cmd1 += " -q -dNOPAUSE -dQUIET -dPARANOIDSAFER -dBATCH";
147
        // Choose rendering device
148
        if (!device.isEmpty())
149
                // user specified device
150
                cmd1 += " -sDEVICE="+device;
151
        else if (ScMW->HavePngAlpha != 0)
152
                cmd1 += " -sDEVICE=png16m";
153
        else
154
                cmd1 += " -sDEVICE=pngalpha";
155
        // and antialiasing
156
        if (prefsManager->appPrefs.gs_AntiAliasText)
157
                cmd1 += " -dTextAlphaBits=4";
158
        if (prefsManager->appPrefs.gs_AntiAliasGraphics)
159
                cmd1 += " -dGraphicsAlphaBits=4";
160
 
161
        // Add any extra font paths being used by Scribus to gs's font search path
162
        PrefsContext *pc = PrefsManager::instance()->prefsFile->getContext("Fonts");
163
        PrefsTable *extraFonts = pc->getTable("ExtraFontDirs");
164
#ifndef _WIN32
165
        if (extraFonts->getRowCount() >= 1)
166
                cmd1 += QString(" -sFONTPATH='%1'").arg(extraFonts->get(0,0));
167
        for (int i = 1; i < extraFonts->getRowCount(); ++i)
168
                cmd1 += QString(":'%1'").arg(extraFonts->get(i,0));
169
#else
170
        if (extraFonts->getRowCount() >= 1)
171
                cmd1 += QString(" -sFONTPATH=\"%1\"").arg(extraFonts->get(0,0));
172
        for (int i = 1; i < extraFonts->getRowCount(); ++i)
173
                cmd1 += QString(";\"%1\"").arg(extraFonts->get(i,0));
174
#endif
175
 
176
        // then add any user specified args and run gs
177
        cmd1 += " " + args_in + " -c showpage";
178
//      qDebug("Calling gs as: %s", cmd1.ascii());
179
        return system(cmd1.local8Bit());
180
}
181
 
182
int  convertPS2PS(QString in, QString out, const QStringList& opts, int level)
183
{
184
        PrefsManager* prefsManager=PrefsManager::instance();
185
        QStringList args;
186
        args.append( getShortPathName(prefsManager->ghostscriptExecutable()) );
187
        args.append( "-q" );
188
        args.append( "-dQUIET" );
189
        args.append( "-dNOPAUSE" );
190
        args.append( "-dPARANOIDSAFER" );
191
        args.append( "-dBATCH" );
5626 jghali 192
        if( level == 2 )
193
        {
194
                int major = 0, minor = 0;
195
                // ps2write cannot be detected with testGSAvailability()
196
                // so determine availability according to gs version.
197
                getNumericGSVersion(major, minor);
198
                if ((major >=8 && minor >= 53) || major > 8)
199
                        args.append( "-sDEVICE=ps2write" );
200
                else
201
                {
202
                        args.append( "-sDEVICE=pswrite" );
203
                        args.append( QString("-dLanguageLevel=%1").arg(level) );
204
                }
205
 
206
        }
207
        else
208
        {
209
                args.append( "-sDEVICE=pswrite" );
210
                if(level <= 3)
211
                        args.append( QString("-dLanguageLevel=%1").arg(level) );
212
        }
4507 cbradney 213
        args += opts;
214
        args.append( QString("-sOutputFile=%1").arg(QDir::convertSeparators(out)) );
215
        args.append( QDir::convertSeparators(in) );
216
        int ret = System( args );
217
        return ret;
218
}
219
 
220
int  testGSAvailability( void )
221
{
222
        QStringList args;
223
        PrefsManager* prefsManager = PrefsManager::instance();
5772 jghali 224
        int ret = testGSAvailability(prefsManager->ghostscriptExecutable());
225
        return ret;
226
}
227
 
228
int testGSAvailability( QString gsPath )
229
{
230
        QStringList args;
231
        args.append( getShortPathName(gsPath) );
4507 cbradney 232
        args.append( "-h" );
233
        int ret = System( args );
234
        return ret;
235
}
236
 
237
int  testGSDeviceAvailability( QString device )
238
{
239
        QStringList args;
240
        PrefsManager* prefsManager = PrefsManager::instance();
241
        args.append( getShortPathName(prefsManager->ghostscriptExecutable()) );
242
        args.append( QString("-sDEVICE=%1").arg( device ) );
243
        args.append( "-c" );
244
        args.append( "quit" );
245
        int ret = System( args );
246
        return ret;
247
}
248
 
249
// Return the GhostScript version string, or QString::null if it couldn't be retrived.
250
QString getGSVersion()
251
{
252
        QString gsVer;
253
        QStringList args;
254
        QString gsExe = getShortPathName(PrefsManager::instance()->ghostscriptExecutable());
255
        args.append(gsExe.local8Bit());
256
        args.append(QString("--version").local8Bit());
257
        QProcess proc(args);
258
        proc.setCommunication(QProcess::Stdout);
259
        proc.start();
260
        while(proc.isRunning())
261
        {
262
#ifndef _WIN32
263
                usleep(5000);
264
#else
265
                Sleep(5);
266
#endif
267
                qApp->processEvents();
268
        }
269
        if(!proc.exitStatus())
270
                gsVer = proc.readLineStdout();
271
        return gsVer;
272
}
273
 
274
// Return the GhostScript major and minor version numbers.
275
bool getNumericGSVersion(int & major, int & minor)
276
{
277
        QString gs_ver_string(getGSVersion());
278
        // gs's version string is of the form MAJOR.MINOR, so look for the .
279
        // then convert to numbers. 7.07 will become (7,7) for example.
280
        bool success = false;
281
        major = gs_ver_string.section('.', 0, 0).toInt(&success);
282
        if (!success)
283
                return false;
284
        minor = gs_ver_string.section('.', 1, 1).toInt(&success);
285
        if (!success)
286
                return false;
287
        return true;
288
}
289
 
290
QString getGSDefaultExeName(void)
291
{
292
        QString gsName;
293
#if defined _WIN32
294
        // Try to locate GhostScript thanks to the registry
295
        DWORD size;
296
        HKEY hKey;
297
        LONG retValue;
298
        DWORD regType = REG_SZ;
299
        char regVersion[MAX_PATH];
300
        char regPath[MAX_PATH];
301
        char gsPath[MAX_PATH];
302
 
303
        // Set gsName to its default value
304
        gsName = "gswin32c.exe";
305
 
306
        // Search AFPL Ghostscript first as it has more chance to be up to date
307
        if( RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\AFPL Ghostscript", &hKey) == ERROR_SUCCESS )
308
                strcpy(regPath, "SOFTWARE\\AFPL Ghostscript");
309
        else if( RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\GPL Ghostscript", &hKey) == ERROR_SUCCESS )
310
                strcpy(regPath, "SOFTWARE\\GPL Ghostscript");
311
        else
312
                return gsName;
313
 
314
        // Search the first SubKey corresponding to the version key
315
        size = sizeof(regVersion) - 1;
316
        retValue = RegEnumKeyEx(hKey, 0, regVersion, &size, NULL, NULL, NULL, NULL);
317
        RegCloseKey(hKey);
318
        if( retValue != ERROR_SUCCESS )
319
                return gsName;
320
 
321
        strcat(regPath, "\\");
322
        strcat(regPath, regVersion);
323
 
324
        // Get the GS_DLL Value
325
        if (RegOpenKey(HKEY_LOCAL_MACHINE, regPath, &hKey) != ERROR_SUCCESS)
326
          return gsName;
327
        size = sizeof(gsPath) - 1;
328
        retValue = RegQueryValueEx(hKey, "GS_DLL", 0, &regType, (LPBYTE) gsPath, &size);
329
        RegCloseKey(hKey);
330
        if( retValue != ERROR_SUCCESS )
331
                return gsName;
332
 
333
        // We now have GhostScript dll path, but we want gswin32c.exe
334
        // Normally gswin32c.exe and gsdll.dll are in the same directory
335
        gsName = gsPath;
336
        size = gsName.findRev("\\");
337
        if(size <= 0)
338
                return QString("gswin32c.exe");
339
        gsName = gsName.left(size + 1);
340
        gsName += "gswin32c.exe";
341
 
342
        // Check GhostScript executable existence.
343
        QFileInfo fInfo(gsName);
344
        if( fInfo.exists() )
345
                gsName.replace("\\", "/"); // Return a qt-styled path
346
        else
347
                gsName = "gswin32c.exe";
348
 
349
#else
350
        gsName = "gs";
351
#endif
352
        return gsName;
353
}
354
 
355
QPixmap LoadPDF(QString fn, int Page, int Size, int *w, int *h)
356
{
357
        QString tmp, cmd1, cmd2;
358
        QString pdfFile = QDir::convertSeparators(fn);
359
        QString tmpFile = QDir::convertSeparators(QDir::homeDirPath()+"/.scribus/sc.png");
360
        QPixmap pm;
361
        int ret = -1;
362
        tmp.setNum(Page);
363
        QStringList args;
364
        args.append("-r72");
365
        args.append("-sOutputFile=\""+tmpFile+"\"");
366
        args.append("-dFirstPage="+tmp);
367
        args.append("-dLastPage="+tmp);
368
        args.append("\""+pdfFile+"\"");
369
        ret = callGS(args);
370
        if (ret == 0)
371
        {
372
                QImage image;
373
                image.load(tmpFile);
374
                unlink(tmpFile);
375
                QImage im2;
376
                *h = image.height();
377
                *w = image.width();
378
                double sx = image.width() / static_cast<double>(Size);
379
                double sy = image.height() / static_cast<double>(Size);
380
                double t = (sy < sx ? sx : sy);
381
                im2 = image.smoothScale(static_cast<int>(image.width() / t), static_cast<int>(image.height() / t));
382
                pm.convertFromImage(im2);
383
                QPainter p;
384
                p.begin(&pm);
385
                p.setBrush(Qt::NoBrush);
386
                p.setPen(Qt::black);
387
                p.drawRect(0, 0, pm.width(), pm.height());
388
                p.end();
389
                im2.detach();
390
        }
391
        return pm;
392
}
393