Rev 25070 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
23829 | jghali | 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 <QApplication> |
||
9 | #include <QMap> |
||
24839 | craig | 10 | #include <QScreen> |
23829 | jghali | 11 | #include <QTemporaryFile> |
12 | |||
13 | #include "outputpreview_pdf.h" |
||
14 | #include "cmsettings.h" |
||
15 | #include "filewatcher.h" |
||
16 | #include "iconmanager.h" |
||
17 | #include "pageitemiterator.h" |
||
18 | #include "pdflib.h" |
||
19 | #include "pdflib_core.h" |
||
20 | #include "prefsfile.h" |
||
21 | #include "prefsmanager.h" |
||
22 | #include "prefstable.h" |
||
23 | #include "sccolor.h" |
||
24 | #include "sccolorengine.h" |
||
25 | #include "scpaths.h" |
||
26 | #include "scribus.h" |
||
27 | #include "scribuscore.h" |
||
28 | #include "scribusdoc.h" |
||
29 | #include "util.h" |
||
30 | #include "util_ghostscript.h" |
||
31 | |||
32 | #include "ui_outputpreviewbase.h" |
||
33 | #include "ui_outputpreview_pdf.h" |
||
34 | |||
35 | OutputPreview_PDF::OutputPreview_PDF(QWidget* parent, ScribusDoc* doc) : |
||
36 | OutputPreviewBase(parent, doc), |
||
37 | m_pdfOptions(doc->pdfOptions()), |
||
38 | m_prefsManager(PrefsManager::instance()) |
||
39 | { |
||
40 | int inkTableWidth = 0; |
||
41 | |||
42 | setModal(true); |
||
43 | setWindowIcon(IconManager::instance().loadIcon("AppIcon.png")); |
||
44 | |||
45 | QString caption = tr("PDF Output Preview"); |
||
46 | setWindowTitle(caption); |
||
47 | |||
48 | m_havePngAlpha = ScCore->havePNGAlpha(); |
||
49 | m_haveTiffSep = ScCore->haveTIFFSep(); |
||
50 | getNumericGSVersion(m_gsVersion); |
||
51 | |||
52 | m_optionsUi = new Ui::OutputPreview_PDF(); |
||
53 | m_optionsUi->setupUi(m_uiBase->optionWidget); |
||
54 | |||
55 | if (m_haveTiffSep) |
||
56 | { |
||
57 | ColorList usedSpots; |
||
58 | doc->getUsedColors(usedSpots, true); |
||
59 | QStringList spots = usedSpots.keys(); |
||
60 | |||
61 | m_inkMax = (spots.count() + 4) * 255; |
||
24010 | jghali | 62 | m_optionsUi->coverThresholdValue->setMaximum((spots.count() + 4) * 100.0); |
23829 | jghali | 63 | |
64 | m_optionsUi->inkTable->setColumnCount(2); |
||
65 | m_optionsUi->inkTable->setRowCount(4 + spots.count()); |
||
66 | m_optionsUi->inkTable->setHorizontalHeaderItem(0, new QTableWidgetItem(IconManager::instance().loadIcon("16/show-object.png"), "")); |
||
67 | m_optionsUi->inkTable->setHorizontalHeaderItem(1, new QTableWidgetItem( tr("Separation Name"))); |
||
68 | |||
69 | QHeaderView *header = m_optionsUi->inkTable->horizontalHeader(); |
||
70 | header->setStretchLastSection(true); |
||
71 | header->setSectionsMovable(false); |
||
72 | header->setSectionResizeMode(QHeaderView::Fixed); |
||
73 | |||
74 | m_optionsUi->inkTable->setColumnWidth(0, 24); |
||
75 | m_optionsUi->inkTable->verticalHeader()->hide(); |
||
76 | m_optionsUi->inkTable->setFocusPolicy(Qt::NoFocus); |
||
77 | m_optionsUi->inkTable->setSizeAdjustPolicy(QTableWidget::AdjustToContentsOnFirstShow); |
||
78 | |||
79 | m_optionsUi->inkTable->setItem(0, 1, new QTableWidgetItem( tr("Cyan"))); |
||
80 | QCheckBox *cp = new QCheckBox(this); |
||
81 | cp->setFocusPolicy(Qt::NoFocus); |
||
82 | cp->setChecked(true); |
||
83 | connect(cp, SIGNAL(clicked()), this, SLOT(toggleCMYK_Colour())); |
||
84 | m_optionsUi->inkTable->setCellWidget(0, 0, cp); |
||
85 | m_inkVisibilities.insert("Cyan", cp); |
||
86 | |||
87 | m_optionsUi->inkTable->setItem(1, 1, new QTableWidgetItem( tr("Magenta"))); |
||
88 | 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(1, 0, cp); |
||
93 | m_inkVisibilities.insert("Magenta", cp); |
||
94 | |||
95 | m_optionsUi->inkTable->setItem(2, 1, new QTableWidgetItem( tr("Yellow"))); |
||
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(2, 0, cp); |
||
101 | m_inkVisibilities.insert("Yellow", cp); |
||
102 | |||
103 | m_optionsUi->inkTable->setItem(3, 1, new QTableWidgetItem( tr("Black"))); |
||
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(3, 0, cp); |
||
109 | m_inkVisibilities.insert("Black", cp); |
||
110 | |||
111 | for (int sp = 0; sp < spots.count(); ++sp) |
||
112 | { |
||
113 | const QString& spotName = spots.at(sp); |
||
114 | m_optionsUi->inkTable->setItem(sp + 4, 1, new QTableWidgetItem(spotName)); |
||
115 | cp = new QCheckBox(this); |
||
116 | cp->setFocusPolicy(Qt::NoFocus); |
||
117 | cp->setChecked(true); |
||
118 | connect(cp, SIGNAL(clicked()), this, SLOT(toggleCMYK_Colour())); |
||
119 | m_optionsUi->inkTable->setCellWidget(sp + 4, 0, cp); |
||
120 | m_inkVisibilities.insert(spotName, cp); |
||
121 | } |
||
122 | |||
123 | inkTableWidth = m_optionsUi->inkTable->columnWidth(1); |
||
124 | |||
23834 | jghali | 125 | bool inkCoverageEnabled = (m_optionsUi->enableCMYK->isChecked()) && (m_optionsUi->displayInkCoverage->isChecked()); |
126 | m_optionsUi->coverThresholdLabel->setEnabled(inkCoverageEnabled); |
||
127 | m_optionsUi->coverThresholdValue->setEnabled(inkCoverageEnabled); |
||
23829 | jghali | 128 | m_optionsUi->coverThresholdValue->setSuffix( tr(" %")); |
129 | |||
130 | connect(header, SIGNAL(sectionClicked(int)), this, SLOT(toggleAllFromHeader())); |
||
131 | connect(m_optionsUi->enableCMYK, SIGNAL(clicked()), this, SLOT(toggleCMYK())); |
||
132 | connect(m_optionsUi->displayInkCoverage, SIGNAL(clicked()), this, SLOT(toggleCMYK_Colour())); |
||
24931 | craig | 133 | connect(m_optionsUi->inkTable, SIGNAL(cellDoubleClicked(int,int)), this, SLOT(onInkTableCellDoubleClicked(int))); |
23829 | jghali | 134 | } |
135 | else |
||
136 | { |
||
137 | m_optionsUi->enableCMYK->setChecked(false); |
||
138 | m_optionsUi->enableCMYK->setVisible(false); |
||
139 | m_optionsUi->inkTable->setVisible(false); |
||
140 | m_optionsUi->displayInkCoverage->setChecked(false); |
||
141 | m_optionsUi->displayInkCoverage->setVisible(false); |
||
142 | m_optionsUi->coverThresholdLabel->setVisible(false); |
||
143 | m_optionsUi->coverThresholdValue->setVisible(false); |
||
144 | } |
||
145 | |||
146 | bool cmykEnabled = m_optionsUi->enableCMYK->isChecked(); |
||
147 | m_optionsUi->inkTable->setEnabled(cmykEnabled); |
||
148 | m_optionsUi->displayInkCoverage->setEnabled(cmykEnabled); |
||
149 | bool isInkCoverageEnabled = m_optionsUi->displayInkCoverage->isChecked(); |
||
23834 | jghali | 150 | m_optionsUi->coverThresholdLabel->setEnabled(cmykEnabled && isInkCoverageEnabled); |
23829 | jghali | 151 | m_optionsUi->coverThresholdValue->setEnabled(cmykEnabled && isInkCoverageEnabled); |
152 | |||
153 | if (m_optionsUi->inkTable->isVisible()) |
||
154 | m_optionsUi->inkTable->setEnabled(m_optionsUi->enableCMYK->isChecked()); |
||
155 | |||
156 | // Restore display settings from preferences |
||
157 | m_optionsUi->antiAliasing->setChecked(m_prefsManager.appPrefs.pdfOutputPreviewPrefs.enableAntiAliasing); |
||
158 | m_optionsUi->showTransparency->setChecked(m_prefsManager.appPrefs.pdfOutputPreviewPrefs.showTransparency); |
||
159 | if (m_optionsUi->inkTable->isVisible() && m_optionsUi->inkTable->isEnabled()) |
||
160 | { |
||
161 | m_optionsUi->enableCMYK->setChecked(m_prefsManager.appPrefs.pdfOutputPreviewPrefs.cmykPreviewMode); |
||
162 | m_inkVisibilities["Cyan"]->setChecked(m_prefsManager.appPrefs.pdfOutputPreviewPrefs.isCyanVisible); |
||
163 | m_inkVisibilities["Magenta"]->setChecked(m_prefsManager.appPrefs.pdfOutputPreviewPrefs.isMagentaVisible); |
||
164 | m_inkVisibilities["Magenta"]->setChecked(m_prefsManager.appPrefs.pdfOutputPreviewPrefs.isYellowVisible); |
||
165 | m_inkVisibilities["Yellow"]->setChecked(m_prefsManager.appPrefs.pdfOutputPreviewPrefs.isBlackVisible); |
||
166 | } |
||
167 | m_optionsUi->displayInkCoverage->setChecked(m_prefsManager.appPrefs.pdfOutputPreviewPrefs.displayInkCoverage); |
||
168 | m_optionsUi->coverThresholdValue->setValue(m_prefsManager.appPrefs.pdfOutputPreviewPrefs.inkCoverageThreshold); |
||
169 | |||
170 | // Generate a template name for temporary files |
||
171 | QTemporaryFile *tempFile = new QTemporaryFile(ScPaths::tempFileDir() + "/scpreview_XXXXXX.pdf"); |
||
172 | if (tempFile->open()) |
||
173 | { |
||
174 | QString tempFileBase = tempFile->fileName(); |
||
175 | tempFile->setAutoRemove(false); |
||
176 | tempFile->close(); |
||
177 | m_tempBaseName = QFileInfo(tempFileBase).completeBaseName(); |
||
178 | } |
||
179 | if (m_tempBaseName.isEmpty()) |
||
180 | m_tempBaseName = "scpreview"; |
||
181 | delete tempFile; |
||
182 | |||
183 | setPDFOptionsToUi(m_pdfOptions); |
||
184 | |||
185 | // Display preview |
||
186 | QPixmap previewPix = createPreview(m_doc->currentPageNumber(), qRound(72 * m_scaleFactor)); |
||
187 | m_previewLabel->setPixmap(previewPix); |
||
188 | m_previewLabel->resize(previewPix.size()); |
||
189 | |||
24049 | jghali | 190 | m_uiBase->pageSelector->setGUIForPage(m_doc->currentPage()->pageNr()); |
191 | |||
23829 | jghali | 192 | int w = m_previewLabel->width() + inkTableWidth + 50; |
24839 | craig | 193 | resize(qMin(ScCore->primaryMainWindow()->screen()->size().width() - 30, w), 500); |
23829 | jghali | 194 | |
195 | //signals and slots |
||
196 | connect(m_uiBase->pageSelector, SIGNAL(pageChanged(int)), this, SLOT(jumpToPage(int))); |
||
197 | connect(m_uiBase->closeButton, SIGNAL(clicked()), this, SLOT(close())); |
||
198 | connect(m_uiBase->exportButton, SIGNAL(clicked()), this, SIGNAL(doExport())); |
||
199 | connect(m_uiBase->scaleBox, SIGNAL(activated(int)), this, SLOT(onScaleBoxValueChanged(int))); |
||
200 | |||
201 | connect(m_optionsUi->pdfVersionCombo, SIGNAL(activated(int)), this, SLOT(onPdfVersionChanged(int))); |
||
202 | connect(m_optionsUi->outputModeCombo, SIGNAL(activated(int)), this, SLOT(onPdfOutputModeChanged(int))); |
||
203 | connect(m_optionsUi->mirrorH, SIGNAL(clicked()), this, SLOT(redisplay())); |
||
204 | connect(m_optionsUi->mirrorV, SIGNAL(clicked()), this, SLOT(redisplay())); |
||
205 | connect(m_optionsUi->clipToMargins, SIGNAL(clicked()), this, SLOT(redisplay())); |
||
206 | connect(m_optionsUi->convertSpots, SIGNAL(clicked()), this, SLOT(redisplay())); |
||
207 | |||
208 | connect(m_optionsUi->antiAliasing, SIGNAL(clicked()), this, SLOT(redisplay())); |
||
209 | connect(m_optionsUi->showTransparency, SIGNAL(clicked()), this, SLOT(redisplay())); |
||
24010 | jghali | 210 | |
211 | connect(m_optionsUi->coverThresholdValue, SIGNAL(valueChanged(double)), this, SLOT(toggleCMYK_Colour())); |
||
23829 | jghali | 212 | } |
213 | |||
214 | OutputPreview_PDF::~OutputPreview_PDF() |
||
215 | { |
||
216 | cleanupTemporaryFiles(); |
||
217 | delete m_optionsUi; |
||
218 | } |
||
219 | |||
220 | bool OutputPreview_PDF::isCMYKPreviewEnabled() const |
||
221 | { |
||
222 | return m_optionsUi->enableCMYK->isChecked(); |
||
223 | } |
||
224 | |||
225 | bool OutputPreview_PDF::isAntialiasingEnabled() const |
||
226 | { |
||
227 | return m_optionsUi->antiAliasing->isChecked(); |
||
228 | } |
||
229 | |||
230 | bool OutputPreview_PDF::isTransparencyEnabled() const |
||
231 | { |
||
232 | return m_optionsUi->showTransparency->isChecked(); |
||
233 | } |
||
234 | |||
235 | bool OutputPreview_PDF::isInkChannelVisible(const QString& ink) |
||
236 | { |
||
237 | if (m_inkVisibilities.contains(ink)) |
||
238 | return m_inkVisibilities[ink]->isChecked(); |
||
239 | return false; |
||
240 | } |
||
241 | |||
242 | bool OutputPreview_PDF::isInkCoverageEnabled() const |
||
243 | { |
||
244 | return m_optionsUi->displayInkCoverage->isChecked(); |
||
245 | } |
||
246 | |||
247 | double OutputPreview_PDF::inkCoverageThreshold() const |
||
248 | { |
||
249 | return m_optionsUi->coverThresholdValue->value(); |
||
250 | } |
||
251 | |||
252 | void OutputPreview_PDF::cleanupTemporaryFiles() |
||
253 | { |
||
254 | QString tempFileDir = ScPaths::tempFileDir(); |
||
255 | QFile::remove(tempFileDir + "/" + m_tempBaseName + ".pdf"); |
||
256 | QFile::remove(tempFileDir + "/" + m_tempBaseName + ".png"); |
||
257 | QDir d(tempFileDir + "/", m_tempBaseName + "*", QDir::Name, QDir::Files | QDir::NoSymLinks); |
||
258 | if ((d.exists()) && (d.count() != 0)) |
||
259 | { |
||
260 | for (uint i = 0; i < d.count(); i++) |
||
261 | QFile::remove(tempFileDir + "/" + d[i]); |
||
262 | } |
||
263 | } |
||
264 | |||
265 | QPixmap OutputPreview_PDF::createPreview(int pageIndex, int res) |
||
266 | { |
||
267 | int ret = -1; |
||
24308 | jghali | 268 | int gsRes = qRound(res * devicePixelRatioF()); |
269 | int w = qRound(m_doc->Pages->at(pageIndex)->width() * gsRes / 72.0); |
||
270 | int h = qRound(m_doc->Pages->at(pageIndex)->height() * gsRes / 72.0); |
||
23829 | jghali | 271 | |
272 | qApp->setOverrideCursor(QCursor(Qt::WaitCursor)); |
||
273 | |||
274 | QPixmap pixmap; |
||
275 | if (pdfOptionsHaveChanged(pageIndex)) |
||
276 | { |
||
277 | bool success = createPreviewFile(pageIndex); |
||
278 | if (!success) |
||
279 | { |
||
280 | imageLoadError(pixmap); |
||
281 | return pixmap; |
||
282 | } |
||
283 | } |
||
284 | |||
285 | if (optionsHaveChanged(pageIndex)) |
||
286 | { |
||
287 | if (m_optionsUi->enableCMYK->isChecked() && m_haveTiffSep) |
||
24308 | jghali | 288 | ret = renderPreviewSep(pageIndex, gsRes); |
23829 | jghali | 289 | else |
24308 | jghali | 290 | ret = renderPreview(pageIndex, gsRes); |
23829 | jghali | 291 | if (ret > 0) |
292 | { |
||
293 | imageLoadError(pixmap); |
||
294 | return pixmap; |
||
295 | } |
||
296 | } |
||
297 | |||
298 | QImage image; |
||
299 | if (m_optionsUi->enableCMYK->isChecked() && m_haveTiffSep) |
||
300 | { |
||
301 | bool loadError; |
||
302 | int cyan, magenta, yellow, black; |
||
303 | |||
304 | ScImage im; |
||
305 | bool mode; |
||
24308 | jghali | 306 | int w2 = w; |
307 | int h2 = h; |
||
23829 | jghali | 308 | image = QImage(w2, h2, QImage::Format_ARGB32); |
309 | image.fill(qRgba(0, 0, 0, 0)); |
||
310 | |||
311 | QStringList separationNames { "Cyan", "Magenta", "Yellow" }; |
||
312 | CMSettings cms(m_doc, "", Intent_Perceptual); |
||
313 | cms.allowColorManagement(false); |
||
314 | for (int i = 0; i < separationNames.count(); ++i) |
||
315 | { |
||
316 | QString separationName = separationNames.at(i); |
||
317 | if (!m_inkVisibilities[separationName]->isChecked()) |
||
318 | continue; |
||
319 | if (m_gsVersion < 854) |
||
320 | loadError = im.loadPicture(ScPaths::tempFileDir() + "/" + m_tempBaseName + ".tif." + separationName + ".tif", 1, cms, ScImage::RGBData, 72, &mode); |
||
321 | else if (m_gsVersion <= 905) |
||
322 | loadError = im.loadPicture(ScPaths::tempFileDir() + "/" + m_tempBaseName + "." + separationName + ".tif", 1, cms, ScImage::RGBData, 72, &mode); |
||
323 | else |
||
324 | loadError = im.loadPicture(ScPaths::tempFileDir() + "/" + m_tempBaseName + "(" + separationName + ").tif", 1, cms, ScImage::RGBData, 72, &mode); |
||
325 | if (!loadError) |
||
326 | { |
||
327 | imageLoadError(pixmap); |
||
328 | return pixmap; |
||
329 | } |
||
330 | if (m_optionsUi->displayInkCoverage->isChecked()) |
||
331 | blendImagesSumUp(image, im); |
||
332 | else |
||
333 | { |
||
334 | int c = (i == 0) ? 255 : 0; |
||
335 | int m = (i == 1) ? 255 : 0; |
||
336 | int j = (i == 2) ? 255 : 0; |
||
337 | blendImages(image, im, ScColor(c, m, j, 0)); |
||
338 | } |
||
339 | } |
||
340 | |||
341 | for (auto sepit = m_sepsToFileNum.begin(); sepit != m_sepsToFileNum.end(); ++sepit) |
||
342 | { |
||
343 | const QCheckBox* checkBox = m_inkVisibilities.value(sepit.key(), nullptr); |
||
344 | if (!checkBox || !checkBox->isChecked()) |
||
345 | continue; |
||
346 | QString sepFileName; |
||
347 | if (m_gsVersion < 854) |
||
348 | sepFileName = QString(ScPaths::tempFileDir() + "/" + m_tempBaseName + ".tif.s%1.tif").arg(sepit.value()); |
||
349 | else if (m_gsVersion <= 905) |
||
350 | sepFileName = QString(ScPaths::tempFileDir() + "/" + m_tempBaseName + ".s%1.tif").arg(sepit.value()); |
||
351 | else |
||
352 | sepFileName = QString(ScPaths::tempFileDir() + "/" + m_tempBaseName + "(%1).tif").arg(sepit.key()); |
||
353 | if (!im.loadPicture(sepFileName, 1, cms, ScImage::RGBData, 72, &mode)) |
||
354 | { |
||
355 | imageLoadError(pixmap); |
||
356 | return pixmap; |
||
357 | } |
||
358 | if (m_optionsUi->displayInkCoverage->isChecked()) |
||
359 | blendImagesSumUp(image, im); |
||
360 | else |
||
361 | blendImages(image, im, m_doc->PageColors[sepit.key()]); |
||
362 | } |
||
363 | |||
364 | if (m_inkVisibilities["Black"]->isChecked()) |
||
365 | { |
||
366 | CMSettings cms(m_doc, "", Intent_Perceptual); |
||
367 | cms.allowColorManagement(false); |
||
368 | if (m_gsVersion < 854) |
||
369 | loadError = im.loadPicture(ScPaths::tempFileDir() + "/" + m_tempBaseName + ".tif.Black.tif", 1, cms, ScImage::RGBData, 72, &mode); |
||
370 | else if (m_gsVersion <= 905) |
||
371 | loadError = im.loadPicture(ScPaths::tempFileDir() + "/" + m_tempBaseName + ".Black.tif", 1, cms, ScImage::RGBData, 72, &mode); |
||
372 | else |
||
373 | loadError = im.loadPicture(ScPaths::tempFileDir() + "/" + m_tempBaseName + "(Black).tif", 1, cms, ScImage::RGBData, 72, &mode); |
||
374 | if (!loadError) |
||
375 | { |
||
376 | imageLoadError(pixmap); |
||
377 | return pixmap; |
||
378 | } |
||
379 | if (m_optionsUi->displayInkCoverage->isChecked()) |
||
380 | blendImagesSumUp(image, im); |
||
381 | else |
||
382 | blendImages(image, im, ScColor(0, 0, 0, 255)); |
||
383 | } |
||
384 | |||
385 | if (m_optionsUi->displayInkCoverage->isChecked()) |
||
386 | { |
||
387 | uint limitVal = (m_optionsUi->coverThresholdValue->value() * 255) / 100; |
||
388 | for (int yi = 0; yi < h2; ++yi) |
||
389 | { |
||
390 | QRgb *q = (QRgb*) image.scanLine(yi); |
||
391 | for (int xi = 0; xi < w2; ++xi) |
||
392 | { |
||
393 | uint greyVal = *q; |
||
394 | if (greyVal != 0) |
||
395 | { |
||
396 | if (limitVal == 0) |
||
397 | { |
||
398 | QColor tmpC; |
||
399 | tmpC.setHsv((greyVal * 359) / m_inkMax, 255, 255); |
||
400 | *q = tmpC.rgba(); |
||
401 | } |
||
402 | else |
||
403 | { |
||
404 | int col = qMin(255 - static_cast<int>(((greyVal * 128) / m_inkMax) * 2), 255); |
||
405 | if ((*q > 0) && (*q < limitVal)) |
||
406 | *q = qRgba(col, col, col, 255); |
||
407 | else |
||
408 | *q = qRgba(col, 0, 0, 255); |
||
409 | } |
||
410 | } |
||
411 | else |
||
412 | { |
||
413 | if (!m_optionsUi->showTransparency->isChecked()) |
||
414 | *q = qRgba(255, 255, 255, 255); |
||
415 | } |
||
416 | q++; |
||
417 | } |
||
418 | } |
||
419 | } |
||
420 | else if (m_doc->HasCMS || ScCore->haveCMS()) |
||
421 | { |
||
422 | QRgb alphaFF = qRgba(0,0,0,255); |
||
423 | QRgb alphaOO = qRgba(255,255,255,0); |
||
424 | ScColorMgmtEngine engine = m_doc->colorEngine; |
||
425 | ScColorProfile cmykProfile = m_doc->HasCMS ? m_doc->DocPrinterProf : ScCore->defaultCMYKProfile; |
||
426 | ScColorProfile rgbProfile = m_doc->HasCMS ? m_doc->DocDisplayProf : ScCore->defaultRGBProfile; |
||
427 | ScColorTransform transCMYK = engine.createTransform(cmykProfile, Format_YMCK_8, rgbProfile, Format_BGRA_8, Intent_Relative_Colorimetric, 0); |
||
428 | for (int yi = 0; yi < h2; ++yi) |
||
429 | { |
||
430 | uchar* ptr = image.scanLine( yi ); |
||
431 | transCMYK.apply(ptr, ptr, image.width()); |
||
432 | QRgb *q = (QRgb *) ptr; |
||
433 | for (int xi = 0; xi < image.width(); xi++, q++) |
||
434 | { |
||
435 | if (m_optionsUi->showTransparency->isChecked()) |
||
436 | { |
||
437 | cyan = qRed(*q); |
||
438 | magenta = qGreen(*q); |
||
439 | yellow = qBlue(*q); |
||
440 | if ((cyan == 255) && (magenta == 255) && (yellow == 255)) |
||
441 | *q = alphaOO; |
||
442 | else |
||
443 | *q |= alphaFF; |
||
444 | } |
||
445 | else |
||
446 | *q |= alphaFF; |
||
447 | } |
||
448 | } |
||
449 | } |
||
450 | else |
||
451 | { |
||
452 | for (int yi = 0; yi < h2; ++yi) |
||
453 | { |
||
454 | QRgb *q = (QRgb*) image.scanLine(yi); |
||
455 | for (int xi = 0; xi < w2; ++xi) |
||
456 | { |
||
457 | cyan = qRed(*q); |
||
458 | magenta = qGreen(*q); |
||
459 | yellow = qBlue(*q); |
||
460 | black = qAlpha(*q); |
||
461 | if ((cyan != 0) || (magenta != 0) || (yellow != 0 ) || (black != 0)) |
||
462 | *q = qRgba(255 - qMin(255, cyan + black), 255 - qMin(255, magenta + black), 255 - qMin(255, yellow + black), 255); |
||
463 | else |
||
464 | { |
||
465 | if (!m_optionsUi->showTransparency->isChecked()) |
||
466 | *q = qRgba(255, 255, 255, 255); |
||
467 | } |
||
468 | q++; |
||
469 | } |
||
470 | } |
||
471 | } |
||
472 | } |
||
473 | else |
||
474 | { |
||
475 | QString previewFile; |
||
476 | if (m_optionsUi->showTransparency->isChecked() && m_havePngAlpha) |
||
477 | previewFile = ScPaths::tempFileDir() + "/" + m_tempBaseName + ".png"; |
||
478 | else |
||
479 | previewFile = ScPaths::tempFileDir() + "/" + m_tempBaseName + ".tif"; |
||
480 | if (!image.load(previewFile)) |
||
481 | { |
||
482 | imageLoadError(pixmap); |
||
483 | return pixmap; |
||
484 | } |
||
485 | image = image.convertToFormat(QImage::Format_ARGB32); |
||
486 | if (m_optionsUi->showTransparency->isChecked() && m_havePngAlpha) |
||
487 | { |
||
488 | int wi = image.width(); |
||
489 | int hi = image.height(); |
||
490 | for (int yi = 0; yi < hi; ++yi) |
||
491 | { |
||
492 | QRgb *s = (QRgb*) image.scanLine(yi); |
||
493 | for (int xi = 0; xi < wi; ++xi) |
||
494 | { |
||
495 | if ((*s) == 0xffffffff) |
||
496 | (*s) &= 0x00ffffff; |
||
497 | s++; |
||
498 | } |
||
499 | } |
||
500 | } |
||
501 | } |
||
502 | |||
24308 | jghali | 503 | image.setDevicePixelRatio(devicePixelRatioF()); |
23829 | jghali | 504 | if (m_optionsUi->showTransparency->isChecked()) |
505 | { |
||
506 | pixmap = QPixmap(image.width(), image.height()); |
||
24308 | jghali | 507 | pixmap.setDevicePixelRatio(devicePixelRatioF()); |
23829 | jghali | 508 | QPainter p; |
509 | QBrush b(QColor(205,205,205), IconManager::instance().loadPixmap("testfill.png")); |
||
510 | p.begin(&pixmap); |
||
511 | p.fillRect(0, 0, image.width(), image.height(), b); |
||
512 | p.drawImage(0, 0, image); |
||
513 | p.end(); |
||
514 | } |
||
515 | else |
||
516 | pixmap = QPixmap::fromImage(image); |
||
24308 | jghali | 517 | pixmap.setDevicePixelRatio(devicePixelRatioF()); |
23829 | jghali | 518 | |
519 | qApp->restoreOverrideCursor(); |
||
520 | updateOptionsFromUI(); |
||
521 | return pixmap; |
||
522 | } |
||
523 | |||
524 | bool OutputPreview_PDF::createPreviewFile(int pageIndex) |
||
525 | { |
||
526 | if (!m_fontEmbeddingWasSet) |
||
527 | { |
||
528 | setupFontEmbedding(m_pdfOptions); |
||
529 | m_fontEmbeddingWasSet = true; |
||
530 | } |
||
531 | |||
532 | std::vector<int> pageNumbers { pageIndex + 1 }; |
||
533 | |||
534 | setUiOptionsToPDFOptions(m_pdfOptions); |
||
535 | m_pdfOptions.Encrypt = false; // Disable PDF encryption for preview |
||
536 | m_pdfOptions.Thumbnails = false; //Disable thumbnails too |
||
537 | |||
538 | QString profileDescription; |
||
539 | if ((m_pdfOptions.Version == PDFVersion::PDF_X3) || (m_pdfOptions.Version == PDFVersion::PDF_X1a) || (m_pdfOptions.Version == PDFVersion::PDF_X4)) |
||
540 | { |
||
541 | if (m_pdfOptions.Info.isEmpty()) |
||
542 | { |
||
543 | auto& printerProfiles = ScCore->PrinterProfiles; |
||
544 | ScColorProfile outputProfile = m_doc->colorEngine.openProfileFromFile( printerProfiles[m_pdfOptions.PrintProf] ); |
||
545 | profileDescription = outputProfile.productDescription(); |
||
546 | m_pdfOptions.Info = profileDescription; |
||
547 | } |
||
548 | m_pdfOptions.MirrorH = false; |
||
549 | m_pdfOptions.MirrorV = false; |
||
550 | m_pdfOptions.PresentMode = false; |
||
551 | } |
||
552 | |||
553 | // Disable crop marks |
||
554 | m_pdfOptions.cropMarks = false; |
||
555 | m_pdfOptions.bleedMarks = false; |
||
556 | m_pdfOptions.registrationMarks = false; |
||
557 | m_pdfOptions.colorMarks = false; |
||
558 | m_pdfOptions.markLength = 20.0; |
||
559 | m_pdfOptions.markOffset = 0.0; |
||
560 | m_pdfOptions.bleeds.set(0, 0, 0, 0); |
||
561 | |||
562 | // Generate PDF |
||
24137 | craig | 563 | // QString errorString; |
23829 | jghali | 564 | QString pdfFileName = ScPaths::tempFileDir() + "/" + m_tempBaseName + ".pdf"; |
565 | |||
566 | ScCore->fileWatcher->forceScan(); |
||
567 | ScCore->fileWatcher->stop(); |
||
568 | PDFlib pdflib(*m_doc, m_pdfOptions); |
||
569 | bool success = pdflib.doExport(pdfFileName, pageNumbers, QMap<int, QImage>()); |
||
570 | success &= !pdflib.exportAborted(); |
||
571 | ScCore->fileWatcher->start(); |
||
572 | |||
573 | return success; |
||
574 | } |
||
575 | |||
576 | int OutputPreview_PDF::renderPreview(int pageIndex, int res) |
||
577 | { |
||
578 | int ret = -1; |
||
579 | QString cmd1; |
||
580 | |||
581 | QStringList args; |
||
582 | QString tmp, tmp2, tmp3; |
||
24308 | jghali | 583 | int w = qRound(m_doc->Pages->at(pageIndex)->width() * res / 72.0); |
584 | int h = qRound(m_doc->Pages->at(pageIndex)->height() * res / 72.0); |
||
585 | |||
23829 | jghali | 586 | args.append( "-q" ); |
587 | args.append( "-dNOPAUSE" ); |
||
588 | args.append( "-dPARANOIDSAFER" ); |
||
589 | args.append( QString("-r%1").arg(tmp.setNum(res)) ); |
||
24308 | jghali | 590 | args.append( QString("-g%1x%2").arg(tmp2.setNum(w), tmp3.setNum(h)) ); |
23829 | jghali | 591 | if (m_optionsUi->enableCMYK->isChecked()) |
592 | { |
||
593 | if (!m_haveTiffSep) |
||
594 | return 1; |
||
24133 | jghali | 595 | args.append("-sDEVICE=tiffsep"); |
23829 | jghali | 596 | } |
597 | else |
||
598 | { |
||
599 | if (m_optionsUi->showTransparency->isChecked() && m_havePngAlpha) |
||
600 | args.append("-sDEVICE=pngalpha"); |
||
601 | else |
||
602 | args.append("-sDEVICE=tiff24nc"); |
||
603 | } |
||
604 | if (m_optionsUi->antiAliasing->isChecked()) |
||
605 | { |
||
24133 | jghali | 606 | args.append("-dTextAlphaBits=4"); |
607 | args.append("-dGraphicsAlphaBits=4"); |
||
23829 | jghali | 608 | } |
609 | if ((m_doc->HasCMS) && (m_gsVersion >= 900)) |
||
610 | { |
||
611 | args.append("-sDefaultCMYKProfile=" + QDir::toNativeSeparators(m_doc->DocPrinterProf.profilePath())); |
||
612 | if (m_optionsUi->enableCMYK->isChecked()) |
||
613 | args.append("-sOutputICCProfile=" + QDir::toNativeSeparators(m_doc->DocPrinterProf.profilePath())); |
||
614 | else |
||
615 | args.append("-sOutputICCProfile=" + QDir::toNativeSeparators(m_doc->DocDisplayProf.profilePath())); |
||
616 | } |
||
617 | else if (ScCore->haveCMS() && (m_gsVersion >= 900)) |
||
618 | { |
||
619 | args.append("-sDefaultCMYKProfile=" + QDir::toNativeSeparators(ScCore->defaultCMYKProfile.profilePath())); |
||
620 | if (m_optionsUi->enableCMYK->isChecked()) |
||
621 | args.append("-sOutputICCProfile=" + QDir::toNativeSeparators(ScCore->defaultCMYKProfile.profilePath())); |
||
622 | else |
||
623 | args.append("-sOutputICCProfile=" + QDir::toNativeSeparators(ScCore->defaultRGBProfile.profilePath())); |
||
624 | } |
||
625 | |||
626 | // Add any extra font paths being used by Scribus to gs's font search path |
||
627 | PrefsContext *pc = m_prefsManager.prefsFile->getContext("Fonts"); |
||
628 | PrefsTable *extraFonts = pc->getTable("ExtraFontDirs"); |
||
629 | const char sep = ScPaths::envPathSeparator; |
||
630 | if (extraFonts->getRowCount() >= 1) |
||
631 | cmd1 = QString("-sFONTPATH=%1").arg(QDir::toNativeSeparators(extraFonts->get(0,0))); |
||
632 | for (int i = 1; i < extraFonts->getRowCount(); ++i) |
||
633 | cmd1 += QString("%1%2").arg(sep).arg(QDir::toNativeSeparators(extraFonts->get(i,0))); |
||
634 | if (!cmd1.isEmpty()) |
||
635 | args.append( cmd1 ); |
||
636 | |||
637 | // then add any final args and call gs |
||
638 | QString tempFileDir = ScPaths::tempFileDir() ; |
||
639 | if (m_optionsUi->enableCMYK->isChecked()) |
||
640 | args.append( QString("-sOutputFile=%1").arg(QDir::toNativeSeparators(tempFileDir + "/" + m_tempBaseName + ".tif")) ); |
||
641 | else if (m_optionsUi->showTransparency->isChecked() && m_havePngAlpha) |
||
642 | args.append( QString("-sOutputFile=%1").arg(QDir::toNativeSeparators(tempFileDir + "/" + m_tempBaseName + ".png")) ); |
||
643 | else |
||
644 | args.append(QString("-sOutputFile=%1").arg(QDir::toNativeSeparators(tempFileDir + "/" + m_tempBaseName + ".tif"))); |
||
645 | args.append( QDir::toNativeSeparators(ScPaths::tempFileDir() + "/" + m_tempBaseName + ".pdf") ); |
||
646 | args.append( "-c" ); |
||
647 | args.append( "showpage" ); |
||
648 | args.append( "-c" ); |
||
649 | args.append( "quit" ); |
||
650 | ret = System(m_prefsManager.ghostscriptExecutable(), args); |
||
651 | return ret; |
||
652 | } |
||
653 | |||
654 | int OutputPreview_PDF::renderPreviewSep(int pageIndex, int res) |
||
655 | { |
||
656 | int ret = -1; |
||
657 | QString cmd; |
||
658 | QStringList args, args1, args2, args3; |
||
659 | |||
660 | QString tmp, tmp2, tmp3; |
||
24308 | jghali | 661 | int w = qRound(m_doc->Pages->at(pageIndex)->width() * res / 72.0); |
662 | int h = qRound(m_doc->Pages->at(pageIndex)->height() * res / 72.0); |
||
23829 | jghali | 663 | |
664 | args1.append( "-q" ); |
||
665 | args1.append( "-dNOPAUSE" ); |
||
666 | args1.append( "-dPARANOIDSAFER" ); |
||
667 | args1.append( QString("-r%1").arg(tmp.setNum(res)) ); |
||
24308 | jghali | 668 | args1.append( QString("-g%1x%2").arg(tmp2.setNum(w), tmp3.setNum(h)) ); |
23829 | jghali | 669 | if (m_optionsUi->antiAliasing->isChecked()) |
670 | { |
||
671 | args1.append("-dTextAlphaBits=4"); |
||
672 | args1.append("-dGraphicsAlphaBits=4"); |
||
673 | } |
||
674 | if ((m_doc->HasCMS) && (m_gsVersion >= 900)) |
||
675 | { |
||
676 | args1.append("-sDefaultCMYKProfile=" + QDir::toNativeSeparators(m_doc->DocPrinterProf.profilePath())); |
||
677 | args1.append("-sOutputICCProfile=" + QDir::toNativeSeparators(m_doc->DocPrinterProf.profilePath())); |
||
678 | } |
||
679 | else if (ScCore->haveCMS() && (m_gsVersion >= 900)) |
||
680 | { |
||
681 | args.append("-sDefaultCMYKProfile=" + QDir::toNativeSeparators(ScCore->defaultCMYKProfile.profilePath())); |
||
682 | args.append("-sOutputICCProfile=" + QDir::toNativeSeparators(ScCore->defaultCMYKProfile.profilePath())); |
||
683 | } |
||
684 | |||
685 | // Add any extra font paths being used by Scribus to gs's font search path |
||
686 | PrefsContext *pc = m_prefsManager.prefsFile->getContext("Fonts"); |
||
687 | PrefsTable *extraFonts = pc->getTable("ExtraFontDirs"); |
||
688 | const char sep = ScPaths::envPathSeparator; |
||
689 | if (extraFonts->getRowCount() >= 1) |
||
690 | cmd = QString("-sFONTPATH=%1").arg(QDir::toNativeSeparators(extraFonts->get(0,0))); |
||
691 | for (int i = 1; i < extraFonts->getRowCount(); ++i) |
||
692 | cmd += QString("%1%2").arg(sep).arg(QDir::toNativeSeparators(extraFonts->get(i,0))); |
||
693 | if (!cmd.isEmpty()) |
||
694 | args1.append(cmd); |
||
695 | args1.append( QString("-sOutputFile=%1").arg(QDir::toNativeSeparators(ScPaths::tempFileDir() + "/" + m_tempBaseName + ".tif")) ); |
||
696 | |||
697 | args2.append( QDir::toNativeSeparators(ScPaths::tempFileDir() + "/" + m_tempBaseName + ".pdf") ); |
||
698 | args2.append("-c"); |
||
699 | args2.append("quit"); |
||
700 | |||
701 | ColorList usedSpots; |
||
702 | m_doc->getUsedColors(usedSpots, true); |
||
703 | QStringList spots = usedSpots.keys(); |
||
704 | args3.append( "-sDEVICE=tiffsep" ); |
||
705 | |||
706 | // args3.append( "-c" ); |
||
707 | cmd = "<< /SeparationColorNames "; |
||
708 | QString allSeps ="[ /Cyan /Magenta /Yellow /Black "; |
||
709 | for (int sp = 0; sp < spots.count(); ++sp) |
||
710 | { |
||
711 | allSeps += "(" + spots[sp] + ") "; |
||
712 | } |
||
713 | allSeps += "]"; |
||
714 | cmd += allSeps + " /SeparationOrder [ /Cyan /Magenta /Yellow /Black] >> setpagedevice"; |
||
715 | QFile fx(QDir::toNativeSeparators(ScPaths::tempFileDir() + "/" + m_tempBaseName + ".sep.ps")); |
||
716 | if (fx.open(QIODevice::WriteOnly)) |
||
717 | { |
||
718 | QTextStream tsx(&fx); |
||
719 | tsx << cmd; |
||
720 | fx.close(); |
||
721 | } |
||
722 | |||
723 | QString gsExe(getShortPathName(m_prefsManager.ghostscriptExecutable())); |
||
724 | ret = System(gsExe, args1 + args3 + args2, ScPaths::tempFileDir() + "/" + m_tempBaseName + ".tif.txt" ); |
||
725 | |||
726 | QFile sepInfo(QDir::toNativeSeparators(ScPaths::tempFileDir() + "/" + m_tempBaseName + ".tif.txt")); |
||
727 | m_sepsToFileNum.clear(); |
||
728 | if (sepInfo.open(QIODevice::ReadOnly)) |
||
729 | { |
||
730 | QString Sname; |
||
731 | QTextStream tsC(&sepInfo); |
||
732 | int counter = 0; |
||
733 | while (!tsC.atEnd()) |
||
734 | { |
||
735 | Sname = tsC.readLine(); |
||
736 | QString tt = Sname.remove("%%SeparationName:").trimmed(); |
||
737 | if (!tt.isEmpty()) |
||
738 | { |
||
739 | m_sepsToFileNum.insert(tt, counter); |
||
740 | counter++; |
||
741 | } |
||
742 | } |
||
25102 | jghali | 743 | sepInfo.close(); |
23829 | jghali | 744 | } |
25102 | jghali | 745 | |
25070 | craig | 746 | QString currSeps; |
23829 | jghali | 747 | uint spc = 0; |
748 | for (int sp = 0; sp < spots.count(); ++sp) |
||
749 | { |
||
750 | currSeps += "(" + spots[sp] + ") "; |
||
751 | spc++; |
||
25102 | jghali | 752 | if (spc > 6) |
23829 | jghali | 753 | { |
754 | args3.clear(); |
||
755 | args3.append("-sDEVICE=tiffsep"); |
||
756 | QFile fx(QDir::toNativeSeparators(ScPaths::tempFileDir() + "/" + m_tempBaseName + ".sep.ps")); |
||
757 | if (fx.open(QIODevice::WriteOnly)) |
||
758 | { |
||
759 | QTextStream tsx(&fx); |
||
760 | tsx << QString("<< /SeparationColorNames " + allSeps + " /SeparationOrder [ " + currSeps + " ] >> setpagedevice"); |
||
761 | fx.close(); |
||
762 | } |
||
763 | args3.append("-f"); |
||
764 | args3.append(QDir::toNativeSeparators(ScPaths::tempFileDir() + "/" + m_tempBaseName + ".sep.ps")); |
||
765 | ret = System(gsExe, args1 + args3 + args2); |
||
25102 | jghali | 766 | currSeps.clear(); |
23829 | jghali | 767 | spc = 0; |
768 | } |
||
769 | } |
||
770 | if (spc != 0) |
||
771 | { |
||
772 | args3.clear(); |
||
773 | args3.append("-sDEVICE=tiffsep"); |
||
774 | QFile fx(QDir::toNativeSeparators(ScPaths::tempFileDir() + "/" + m_tempBaseName + ".sep.ps")); |
||
775 | if (fx.open(QIODevice::WriteOnly)) |
||
776 | { |
||
777 | QTextStream tsx(&fx); |
||
24133 | jghali | 778 | tsx << QString("<< /SeparationColorNames " + allSeps + " /SeparationOrder [ " + currSeps + " ] >> setpagedevice"); |
23829 | jghali | 779 | fx.close(); |
780 | } |
||
781 | args3.append("-f"); |
||
782 | args3.append(QDir::toNativeSeparators(ScPaths::tempFileDir() + "/" + m_tempBaseName + ".sep.ps")); |
||
783 | ret = System(gsExe, args1 + args3 + args2); |
||
784 | } |
||
785 | return ret; |
||
786 | } |
||
787 | |||
788 | void OutputPreview_PDF::setupFontEmbedding(PDFOptions& options) |
||
789 | { |
||
790 | QMap<QString, int> usedFonts = m_doc->reorganiseFonts(); |
||
791 | QStringList docFonts = usedFonts.keys(); |
||
792 | |||
793 | // Simple case: no font embedding |
||
794 | if (m_pdfOptions.FontEmbedding == PDFOptions::DontEmbed) |
||
795 | { |
||
796 | m_pdfOptions.OutlineList.clear(); |
||
797 | m_pdfOptions.EmbedList.clear(); |
||
798 | m_pdfOptions.SubsetList.clear(); |
||
799 | return; |
||
800 | } |
||
801 | |||
802 | // Simple case: all fonts are outlined |
||
803 | if (m_pdfOptions.FontEmbedding == PDFOptions::OutlineFonts) |
||
804 | { |
||
805 | m_pdfOptions.OutlineList = docFonts; |
||
806 | m_pdfOptions.EmbedList.clear(); |
||
807 | m_pdfOptions.SubsetList.clear(); |
||
808 | return; |
||
809 | } |
||
810 | |||
811 | if (m_pdfOptions.EmbedList.count() != 0) |
||
812 | { |
||
813 | QList<QString> tmpEm; |
||
814 | for (auto itef = m_pdfOptions.EmbedList.begin(); itef != m_pdfOptions.EmbedList.end(); ++itef) |
||
815 | { |
||
816 | if (usedFonts.contains((*itef))) |
||
817 | tmpEm.append((*itef)); |
||
818 | } |
||
819 | m_pdfOptions.EmbedList = tmpEm; |
||
820 | } |
||
821 | if (m_pdfOptions.SubsetList.count() != 0) |
||
822 | { |
||
823 | QList<QString> tmpEm; |
||
824 | for (auto itef = m_pdfOptions.SubsetList.begin(); itef != m_pdfOptions.SubsetList.end(); ++itef) |
||
825 | { |
||
826 | if (usedFonts.contains((*itef))) |
||
827 | tmpEm.append((*itef)); |
||
828 | } |
||
829 | m_pdfOptions.SubsetList = tmpEm; |
||
830 | } |
||
831 | |||
832 | // Build a list of all fonts used in Annotations |
||
833 | QMap<QString, QString> annotationFonts; |
||
834 | |||
835 | int pageItOptions = PageItemIterator::IterateInGroups | PageItemIterator::IterateInDocItems | PageItemIterator::IterateInMasterItems | PageItemIterator::IterateInFrameItems; |
||
836 | for (PageItemIterator it(m_doc, pageItOptions); *it; ++it) |
||
837 | { |
||
838 | PageItem *currItem = *it; |
||
839 | if (((currItem->itemType() == PageItem::TextFrame) || (currItem->itemType() == PageItem::PathText)) && (currItem->isAnnotation())) |
||
840 | { |
||
841 | int annotType = currItem->annotation().Type(); |
||
842 | bool mustEmbed = ((annotType >= Annotation::Button) && (annotType <= Annotation::Listbox) && (annotType != Annotation::Checkbox)); |
||
843 | if (currItem->itemText.length() > 0 || mustEmbed) |
||
844 | annotationFonts.insert(currItem->itemText.defaultStyle().charStyle().font().replacementName(), QString()); |
||
845 | } |
||
846 | } |
||
847 | |||
848 | const auto& allFonts = m_prefsManager.appPrefs.fontPrefs.AvailFonts; |
||
849 | PDFVersion pdfVer = m_pdfOptions.Version; |
||
850 | |||
851 | if ((m_pdfOptions.EmbedList.count() == 0) && (m_pdfOptions.SubsetList.count() == 0) && (m_pdfOptions.firstUse)) |
||
852 | { |
||
853 | for (int i = 0; i < docFonts.count(); ++i) |
||
854 | { |
||
855 | QString fontName = docFonts.at(i); |
||
856 | const ScFace fontFace = allFonts[fontName]; |
||
857 | if (!fontFace.subset() && (!fontFace.isOTF() || pdfVer.supportsEmbeddedOpenTypeFonts())) |
||
858 | m_pdfOptions.EmbedList.append(fontName); |
||
859 | else if (annotationFonts.contains(fontName)) |
||
860 | m_pdfOptions.EmbedList.append(fontName); |
||
861 | else |
||
862 | m_pdfOptions.SubsetList.append(fontName); |
||
863 | } |
||
864 | } |
||
865 | else |
||
866 | { |
||
867 | for (int i = 0; i < docFonts.count(); ++i) |
||
868 | { |
||
869 | QString fontName = docFonts.at(i); |
||
870 | const ScFace fontFace = allFonts[fontName]; |
||
871 | if (m_pdfOptions.EmbedList.contains(fontName) && (!fontFace.isOTF() || m_pdfOptions.supportsEmbeddedOpenTypeFonts()) && !fontFace.subset()) |
||
872 | continue; |
||
873 | if (!m_pdfOptions.SubsetList.contains(fontName)) |
||
874 | m_pdfOptions.SubsetList.append(fontName); |
||
875 | } |
||
876 | |||
877 | for (auto itAnn = annotationFonts.begin(); itAnn != annotationFonts.end(); ++itAnn) |
||
878 | { |
||
24935 | craig | 879 | const QString& annotFont = itAnn.key(); |
23829 | jghali | 880 | if (!m_pdfOptions.EmbedList.contains(annotFont)) |
881 | m_pdfOptions.EmbedList.append(annotFont); |
||
882 | int subsetIndex = m_pdfOptions.SubsetList.indexOf(annotFont); |
||
883 | if (subsetIndex >= 0) |
||
884 | m_pdfOptions.SubsetList.removeAll(annotFont); |
||
885 | } |
||
886 | } |
||
887 | } |
||
888 | |||
889 | bool OutputPreview_PDF::optionsHaveChanged(int pageIndex) const |
||
890 | { |
||
891 | if (m_currentPage != pageIndex) |
||
892 | return true; |
||
24308 | jghali | 893 | if (m_scaleMode != m_uiBase->scaleBox->currentIndex()) |
23829 | jghali | 894 | return true; |
895 | if (m_cmykPreviewMode != m_optionsUi->enableCMYK->isChecked()) |
||
896 | return true; |
||
897 | if (m_useAntialiasing != m_optionsUi->antiAliasing->isChecked()) |
||
898 | return true; |
||
899 | if (m_showTransparency != m_optionsUi->showTransparency->isChecked()) |
||
900 | return true; |
||
901 | |||
902 | if (m_pdfVersion != m_optionsUi->pdfVersionCombo->version()) |
||
903 | return true; |
||
904 | if (m_pdfOutputMode != m_optionsUi->outputModeCombo->currentIndex()) |
||
905 | return true; |
||
906 | if (m_mirrorH != m_optionsUi->mirrorH->isChecked()) |
||
907 | return true; |
||
908 | if (m_mirrorV != m_optionsUi->mirrorV->isChecked()) |
||
909 | return true; |
||
910 | if (m_clipToMargins != m_optionsUi->clipToMargins->isChecked()) |
||
911 | return true; |
||
912 | if (m_convertSpots != m_optionsUi->convertSpots->isChecked()) |
||
913 | return true; |
||
914 | |||
915 | return false; |
||
916 | } |
||
917 | |||
918 | bool OutputPreview_PDF::pdfOptionsHaveChanged(int pageIndex) const |
||
919 | { |
||
920 | if (m_currentPage != pageIndex) |
||
921 | return true; |
||
922 | |||
923 | if (m_pdfVersion != m_optionsUi->pdfVersionCombo->version()) |
||
924 | return true; |
||
925 | if (m_pdfOutputMode != m_optionsUi->outputModeCombo->currentIndex()) |
||
926 | return true; |
||
927 | if (m_mirrorH != m_optionsUi->mirrorH->isChecked()) |
||
928 | return true; |
||
929 | if (m_mirrorV != m_optionsUi->mirrorV->isChecked()) |
||
930 | return true; |
||
931 | if (m_clipToMargins != m_optionsUi->clipToMargins->isChecked()) |
||
932 | return true; |
||
933 | if (m_convertSpots != m_optionsUi->convertSpots->isChecked()) |
||
934 | return true; |
||
935 | |||
936 | return false; |
||
937 | } |
||
938 | |||
939 | void OutputPreview_PDF::setPDFOptionsToOptions(PDFOptions& pdfOptions) |
||
940 | { |
||
941 | m_pdfVersion = pdfOptions.Version; |
||
942 | |||
943 | if (pdfOptions.UseRGB) |
||
944 | m_pdfOutputMode = 0; |
||
945 | else if (pdfOptions.isGrayscale) |
||
946 | m_pdfOutputMode = 2; |
||
947 | else |
||
948 | m_pdfOutputMode = 1; |
||
949 | |||
950 | m_mirrorH = pdfOptions.MirrorH; |
||
951 | m_mirrorV = pdfOptions.MirrorV; |
||
952 | m_clipToMargins = pdfOptions.doClip; |
||
953 | m_convertSpots = !pdfOptions.UseSpotColors; |
||
954 | } |
||
955 | |||
956 | void OutputPreview_PDF::setPDFOptionsToUi(PDFOptions& pdfOptions) |
||
957 | { |
||
958 | m_optionsUi->pdfVersionCombo->setPDFXEnabled(m_doc->HasCMS && !ScCore->PDFXProfiles.isEmpty()); |
||
959 | m_optionsUi->pdfVersionCombo->setVersion(pdfOptions.Version); |
||
960 | |||
961 | if (pdfOptions.UseRGB) |
||
962 | m_optionsUi->outputModeCombo->setCurrentIndex(0); |
||
963 | else if (pdfOptions.isGrayscale) |
||
964 | m_optionsUi->outputModeCombo->setCurrentIndex(2); |
||
965 | else |
||
966 | m_optionsUi->outputModeCombo->setCurrentIndex(1); |
||
967 | |||
968 | m_optionsUi->mirrorH->setChecked(pdfOptions.MirrorH); |
||
969 | m_optionsUi->mirrorV->setChecked(pdfOptions.MirrorV); |
||
970 | m_optionsUi->clipToMargins->setChecked(pdfOptions.doClip); |
||
971 | m_optionsUi->convertSpots->setChecked(!pdfOptions.UseSpotColors); |
||
23834 | jghali | 972 | |
973 | bool cmykEnabled = (m_optionsUi->outputModeCombo->currentIndex() > 0); |
||
974 | bool cmykUserEnabled = m_optionsUi->enableCMYK->isChecked(); |
||
975 | |||
976 | m_optionsUi->enableCMYK->setEnabled(cmykEnabled); |
||
977 | m_optionsUi->enableCMYK->setChecked(cmykEnabled && cmykUserEnabled); |
||
978 | m_optionsUi->inkTable->setEnabled(cmykEnabled && cmykUserEnabled); |
||
979 | m_optionsUi->displayInkCoverage->setEnabled(cmykEnabled && cmykUserEnabled); |
||
980 | bool isInkCoverageEnabled = m_optionsUi->displayInkCoverage->isChecked(); |
||
981 | m_optionsUi->coverThresholdLabel->setEnabled(cmykEnabled && cmykUserEnabled && isInkCoverageEnabled); |
||
982 | m_optionsUi->coverThresholdValue->setEnabled(cmykEnabled && cmykUserEnabled && isInkCoverageEnabled); |
||
23829 | jghali | 983 | } |
984 | |||
985 | void OutputPreview_PDF::setUiOptionsToPDFOptions(PDFOptions& pdfOptions) |
||
986 | { |
||
987 | pdfOptions.Version = m_optionsUi->pdfVersionCombo->version(); |
||
988 | if (!pdfOptions.Version.supportsOCGs()) |
||
989 | pdfOptions.useLayers = false; |
||
990 | |||
991 | if (m_optionsUi->outputModeCombo->currentIndex() == 0) |
||
992 | { |
||
993 | pdfOptions.isGrayscale = false; |
||
994 | pdfOptions.UseRGB = true; |
||
995 | pdfOptions.UseProfiles = false; |
||
996 | pdfOptions.UseProfiles2 = false; |
||
997 | } |
||
998 | else if (m_optionsUi->outputModeCombo->currentIndex() == 2) |
||
999 | { |
||
1000 | pdfOptions.isGrayscale = true; |
||
1001 | pdfOptions.UseRGB = false; |
||
1002 | pdfOptions.UseProfiles = false; |
||
1003 | pdfOptions.UseProfiles2 = false; |
||
1004 | } |
||
1005 | else |
||
1006 | { |
||
1007 | pdfOptions.isGrayscale = false; |
||
1008 | pdfOptions.UseRGB = false; |
||
1009 | /*if (ScCore->haveCMS()) |
||
1010 | { |
||
1011 | pdfOptions.UseProfiles = EmbedProfs->isChecked(); |
||
1012 | pdfOptions.UseProfiles2 = EmbedProfs2->isChecked(); |
||
1013 | pdfOptions.Intent = IntendS->currentIndex(); |
||
1014 | pdfOptions.Intent2 = IntendI->currentIndex(); |
||
1015 | pdfOptions.EmbeddedI = NoEmbedded->isChecked(); |
||
1016 | pdfOptions.SolidProf = SolidPr->currentText(); |
||
1017 | pdfOptions.ImageProf = ImageP->currentText(); |
||
1018 | pdfOptions.PrintProf = PrintProfC->currentText(); |
||
1019 | }*/ |
||
1020 | } |
||
1021 | |||
1022 | // Force font embedding for PDF-X/1 |
||
1023 | if (pdfOptions.Version.isPDFX() && (pdfOptions.FontEmbedding == PDFOptions::DontEmbed)) |
||
1024 | { |
||
1025 | m_fontEmbeddingWasSet = false; |
||
1026 | pdfOptions.EmbedList.clear(); |
||
1027 | pdfOptions.SubsetList.clear(); |
||
1028 | pdfOptions.FontEmbedding = PDFOptions::EmbedFonts; |
||
1029 | setupFontEmbedding(m_pdfOptions); |
||
1030 | m_fontEmbeddingWasSet = true; |
||
1031 | } |
||
1032 | |||
1033 | // PDF/X-1, no profile embedding |
||
1034 | if (pdfOptions.Version == PDFVersion::PDF_X1a) |
||
1035 | { |
||
1036 | pdfOptions.UseProfiles = false; |
||
1037 | pdfOptions.UseProfiles2 = false; |
||
1038 | } |
||
1039 | // PDF/X-3 or PDF/X-4, enforcing color profiles on images |
||
1040 | if (pdfOptions.Version == PDFVersion::PDF_X3 || pdfOptions.Version == PDFVersion::PDF_X4) |
||
1041 | pdfOptions.UseProfiles2 = true; |
||
1042 | |||
1043 | pdfOptions.MirrorH = m_optionsUi->mirrorH->isChecked(); |
||
1044 | pdfOptions.MirrorV = m_optionsUi->mirrorV->isChecked(); |
||
1045 | pdfOptions.doClip = m_optionsUi->clipToMargins->isChecked(); |
||
1046 | pdfOptions.UseSpotColors = !m_optionsUi->convertSpots->isChecked(); |
||
1047 | } |
||
1048 | |||
1049 | void OutputPreview_PDF::updateOptionsFromUI() |
||
1050 | { |
||
1051 | m_pdfVersion = m_optionsUi->pdfVersionCombo->version(); |
||
1052 | m_pdfOutputMode = m_optionsUi->outputModeCombo->currentIndex(); |
||
1053 | m_mirrorH = m_optionsUi->mirrorH->isChecked(); |
||
1054 | m_mirrorV = m_optionsUi->mirrorV->isChecked(); |
||
1055 | m_clipToMargins = m_optionsUi->clipToMargins->isChecked(); |
||
1056 | m_convertSpots = m_optionsUi->convertSpots->isChecked(); |
||
1057 | |||
1058 | m_currentPage = m_uiBase->pageSelector->getCurrentPage() - 1; |
||
24308 | jghali | 1059 | m_scaleMode = m_uiBase->scaleBox->currentIndex(); |
23829 | jghali | 1060 | m_cmykPreviewMode = m_optionsUi->enableCMYK->isChecked(); |
1061 | m_useAntialiasing = m_optionsUi->antiAliasing->isChecked(); |
||
1062 | m_showTransparency = m_optionsUi->showTransparency->isChecked(); |
||
1063 | } |
||
1064 | |||
1065 | void OutputPreview_PDF::onPdfVersionChanged(int index) |
||
1066 | { |
||
1067 | bool isPDFX = m_optionsUi->pdfVersionCombo->versionIsPDFX(); |
||
1068 | m_optionsUi->outputModeCombo->setEnabled(!isPDFX); |
||
1069 | |||
1070 | if (isPDFX) |
||
1071 | { |
||
1072 | m_optionsUi->outputModeCombo->setCurrentIndex(1); |
||
1073 | m_optionsUi->outputModeCombo->setEnabled(false); |
||
1074 | onPdfOutputModeChanged(1); |
||
1075 | } |
||
1076 | |||
1077 | redisplay(); |
||
1078 | } |
||
1079 | |||
23834 | jghali | 1080 | void OutputPreview_PDF::onPdfOutputModeChanged(int /*index*/) |
23829 | jghali | 1081 | { |
1082 | bool cmykEnabled = (m_optionsUi->outputModeCombo->currentIndex() > 0); |
||
23834 | jghali | 1083 | bool cmykUserEnabled = m_optionsUi->enableCMYK->isChecked(); |
23829 | jghali | 1084 | |
1085 | m_optionsUi->enableCMYK->setEnabled(cmykEnabled); |
||
23834 | jghali | 1086 | m_optionsUi->enableCMYK->setChecked(cmykEnabled && cmykUserEnabled); |
1087 | m_optionsUi->inkTable->setEnabled(cmykEnabled && cmykUserEnabled); |
||
1088 | m_optionsUi->displayInkCoverage->setEnabled(cmykEnabled && cmykUserEnabled); |
||
23829 | jghali | 1089 | bool isInkCoverageEnabled = m_optionsUi->displayInkCoverage->isChecked(); |
23834 | jghali | 1090 | m_optionsUi->coverThresholdLabel->setEnabled(cmykEnabled && cmykUserEnabled && isInkCoverageEnabled); |
1091 | m_optionsUi->coverThresholdValue->setEnabled(cmykEnabled && cmykUserEnabled && isInkCoverageEnabled); |
||
23829 | jghali | 1092 | |
1093 | redisplay(); |
||
1094 | } |
||
1095 | |||
1096 | void OutputPreview_PDF::onInkTableCellDoubleClicked(int row) |
||
1097 | { |
||
1098 | if (!m_haveTiffSep) |
||
1099 | return; |
||
1100 | |||
1101 | for (auto sepIt = m_inkVisibilities.begin(); sepIt != m_inkVisibilities.end(); ++sepIt) |
||
1102 | sepIt.value()->setChecked(false); |
||
1103 | ((QCheckBox*)(m_optionsUi->inkTable->cellWidget(row, 0)))->setChecked(true); |
||
1104 | |||
1105 | if (m_optionsUi->enableCMYK->isChecked()) |
||
1106 | m_previewLabel->setPixmap(createPreview(m_currentPage, qRound(72 * m_scaleFactor))); |
||
24841 | craig | 1107 | m_previewLabel->resize(m_previewLabel->pixmap().size()); |
23829 | jghali | 1108 | } |
1109 | |||
1110 | void OutputPreview_PDF::toggleAllFromHeader() |
||
1111 | { |
||
1112 | if (!m_haveTiffSep) |
||
1113 | return; |
||
1114 | |||
1115 | for (auto sepIt = m_inkVisibilities.begin(); sepIt != m_inkVisibilities.end(); ++sepIt) |
||
1116 | sepIt.value()->setChecked(true); |
||
1117 | |||
1118 | if (m_optionsUi->enableCMYK->isChecked()) |
||
1119 | m_previewLabel->setPixmap(createPreview(m_currentPage, qRound(72 * m_scaleFactor))); |
||
24841 | craig | 1120 | m_previewLabel->resize(m_previewLabel->pixmap().size()); |
23829 | jghali | 1121 | } |
1122 | |||
1123 | void OutputPreview_PDF::toggleCMYK() |
||
1124 | { |
||
1125 | if (!m_haveTiffSep) |
||
1126 | return; |
||
1127 | |||
1128 | bool cmykEnabled = m_optionsUi->enableCMYK->isChecked(); |
||
1129 | m_optionsUi->inkTable->setEnabled(cmykEnabled); |
||
1130 | m_optionsUi->displayInkCoverage->setEnabled(cmykEnabled); |
||
1131 | bool isInkCoverageEnabled = m_optionsUi->displayInkCoverage->isChecked(); |
||
23834 | jghali | 1132 | m_optionsUi->coverThresholdLabel->setEnabled(cmykEnabled && isInkCoverageEnabled); |
23829 | jghali | 1133 | m_optionsUi->coverThresholdValue->setEnabled(cmykEnabled && isInkCoverageEnabled); |
1134 | |||
1135 | redisplay(); |
||
1136 | } |
||
1137 | |||
1138 | void OutputPreview_PDF::toggleCMYK_Colour() |
||
1139 | { |
||
1140 | if (m_haveTiffSep) |
||
1141 | { |
||
23834 | jghali | 1142 | bool inkCoverageEnabled = (m_optionsUi->enableCMYK->isChecked()) && (m_optionsUi->displayInkCoverage->isChecked()); |
1143 | m_optionsUi->coverThresholdLabel->setEnabled(inkCoverageEnabled); |
||
1144 | m_optionsUi->coverThresholdValue->setEnabled(inkCoverageEnabled); |
||
23829 | jghali | 1145 | } |
1146 | if (m_optionsUi->enableCMYK->isChecked()) |
||
1147 | m_previewLabel->setPixmap(createPreview(m_currentPage, qRound(72 * m_scaleFactor))); |
||
24841 | craig | 1148 | m_previewLabel->resize(m_previewLabel->pixmap().size()); |
23829 | jghali | 1149 | } |
1150 | |||
1151 | void OutputPreview_PDF::imageLoadError(QPixmap &pixmap) |
||
1152 | { |
||
1153 | pixmap = QPixmap(1, 1); |
||
1154 | qApp->restoreOverrideCursor(); |
||
1155 | updateOptionsFromUI(); |
||
24137 | craig | 1156 | } |