Subversion Repositories Scribus

Rev

Rev 24826 | 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 <QDesktopWidget>
10
#include <QMap>
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()));
133
                connect(m_optionsUi->inkTable, SIGNAL(cellDoubleClicked(int, int)), this, SLOT(onInkTableCellDoubleClicked(int)));
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;
193
        resize(qMin(QApplication::desktop()->width() - 30, w), 500);
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
                }
25101 jghali 743
                sepInfo.close();
23829 jghali 744
        }
25101 jghali 745
 
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++;
25101 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);
25101 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
                {
879
                        QString annotFont = itAnn.key();
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)));
1107
        m_previewLabel->resize(m_previewLabel->pixmap()->size());
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)));
1120
        m_previewLabel->resize(m_previewLabel->pixmap()->size());
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)));
1148
        m_previewLabel->resize(m_previewLabel->pixmap()->size());
1149
}
1150
 
1151
void OutputPreview_PDF::imageLoadError(QPixmap &pixmap)
1152
{
1153
        pixmap = QPixmap(1, 1);
1154
        qApp->restoreOverrideCursor();
1155
        updateOptionsFromUI();
24137 craig 1156
}