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 #include <QDir>
9 #include <QFileInfo>
10 #include <QImage>
11 #include <QTemporaryFile>
12 #include <QTransform>
13 
14 #include "commonstrings.h"
15 #include "cmsettings.h"
16 #include "iconmanager.h"
17 #include "prefsfile.h"
18 #include "prefsmanager.h"
19 #include "prefstable.h"
20 #include "printpreviewcreator_ps.h"
21 #include "pslib.h"
22 #include "sccolorengine.h"
23 #include "scpaths.h"
24 #include "scribuscore.h"
25 #include "scribusdoc.h"
26 #include "util.h"
27 #include "util_ghostscript.h"
28 #include "util_printer.h"
29 
PrintPreviewCreator_PS(ScribusDoc * doc)30 PrintPreviewCreator_PS::PrintPreviewCreator_PS(ScribusDoc* doc) :
31 	SeparationPreviewCreator(doc),
32 	m_prefsManager(PrefsManager::instance())
33 {
34 	m_printOptions.prnLanguage = PrintLanguage::PostScript3;
35 
36 	// Generate a template name for temporary files
37 	QTemporaryFile *tempFile = new QTemporaryFile(ScPaths::tempFileDir() + "/scpspreview_XXXXXX.png");
38 	if (tempFile->open())
39 	{
40 		QString tempFileBase = tempFile->fileName();
41 		tempFile->setAutoRemove(false);
42 		tempFile->close();
43 		m_tempBaseName = QFileInfo(tempFileBase).completeBaseName();
44 	}
45 	if (m_tempBaseName.isEmpty())
46 		m_tempBaseName = "scpspreview";
47 	delete tempFile;
48 }
49 
~PrintPreviewCreator_PS()50 PrintPreviewCreator_PS::~PrintPreviewCreator_PS()
51 {
52 	cleanupTemporaryFiles();
53 }
54 
cleanupTemporaryFiles()55 void PrintPreviewCreator_PS::cleanupTemporaryFiles()
56 {
57 	QString tempFileDir = ScPaths::tempFileDir();
58 	QFile::remove(tempFileDir + "/" + m_tempBaseName + ".ps");
59 	QFile::remove(tempFileDir + "/" + m_tempBaseName + ".png");
60 	QDir d(tempFileDir + "/", m_tempBaseName + "*", QDir::Name, QDir::Files | QDir::NoSymLinks);
61 	if ((d.exists()) && (d.count() != 0))
62 	{
63 		for (uint i = 0; i < d.count(); i++)
64 			QFile::remove(tempFileDir + "/" + d[i]);
65 	}
66 }
67 
createPreview(int pageIndex)68 QPixmap PrintPreviewCreator_PS::createPreview(int pageIndex)
69 {
70 	int ret = -1;
71 	int gsRes = qRound(m_previewResolution * m_devicePixelRatio);
72 	int w = qRound(m_doc->Pages->at(pageIndex)->width() * gsRes / 72.0);
73 	int h = qRound(m_doc->Pages->at(pageIndex)->height() * gsRes / 72.0);
74 
75 	QPixmap pixmap;
76 	if (m_printOptionsChanged || (m_pageIndex != pageIndex))
77 	{
78 		bool success = createPreviewFile(pageIndex);
79 		if (!success)
80 		{
81 			imageLoadError(pixmap, pageIndex);
82 			return pixmap;
83 		}
84 	}
85 
86 	if (m_printOptionsChanged || m_renderingOptionsChanged || (m_pageIndex != pageIndex))
87 	{
88 		if (m_sepPreviewEnabled && m_haveTiffSep)
89 			ret = renderPreviewSep(pageIndex, gsRes);
90 		else
91 			ret = renderPreview(pageIndex, gsRes);
92 		if (ret > 0)
93 		{
94 			imageLoadError(pixmap, pageIndex);
95 			return pixmap;
96 		}
97 	}
98 
99 	QImage image;
100 	if (m_sepPreviewEnabled && m_haveTiffSep)
101 	{
102 		bool loadError;
103 		int cyan, magenta, yellow, black;
104 
105 		ScImage im;
106 		bool mode;
107 		int w2 = w;
108 		int h2 = h;
109 		if (m_doc->Pages->at(pageIndex)->orientation() == 1)
110 			std::swap(w2, h2);
111 		image = QImage(w2, h2, QImage::Format_ARGB32);
112 		image.fill(qRgba(0, 0, 0, 0));
113 
114 		QStringList separationNames { "Cyan", "Magenta", "Yellow" };
115 		CMSettings cms(m_doc, "", Intent_Perceptual);
116 		cms.allowColorManagement(false);
117 		for (int i = 0; i < separationNames.count(); ++i)
118 		{
119 			QString separationName = separationNames.at(i);
120 			if (!isSeparationVisible(separationName))
121 				continue;
122 			if (m_gsVersion < 854)
123 				loadError = im.loadPicture(ScPaths::tempFileDir() + "/" + m_tempBaseName + ".tif." + separationName + ".tif", 1, cms, ScImage::RGBData, 72, &mode);
124 			else if (m_gsVersion <= 905)
125 				loadError = im.loadPicture(ScPaths::tempFileDir() + "/" + m_tempBaseName + "." + separationName + ".tif", 1, cms, ScImage::RGBData, 72, &mode);
126 			else
127 				loadError = im.loadPicture(ScPaths::tempFileDir() + "/" + m_tempBaseName + "(" + separationName + ").tif", 1, cms, ScImage::RGBData, 72, &mode);
128 			if (!loadError)
129 			{
130 				imageLoadError(pixmap, pageIndex);
131 				return pixmap;
132 			}
133 			if (m_showInkCoverage)
134 				blendImagesSumUp(image, im);
135 			else
136 			{
137 				int c = (i == 0) ? 255 : 0;
138 				int m = (i == 1) ? 255 : 0;
139 				int j = (i == 2) ? 255 : 0;
140 				blendImages(image, im, ScColor(c, m, j, 0));
141 			}
142 		}
143 
144 		for (auto sepit = m_sepsToFileNum.begin(); sepit != m_sepsToFileNum.end(); ++sepit)
145 		{
146 			bool visibleSeparation = m_separationVisibilities.value(sepit.key(), false);
147 			if (!visibleSeparation)
148 				continue;
149 			QString sepFileName;
150 			if (m_gsVersion < 854)
151 				sepFileName = QString(ScPaths::tempFileDir() + "/" + m_tempBaseName + ".tif.s%1.tif").arg(sepit.value());
152 			else if (m_gsVersion <= 905)
153 				sepFileName = QString(ScPaths::tempFileDir() + "/" + m_tempBaseName + ".s%1.tif").arg(sepit.value());
154 			else
155 				sepFileName = QString(ScPaths::tempFileDir() + "/" + m_tempBaseName + "(%1).tif").arg(sepit.key());
156 			if (!im.loadPicture(sepFileName, 1, cms, ScImage::RGBData, 72, &mode))
157 			{
158 				imageLoadError(pixmap, pageIndex);
159 				return pixmap;
160 			}
161 			if (m_showInkCoverage)
162 				blendImagesSumUp(image, im);
163 			else
164 				blendImages(image, im, m_doc->PageColors[sepit.key()]);
165 		}
166 
167 		if (m_separationVisibilities.value("Black", false))
168 		{
169 			CMSettings cms(m_doc, "", Intent_Perceptual);
170 			cms.allowColorManagement(false);
171 			if (m_gsVersion < 854)
172 				loadError = im.loadPicture(ScPaths::tempFileDir() + "/" + m_tempBaseName + ".tif.Black.tif", 1, cms, ScImage::RGBData, 72, &mode);
173 			else if (m_gsVersion <= 905)
174 				loadError = im.loadPicture(ScPaths::tempFileDir() + "/" + m_tempBaseName + ".Black.tif", 1, cms, ScImage::RGBData, 72, &mode);
175 			else
176 				loadError = im.loadPicture(ScPaths::tempFileDir() + "/" + m_tempBaseName + "(Black).tif", 1, cms, ScImage::RGBData, 72, &mode);
177 			if (!loadError)
178 			{
179 				imageLoadError(pixmap, pageIndex);
180 				return pixmap;
181 			}
182 			if (m_showInkCoverage)
183 				blendImagesSumUp(image, im);
184 			else
185 				blendImages(image, im, ScColor(0, 0, 0, 255));
186 		}
187 
188 		if (m_showInkCoverage)
189 		{
190 			uint limitVal = (m_inkCoverageThreshold * 255) / 100;
191 			for (int yi = 0; yi < h2; ++yi)
192 			{
193 				QRgb *q = (QRgb*) image.scanLine(yi);
194 				for (int xi = 0; xi < w2; ++xi)
195 				{
196 					uint greyVal = *q;
197 					if (greyVal != 0)
198 					{
199 						if (limitVal == 0)
200 						{
201 							QColor tmpC;
202 							tmpC.setHsv((greyVal * 359) / m_inkMax, 255, 255);
203 							*q = tmpC.rgba();
204 						}
205 						else
206 						{
207 							int col = qMin(255 - static_cast<int>(((greyVal * 128) / m_inkMax) * 2), 255);
208 							if ((*q > 0) && (*q < limitVal))
209 								*q = qRgba(col, col, col, 255);
210 							else
211 								*q = qRgba(col, 0, 0, 255);
212 						}
213 					}
214 					else
215 					{
216 						if (!m_showTransparency)
217 							*q = qRgba(255, 255, 255, 255);
218 					}
219 					q++;
220 				}
221 			}
222 		}
223 		else if (m_doc->HasCMS || ScCore->haveCMS())
224 		{
225 			QRgb alphaFF = qRgba(0,0,0,255);
226 			QRgb alphaOO = qRgba(255,255,255,0);
227 			ScColorMgmtEngine engine = m_doc->colorEngine;
228 			ScColorProfile cmykProfile = m_doc->HasCMS ? m_doc->DocPrinterProf : ScCore->defaultCMYKProfile;
229 			ScColorProfile rgbProfile  = m_doc->HasCMS ? m_doc->DocDisplayProf : ScCore->defaultRGBProfile;
230 			ScColorTransform transCMYK = engine.createTransform(cmykProfile, Format_YMCK_8, rgbProfile, Format_BGRA_8, Intent_Relative_Colorimetric, 0);
231 			for (int yi = 0; yi < h2; ++yi)
232 			{
233 				uchar* ptr = image.scanLine( yi );
234 				transCMYK.apply(ptr, ptr, image.width());
235 				QRgb *q = (QRgb *) ptr;
236 				for (int xi = 0; xi < image.width(); xi++, q++)
237 				{
238 					if (m_showTransparency)
239 					{
240 						cyan = qRed(*q);
241 						magenta = qGreen(*q);
242 						yellow = qBlue(*q);
243 						if	((cyan == 255) && (magenta == 255) && (yellow == 255))
244 							*q = alphaOO;
245 						else
246 							*q |= alphaFF;
247 					}
248 					else
249 						*q |= alphaFF;
250 				}
251 			}
252 		}
253 		else
254 		{
255 			for (int yi = 0; yi < h2; ++yi)
256 			{
257 				QRgb *q = (QRgb*) image.scanLine(yi);
258 				for (int xi = 0; xi < w2; ++xi)
259 				{
260 					cyan = qRed(*q);
261 					magenta = qGreen(*q);
262 					yellow = qBlue(*q);
263 					black = qAlpha(*q);
264 					if ((cyan != 0) || (magenta != 0) || (yellow != 0 ) || (black != 0))
265 						*q = qRgba(255 - qMin(255, cyan + black), 255 - qMin(255, magenta + black), 255 - qMin(255, yellow + black), 255);
266 					else
267 					{
268 						if (!m_showTransparency)
269 							*q = qRgba(255, 255, 255, 255);
270 					}
271 					q++;
272 				}
273 			}
274 		}
275 	}
276 	else
277 	{
278 		QString previewFile;
279 		if (m_showTransparency && m_havePngAlpha)
280 			previewFile = ScPaths::tempFileDir() + "/" + m_tempBaseName + ".png";
281 		else
282 			previewFile = ScPaths::tempFileDir() + "/" + m_tempBaseName + ".tif";
283 		if (!image.load(previewFile))
284 		{
285 			imageLoadError(pixmap, pageIndex);
286 			return pixmap;
287 		}
288 		image = image.convertToFormat(QImage::Format_ARGB32);
289 		if (m_showTransparency && m_havePngAlpha)
290 		{
291 			int wi = image.width();
292 			int hi = image.height();
293 			for (int yi = 0; yi < hi; ++yi)
294 			{
295 				QRgb *s = (QRgb*) image.scanLine(yi);
296 				for (int xi = 0; xi < wi; ++xi)
297 				{
298 					if ((*s) == 0xffffffff)
299 						(*s) &= 0x00ffffff;
300 					s++;
301 				}
302 			}
303 		}
304 	}
305 
306 	const ScPage* page = m_doc->Pages->at(pageIndex);
307 	if ((page->orientation() == 1) && (image.width() < image.height()))
308 		image = image.transformed( QTransform(0, 1, -1, 0, 0, 0) );
309 
310 	image.setDevicePixelRatio(m_devicePixelRatio);
311 	if (m_showTransparency)
312 	{
313 		pixmap = QPixmap(image.width(), image.height());
314 		pixmap.setDevicePixelRatio(m_devicePixelRatio);
315 		QPainter p;
316 		QBrush b(QColor(205,205,205), IconManager::instance().loadPixmap("testfill.png"));
317 		p.begin(&pixmap);
318 		p.fillRect(0, 0, image.width(), image.height(), b);
319 		p.drawImage(0, 0, image);
320 		p.end();
321 	}
322 	else
323 		pixmap = QPixmap::fromImage(image);
324 	pixmap.setDevicePixelRatio(m_devicePixelRatio);
325 
326 	m_pageIndex = pageIndex;
327 	m_printOptionsChanged = false;
328 	m_renderingOptionsChanged = false;
329 
330 	return pixmap;
331 }
332 
createPreviewFile(int pageIndex)333 bool PrintPreviewCreator_PS::createPreviewFile(int pageIndex)
334 {
335 	std::vector<int> pageNumbers { pageIndex + 1 };
336 
337 	PrintOptions printOptions(m_printOptions);
338 	printOptions.pageNumbers = pageNumbers;
339 	printOptions.outputSeparations = false;
340 	printOptions.separationName = "All";
341 	printOptions.allSeparations = QStringList();
342 	printOptions.setDevParam = false;
343 
344 	// Disable crop marks
345 	printOptions.cropMarks = false;
346 	printOptions.bleedMarks = false;
347 	printOptions.registrationMarks = false;
348 	printOptions.colorMarks = false;
349 	printOptions.markLength = 20.0;
350 	printOptions.markOffset = 0.0;
351 	printOptions.bleeds.set(0, 0, 0, 0);
352 
353 	// Generate PostScript
354 	QString psFileName = ScPaths::tempFileDir() + "/"  + m_tempBaseName + ".ps";
355 
356 	PSLib *psLib = new PSLib(m_doc, printOptions, PSLib::OutputPS, &m_doc->PageColors);
357 	if (!psLib)
358 		return false;
359 	bool success = (psLib->createPS(psFileName) == 0);
360 	delete psLib;
361 
362 	// TODO : Postscript level < 3
363 	if (success && (printOptions.prnLanguage != PrintLanguage::PostScript3))
364 	{
365 		// use gs to convert our PS to a lower version
366 		QStringList opts;
367 		const ScPage* page = m_doc->Pages->at(pageIndex);
368 		double pageWidth = page->width();
369 		double pageHeight = page->height();
370 		if (page->orientation() == 1)
371 			std::swap(pageWidth, pageHeight);
372 		opts.append( QString("-dDEVICEWIDTHPOINTS=%1").arg(QString::number(pageWidth)) );
373 		opts.append( QString("-dDEVICEHEIGHTPOINTS=%1").arg(QString::number(pageHeight)) );
374 
375 		QString outFileName = ScPaths::tempFileDir() + "/"  + m_tempBaseName + ".ps" + QString::number((int) printOptions.prnLanguage);
376 		success = (convertPS2PS(psFileName, outFileName, opts, (int) printOptions.prnLanguage) == 0);
377 		if (!success)
378 			return false;
379 		success &= QFile::remove(psFileName);
380 		success &= QFile::rename(outFileName, psFileName);
381 	}
382 
383 	return success;
384 }
385 
renderPreview(int pageIndex,int res)386 int PrintPreviewCreator_PS::renderPreview(int pageIndex, int res)
387 {
388 	int ret = -1;
389 	QString cmd1;
390 
391 	QStringList args;
392 	QString tmp, tmp2, tmp3;
393 	int w = qRound(m_doc->Pages->at(pageIndex)->width() * res / 72.0);
394 	int h = qRound(m_doc->Pages->at(pageIndex)->height() * res / 72.0);
395 	if (m_doc->Pages->at(pageIndex)->orientation() == 1)
396 		std::swap(w, h);
397 
398 	args.append( "-q" );
399 	args.append( "-dNOPAUSE" );
400 	args.append( "-dPARANOIDSAFER" );
401 	args.append( QString("-r%1").arg(tmp.setNum(res)) );
402 	args.append( QString("-g%1x%2").arg(tmp2.setNum(w), tmp3.setNum(h)) );
403 	if (m_sepPreviewEnabled)
404 	{
405 		if (!m_haveTiffSep)
406 			return 1;
407 		args.append("-sDEVICE=tiffsep");
408 	}
409 	else
410 	{
411 		if (m_showTransparency && m_havePngAlpha)
412 			args.append("-sDEVICE=pngalpha");
413 		else
414 			args.append("-sDEVICE=tiff24nc");
415 	}
416 	if (m_useAntialiasing)
417 	{
418 		args.append("-dTextAlphaBits=4");
419 		args.append("-dGraphicsAlphaBits=4");
420 	}
421 	if ((m_doc->HasCMS) && (m_gsVersion >= 900))
422 	{
423 		args.append("-sDefaultCMYKProfile=" + QDir::toNativeSeparators(m_doc->DocPrinterProf.profilePath()));
424 		if (m_sepPreviewEnabled)
425 			args.append("-sOutputICCProfile=" + QDir::toNativeSeparators(m_doc->DocPrinterProf.profilePath()));
426 		else
427 			args.append("-sOutputICCProfile=" + QDir::toNativeSeparators(m_doc->DocDisplayProf.profilePath()));
428 	}
429 	else if (ScCore->haveCMS() && (m_gsVersion >= 900))
430 	{
431 		args.append("-sDefaultCMYKProfile=" + QDir::toNativeSeparators(ScCore->defaultCMYKProfile.profilePath()));
432 		if (m_sepPreviewEnabled)
433 			args.append("-sOutputICCProfile=" + QDir::toNativeSeparators(ScCore->defaultCMYKProfile.profilePath()));
434 		else
435 			args.append("-sOutputICCProfile=" + QDir::toNativeSeparators(ScCore->defaultRGBProfile.profilePath()));
436 	}
437 
438 	// Add any extra font paths being used by Scribus to gs's font search path
439 	PrefsContext *pc = m_prefsManager.prefsFile->getContext("Fonts");
440 	PrefsTable *extraFonts = pc->getTable("ExtraFontDirs");
441 	const char sep = ScPaths::envPathSeparator;
442 	if (extraFonts->getRowCount() >= 1)
443 		cmd1 = QString("-sFONTPATH=%1").arg(QDir::toNativeSeparators(extraFonts->get(0,0)));
444 	for (int i = 1; i < extraFonts->getRowCount(); ++i)
445 		cmd1 += QString("%1%2").arg(sep).arg(QDir::toNativeSeparators(extraFonts->get(i,0)));
446 	if (!cmd1.isEmpty())
447 		args.append( cmd1 );
448 
449 	// then add any final args and call gs
450 	QString tempFileDir = ScPaths::tempFileDir() ;
451 	if (m_sepPreviewEnabled)
452 		args.append( QString("-sOutputFile=%1").arg(QDir::toNativeSeparators(tempFileDir + "/" + m_tempBaseName + ".tif")) );
453 	else if (m_showTransparency && m_havePngAlpha)
454 		args.append( QString("-sOutputFile=%1").arg(QDir::toNativeSeparators(tempFileDir + "/" + m_tempBaseName + ".png")) );
455 	else
456 		args.append(QString("-sOutputFile=%1").arg(QDir::toNativeSeparators(tempFileDir + "/" + m_tempBaseName + ".tif")));
457 	args.append( QDir::toNativeSeparators(ScPaths::tempFileDir() + "/" + m_tempBaseName + ".ps") );
458 	args.append( "-c" );
459 	args.append( "showpage" );
460 	args.append( "-c" );
461 	args.append( "quit" );
462 	ret = System(m_prefsManager.ghostscriptExecutable(), args);
463 	return ret;
464 }
465 
renderPreviewSep(int pageIndex,int res)466 int PrintPreviewCreator_PS::renderPreviewSep(int pageIndex, int res)
467 {
468 	int ret = -1;
469 	QString cmd;
470 	QStringList args, args1, args2, args3;
471 
472 	QString tmp, tmp2, tmp3;
473 	int w = qRound(m_doc->Pages->at(pageIndex)->width() * res / 72.0);
474 	int h = qRound(m_doc->Pages->at(pageIndex)->height() * res / 72.0);
475 	if (m_doc->Pages->at(pageIndex)->orientation() == 1)
476 		std::swap(w, h);
477 
478 	args1.append( "-q" );
479 	args1.append( "-dNOPAUSE" );
480 	args1.append( "-dPARANOIDSAFER" );
481 	args1.append( QString("-r%1").arg(tmp.setNum(res)) );
482 	args1.append( QString("-g%1x%2").arg(tmp2.setNum(w), tmp3.setNum(h)) );
483 	if (m_useAntialiasing)
484 	{
485 		args1.append("-dTextAlphaBits=4");
486 		args1.append("-dGraphicsAlphaBits=4");
487 	}
488 	if ((m_doc->HasCMS) && (m_gsVersion >= 900))
489 	{
490 		args1.append("-sDefaultCMYKProfile=" + QDir::toNativeSeparators(m_doc->DocPrinterProf.profilePath()));
491 		args1.append("-sOutputICCProfile=" + QDir::toNativeSeparators(m_doc->DocPrinterProf.profilePath()));
492 	}
493 	else if (ScCore->haveCMS() && (m_gsVersion >= 900))
494 	{
495 		args.append("-sDefaultCMYKProfile=" + QDir::toNativeSeparators(ScCore->defaultCMYKProfile.profilePath()));
496 		args.append("-sOutputICCProfile=" + QDir::toNativeSeparators(ScCore->defaultCMYKProfile.profilePath()));
497 	}
498 
499 	// Add any extra font paths being used by Scribus to gs's font search path
500 	PrefsContext *pc = m_prefsManager.prefsFile->getContext("Fonts");
501 	PrefsTable *extraFonts = pc->getTable("ExtraFontDirs");
502 	const char sep = ScPaths::envPathSeparator;
503 	if (extraFonts->getRowCount() >= 1)
504 		cmd = QString("-sFONTPATH=%1").arg(QDir::toNativeSeparators(extraFonts->get(0,0)));
505 	for (int i = 1; i < extraFonts->getRowCount(); ++i)
506 		cmd += QString("%1%2").arg(sep).arg(QDir::toNativeSeparators(extraFonts->get(i,0)));
507 	if (!cmd.isEmpty())
508 		args1.append(cmd);
509 	args1.append( QString("-sOutputFile=%1").arg(QDir::toNativeSeparators(ScPaths::tempFileDir() + "/" + m_tempBaseName + ".tif")) );
510 
511 	args2.append( QDir::toNativeSeparators(ScPaths::tempFileDir() + "/" + m_tempBaseName + ".ps") );
512 	args2.append("-c");
513 	args2.append("quit");
514 
515 	ColorList usedSpots;
516 	m_doc->getUsedColors(usedSpots, true);
517 	QStringList spots = usedSpots.keys();
518 	args3.append( "-sDEVICE=tiffsep" );
519 
520 //	args3.append( "-c" );
521 	cmd = "<< /SeparationColorNames ";
522 	QString allSeps ="[ /Cyan /Magenta /Yellow /Black ";
523 	for (int sp = 0; sp < spots.count(); ++sp)
524 	{
525 		allSeps += "(" + spots[sp] + ") ";
526 	}
527 	allSeps += "]";
528 	cmd += allSeps + " /SeparationOrder [ /Cyan /Magenta /Yellow /Black] >> setpagedevice";
529 	QFile fx(QDir::toNativeSeparators(ScPaths::tempFileDir() + "/" +  m_tempBaseName + ".sep.ps"));
530 	if (fx.open(QIODevice::WriteOnly))
531 	{
532 		QTextStream tsx(&fx);
533 		tsx << cmd;
534 		fx.close();
535 	}
536 
537 	QString gsExe(getShortPathName(m_prefsManager.ghostscriptExecutable()));
538 	ret = System(gsExe, args1 + args3 + args2, ScPaths::tempFileDir() + "/" +  m_tempBaseName + ".tif.txt" );
539 
540 	QFile sepInfo(QDir::toNativeSeparators(ScPaths::tempFileDir() + "/" +  m_tempBaseName + ".tif.txt"));
541 	m_sepsToFileNum.clear();
542 	if (sepInfo.open(QIODevice::ReadOnly))
543 	{
544 		QString Sname;
545 		QTextStream tsC(&sepInfo);
546 		int counter = 0;
547 		while (!tsC.atEnd())
548 		{
549 			Sname = tsC.readLine();
550 			QString tt = Sname.remove("%%SeparationName:").trimmed();
551 			if (!tt.isEmpty())
552 			{
553 				m_sepsToFileNum.insert(tt, counter);
554 				counter++;
555 			}
556 		}
557 	}
558 	sepInfo.close();
559 	QString currSeps = "";
560 	uint spc = 0;
561 	for (int sp = 0; sp < spots.count(); ++sp)
562 	{
563 		currSeps += "(" + spots[sp] + ") ";
564 		spc++;
565 		if (sp > 6)
566 		{
567 			args3.clear();
568 			args3.append("-sDEVICE=tiffsep");
569 			QFile fx(QDir::toNativeSeparators(ScPaths::tempFileDir() + "/" +  m_tempBaseName + ".sep.ps"));
570 			if (fx.open(QIODevice::WriteOnly))
571 			{
572 				QTextStream tsx(&fx);
573 				tsx << QString("<< /SeparationColorNames " + allSeps + " /SeparationOrder [ " + currSeps + " ] >> setpagedevice");
574 				fx.close();
575 			}
576 			args3.append("-f");
577 			args3.append(QDir::toNativeSeparators(ScPaths::tempFileDir() + "/" +  m_tempBaseName + ".sep.ps"));
578 			ret = System(gsExe, args1 + args3 + args2);
579 			currSeps = "";
580 			spc = 0;
581 		}
582 	}
583 	if (spc != 0)
584 	{
585 		args3.clear();
586 		args3.append("-sDEVICE=tiffsep");
587 		QFile fx(QDir::toNativeSeparators(ScPaths::tempFileDir() + "/" +  m_tempBaseName + ".sep.ps"));
588 		if (fx.open(QIODevice::WriteOnly))
589 		{
590 			QTextStream tsx(&fx);
591 			tsx << QString("<< /SeparationColorNames " + allSeps + " /SeparationOrder [ " + currSeps + " ] >> setpagedevice");
592 			fx.close();
593 		}
594 		args3.append("-f");
595 		args3.append(QDir::toNativeSeparators(ScPaths::tempFileDir() + "/" +  m_tempBaseName + ".sep.ps"));
596 		ret = System(gsExe, args1 + args3 + args2);
597 	}
598 	return ret;
599 }
600 
setPrintOptions(const PrintOptions & options)601 void PrintPreviewCreator_PS::setPrintOptions(const PrintOptions& options)
602 {
603 	m_printOptions = options;
604 	m_printOptions.prnLanguage = PrintLanguage::PostScript3;
605 	m_printOptionsChanged = true;
606 }
607 
imageLoadError(QPixmap & pixmap,int page)608 void PrintPreviewCreator_PS::imageLoadError(QPixmap &pixmap, int page)
609 {
610 	pixmap = QPixmap(1, 1);
611 	m_pageIndex = page;
612 	m_printOptionsChanged = false;
613 	m_renderingOptionsChanged = false;
614 }
615