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 <algorithm>
9 
10 #include <QApplication>
11 #include <QDesktopWidget>
12 #include <QMap>
13 #include <QTransform>
14 #include <QTemporaryFile>
15 
16 #include "outputpreview_ps.h"
17 #include "commonstrings.h"
18 #include "cmsettings.h"
19 #include "filewatcher.h"
20 #include "iconmanager.h"
21 #include "pageitemiterator.h"
22 #include "pslib.h"
23 #include "prefsfile.h"
24 #include "prefsmanager.h"
25 #include "prefstable.h"
26 #include "sccolor.h"
27 #include "sccolorengine.h"
28 #include "scpaths.h"
29 #include "scribus.h"
30 #include "scribuscore.h"
31 #include "scribusdoc.h"
32 #include "util.h"
33 #include "util_ghostscript.h"
34 #include "util_printer.h"
35 
36 #include "ui_outputpreviewbase.h"
37 #include "ui_outputpreview_ps.h"
38 
OutputPreview_PS(QWidget * parent,ScribusDoc * doc)39 OutputPreview_PS::OutputPreview_PS(QWidget* parent, ScribusDoc* doc) :
40 	OutputPreviewBase(parent, doc),
41 	m_printOptions(doc->Print_Options),
42 	m_prefsManager(PrefsManager::instance())
43 {
44 	int inkTableWidth = 0;
45 
46 	setModal(true);
47 	setWindowIcon(IconManager::instance().loadIcon("AppIcon.png"));
48 
49 	QString caption = tr("PostScript Output Preview");
50 	setWindowTitle(caption);
51 
52 	m_havePngAlpha = ScCore->havePNGAlpha();
53 	m_haveTiffSep  = ScCore->haveTIFFSep();
54 	getNumericGSVersion(m_gsVersion);
55 
56 	m_optionsUi = new Ui::OutputPreview_PS();
57 	m_optionsUi->setupUi(m_uiBase->optionWidget);
58 
59 	m_optionsUi->psLevelCombo->addItem(CommonStrings::trPostScript1);
60 	m_optionsUi->psLevelCombo->addItem(CommonStrings::trPostScript2);
61 	m_optionsUi->psLevelCombo->addItem(CommonStrings::trPostScript3);
62 
63 	if (m_haveTiffSep)
64 	{
65 		ColorList usedSpots;
66 		doc->getUsedColors(usedSpots, true);
67 		QStringList spots = usedSpots.keys();
68 
69 		m_inkMax = (spots.count() + 4) * 255;
70 		m_optionsUi->coverThresholdValue->setMaximum((spots.count() + 4) * 100.0);
71 
72 		m_optionsUi->inkTable->setColumnCount(2);
73 		m_optionsUi->inkTable->setRowCount(4 + spots.count());
74 		m_optionsUi->inkTable->setHorizontalHeaderItem(0, new QTableWidgetItem(IconManager::instance().loadIcon("16/show-object.png"), ""));
75 		m_optionsUi->inkTable->setHorizontalHeaderItem(1, new QTableWidgetItem( tr("Separation Name")));
76 
77 		QHeaderView *header = m_optionsUi->inkTable->horizontalHeader();
78 		header->setStretchLastSection(true);
79 		header->setSectionsMovable(false);
80 		header->setSectionResizeMode(QHeaderView::Fixed);
81 
82 		m_optionsUi->inkTable->setColumnWidth(0, 24);
83 		m_optionsUi->inkTable->verticalHeader()->hide();
84 		m_optionsUi->inkTable->setFocusPolicy(Qt::NoFocus);
85 		m_optionsUi->inkTable->setSizeAdjustPolicy(QTableWidget::AdjustToContentsOnFirstShow);
86 
87 		m_optionsUi->inkTable->setItem(0, 1, new QTableWidgetItem( tr("Cyan")));
88 		QCheckBox *cp = new QCheckBox(this);
89 		cp->setFocusPolicy(Qt::NoFocus);
90 		cp->setChecked(true);
91 		connect(cp, SIGNAL(clicked()), this, SLOT(toggleCMYK_Colour()));
92 		m_optionsUi->inkTable->setCellWidget(0, 0, cp);
93 		m_inkVisibilities.insert("Cyan", cp);
94 
95 		m_optionsUi->inkTable->setItem(1, 1, new QTableWidgetItem( tr("Magenta")));
96 		cp = new QCheckBox(this);
97 		cp->setFocusPolicy(Qt::NoFocus);
98 		cp->setChecked(true);
99 		connect(cp, SIGNAL(clicked()), this, SLOT(toggleCMYK_Colour()));
100 		m_optionsUi->inkTable->setCellWidget(1, 0, cp);
101 		m_inkVisibilities.insert("Magenta", cp);
102 
103 		m_optionsUi->inkTable->setItem(2, 1, new QTableWidgetItem( tr("Yellow")));
104 		cp = new QCheckBox(this);
105 		cp->setFocusPolicy(Qt::NoFocus);
106 		cp->setChecked(true);
107 		connect(cp, SIGNAL(clicked()), this, SLOT(toggleCMYK_Colour()));
108 		m_optionsUi->inkTable->setCellWidget(2, 0, cp);
109 		m_inkVisibilities.insert("Yellow", cp);
110 
111 		m_optionsUi->inkTable->setItem(3, 1, new QTableWidgetItem( tr("Black")));
112 		cp = new QCheckBox(this);
113 		cp->setFocusPolicy(Qt::NoFocus);
114 		cp->setChecked(true);
115 		connect(cp, SIGNAL(clicked()), this, SLOT(toggleCMYK_Colour()));
116 		m_optionsUi->inkTable->setCellWidget(3, 0, cp);
117 		m_inkVisibilities.insert("Black", cp);
118 
119 		for (int sp = 0; sp < spots.count(); ++sp)
120 		{
121 			const QString& spotName = spots.at(sp);
122 			m_optionsUi->inkTable->setItem(sp + 4, 1, new QTableWidgetItem(spotName));
123 			cp = new QCheckBox(this);
124 			cp->setFocusPolicy(Qt::NoFocus);
125 			cp->setChecked(true);
126 			connect(cp, SIGNAL(clicked()), this, SLOT(toggleCMYK_Colour()));
127 			m_optionsUi->inkTable->setCellWidget(sp + 4, 0, cp);
128 			m_inkVisibilities.insert(spotName, cp);
129 		}
130 
131 		inkTableWidth = m_optionsUi->inkTable->columnWidth(1);
132 
133 		bool inkCoverageEnabled = (m_optionsUi->enableCMYK->isChecked()) && (m_optionsUi->displayInkCoverage->isChecked());
134 		m_optionsUi->coverThresholdLabel->setEnabled(inkCoverageEnabled);
135 		m_optionsUi->coverThresholdValue->setEnabled(inkCoverageEnabled);
136 		m_optionsUi->coverThresholdValue->setSuffix( tr(" %"));
137 
138 		connect(header, SIGNAL(sectionClicked(int)), this, SLOT(toggleAllFromHeader()));
139 		connect(m_optionsUi->enableCMYK, SIGNAL(clicked()), this, SLOT(toggleCMYK()));
140 		connect(m_optionsUi->displayInkCoverage, SIGNAL(clicked()), this, SLOT(toggleCMYK_Colour()));
141 		connect(m_optionsUi->inkTable, SIGNAL(cellDoubleClicked(int, int)), this, SLOT(onInkTableCellDoubleClicked(int)));
142 	}
143 	else
144 	{
145 		m_optionsUi->enableCMYK->setChecked(false);
146 		m_optionsUi->enableCMYK->setVisible(false);
147 		m_optionsUi->inkTable->setVisible(false);
148 		m_optionsUi->displayInkCoverage->setChecked(false);
149 		m_optionsUi->displayInkCoverage->setVisible(false);
150 		m_optionsUi->coverThresholdLabel->setVisible(false);
151 		m_optionsUi->coverThresholdValue->setVisible(false);
152 	}
153 
154 	bool cmykEnabled = m_optionsUi->enableCMYK->isChecked();
155 	m_optionsUi->inkTable->setEnabled(cmykEnabled);
156 	m_optionsUi->displayInkCoverage->setEnabled(cmykEnabled);
157 	bool isInkCoverageEnabled = m_optionsUi->displayInkCoverage->isChecked();
158 	m_optionsUi->coverThresholdLabel->setEnabled(cmykEnabled && isInkCoverageEnabled);
159 	m_optionsUi->coverThresholdValue->setEnabled(cmykEnabled && isInkCoverageEnabled);
160 
161 	if (m_optionsUi->inkTable->isVisible())
162 		m_optionsUi->inkTable->setEnabled(m_optionsUi->enableCMYK->isChecked());
163 
164 	// Restore display settings from preferences
165 	m_optionsUi->antiAliasing->setChecked(m_prefsManager.appPrefs.psOutputPreviewPrefs.enableAntiAliasing);
166 	m_optionsUi->showTransparency->setChecked(m_prefsManager.appPrefs.psOutputPreviewPrefs.showTransparency);
167 	if (m_optionsUi->inkTable->isVisible() && m_optionsUi->inkTable->isEnabled())
168 	{
169 		m_optionsUi->enableCMYK->setChecked(m_prefsManager.appPrefs.psOutputPreviewPrefs.cmykPreviewMode);
170 		m_inkVisibilities["Cyan"]->setChecked(m_prefsManager.appPrefs.psOutputPreviewPrefs.isCyanVisible);
171 		m_inkVisibilities["Magenta"]->setChecked(m_prefsManager.appPrefs.psOutputPreviewPrefs.isMagentaVisible);
172 		m_inkVisibilities["Magenta"]->setChecked(m_prefsManager.appPrefs.psOutputPreviewPrefs.isYellowVisible);
173 		m_inkVisibilities["Yellow"]->setChecked(m_prefsManager.appPrefs.psOutputPreviewPrefs.isBlackVisible);
174 	}
175 	m_optionsUi->displayInkCoverage->setChecked(m_prefsManager.appPrefs.psOutputPreviewPrefs.displayInkCoverage);
176 	m_optionsUi->coverThresholdValue->setValue(m_prefsManager.appPrefs.psOutputPreviewPrefs.inkCoverageThreshold);
177 
178 	// Generate a template name for temporary files
179 	QTemporaryFile *tempFile = new QTemporaryFile(ScPaths::tempFileDir() + "/scpreview_XXXXXX.ps");
180 	if (tempFile->open())
181 	{
182 		QString tempFileBase = tempFile->fileName();
183 		tempFile->setAutoRemove(false);
184 		tempFile->close();
185 		m_tempBaseName = QFileInfo(tempFileBase).completeBaseName();
186 	}
187 	if (m_tempBaseName.isEmpty())
188 		m_tempBaseName = "scpreview";
189 	delete tempFile;
190 
191 	if (m_printOptions.firstUse)
192 		PrinterUtil::getDefaultPrintOptions(m_printOptions, m_doc->bleedsVal());
193 	m_printOptions.prnLanguage = PrintLanguage::PostScript3;
194 	m_printOptions.outputSeparations = false;
195 	m_printOptions.separationName = "All";
196 	m_printOptions.allSeparations = QStringList();
197 	m_printOptions.setDevParam = false;
198 	m_printOptions.cropMarks = false;
199 	m_printOptions.bleedMarks = false;
200 	m_printOptions.registrationMarks = false;
201 	m_printOptions.colorMarks = false;
202 	m_printOptions.markLength = 20.0;
203 	m_printOptions.markOffset = 0.0;
204 	m_printOptions.bleeds.set(0, 0, 0, 0);
205 	setPrintOptionsToUi(m_printOptions);
206 
207 	// Display preview
208 	QPixmap previewPix = createPreview(m_doc->currentPageNumber(), qRound(72 * m_scaleFactor));
209 	m_previewLabel->setPixmap(previewPix);
210 	m_previewLabel->resize(previewPix.size());
211 
212 	m_uiBase->pageSelector->setGUIForPage(m_doc->currentPage()->pageNr());
213 
214 	int w = m_previewLabel->width() + inkTableWidth + 50;
215 	resize(qMin(QApplication::desktop()->width() - 30, w), 500);
216 
217 	//signals and slots
218 	connect(m_uiBase->pageSelector, SIGNAL(pageChanged(int)), this, SLOT(jumpToPage(int)));
219 	connect(m_uiBase->closeButton, SIGNAL(clicked()), this, SLOT(close()));
220 	connect(m_uiBase->exportButton, SIGNAL(clicked()), this, SIGNAL(doExport()));
221 	connect(m_uiBase->scaleBox, SIGNAL(activated(int)), this, SLOT(onScaleBoxValueChanged(int)));
222 
223 	connect(m_optionsUi->psLevelCombo, SIGNAL(activated(int)), this, SLOT(onPSLevelChanged(int)));
224 	connect(m_optionsUi->colorOutputMode, SIGNAL(activated(int)), this, SLOT(onColorOutputModeChanged(int)));
225 	connect(m_optionsUi->mirrorH, SIGNAL(clicked()), this, SLOT(redisplay()));
226 	connect(m_optionsUi->mirrorV, SIGNAL(clicked()), this, SLOT(redisplay()));
227 	connect(m_optionsUi->clipToMargins, SIGNAL(clicked()), this, SLOT(redisplay()));
228 	connect(m_optionsUi->convertSpots, SIGNAL(clicked()), this, SLOT(redisplay()));
229 	connect(m_optionsUi->enableGCR, SIGNAL(clicked()), this, SLOT(redisplay()));
230 
231 	connect(m_optionsUi->antiAliasing, SIGNAL(clicked()), this, SLOT(redisplay()));
232 	connect(m_optionsUi->showTransparency, SIGNAL(clicked()), this, SLOT(redisplay()));
233 
234 	connect(m_optionsUi->coverThresholdValue, SIGNAL(valueChanged(double)), this, SLOT(toggleCMYK_Colour()));
235 }
236 
~OutputPreview_PS()237 OutputPreview_PS::~OutputPreview_PS()
238 {
239 	cleanupTemporaryFiles();
240 	delete m_optionsUi;
241 }
242 
postscriptLevel() const243 int OutputPreview_PS::postscriptLevel() const
244 {
245 	return m_optionsUi->psLevelCombo->currentIndex() + 1;
246 }
247 
isCMYKPreviewEnabled() const248 bool OutputPreview_PS::isCMYKPreviewEnabled() const
249 {
250 	return m_optionsUi->enableCMYK->isChecked();
251 }
252 
isAntialiasingEnabled() const253 bool OutputPreview_PS::isAntialiasingEnabled() const
254 {
255 	return m_optionsUi->antiAliasing->isChecked();
256 }
257 
isTransparencyEnabled() const258 bool OutputPreview_PS::isTransparencyEnabled() const
259 {
260 	return m_optionsUi->showTransparency->isChecked();
261 }
262 
isInkChannelVisible(const QString & ink)263 bool OutputPreview_PS::isInkChannelVisible(const QString& ink)
264 {
265 	if (m_inkVisibilities.contains(ink))
266 		return m_inkVisibilities[ink]->isChecked();
267 	return false;
268 }
269 
isInkCoverageEnabled() const270 bool OutputPreview_PS::isInkCoverageEnabled() const
271 {
272 	return m_optionsUi->displayInkCoverage->isChecked();
273 }
274 
inkCoverageThreshold() const275 double OutputPreview_PS::inkCoverageThreshold() const
276 {
277 	return m_optionsUi->coverThresholdValue->value();
278 }
279 
cleanupTemporaryFiles()280 void OutputPreview_PS::cleanupTemporaryFiles()
281 {
282 	QString tempFileDir = ScPaths::tempFileDir();
283 	QFile::remove(tempFileDir + "/" + m_tempBaseName + ".ps");
284 	QFile::remove(tempFileDir + "/" + m_tempBaseName + ".png");
285 	QDir d(tempFileDir + "/", m_tempBaseName + "*", QDir::Name, QDir::Files | QDir::NoSymLinks);
286 	if ((d.exists()) && (d.count() != 0))
287 	{
288 		for (uint i = 0; i < d.count(); i++)
289 			QFile::remove(tempFileDir + "/" + d[i]);
290 	}
291 }
292 
createPreview(int pageIndex,int res)293 QPixmap OutputPreview_PS::createPreview(int pageIndex, int res)
294 {
295 	int ret = -1;
296 	int gsRes = qRound(res * devicePixelRatioF());
297 	int w = qRound(m_doc->Pages->at(pageIndex)->width() * gsRes / 72.0);
298 	int h = qRound(m_doc->Pages->at(pageIndex)->height() * gsRes / 72.0);
299 
300 	qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
301 
302 	QPixmap pixmap;
303 	if (psOptionsHaveChanged(pageIndex))
304 	{
305 		bool success = createPreviewFile(pageIndex);
306 		if (!success)
307 		{
308 			imageLoadError(pixmap);
309 			return pixmap;
310 		}
311 	}
312 
313 	if (optionsHaveChanged(pageIndex))
314 	{
315 		if (m_optionsUi->enableCMYK->isChecked() && m_haveTiffSep)
316 			ret = renderPreviewSep(pageIndex, gsRes);
317 		else
318 			ret = renderPreview(pageIndex, gsRes);
319 		if (ret > 0)
320 		{
321 			imageLoadError(pixmap);
322 			return pixmap;
323 		}
324 	}
325 
326 	QImage image;
327 	if (m_optionsUi->enableCMYK->isChecked() && m_haveTiffSep)
328 	{
329 		bool loadError;
330 		int cyan, magenta, yellow, black;
331 
332 		ScImage im;
333 		bool mode;
334 		int w2 = w;
335 		int h2 = h;
336 		if (m_doc->Pages->at(pageIndex)->orientation() == 1)
337 			std::swap(w2, h2);
338 		image = QImage(w2, h2, QImage::Format_ARGB32);
339 		image.fill(qRgba(0, 0, 0, 0));
340 
341 		QStringList separationNames { "Cyan", "Magenta", "Yellow" };
342 		CMSettings cms(m_doc, "", Intent_Perceptual);
343 		cms.allowColorManagement(false);
344 		for (int i = 0; i < separationNames.count(); ++i)
345 		{
346 			QString separationName = separationNames.at(i);
347 			if (!m_inkVisibilities[separationName]->isChecked())
348 				continue;
349 			if (m_gsVersion < 854)
350 				loadError = im.loadPicture(ScPaths::tempFileDir() + "/" + m_tempBaseName + ".tif." + separationName + ".tif", 1, cms, ScImage::RGBData, 72, &mode);
351 			else if (m_gsVersion <= 905)
352 				loadError = im.loadPicture(ScPaths::tempFileDir() + "/" + m_tempBaseName + "." + separationName + ".tif", 1, cms, ScImage::RGBData, 72, &mode);
353 			else
354 				loadError = im.loadPicture(ScPaths::tempFileDir() + "/" + m_tempBaseName + "(" + separationName + ").tif", 1, cms, ScImage::RGBData, 72, &mode);
355 			if (!loadError)
356 			{
357 				imageLoadError(pixmap);
358 				return pixmap;
359 			}
360 			if (m_optionsUi->displayInkCoverage->isChecked())
361 				blendImagesSumUp(image, im);
362 			else
363 			{
364 				int c = (i == 0) ? 255 : 0;
365 				int m = (i == 1) ? 255 : 0;
366 				int j = (i == 2) ? 255 : 0;
367 				blendImages(image, im, ScColor(c, m, j, 0));
368 			}
369 		}
370 
371 		for (auto sepit = m_sepsToFileNum.begin(); sepit != m_sepsToFileNum.end(); ++sepit)
372 		{
373 			const QCheckBox* checkBox = m_inkVisibilities.value(sepit.key(), nullptr);
374 			if (!checkBox || !checkBox->isChecked())
375 				continue;
376 			QString sepFileName;
377 			if (m_gsVersion < 854)
378 				sepFileName = QString(ScPaths::tempFileDir() + "/" + m_tempBaseName + ".tif.s%1.tif").arg(sepit.value());
379 			else if (m_gsVersion <= 905)
380 				sepFileName = QString(ScPaths::tempFileDir() + "/" + m_tempBaseName + ".s%1.tif").arg(sepit.value());
381 			else
382 				sepFileName = QString(ScPaths::tempFileDir() + "/" + m_tempBaseName + "(%1).tif").arg(sepit.key());
383 			if (!im.loadPicture(sepFileName, 1, cms, ScImage::RGBData, 72, &mode))
384 			{
385 				imageLoadError(pixmap);
386 				return pixmap;
387 			}
388 			if (m_optionsUi->displayInkCoverage->isChecked())
389 				blendImagesSumUp(image, im);
390 			else
391 				blendImages(image, im, m_doc->PageColors[sepit.key()]);
392 		}
393 
394 		if (m_inkVisibilities["Black"]->isChecked())
395 		{
396 			CMSettings cms(m_doc, "", Intent_Perceptual);
397 			cms.allowColorManagement(false);
398 			if (m_gsVersion < 854)
399 				loadError = im.loadPicture(ScPaths::tempFileDir() + "/" + m_tempBaseName + ".tif.Black.tif", 1, cms, ScImage::RGBData, 72, &mode);
400 			else if (m_gsVersion <= 905)
401 				loadError = im.loadPicture(ScPaths::tempFileDir() + "/" + m_tempBaseName + ".Black.tif", 1, cms, ScImage::RGBData, 72, &mode);
402 			else
403 				loadError = im.loadPicture(ScPaths::tempFileDir() + "/" + m_tempBaseName + "(Black).tif", 1, cms, ScImage::RGBData, 72, &mode);
404 			if (!loadError)
405 			{
406 				imageLoadError(pixmap);
407 				return pixmap;
408 			}
409 			if (m_optionsUi->displayInkCoverage->isChecked())
410 				blendImagesSumUp(image, im);
411 			else
412 				blendImages(image, im, ScColor(0, 0, 0, 255));
413 		}
414 
415 		if (m_optionsUi->displayInkCoverage->isChecked())
416 		{
417 			uint limitVal = (m_optionsUi->coverThresholdValue->value() * 255) / 100;
418 			for (int yi = 0; yi < h2; ++yi)
419 			{
420 				QRgb *q = (QRgb*) image.scanLine(yi);
421 				for (int xi = 0; xi < w2; ++xi)
422 				{
423 					uint greyVal = *q;
424 					if (greyVal != 0)
425 					{
426 						if (limitVal == 0)
427 						{
428 							QColor tmpC;
429 							tmpC.setHsv((greyVal * 359) / m_inkMax, 255, 255);
430 							*q = tmpC.rgba();
431 						}
432 						else
433 						{
434 							int col = qMin(255 - static_cast<int>(((greyVal * 128) / m_inkMax) * 2), 255);
435 							if ((*q > 0) && (*q < limitVal))
436 								*q = qRgba(col, col, col, 255);
437 							else
438 								*q = qRgba(col, 0, 0, 255);
439 						}
440 					}
441 					else
442 					{
443 						if (!m_optionsUi->showTransparency->isChecked())
444 							*q = qRgba(255, 255, 255, 255);
445 					}
446 					q++;
447 				}
448 			}
449 		}
450 		else if (m_doc->HasCMS || ScCore->haveCMS())
451 		{
452 			QRgb alphaFF = qRgba(0,0,0,255);
453 			QRgb alphaOO = qRgba(255,255,255,0);
454 			ScColorMgmtEngine engine = m_doc->colorEngine;
455 			ScColorProfile cmykProfile = m_doc->HasCMS ? m_doc->DocPrinterProf : ScCore->defaultCMYKProfile;
456 			ScColorProfile rgbProfile  = m_doc->HasCMS ? m_doc->DocDisplayProf : ScCore->defaultRGBProfile;
457 			ScColorTransform transCMYK = engine.createTransform(cmykProfile, Format_YMCK_8, rgbProfile, Format_BGRA_8, Intent_Relative_Colorimetric, 0);
458 			for (int yi = 0; yi < h2; ++yi)
459 			{
460 				uchar* ptr = image.scanLine( yi );
461 				transCMYK.apply(ptr, ptr, image.width());
462 				QRgb *q = (QRgb *) ptr;
463 				for (int xi = 0; xi < image.width(); xi++, q++)
464 				{
465 					if (m_optionsUi->showTransparency->isChecked())
466 					{
467 						cyan = qRed(*q);
468 						magenta = qGreen(*q);
469 						yellow = qBlue(*q);
470 						if	((cyan == 255) && (magenta == 255) && (yellow == 255))
471 							*q = alphaOO;
472 						else
473 							*q |= alphaFF;
474 					}
475 					else
476 						*q |= alphaFF;
477 				}
478 			}
479 		}
480 		else
481 		{
482 			for (int yi = 0; yi < h2; ++yi)
483 			{
484 				QRgb *q = (QRgb*) image.scanLine(yi);
485 				for (int xi = 0; xi < w2; ++xi)
486 				{
487 					cyan = qRed(*q);
488 					magenta = qGreen(*q);
489 					yellow = qBlue(*q);
490 					black = qAlpha(*q);
491 					if ((cyan != 0) || (magenta != 0) || (yellow != 0 ) || (black != 0))
492 						*q = qRgba(255 - qMin(255, cyan + black), 255 - qMin(255, magenta + black), 255 - qMin(255, yellow + black), 255);
493 					else
494 					{
495 						if (!m_optionsUi->showTransparency->isChecked())
496 							*q = qRgba(255, 255, 255, 255);
497 					}
498 					q++;
499 				}
500 			}
501 		}
502 	}
503 	else
504 	{
505 		QString previewFile;
506 		if (m_optionsUi->showTransparency->isChecked() && m_havePngAlpha)
507 			previewFile = ScPaths::tempFileDir() + "/" + m_tempBaseName + ".png";
508 		else
509 			previewFile = ScPaths::tempFileDir() + "/" + m_tempBaseName + ".tif";
510 		if (!image.load(previewFile))
511 		{
512 			imageLoadError(pixmap);
513 			return pixmap;
514 		}
515 		image = image.convertToFormat(QImage::Format_ARGB32);
516 		if (m_optionsUi->showTransparency->isChecked() && m_havePngAlpha)
517 		{
518 			int wi = image.width();
519 			int hi = image.height();
520 			for (int yi = 0; yi < hi; ++yi)
521 			{
522 				QRgb *s = (QRgb*) image.scanLine(yi);
523 				for (int xi = 0; xi < wi; ++xi)
524 				{
525 					if ((*s) == 0xffffffff)
526 						(*s) &= 0x00ffffff;
527 					s++;
528 				}
529 			}
530 		}
531 	}
532 
533 	const ScPage* page = m_doc->Pages->at(pageIndex);
534 	if ((page->orientation() == 1) && (image.width() < image.height()))
535 		image = image.transformed( QTransform(0, 1, -1, 0, 0, 0) );
536 
537 	image.setDevicePixelRatio(devicePixelRatioF());
538 	if (m_optionsUi->showTransparency->isChecked())
539 	{
540 		pixmap = QPixmap(image.width(), image.height());
541 		pixmap.setDevicePixelRatio(devicePixelRatioF());
542 		QPainter p;
543 		QBrush b(QColor(205,205,205), IconManager::instance().loadPixmap("testfill.png"));
544 		p.begin(&pixmap);
545 		p.fillRect(0, 0, image.width(), image.height(), b);
546 		p.drawImage(0, 0, image);
547 		p.end();
548 	}
549 	else
550 		pixmap = QPixmap::fromImage(image);
551 	pixmap.setDevicePixelRatio(devicePixelRatioF());
552 
553 	qApp->restoreOverrideCursor();
554 	updateOptionsFromUI();
555 	return pixmap;
556 }
557 
createPreviewFile(int pageIndex)558 bool OutputPreview_PS::createPreviewFile(int pageIndex)
559 {
560 	std::vector<int> pageNumbers { pageIndex + 1 };
561 
562 	setUiOptionsToPrintOptions(m_printOptions);
563 	m_printOptions.pageNumbers = pageNumbers;
564 	m_printOptions.outputSeparations = false;
565 	m_printOptions.separationName = "All";
566 	m_printOptions.allSeparations = QStringList();
567 	m_printOptions.setDevParam = false;
568 
569 	// Disable crop marks
570 	m_printOptions.cropMarks = false;
571 	m_printOptions.bleedMarks = false;
572 	m_printOptions.registrationMarks = false;
573 	m_printOptions.colorMarks = false;
574 	m_printOptions.markLength = 20.0;
575 	m_printOptions.markOffset = 0.0;
576 	m_printOptions.bleeds.set(0, 0, 0, 0);
577 
578 	// Generate PostScript
579 	QString psFileName = ScPaths::tempFileDir() + "/"  + m_tempBaseName + ".ps";
580 
581 	PSLib *psLib = new PSLib(m_doc, m_printOptions, PSLib::OutputPS, &m_doc->PageColors);
582 	if (!psLib)
583 		return false;
584 	bool success = (psLib->createPS(psFileName) == 0);
585 	delete psLib;
586 
587 	// TODO : Postscript level < 3
588 	if (success && (m_printOptions.prnLanguage != PrintLanguage::PostScript3))
589 	{
590 		// use gs to convert our PS to a lower version
591 		QStringList opts;
592 		const ScPage* page = m_doc->Pages->at(pageIndex);
593 		double pageWidth = page->width();
594 		double pageHeight = page->height();
595 		if (page->orientation() == 1)
596 			std::swap(pageWidth, pageHeight);
597 		opts.append( QString("-dDEVICEWIDTHPOINTS=%1").arg(QString::number(pageWidth)) );
598 		opts.append( QString("-dDEVICEHEIGHTPOINTS=%1").arg(QString::number(pageHeight)) );
599 
600 		QString outFileName = ScPaths::tempFileDir() + "/"  + m_tempBaseName + ".ps" + QString::number((int) m_printOptions.prnLanguage);
601 		success = (convertPS2PS(psFileName, outFileName, opts, (int) m_printOptions.prnLanguage) == 0);
602 		if (!success)
603 			return false;
604 		success &= QFile::remove(psFileName);
605 		success &= QFile::rename(outFileName, psFileName);
606 	}
607 
608 	return success;
609 }
610 
renderPreview(int pageIndex,int res)611 int OutputPreview_PS::renderPreview(int pageIndex, int res)
612 {
613 	int ret = -1;
614 	QString cmd1;
615 
616 	QStringList args;
617 	QString tmp, tmp2, tmp3;
618 	int w = qRound(m_doc->Pages->at(pageIndex)->width() * res / 72.0);
619 	int h = qRound(m_doc->Pages->at(pageIndex)->height() * res / 72.0);
620 	if (m_doc->Pages->at(pageIndex)->orientation() == 1)
621 		std::swap(w, h);
622 
623 	args.append( "-q" );
624 	args.append( "-dNOPAUSE" );
625 	args.append( "-dPARANOIDSAFER" );
626 	args.append( QString("-r%1").arg(tmp.setNum(res)) );
627 	args.append( QString("-g%1x%2").arg(tmp2.setNum(w), tmp3.setNum(h)) );
628 	if (m_optionsUi->enableCMYK->isChecked())
629 	{
630 		if (!m_haveTiffSep)
631 			return 1;
632 		args.append("-sDEVICE=tiffsep");
633 	}
634 	else
635 	{
636 		if (m_optionsUi->showTransparency->isChecked() && m_havePngAlpha)
637 			args.append("-sDEVICE=pngalpha");
638 		else
639 			args.append("-sDEVICE=tiff24nc");
640 	}
641 	if (m_optionsUi->antiAliasing->isChecked())
642 	{
643 		args.append("-dTextAlphaBits=4");
644 		args.append("-dGraphicsAlphaBits=4");
645 	}
646 	if ((m_doc->HasCMS) && (m_gsVersion >= 900))
647 	{
648 		args.append("-sDefaultCMYKProfile=" + QDir::toNativeSeparators(m_doc->DocPrinterProf.profilePath()));
649 		if (m_optionsUi->enableCMYK->isChecked())
650 			args.append("-sOutputICCProfile=" + QDir::toNativeSeparators(m_doc->DocPrinterProf.profilePath()));
651 		else
652 			args.append("-sOutputICCProfile=" + QDir::toNativeSeparators(m_doc->DocDisplayProf.profilePath()));
653 	}
654 	else if (ScCore->haveCMS() && (m_gsVersion >= 900))
655 	{
656 		args.append("-sDefaultCMYKProfile=" + QDir::toNativeSeparators(ScCore->defaultCMYKProfile.profilePath()));
657 		if (m_optionsUi->enableCMYK->isChecked())
658 			args.append("-sOutputICCProfile=" + QDir::toNativeSeparators(ScCore->defaultCMYKProfile.profilePath()));
659 		else
660 			args.append("-sOutputICCProfile=" + QDir::toNativeSeparators(ScCore->defaultRGBProfile.profilePath()));
661 	}
662 
663 	// Add any extra font paths being used by Scribus to gs's font search path
664 	PrefsContext *pc = m_prefsManager.prefsFile->getContext("Fonts");
665 	PrefsTable *extraFonts = pc->getTable("ExtraFontDirs");
666 	const char sep = ScPaths::envPathSeparator;
667 	if (extraFonts->getRowCount() >= 1)
668 		cmd1 = QString("-sFONTPATH=%1").arg(QDir::toNativeSeparators(extraFonts->get(0,0)));
669 	for (int i = 1; i < extraFonts->getRowCount(); ++i)
670 		cmd1 += QString("%1%2").arg(sep).arg(QDir::toNativeSeparators(extraFonts->get(i,0)));
671 	if (!cmd1.isEmpty())
672 		args.append( cmd1 );
673 
674 	// then add any final args and call gs
675 	QString tempFileDir = ScPaths::tempFileDir() ;
676 	if (m_optionsUi->enableCMYK->isChecked())
677 		args.append( QString("-sOutputFile=%1").arg(QDir::toNativeSeparators(tempFileDir + "/" + m_tempBaseName + ".tif")) );
678 	else if (m_optionsUi->showTransparency->isChecked() && m_havePngAlpha)
679 		args.append( QString("-sOutputFile=%1").arg(QDir::toNativeSeparators(tempFileDir + "/" + m_tempBaseName + ".png")) );
680 	else
681 		args.append(QString("-sOutputFile=%1").arg(QDir::toNativeSeparators(tempFileDir + "/" + m_tempBaseName + ".tif")));
682 	args.append( QDir::toNativeSeparators(ScPaths::tempFileDir() + "/" + m_tempBaseName + ".ps") );
683 	args.append( "-c" );
684 	args.append( "showpage" );
685 	args.append( "-c" );
686 	args.append( "quit" );
687 	ret = System(m_prefsManager.ghostscriptExecutable(), args);
688 	return ret;
689 }
690 
renderPreviewSep(int pageIndex,int res)691 int OutputPreview_PS::renderPreviewSep(int pageIndex, int res)
692 {
693 	int ret = -1;
694 	QString cmd;
695 	QStringList args, args1, args2, args3;
696 
697 	QString tmp, tmp2, tmp3;
698 	int w = qRound(m_doc->Pages->at(pageIndex)->width() * res / 72.0);
699 	int h = qRound(m_doc->Pages->at(pageIndex)->height() * res / 72.0);
700 	if (m_doc->Pages->at(pageIndex)->orientation() == 1)
701 		std::swap(w, h);
702 
703 	args1.append( "-q" );
704 	args1.append( "-dNOPAUSE" );
705 	args1.append( "-dPARANOIDSAFER" );
706 	args1.append( QString("-r%1").arg(tmp.setNum(res)) );
707 	args1.append( QString("-g%1x%2").arg(tmp2.setNum(w), tmp3.setNum(h)) );
708 	if (m_optionsUi->antiAliasing->isChecked())
709 	{
710 		args1.append("-dTextAlphaBits=4");
711 		args1.append("-dGraphicsAlphaBits=4");
712 	}
713 	if ((m_doc->HasCMS) && (m_gsVersion >= 900))
714 	{
715 		args1.append("-sDefaultCMYKProfile=" + QDir::toNativeSeparators(m_doc->DocPrinterProf.profilePath()));
716 		args1.append("-sOutputICCProfile=" + QDir::toNativeSeparators(m_doc->DocPrinterProf.profilePath()));
717 	}
718 	else if (ScCore->haveCMS() && (m_gsVersion >= 900))
719 	{
720 		args.append("-sDefaultCMYKProfile=" + QDir::toNativeSeparators(ScCore->defaultCMYKProfile.profilePath()));
721 		args.append("-sOutputICCProfile=" + QDir::toNativeSeparators(ScCore->defaultCMYKProfile.profilePath()));
722 	}
723 
724 	// Add any extra font paths being used by Scribus to gs's font search path
725 	PrefsContext *pc = m_prefsManager.prefsFile->getContext("Fonts");
726 	PrefsTable *extraFonts = pc->getTable("ExtraFontDirs");
727 	const char sep = ScPaths::envPathSeparator;
728 	if (extraFonts->getRowCount() >= 1)
729 		cmd = QString("-sFONTPATH=%1").arg(QDir::toNativeSeparators(extraFonts->get(0,0)));
730 	for (int i = 1; i < extraFonts->getRowCount(); ++i)
731 		cmd += QString("%1%2").arg(sep).arg(QDir::toNativeSeparators(extraFonts->get(i,0)));
732 	if (!cmd.isEmpty())
733 		args1.append(cmd);
734 	args1.append( QString("-sOutputFile=%1").arg(QDir::toNativeSeparators(ScPaths::tempFileDir() + "/" + m_tempBaseName + ".tif")) );
735 
736 	args2.append( QDir::toNativeSeparators(ScPaths::tempFileDir() + "/" + m_tempBaseName + ".ps") );
737 	args2.append("-c");
738 	args2.append("quit");
739 
740 	ColorList usedSpots;
741 	m_doc->getUsedColors(usedSpots, true);
742 	QStringList spots = usedSpots.keys();
743 	args3.append( "-sDEVICE=tiffsep" );
744 
745 //	args3.append( "-c" );
746 	cmd = "<< /SeparationColorNames ";
747 	QString allSeps ="[ /Cyan /Magenta /Yellow /Black ";
748 	for (int sp = 0; sp < spots.count(); ++sp)
749 	{
750 		allSeps += "(" + spots[sp] + ") ";
751 	}
752 	allSeps += "]";
753 	cmd += allSeps + " /SeparationOrder [ /Cyan /Magenta /Yellow /Black] >> setpagedevice";
754 	QFile fx(QDir::toNativeSeparators(ScPaths::tempFileDir() + "/" +  m_tempBaseName + ".sep.ps"));
755 	if (fx.open(QIODevice::WriteOnly))
756 	{
757 		QTextStream tsx(&fx);
758 		tsx << cmd;
759 		fx.close();
760 	}
761 
762 	QString gsExe(getShortPathName(m_prefsManager.ghostscriptExecutable()));
763 	ret = System(gsExe, args1 + args3 + args2, ScPaths::tempFileDir() + "/" +  m_tempBaseName + ".tif.txt" );
764 
765 	QFile sepInfo(QDir::toNativeSeparators(ScPaths::tempFileDir() + "/" +  m_tempBaseName + ".tif.txt"));
766 	m_sepsToFileNum.clear();
767 	if (sepInfo.open(QIODevice::ReadOnly))
768 	{
769 		QString Sname;
770 		QTextStream tsC(&sepInfo);
771 		int counter = 0;
772 		while (!tsC.atEnd())
773 		{
774 			Sname = tsC.readLine();
775 			QString tt = Sname.remove("%%SeparationName:").trimmed();
776 			if (!tt.isEmpty())
777 			{
778 				m_sepsToFileNum.insert(tt, counter);
779 				counter++;
780 			}
781 		}
782 	}
783 	sepInfo.close();
784 	QString currSeps = "";
785 	uint spc = 0;
786 	for (int sp = 0; sp < spots.count(); ++sp)
787 	{
788 		currSeps += "(" + spots[sp] + ") ";
789 		spc++;
790 		if (sp > 6)
791 		{
792 			args3.clear();
793 			args3.append("-sDEVICE=tiffsep");
794 			QFile fx(QDir::toNativeSeparators(ScPaths::tempFileDir() + "/" +  m_tempBaseName + ".sep.ps"));
795 			if (fx.open(QIODevice::WriteOnly))
796 			{
797 				QTextStream tsx(&fx);
798 				tsx << QString("<< /SeparationColorNames " + allSeps + " /SeparationOrder [ " + currSeps + " ] >> setpagedevice");
799 				fx.close();
800 			}
801 			args3.append("-f");
802 			args3.append(QDir::toNativeSeparators(ScPaths::tempFileDir() + "/" +  m_tempBaseName + ".sep.ps"));
803 			ret = System(gsExe, args1 + args3 + args2);
804 			currSeps = "";
805 			spc = 0;
806 		}
807 	}
808 	if (spc != 0)
809 	{
810 		args3.clear();
811 		args3.append("-sDEVICE=tiffsep");
812 		QFile fx(QDir::toNativeSeparators(ScPaths::tempFileDir() + "/" +  m_tempBaseName + ".sep.ps"));
813 		if (fx.open(QIODevice::WriteOnly))
814 		{
815 			QTextStream tsx(&fx);
816 			tsx << QString("<< /SeparationColorNames " + allSeps + " /SeparationOrder [ " + currSeps + " ] >> setpagedevice");
817 			fx.close();
818 		}
819 		args3.append("-f");
820 		args3.append(QDir::toNativeSeparators(ScPaths::tempFileDir() + "/" +  m_tempBaseName + ".sep.ps"));
821 		ret = System(gsExe, args1 + args3 + args2);
822 	}
823 	return ret;
824 }
825 
optionsHaveChanged(int pageIndex) const826 bool OutputPreview_PS::optionsHaveChanged(int pageIndex) const
827 {
828 	if (m_currentPage != pageIndex)
829 		return true;
830 	if (m_scaleMode != m_uiBase->scaleBox->currentIndex())
831 		return true;
832 	if (m_cmykPreviewMode != m_optionsUi->enableCMYK->isChecked())
833 		return true;
834 	if (m_useAntialiasing != m_optionsUi->antiAliasing->isChecked())
835 		return true;
836 	if (m_showTransparency != m_optionsUi->showTransparency->isChecked())
837 		return true;
838 
839 	if (m_psLevel != m_optionsUi->psLevelCombo->currentIndex() + 1)
840 		return true;
841 	if (m_colorOutputMode != m_optionsUi->colorOutputMode->currentIndex())
842 		return true;
843 	if (m_mirrorH != m_optionsUi->mirrorH->isChecked())
844 		return true;
845 	if (m_mirrorV != m_optionsUi->mirrorV->isChecked())
846 		return true;
847 	if (m_clipToMargins != m_optionsUi->clipToMargins->isChecked())
848 		return true;
849 	if (m_convertSpots != m_optionsUi->convertSpots->isChecked())
850 		return true;
851 	if (m_enableGCR != m_optionsUi->enableGCR->isChecked())
852 		return true;
853 
854 	return false;
855 }
856 
psOptionsHaveChanged(int pageIndex) const857 bool OutputPreview_PS::psOptionsHaveChanged(int pageIndex) const
858 {
859 	if (m_currentPage != pageIndex)
860 		return true;
861 
862 	if (m_psLevel != m_optionsUi->psLevelCombo->currentIndex() + 1)
863 		return true;
864 	if (m_colorOutputMode != m_optionsUi->colorOutputMode->currentIndex())
865 		return true;
866 	if (m_mirrorH != m_optionsUi->mirrorH->isChecked())
867 		return true;
868 	if (m_mirrorV != m_optionsUi->mirrorV->isChecked())
869 		return true;
870 	if (m_clipToMargins != m_optionsUi->clipToMargins->isChecked())
871 		return true;
872 	if (m_convertSpots != m_optionsUi->convertSpots->isChecked())
873 		return true;
874 	if (m_enableGCR != m_optionsUi->enableGCR->isChecked())
875 		return true;
876 
877 	return false;
878 }
879 
setPrintOptionsToOptions(PrintOptions & prnOptions)880 void OutputPreview_PS::setPrintOptionsToOptions(PrintOptions& prnOptions)
881 {
882 	// TODO : finish
883 	m_psLevel = qMax(1, qMin((int) prnOptions.prnLanguage, 3));
884 
885 	m_colorOutputMode = prnOptions.useColor ? 0 : 1;
886 	m_mirrorH = prnOptions.mirrorH;
887 	m_mirrorV = prnOptions.mirrorV;
888 	m_clipToMargins = prnOptions.doClip;
889 	m_convertSpots  = !prnOptions.useSpotColors;
890 	m_enableGCR = prnOptions.doGCR;
891 }
892 
setPrintOptionsToUi(PrintOptions & prnOptions)893 void OutputPreview_PS::setPrintOptionsToUi(PrintOptions& prnOptions)
894 {
895 	// TODO : finish
896 	int psLevel = qMax(1, qMin((int) prnOptions.prnLanguage, 3));
897 	m_optionsUi->psLevelCombo->setCurrentIndex(psLevel - 1);
898 
899 	m_optionsUi->colorOutputMode->setCurrentIndex(prnOptions.useColor ? 0 : 1);
900 	m_optionsUi->mirrorH->setChecked(prnOptions.mirrorH);
901 	m_optionsUi->mirrorV->setChecked(prnOptions.mirrorV);
902 	m_optionsUi->clipToMargins->setChecked(prnOptions.doClip);
903 	m_optionsUi->convertSpots->setChecked(!prnOptions.useSpotColors);
904 	m_optionsUi->enableGCR->setChecked(prnOptions.doGCR);
905 
906 	bool cmykEnabled = m_optionsUi->enableCMYK->isChecked();
907 	m_optionsUi->inkTable->setEnabled(cmykEnabled);
908 	m_optionsUi->displayInkCoverage->setEnabled(cmykEnabled);
909 	bool isInkCoverageEnabled = m_optionsUi->displayInkCoverage->isChecked();
910 	m_optionsUi->coverThresholdLabel->setEnabled(cmykEnabled && isInkCoverageEnabled);
911 	m_optionsUi->coverThresholdValue->setEnabled(cmykEnabled && isInkCoverageEnabled);
912 }
913 
setUiOptionsToPrintOptions(PrintOptions & prnOptions)914 void OutputPreview_PS::setUiOptionsToPrintOptions(PrintOptions& prnOptions)
915 {
916 	// TODO : finish
917 	prnOptions.prnLanguage = (PrintLanguage) (m_optionsUi->psLevelCombo->currentIndex() + 1);
918 
919 	prnOptions.useColor = (m_optionsUi->colorOutputMode->currentIndex() == 0);
920 	prnOptions.mirrorH = m_optionsUi->mirrorH->isChecked();
921 	prnOptions.mirrorV = m_optionsUi->mirrorV->isChecked();
922 	prnOptions.doClip  = m_optionsUi->clipToMargins->isChecked();
923 	prnOptions.useSpotColors = !m_optionsUi->convertSpots->isChecked();
924 	prnOptions.doGCR = m_optionsUi->enableGCR->isChecked();
925 }
926 
updateOptionsFromUI()927 void OutputPreview_PS::updateOptionsFromUI()
928 {
929 	// TODO : finish
930 	m_psLevel = m_optionsUi->psLevelCombo->currentIndex() + 1;
931 	m_colorOutputMode = m_optionsUi->colorOutputMode->currentIndex();
932 	m_mirrorH = m_optionsUi->mirrorH->isChecked();
933 	m_mirrorV = m_optionsUi->mirrorV->isChecked();
934 	m_clipToMargins = m_optionsUi->clipToMargins->isChecked();
935 	m_convertSpots = m_optionsUi->convertSpots->isChecked();
936 	m_enableGCR = m_optionsUi->enableGCR->isChecked();
937 
938 	m_currentPage = m_uiBase->pageSelector->getCurrentPage() - 1;
939 	m_scaleMode = m_uiBase->scaleBox->currentIndex();
940 	m_cmykPreviewMode = m_optionsUi->enableCMYK->isChecked();
941 	m_useAntialiasing = m_optionsUi->antiAliasing->isChecked();
942 	m_showTransparency = m_optionsUi->showTransparency->isChecked();
943 }
944 
onPSLevelChanged(int)945 void OutputPreview_PS::onPSLevelChanged(int /*index*/)
946 {
947 	redisplay();
948 }
949 
onColorOutputModeChanged(int)950 void OutputPreview_PS::onColorOutputModeChanged(int /*index*/)
951 {
952 	redisplay();
953 }
954 
onInkTableCellDoubleClicked(int row)955 void OutputPreview_PS::onInkTableCellDoubleClicked(int row)
956 {
957 	if (!m_haveTiffSep)
958 		return;
959 
960 	for (auto sepIt = m_inkVisibilities.begin(); sepIt != m_inkVisibilities.end(); ++sepIt)
961 		sepIt.value()->setChecked(false);
962 	((QCheckBox*)(m_optionsUi->inkTable->cellWidget(row, 0)))->setChecked(true);
963 
964 	if (m_optionsUi->enableCMYK->isChecked())
965 		m_previewLabel->setPixmap(createPreview(m_currentPage, qRound(72 * m_scaleFactor)));
966 	m_previewLabel->resize(m_previewLabel->pixmap()->size());
967 }
968 
toggleAllFromHeader()969 void OutputPreview_PS::toggleAllFromHeader()
970 {
971 	if (!m_haveTiffSep)
972 		return;
973 
974 	for (auto sepIt = m_inkVisibilities.begin(); sepIt != m_inkVisibilities.end(); ++sepIt)
975 		sepIt.value()->setChecked(true);
976 
977 	if (m_optionsUi->enableCMYK->isChecked())
978 		m_previewLabel->setPixmap(createPreview(m_currentPage, qRound(72 * m_scaleFactor)));
979 	m_previewLabel->resize(m_previewLabel->pixmap()->size());
980 }
981 
toggleCMYK()982 void OutputPreview_PS::toggleCMYK()
983 {
984 	if (!m_haveTiffSep)
985 		return;
986 
987 	bool cmykEnabled = m_optionsUi->enableCMYK->isChecked();
988 	m_optionsUi->inkTable->setEnabled(cmykEnabled);
989 	m_optionsUi->displayInkCoverage->setEnabled(cmykEnabled);
990 	bool isInkCoverageEnabled = m_optionsUi->displayInkCoverage->isChecked();
991 	m_optionsUi->coverThresholdLabel->setEnabled(cmykEnabled && isInkCoverageEnabled);
992 	m_optionsUi->coverThresholdValue->setEnabled(cmykEnabled && isInkCoverageEnabled);
993 
994 	redisplay();
995 }
996 
toggleCMYK_Colour()997 void OutputPreview_PS::toggleCMYK_Colour()
998 {
999 	if (m_haveTiffSep)
1000 	{
1001 		bool inkCoverageEnabled = (m_optionsUi->enableCMYK->isChecked()) && (m_optionsUi->displayInkCoverage->isChecked());
1002 		m_optionsUi->coverThresholdLabel->setEnabled(inkCoverageEnabled);
1003 		m_optionsUi->coverThresholdValue->setEnabled(inkCoverageEnabled);
1004 	}
1005 	if (m_optionsUi->enableCMYK->isChecked())
1006 		m_previewLabel->setPixmap(createPreview(m_currentPage, qRound(72 * m_scaleFactor)));
1007 	m_previewLabel->resize(m_previewLabel->pixmap()->size());
1008 }
1009 
imageLoadError(QPixmap & pixmap)1010 void OutputPreview_PS::imageLoadError(QPixmap &pixmap)
1011 {
1012 	pixmap = QPixmap(1, 1);
1013 	qApp->restoreOverrideCursor();
1014 	updateOptionsFromUI();
1015 }
1016