Rev 25050 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
16729 | fschmid | 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 | |||
22738 | jghali | 8 | #include <cstdlib> |
24693 | jghali | 9 | #include <memory> |
22738 | jghali | 10 | |
16729 | fschmid | 11 | #include <QByteArray> |
12 | #include <QCursor> |
||
22738 | jghali | 13 | #include <QDebug> |
16729 | fschmid | 14 | #include <QDrag> |
15 | #include <QFile> |
||
17851 | fschmid | 16 | #include <QInputDialog> |
16729 | fschmid | 17 | #include <QList> |
18 | #include <QMimeData> |
||
19 | #include <QStack> |
||
22738 | jghali | 20 | |
17869 | fschmid | 21 | #include <poppler/ErrorCodes.h> |
22 | #include <poppler/GlobalParams.h> |
||
20125 | fschmid | 23 | #include <poppler/OptionalContent.h> |
17869 | fschmid | 24 | #include <poppler/PageTransition.h> |
25 | #include <poppler/ViewerPreferences.h> |
||
26 | #include <poppler/poppler-config.h> |
||
22154 | jghali | 27 | #include <poppler/cpp/poppler-version.h> |
17869 | fschmid | 28 | #include <poppler/SplashOutputDev.h> |
29 | #include <poppler/splash/SplashBitmap.h> |
||
16729 | fschmid | 30 | |
31 | #include "importpdf.h" |
||
22738 | jghali | 32 | #include "importpdfconfig.h" |
24374 | jghali | 33 | #include "pdftextrecognition.h" |
22738 | jghali | 34 | #include "slaoutput.h" |
16729 | fschmid | 35 | |
36 | #include "commonstrings.h" |
||
37 | #include "loadsaveplugin.h" |
||
38 | #include "pagesize.h" |
||
17880 | fschmid | 39 | #include "pdfimportoptions.h" |
17849 | fschmid | 40 | #include "pdfoptions.h" |
16729 | fschmid | 41 | #include "prefscontext.h" |
42 | #include "prefsfile.h" |
||
43 | #include "prefsmanager.h" |
||
44 | #include "prefstable.h" |
||
45 | #include "rawimage.h" |
||
46 | #include "scclocale.h" |
||
47 | #include "sccolorengine.h" |
||
48 | #include "scconfig.h" |
||
49 | #include "scmimedata.h" |
||
50 | #include "scpaths.h" |
||
51 | #include "scribus.h" |
||
52 | #include "scribusXml.h" |
||
53 | #include "scribuscore.h" |
||
54 | #include "sctextstream.h" |
||
55 | #include "selection.h" |
||
56 | #include "undomanager.h" |
||
57 | #include "util.h" |
||
58 | #include "util_formats.h" |
||
59 | #include "util_math.h" |
||
24989 | jghali | 60 | #include "util_os.h" |
16729 | fschmid | 61 | |
17031 | jghali | 62 | #include "ui/customfdialog.h" |
63 | #include "ui/missing.h" |
||
64 | #include "ui/multiprogressdialog.h" |
||
65 | #include "ui/propertiespalette.h" |
||
16729 | fschmid | 66 | |
67 | PdfPlug::PdfPlug(ScribusDoc* doc, int flags) |
||
68 | { |
||
24455 | jghali | 69 | m_tmpSele = new Selection(this, false); |
16729 | fschmid | 70 | m_Doc = doc; |
24455 | jghali | 71 | m_importerFlags = flags; |
72 | m_interactive = (flags & LoadSavePlugin::lfInteractive); |
||
73 | m_noDialogs = (flags & LoadSavePlugin::lfNoDialogs); |
||
16729 | fschmid | 74 | } |
75 | |||
22635 | craig | 76 | QImage PdfPlug::readThumbnail(const QString& fName) |
16729 | fschmid | 77 | { |
23395 | jghali | 78 | globalParams.reset(new GlobalParams()); |
25123 | jghali | 79 | globalParams->setErrQuiet(true); |
24693 | jghali | 80 | |
24985 | jghali | 81 | QString pdfFile = QDir::toNativeSeparators(fName); |
24989 | jghali | 82 | QByteArray encodedFileName = os_is_win() ? pdfFile.toUtf8() : QFile::encodeName(pdfFile); |
24982 | jghali | 83 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(22, 3, 0) |
24989 | jghali | 84 | auto fname = std::make_unique<GooString>(encodedFileName.data()); |
85 | PDFDoc pdfDoc{ std::move(fname) }; |
||
24982 | jghali | 86 | #else |
24989 | jghali | 87 | auto fname = new GooString(encodedFileName.data()); |
24693 | jghali | 88 | PDFDoc pdfDoc{fname, nullptr, nullptr, nullptr}; |
24982 | jghali | 89 | #endif |
24693 | jghali | 90 | if (!pdfDoc.isOk() || pdfDoc.getErrorCode() == errEncrypted) |
91 | return QImage(); |
||
92 | |||
93 | double h = pdfDoc.getPageMediaHeight(1); |
||
94 | double w = pdfDoc.getPageMediaWidth(1); |
||
95 | double scale = qMin(500.0 / h, 500.0 / w); |
||
96 | double hDPI = 72.0 * scale; |
||
97 | double vDPI = 72.0 * scale; |
||
98 | SplashColor bgColor; |
||
99 | bgColor[0] = 255; |
||
100 | bgColor[1] = 255; |
||
101 | bgColor[2] = 255; |
||
25123 | jghali | 102 | SplashOutputDev dev(splashModeXBGR8, 4, false, bgColor, true); |
103 | dev.setVectorAntialias(true); |
||
104 | dev.setFreeTypeHinting(true, false); |
||
24693 | jghali | 105 | dev.startDoc(&pdfDoc); |
25123 | jghali | 106 | pdfDoc.displayPage(&dev, 1, hDPI, vDPI, 0, true, false, false); |
24693 | jghali | 107 | SplashBitmap *bitmap = dev.getBitmap(); |
108 | int bw = bitmap->getWidth(); |
||
109 | int bh = bitmap->getHeight(); |
||
110 | SplashColorPtr dataPtr = bitmap->getDataPtr(); |
||
111 | if (QSysInfo::BigEndian == QSysInfo::ByteOrder) |
||
112 | { |
||
113 | uchar c; |
||
114 | int count = bw * bh * 4; |
||
115 | for (int k = 0; k < count; k += 4) |
||
17869 | fschmid | 116 | { |
24693 | jghali | 117 | c = dataPtr[k]; |
118 | dataPtr[k] = dataPtr[k + 3]; |
||
119 | dataPtr[k + 3] = c; |
||
120 | c = dataPtr[k + 1]; |
||
121 | dataPtr[k + 1] = dataPtr[k + 2]; |
||
122 | dataPtr[k + 2] = c; |
||
17869 | fschmid | 123 | } |
124 | } |
||
24693 | jghali | 125 | // construct a qimage SHARING the raw bitmap data in memory |
126 | QImage tmpimg( dataPtr, bw, bh, QImage::Format_ARGB32 ); |
||
127 | QImage image = tmpimg.copy(); |
||
128 | image.setText("XSize", QString("%1").arg(w)); |
||
129 | image.setText("YSize", QString("%1").arg(h)); |
||
130 | |||
131 | return image; |
||
17869 | fschmid | 132 | } |
16729 | fschmid | 133 | |
22609 | craig | 134 | bool PdfPlug::import(const QString& fNameIn, const TransactionSettings& trSettings, int flags, bool showProgress) |
16729 | fschmid | 135 | { |
23961 | craig | 136 | #ifdef Q_OS_MACOS |
23082 | jghali | 137 | showProgress = false; |
19809 | craig | 138 | #endif |
16729 | fschmid | 139 | bool success = false; |
24455 | jghali | 140 | m_interactive = (flags & LoadSavePlugin::lfInteractive); |
141 | m_importerFlags = flags; |
||
142 | m_cancel = false; |
||
16729 | fschmid | 143 | bool ret = false; |
25001 | jghali | 144 | QFileInfo fi(fNameIn); |
16729 | fschmid | 145 | if ( !ScCore->usingGUI() ) |
146 | { |
||
24455 | jghali | 147 | m_interactive = false; |
16729 | fschmid | 148 | showProgress = false; |
149 | } |
||
24455 | jghali | 150 | m_baseFile = QDir::cleanPath(QDir::toNativeSeparators(fi.absolutePath()+"/")); |
16729 | fschmid | 151 | if ( showProgress ) |
152 | { |
||
22609 | craig | 153 | ScribusMainWindow* mw = (m_Doc==nullptr) ? ScCore->primaryMainWindow() : m_Doc->scMW(); |
24455 | jghali | 154 | m_progressDialog = new MultiProgressDialog( tr("Importing: %1").arg(fi.fileName()), CommonStrings::tr_Cancel, mw ); |
23820 | craig | 155 | QStringList barNames("GI"); |
156 | QStringList barTexts(tr("Analyzing File:")); |
||
16729 | fschmid | 157 | QList<bool> barsNumeric; |
158 | barsNumeric << false; |
||
24455 | jghali | 159 | m_progressDialog->addExtraProgressBars(barNames, barTexts, barsNumeric); |
160 | m_progressDialog->setOverallTotalSteps(3); |
||
161 | m_progressDialog->setOverallProgress(0); |
||
162 | m_progressDialog->setProgress("GI", 0); |
||
163 | m_progressDialog->show(); |
||
164 | connect(m_progressDialog, SIGNAL(canceled()), this, SLOT(cancelRequested())); |
||
16729 | fschmid | 165 | qApp->processEvents(); |
166 | } |
||
167 | else |
||
24455 | jghali | 168 | m_progressDialog = nullptr; |
16729 | fschmid | 169 | /* Set default Page to size defined in Preferences */ |
24455 | jghali | 170 | if (m_progressDialog) |
16729 | fschmid | 171 | { |
24455 | jghali | 172 | m_progressDialog->setOverallProgress(1); |
16729 | fschmid | 173 | qApp->processEvents(); |
174 | } |
||
23275 | jghali | 175 | double docWidth = PrefsManager::instance().appPrefs.docSetupPrefs.pageWidth; |
176 | double docHeight = PrefsManager::instance().appPrefs.docSetupPrefs.pageHeight; |
||
24455 | jghali | 177 | if (!m_interactive || (flags & LoadSavePlugin::lfInsertPage)) |
16729 | fschmid | 178 | { |
179 | m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false); |
||
180 | m_Doc->addPage(0); |
||
181 | m_Doc->view()->addPage(0, true); |
||
182 | } |
||
183 | else |
||
184 | { |
||
185 | if (!m_Doc || (flags & LoadSavePlugin::lfCreateDoc)) |
||
186 | { |
||
24455 | jghali | 187 | m_Doc = ScCore->primaryMainWindow()->doFileNew(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, 0, 0, 0, 0, 1, "Custom", true); |
16729 | fschmid | 188 | ScCore->primaryMainWindow()->HaveNewDoc(); |
189 | ret = true; |
||
190 | } |
||
191 | } |
||
23275 | jghali | 192 | |
24455 | jghali | 193 | if ((ret) || (!m_interactive)) |
16729 | fschmid | 194 | { |
195 | if (docWidth > docHeight) |
||
196 | m_Doc->setPageOrientation(1); |
||
197 | else |
||
198 | m_Doc->setPageOrientation(0); |
||
199 | m_Doc->setPageSize("Custom"); |
||
200 | } |
||
22527 | craig | 201 | if ((!(flags & LoadSavePlugin::lfLoadAsPattern)) && (m_Doc->view() != nullptr)) |
23390 | craig | 202 | m_Doc->view()->deselectItems(); |
24455 | jghali | 203 | m_elements.clear(); |
16729 | fschmid | 204 | m_Doc->setLoading(true); |
205 | m_Doc->DoDrawing = false; |
||
22527 | craig | 206 | if ((!(flags & LoadSavePlugin::lfLoadAsPattern)) && (m_Doc->view() != nullptr)) |
16729 | fschmid | 207 | m_Doc->view()->updatesOn(false); |
208 | m_Doc->scMW()->setScriptRunning(true); |
||
18181 | fschmid | 209 | qApp->setOverrideCursor(QCursor(Qt::WaitCursor)); |
16729 | fschmid | 210 | QString CurDirP = QDir::currentPath(); |
211 | QDir::setCurrent(fi.path()); |
||
22635 | craig | 212 | if (convert(fNameIn)) |
16729 | fschmid | 213 | { |
24455 | jghali | 214 | m_tmpSele->clear(); |
16729 | fschmid | 215 | QDir::setCurrent(CurDirP); |
24455 | jghali | 216 | if ((m_elements.count() == 1) && (!(m_importerFlags & LoadSavePlugin::lfCreateDoc))) |
17905 | fschmid | 217 | { |
24455 | jghali | 218 | PageItem *gr = m_elements[0]; |
18514 | fschmid | 219 | if (gr->isGroup()) |
220 | m_Doc->resizeGroupToContents(gr); |
||
17905 | fschmid | 221 | } |
24455 | jghali | 222 | if ((m_elements.count() > 1) && (!(m_importerFlags & LoadSavePlugin::lfCreateDoc))) |
17905 | fschmid | 223 | { |
24455 | jghali | 224 | PageItem *gr = m_Doc->groupObjectsList(m_elements); |
17905 | fschmid | 225 | m_Doc->resizeGroupToContents(gr); |
226 | } |
||
16729 | fschmid | 227 | m_Doc->DoDrawing = true; |
228 | m_Doc->scMW()->setScriptRunning(false); |
||
229 | m_Doc->setLoading(false); |
||
230 | qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor)); |
||
24455 | jghali | 231 | if ((m_elements.count() > 0) && (!ret) && (m_interactive)) |
16729 | fschmid | 232 | { |
233 | if (flags & LoadSavePlugin::lfScripted) |
||
234 | { |
||
235 | bool loadF = m_Doc->isLoading(); |
||
236 | m_Doc->setLoading(false); |
||
237 | m_Doc->changed(); |
||
238 | m_Doc->setLoading(loadF); |
||
239 | if (!(flags & LoadSavePlugin::lfLoadAsPattern)) |
||
240 | { |
||
241 | m_Doc->m_Selection->delaySignalsOn(); |
||
24455 | jghali | 242 | for (int dre=0; dre < m_elements.count(); ++dre) |
16729 | fschmid | 243 | { |
24455 | jghali | 244 | m_Doc->m_Selection->addItem(m_elements.at(dre), true); |
16729 | fschmid | 245 | } |
246 | m_Doc->m_Selection->delaySignalsOff(); |
||
247 | m_Doc->m_Selection->setGroupRect(); |
||
22527 | craig | 248 | if (m_Doc->view() != nullptr) |
19856 | fschmid | 249 | m_Doc->view()->updatesOn(true); |
16729 | fschmid | 250 | } |
251 | } |
||
252 | else |
||
253 | { |
||
254 | m_Doc->DragP = true; |
||
22609 | craig | 255 | m_Doc->DraggedElem = nullptr; |
16729 | fschmid | 256 | m_Doc->DragElements.clear(); |
257 | m_Doc->m_Selection->delaySignalsOn(); |
||
24455 | jghali | 258 | for (int dre = 0; dre < m_elements.count(); ++dre) |
16729 | fschmid | 259 | { |
24455 | jghali | 260 | m_tmpSele->addItem(m_elements.at(dre), true); |
16729 | fschmid | 261 | } |
24455 | jghali | 262 | m_tmpSele->setGroupRect(); |
263 | ScElemMimeData* md = ScriXmlDoc::writeToMimeData(m_Doc, m_tmpSele); |
||
264 | m_Doc->itemSelection_DeleteItem(m_tmpSele); |
||
16729 | fschmid | 265 | m_Doc->view()->updatesOn(true); |
266 | m_Doc->m_Selection->delaySignalsOff(); |
||
267 | // We must copy the TransationSettings object as it is owned |
||
268 | // by handleObjectImport method afterwards |
||
269 | TransactionSettings* transacSettings = new TransactionSettings(trSettings); |
||
270 | m_Doc->view()->handleObjectImport(md, transacSettings); |
||
271 | m_Doc->DragP = false; |
||
22609 | craig | 272 | m_Doc->DraggedElem = nullptr; |
16729 | fschmid | 273 | m_Doc->DragElements.clear(); |
274 | } |
||
275 | } |
||
276 | else |
||
277 | { |
||
278 | m_Doc->changed(); |
||
279 | m_Doc->reformPages(); |
||
280 | if (!(flags & LoadSavePlugin::lfLoadAsPattern)) |
||
281 | m_Doc->view()->updatesOn(true); |
||
282 | } |
||
283 | success = true; |
||
284 | } |
||
285 | else |
||
286 | { |
||
287 | QDir::setCurrent(CurDirP); |
||
288 | m_Doc->DoDrawing = true; |
||
289 | m_Doc->scMW()->setScriptRunning(false); |
||
290 | if (!(flags & LoadSavePlugin::lfLoadAsPattern)) |
||
291 | m_Doc->view()->updatesOn(true); |
||
292 | qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor)); |
||
18076 | fschmid | 293 | success = false; |
16729 | fschmid | 294 | } |
24455 | jghali | 295 | if (m_interactive) |
16729 | fschmid | 296 | m_Doc->setLoading(false); |
297 | //CB If we have a gui we must refresh it if we have used the progressbar |
||
298 | if (!(flags & LoadSavePlugin::lfLoadAsPattern)) |
||
299 | { |
||
24455 | jghali | 300 | if ((showProgress) && (!m_interactive)) |
16729 | fschmid | 301 | m_Doc->view()->DrawNew(); |
302 | } |
||
18181 | fschmid | 303 | qApp->restoreOverrideCursor(); |
16729 | fschmid | 304 | return success; |
305 | } |
||
306 | |||
307 | PdfPlug::~PdfPlug() |
||
308 | { |
||
24455 | jghali | 309 | delete m_progressDialog; |
310 | delete m_tmpSele; |
||
24693 | jghali | 311 | delete m_pdfDoc; |
16729 | fschmid | 312 | } |
313 | |||
21958 | craig | 314 | bool PdfPlug::convert(const QString& fn) |
16729 | fschmid | 315 | { |
17448 | fschmid | 316 | bool firstPg = true; |
17498 | fschmid | 317 | int baseLayer = m_Doc->activeLayer(); |
24455 | jghali | 318 | m_importedColors.clear(); |
319 | if (m_progressDialog) |
||
16729 | fschmid | 320 | { |
24455 | jghali | 321 | m_progressDialog->setOverallProgress(2); |
322 | m_progressDialog->setLabel("GI", tr("Generating Items")); |
||
323 | m_progressDialog->setBusyIndicator("GI"); |
||
16729 | fschmid | 324 | qApp->processEvents(); |
325 | } |
||
326 | |||
23395 | jghali | 327 | globalParams.reset(new GlobalParams()); |
25123 | jghali | 328 | globalParams->setErrQuiet(true); |
24985 | jghali | 329 | |
24693 | jghali | 330 | QList<OptionalContentGroup*> ocgGroups; |
24989 | jghali | 331 | QByteArray encodedFileName = os_is_win() ? fn.toUtf8() : QFile::encodeName(fn); |
24982 | jghali | 332 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(22, 3, 0) |
24989 | jghali | 333 | auto fname = std::make_unique<GooString>(encodedFileName.data()); |
334 | auto pdfDoc = std::make_unique<PDFDoc>(std::move(fname)); |
||
24982 | jghali | 335 | #else |
24989 | jghali | 336 | auto fname = new GooString(encodedFileName.data()); |
337 | auto pdfDoc = std::make_unique<PDFDoc>(fname, nullptr, nullptr, nullptr); |
||
24982 | jghali | 338 | #endif |
24693 | jghali | 339 | if (pdfDoc) |
16729 | fschmid | 340 | { |
24693 | jghali | 341 | if (pdfDoc->getErrorCode() == errEncrypted) |
342 | { |
||
343 | pdfDoc = nullptr; |
||
344 | if (m_progressDialog) |
||
345 | m_progressDialog->hide(); |
||
346 | qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor)); |
||
347 | ScribusMainWindow* mw = m_Doc->scMW(); |
||
348 | bool ok; |
||
349 | QString text = QInputDialog::getText(mw, tr("Open PDF-File"), tr("Password"), QLineEdit::Normal, "", &ok); |
||
350 | if (ok && !text.isEmpty()) |
||
351 | { |
||
24982 | jghali | 352 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(22, 3, 0) |
24989 | jghali | 353 | auto fname = std::make_unique<GooString>(encodedFileName.data()); |
24982 | jghali | 354 | std::optional<GooString> userPW(std::in_place, text.toLocal8Bit().data()); |
24989 | jghali | 355 | pdfDoc.reset(new PDFDoc(std::move(fname), userPW, userPW, nullptr)); |
24982 | jghali | 356 | #else |
24989 | jghali | 357 | auto fname = new GooString(encodedFileName.data()); |
24693 | jghali | 358 | auto userPW = new GooString(text.toLocal8Bit().data()); |
359 | pdfDoc.reset(new PDFDoc(fname, userPW, userPW, nullptr)); |
||
24982 | jghali | 360 | #endif |
24693 | jghali | 361 | qApp->changeOverrideCursor(QCursor(Qt::WaitCursor)); |
362 | } |
||
363 | if ((!pdfDoc) || (pdfDoc->getErrorCode() != errNone)) |
||
364 | { |
||
365 | if (m_progressDialog) |
||
366 | m_progressDialog->close(); |
||
367 | return false; |
||
368 | } |
||
369 | if (m_progressDialog) |
||
370 | m_progressDialog->show(); |
||
371 | } |
||
372 | if (pdfDoc->isOk()) |
||
16729 | fschmid | 373 | { |
24693 | jghali | 374 | std::vector<int> pageNs; |
375 | QString pageString = "*"; |
||
376 | m_pdfDoc = pdfDoc.get(); |
||
377 | double hDPI = 72.0; |
||
378 | double vDPI = 72.0; |
||
379 | int firstPage = 1; |
||
380 | int lastPage = pdfDoc->getNumPages(); |
||
25123 | jghali | 381 | bool useMediaBox = true; |
382 | bool crop = true; |
||
383 | bool printing = false; |
||
24693 | jghali | 384 | const PDFRectangle *mediaBox = pdfDoc->getPage(1)->getMediaBox(); |
385 | QRectF mediaRect = QRectF(QPointF(mediaBox->x1, mediaBox->y1), QPointF(mediaBox->x2, mediaBox->y2)).normalized(); |
||
386 | bool boxesAreDifferent = false; |
||
387 | if (getCBox(Crop_Box, 1) != mediaRect) |
||
388 | boxesAreDifferent = true; |
||
389 | else if (getCBox(Trim_Box, 1) != mediaRect) |
||
390 | boxesAreDifferent = true; |
||
391 | else if (getCBox(Bleed_Box, 1) != mediaRect) |
||
392 | boxesAreDifferent = true; |
||
393 | else if (getCBox(Art_Box, 1) != mediaRect) |
||
394 | boxesAreDifferent = true; |
||
395 | bool cropped = false; |
||
396 | bool importTextAsVectors = true; |
||
397 | int contentRect = Media_Box; |
||
398 | if ((m_interactive && !m_noDialogs) || (m_importerFlags & LoadSavePlugin::lfCreateDoc)) |
||
17851 | fschmid | 399 | { |
24455 | jghali | 400 | if (m_progressDialog) |
401 | m_progressDialog->hide(); |
||
17851 | fschmid | 402 | qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor)); |
24693 | jghali | 403 | PdfImportOptions optImp(ScCore->primaryMainWindow()); |
25001 | jghali | 404 | QFileInfo fi(fn); |
24693 | jghali | 405 | optImp.setUpOptions(fi.fileName(), firstPage, lastPage, m_interactive, boxesAreDifferent, this); |
406 | if (!optImp.exec()) |
||
17851 | fschmid | 407 | { |
24455 | jghali | 408 | if (m_progressDialog) |
409 | m_progressDialog->close(); |
||
24693 | jghali | 410 | m_pdfDoc = nullptr; |
17851 | fschmid | 411 | return false; |
412 | } |
||
24693 | jghali | 413 | pageString = optImp.getPagesString(); |
414 | contentRect = optImp.getCropBox(); |
||
415 | cropped = optImp.croppingEnabled(); |
||
416 | if (!cropped) |
||
417 | crop = cropped; |
||
418 | importTextAsVectors = optImp.getImportAsVectors(); |
||
419 | // When displaying pages slices, we should always set useMediaBox to true |
||
420 | // in order to use MediaBox (x, y) as coordinate system |
||
421 | if (contentRect != Media_Box) |
||
25123 | jghali | 422 | useMediaBox = false; |
24693 | jghali | 423 | if (cropped) |
25123 | jghali | 424 | useMediaBox = true; |
24693 | jghali | 425 | qApp->changeOverrideCursor(QCursor(Qt::WaitCursor)); |
24455 | jghali | 426 | if (m_progressDialog) |
427 | m_progressDialog->show(); |
||
17851 | fschmid | 428 | } |
24693 | jghali | 429 | |
430 | parsePagesString(pageString, &pageNs, lastPage); |
||
431 | if (m_progressDialog) |
||
16729 | fschmid | 432 | { |
24693 | jghali | 433 | m_progressDialog->setTotalSteps("GI", pageNs.size()); |
434 | qApp->processEvents(); |
||
435 | } |
||
436 | if (pageNs.size() <= 0) { |
||
437 | m_pdfDoc = nullptr; |
||
438 | return false; |
||
439 | } |
||
24375 | jghali | 440 | |
24693 | jghali | 441 | firstPage = pageNs[0]; |
442 | std::unique_ptr<SlaOutputDev> dev; |
||
443 | if (importTextAsVectors) |
||
444 | dev.reset(new SlaOutputDev(m_Doc, &m_elements, &m_importedColors, m_importerFlags)); |
||
445 | else |
||
446 | dev.reset(new PdfTextOutputDev(m_Doc, &m_elements, &m_importedColors, m_importerFlags)); |
||
24375 | jghali | 447 | |
24693 | jghali | 448 | if (dev->isOk()) |
449 | { |
||
450 | OCGs* ocg = pdfDoc->getOptContentConfig(); |
||
451 | if (ocg && ocg->hasOCGs()) |
||
17444 | fschmid | 452 | { |
24693 | jghali | 453 | QStringList ocgNames; |
454 | Array *order = ocg->getOrderArray(); |
||
455 | if (order) |
||
17444 | fschmid | 456 | { |
24693 | jghali | 457 | for (int i = 0; i < order->getLength (); ++i) |
17444 | fschmid | 458 | { |
24693 | jghali | 459 | Object orderItem = order->get(i); |
460 | if (orderItem.isDict()) |
||
17444 | fschmid | 461 | { |
25123 | jghali | 462 | const Object & ref = order->getNF(i); |
24693 | jghali | 463 | if (ref.isRef()) |
17444 | fschmid | 464 | { |
24693 | jghali | 465 | OptionalContentGroup *oc = ocg->findOcgByRef(ref.getRef()); |
466 | QString ocgName = UnicodeParsedString(oc->getName()); |
||
467 | if (!ocgNames.contains(ocgName)) |
||
17444 | fschmid | 468 | { |
24693 | jghali | 469 | ocgGroups.prepend(oc); |
470 | ocgNames.append(ocgName); |
||
17444 | fschmid | 471 | } |
472 | } |
||
473 | } |
||
17448 | fschmid | 474 | else |
17444 | fschmid | 475 | { |
22703 | jghali | 476 | const auto& ocgs = ocg->getOCGs (); |
477 | for (const auto& ocg : ocgs) |
||
17448 | fschmid | 478 | { |
22703 | jghali | 479 | OptionalContentGroup *oc = ocg.second.get(); |
480 | QString ocgName = UnicodeParsedString(oc->getName()); |
||
481 | if (!ocgNames.contains(ocgName)) |
||
482 | { |
||
483 | ocgGroups.prepend(oc); |
||
484 | ocgNames.append(ocgName); |
||
485 | } |
||
486 | } |
||
17444 | fschmid | 487 | } |
488 | } |
||
489 | } |
||
24693 | jghali | 490 | else |
16729 | fschmid | 491 | { |
24693 | jghali | 492 | const auto& ocgs = ocg->getOCGs (); |
493 | for (const auto& ocg : ocgs) |
||
17448 | fschmid | 494 | { |
24693 | jghali | 495 | OptionalContentGroup *oc = ocg.second.get(); |
496 | QString ocgName = UnicodeParsedString(oc->getName()); |
||
497 | if (!ocgNames.contains(ocgName)) |
||
17448 | fschmid | 498 | { |
24693 | jghali | 499 | ocgGroups.prepend(oc); |
500 | ocgNames.append(ocgName); |
||
17448 | fschmid | 501 | } |
502 | } |
||
24693 | jghali | 503 | } |
504 | } |
||
22738 | jghali | 505 | |
24693 | jghali | 506 | const int zeroRotate = 0; |
507 | dev->startDoc(pdfDoc.get(), pdfDoc->getXRef(), pdfDoc->getCatalog()); |
||
508 | dev->rotate = pdfDoc->getPageRotate(firstPage); |
||
509 | bool rotated = dev->rotate == 90 || dev->rotate == 270; |
||
510 | |||
511 | if (m_importerFlags & LoadSavePlugin::lfCreateDoc) |
||
512 | { |
||
513 | if (ocg && ocg->hasOCGs()) |
||
514 | { |
||
515 | QString actL(m_Doc->activeLayerName()); |
||
25050 | craig | 516 | int currentLayer; |
24693 | jghali | 517 | for (int i = 0; i < ocgGroups.count(); i++) |
518 | { |
||
519 | OptionalContentGroup *oc = ocgGroups[i]; |
||
520 | if (actL != UnicodeParsedString(oc->getName())) |
||
521 | currentLayer = m_Doc->addLayer(UnicodeParsedString(oc->getName()), false); |
||
522 | else |
||
523 | currentLayer = m_Doc->layerIDFromName(UnicodeParsedString(oc->getName())); |
||
524 | if (oc->getState() == OptionalContentGroup::On) |
||
525 | m_Doc->setLayerVisible(currentLayer, true); |
||
526 | else if (oc->getViewState() == OptionalContentGroup::ocUsageOn) |
||
527 | m_Doc->setLayerVisible(currentLayer, true); |
||
528 | else |
||
529 | m_Doc->setLayerVisible(currentLayer, false); |
||
530 | if ((oc->getPrintState() == OptionalContentGroup::ocUsageOn) || (oc->getPrintState() == OptionalContentGroup::ocUsageUnset)) |
||
531 | m_Doc->setLayerPrintable(currentLayer, true); |
||
532 | else |
||
533 | m_Doc->setLayerPrintable(currentLayer, false); |
||
534 | oc->setState(OptionalContentGroup::Off); |
||
535 | } |
||
536 | dev->layersSetByOCG = true; |
||
537 | } |
||
538 | |||
539 | Object info = pdfDoc->getDocInfo(); |
||
540 | if (info.isDict()) |
||
541 | { |
||
542 | Object obj; |
||
543 | Dict *infoDict = info.getDict(); |
||
544 | obj = infoDict->lookup((char*) "Title"); |
||
545 | if (obj.isString()) |
||
546 | { |
||
547 | m_Doc->documentInfo().setTitle(UnicodeParsedString(obj.getString())); |
||
548 | } |
||
549 | obj = infoDict->lookup((char*) "Author"); |
||
550 | if (obj.isString()) |
||
551 | { |
||
552 | m_Doc->documentInfo().setAuthor(UnicodeParsedString(obj.getString())); |
||
553 | } |
||
554 | obj = infoDict->lookup((char*) "Subject"); |
||
555 | if (obj.isString()) |
||
556 | { |
||
557 | m_Doc->documentInfo().setSubject(UnicodeParsedString(obj.getString())); |
||
558 | } |
||
559 | obj = infoDict->lookup((char*) "Keywords"); |
||
560 | if (obj.isString()) |
||
561 | { |
||
562 | // s1 = obj.getString(); |
||
563 | m_Doc->documentInfo().setKeywords(UnicodeParsedString(obj.getString())); |
||
564 | } |
||
565 | } |
||
566 | info = Object(); |
||
567 | |||
568 | if (cropped) |
||
569 | { |
||
570 | QRectF crBox = getCBox(contentRect, pageNs[0]); |
||
571 | if (rotated) |
||
572 | { |
||
573 | m_Doc->setPageWidth(crBox.height()); |
||
574 | m_Doc->setPageHeight(crBox.width()); |
||
575 | } |
||
576 | else |
||
577 | { |
||
578 | m_Doc->setPageHeight(crBox.height()); |
||
579 | m_Doc->setPageWidth(crBox.width()); |
||
580 | } |
||
581 | } |
||
582 | else |
||
583 | { |
||
584 | if (rotated) |
||
585 | { |
||
586 | m_Doc->setPageWidth(pdfDoc->getPageMediaHeight(pageNs[0])); |
||
587 | m_Doc->setPageHeight(pdfDoc->getPageMediaWidth(pageNs[0])); |
||
588 | } |
||
589 | else |
||
590 | { |
||
591 | m_Doc->setPageHeight(pdfDoc->getPageMediaHeight(pageNs[0])); |
||
592 | m_Doc->setPageWidth(pdfDoc->getPageMediaWidth(pageNs[0])); |
||
593 | } |
||
594 | } |
||
595 | m_Doc->setPageSize("Custom"); |
||
596 | // m_Doc->pdfOptions().PresentVals.clear(); |
||
597 | for (size_t i = 0; i < pageNs.size(); ++i) |
||
598 | { |
||
599 | if (m_progressDialog) |
||
600 | { |
||
601 | m_progressDialog->setProgress("GI", i); |
||
602 | qApp->processEvents(); |
||
603 | } |
||
604 | int pp = pageNs[i]; |
||
605 | m_Doc->setActiveLayer(baseLayer); |
||
606 | if (firstPg) |
||
607 | firstPg = false; |
||
608 | else |
||
609 | m_Doc->addPage(i); |
||
610 | QRectF mdBox = getCBox(0, pp); |
||
611 | QRectF crBox = getCBox(contentRect, pp); |
||
18004 | fschmid | 612 | if (cropped) |
17885 | fschmid | 613 | { |
18000 | fschmid | 614 | if (rotated) |
615 | { |
||
24693 | jghali | 616 | m_Doc->currentPage()->setInitialWidth(crBox.height()); |
617 | m_Doc->currentPage()->setInitialHeight(crBox.width()); |
||
618 | m_Doc->currentPage()->setWidth(crBox.height()); |
||
619 | m_Doc->currentPage()->setHeight(crBox.width()); |
||
620 | dev->cropOffsetX = crBox.y(); |
||
621 | dev->cropOffsetY = crBox.x(); |
||
18000 | fschmid | 622 | } |
623 | else |
||
624 | { |
||
24693 | jghali | 625 | m_Doc->currentPage()->setInitialHeight(crBox.height()); |
626 | m_Doc->currentPage()->setInitialWidth(crBox.width()); |
||
627 | m_Doc->currentPage()->setHeight(crBox.height()); |
||
628 | m_Doc->currentPage()->setWidth(crBox.width()); |
||
629 | dev->cropOffsetX = crBox.x(); |
||
630 | dev->cropOffsetY = crBox.y(); |
||
18000 | fschmid | 631 | } |
17885 | fschmid | 632 | } |
633 | else |
||
634 | { |
||
18000 | fschmid | 635 | if (rotated) |
636 | { |
||
24693 | jghali | 637 | m_Doc->currentPage()->setInitialWidth(pdfDoc->getPageMediaHeight(pp)); |
638 | m_Doc->currentPage()->setInitialHeight(pdfDoc->getPageMediaWidth(pp)); |
||
639 | m_Doc->currentPage()->setWidth(pdfDoc->getPageMediaHeight(pp)); |
||
640 | m_Doc->currentPage()->setHeight(pdfDoc->getPageMediaWidth(pp)); |
||
18000 | fschmid | 641 | } |
642 | else |
||
643 | { |
||
24693 | jghali | 644 | m_Doc->currentPage()->setInitialHeight(pdfDoc->getPageMediaHeight(pp)); |
645 | m_Doc->currentPage()->setInitialWidth(pdfDoc->getPageMediaWidth(pp)); |
||
646 | m_Doc->currentPage()->setHeight(pdfDoc->getPageMediaHeight(pp)); |
||
647 | m_Doc->currentPage()->setWidth(pdfDoc->getPageMediaWidth(pp)); |
||
18000 | fschmid | 648 | } |
17885 | fschmid | 649 | } |
24693 | jghali | 650 | m_Doc->currentPage()->setMasterPageNameNormal(); |
651 | m_Doc->currentPage()->setSize("Custom"); |
||
652 | m_Doc->reformPages(true); |
||
653 | if (ocg && ocg->hasOCGs()) |
||
17448 | fschmid | 654 | { |
24693 | jghali | 655 | for (int j = 0; j < ocgGroups.count(); j++) |
24688 | jghali | 656 | { |
24693 | jghali | 657 | OptionalContentGroup *oc = ocgGroups[j]; |
658 | oc->setState(OptionalContentGroup::On); |
||
659 | if (cropped) |
||
660 | pdfDoc->displayPageSlice(dev.get(), pp, hDPI, vDPI, zeroRotate, useMediaBox, crop, printing, crBox.x() - mdBox.x(), mdBox.bottom() - crBox.bottom(), crBox.width(), crBox.height(), nullptr, nullptr, dev->annotations_callback, dev.get()); |
||
661 | else |
||
662 | pdfDoc->displayPage(dev.get(), pp, hDPI, vDPI, zeroRotate, useMediaBox, crop, printing, nullptr, nullptr, dev->annotations_callback, dev.get()); |
||
663 | oc->setState(OptionalContentGroup::Off); |
||
24688 | jghali | 664 | } |
24693 | jghali | 665 | } |
666 | else |
||
667 | { |
||
18004 | fschmid | 668 | if (cropped) |
24693 | jghali | 669 | pdfDoc->displayPageSlice(dev.get(), pp, hDPI, vDPI, zeroRotate, useMediaBox, crop, printing, crBox.x() - mdBox.x(), mdBox.bottom() - crBox.bottom(), crBox.width(), crBox.height(), nullptr, nullptr, dev->annotations_callback, dev.get()); |
17885 | fschmid | 670 | else |
24693 | jghali | 671 | pdfDoc->displayPage(dev.get(), pp, hDPI, vDPI, zeroRotate, useMediaBox, crop, printing, nullptr, nullptr, dev->annotations_callback, dev.get()); |
672 | } |
||
673 | |||
674 | PDFPresentationData ef; |
||
675 | Object trans = pdfDoc->getPage(pp)->getTrans(); |
||
676 | Object *transi = &trans; |
||
677 | if (transi->isDict()) |
||
678 | { |
||
679 | m_Doc->pdfOptions().PresentMode = true; |
||
680 | PageTransition pgTrans(transi); |
||
681 | ef.pageViewDuration = pdfDoc->getPage(pp)->getDuration(); |
||
682 | ef.pageEffectDuration = pgTrans.getDuration(); |
||
683 | ef.Dm = pgTrans.getAlignment() == transitionHorizontal ? 0 : 1; |
||
684 | ef.M = pgTrans.getDirection() == transitionInward ? 0 : 1; |
||
685 | int ang = pgTrans.getAngle(); |
||
686 | if (ang == 0) |
||
687 | ef.Di = 0; |
||
688 | else if (ang == 270) |
||
689 | ef.Di = 1; |
||
690 | else if (ang == 90) |
||
691 | ef.Di = 2; |
||
692 | else if (ang == 180) |
||
693 | ef.Di = 3; |
||
694 | else if (ang == 315) |
||
695 | ef.Di = 4; |
||
696 | PageTransitionType trType = pgTrans.getType(); |
||
697 | if (trType == transitionReplace) |
||
698 | ef.effectType = 0; |
||
699 | else if (trType == transitionBlinds) |
||
700 | ef.effectType = 1; |
||
701 | else if (trType == transitionBox) |
||
702 | ef.effectType = 2; |
||
703 | else if (trType == transitionDissolve) |
||
704 | ef.effectType = 3; |
||
705 | else if (trType == transitionGlitter) |
||
706 | ef.effectType = 4; |
||
707 | else if (trType == transitionSplit) |
||
708 | ef.effectType = 5; |
||
709 | else if (trType == transitionWipe) |
||
710 | ef.effectType = 6; |
||
711 | else if (trType == transitionPush) |
||
712 | ef.effectType = 7; |
||
713 | else if (trType == transitionCover) |
||
714 | ef.effectType = 8; |
||
715 | else if (trType == transitionUncover) |
||
716 | ef.effectType = 9; |
||
717 | else if (trType == transitionFade) |
||
718 | ef.effectType = 10; |
||
719 | } |
||
720 | m_Doc->currentPage()->PresentVals = ef; |
||
721 | } |
||
722 | int numjs = pdfDoc->getCatalog()->numJS(); |
||
723 | if (numjs > 0) |
||
724 | { |
||
725 | NameTree jsNameTreeP; |
||
726 | Object catDict = pdfDoc->getXRef()->getCatalog(); |
||
727 | if (catDict.isDict()) |
||
728 | { |
||
729 | Object names = catDict.dictLookup("Names"); |
||
730 | if (names.isDict()) |
||
17885 | fschmid | 731 | { |
24693 | jghali | 732 | Object obj = names.dictLookup("JavaScript"); |
733 | jsNameTreeP.init(pdfDoc->getXRef(), &obj); |
||
17885 | fschmid | 734 | } |
24693 | jghali | 735 | for (int a = 0; a < numjs; a++) |
17448 | fschmid | 736 | { |
24693 | jghali | 737 | m_Doc->JavaScripts.insert(UnicodeParsedString(jsNameTreeP.getName(a)), UnicodeParsedString(pdfDoc->getCatalog()->getJS(a))); |
17448 | fschmid | 738 | } |
24693 | jghali | 739 | names = catDict.dictLookup("OpenAction"); |
740 | if (names.isDict()) |
||
18004 | fschmid | 741 | { |
24693 | jghali | 742 | std::unique_ptr<LinkAction> linkActionUPtr = LinkAction::parseAction(&names, pdfDoc->getCatalog()->getBaseURI()); |
743 | LinkAction *linkAction = linkActionUPtr.get(); |
||
744 | if (linkAction && (linkAction->getKind() == actionJavaScript)) |
||
745 | { |
||
746 | LinkJavaScript *jsa = (LinkJavaScript*) linkAction; |
||
747 | if (jsa->isOk()) |
||
17857 | fschmid | 748 | { |
24693 | jghali | 749 | QString script = UnicodeParsedString(jsa->getScript()); |
750 | if (script.startsWith("this.")) |
||
17857 | fschmid | 751 | { |
24693 | jghali | 752 | script.remove(0, 5); |
753 | script.remove("()"); |
||
754 | if (m_Doc->JavaScripts.contains(script)) |
||
755 | m_Doc->pdfOptions().openAction = script; |
||
17857 | fschmid | 756 | } |
757 | } |
||
758 | } |
||
17847 | fschmid | 759 | } |
760 | } |
||
16729 | fschmid | 761 | } |
24693 | jghali | 762 | m_Doc->pdfOptions().Version = (PDFVersion::Version) qMin(16, qMax(13, pdfDoc->getPDFMajorVersion() * 10 + pdfDoc->getPDFMinorVersion())); |
763 | ViewerPreferences *viewPrefs = pdfDoc->getCatalog()->getViewerPreferences(); |
||
764 | if (viewPrefs) |
||
17448 | fschmid | 765 | { |
24693 | jghali | 766 | m_Doc->pdfOptions().Binding = viewPrefs->getDirection() == ViewerPreferences::directionL2R ? 0 : 1; |
767 | m_Doc->pdfOptions().hideMenuBar = viewPrefs->getHideMenubar(); |
||
768 | m_Doc->pdfOptions().hideToolBar = viewPrefs->getHideToolbar(); |
||
769 | m_Doc->pdfOptions().fitWindow = viewPrefs->getFitWindow(); |
||
770 | } |
||
771 | Catalog::PageMode pgm = pdfDoc->getCatalog()->getPageMode(); |
||
772 | m_Doc->pdfOptions().displayFullscreen = (pgm == Catalog::pageModeFullScreen); |
||
773 | m_Doc->pdfOptions().displayThumbs = (pgm == Catalog::pageModeThumbs); |
||
774 | m_Doc->pdfOptions().displayBookmarks = (pgm == Catalog::pageModeOutlines); |
||
775 | m_Doc->pdfOptions().displayLayers = (pgm == Catalog::pageModeOC); |
||
776 | Catalog::PageLayout pgl = pdfDoc->getCatalog()->getPageLayout(); |
||
777 | if (pgl == Catalog::pageLayoutSinglePage) |
||
778 | m_Doc->pdfOptions().PageLayout = PDFOptions::SinglePage; |
||
779 | else if (pgl == Catalog::pageLayoutOneColumn) |
||
780 | m_Doc->pdfOptions().PageLayout = PDFOptions::OneColumn; |
||
781 | else if ((pgl == Catalog::pageLayoutTwoColumnLeft) || (pgl == Catalog::pageLayoutTwoPageLeft)) |
||
782 | { |
||
783 | m_Doc->setPagePositioning(1); |
||
784 | m_Doc->setPageSetFirstPage(1, 0); |
||
785 | m_Doc->pdfOptions().PageLayout = PDFOptions::TwoColumnLeft; |
||
786 | } |
||
787 | else if ((pgl == Catalog::pageLayoutTwoColumnRight) || (pgl == Catalog::pageLayoutTwoPageRight)) |
||
788 | { |
||
789 | m_Doc->setPagePositioning(1); |
||
790 | m_Doc->setPageSetFirstPage(1, 1); |
||
791 | m_Doc->pdfOptions().PageLayout = PDFOptions::TwoColumnRight; |
||
792 | } |
||
793 | } |
||
794 | else |
||
795 | { |
||
796 | if (ocg && ocg->hasOCGs()) |
||
797 | { |
||
798 | for (int a = 0; a < ocgGroups.count(); a++) |
||
17448 | fschmid | 799 | { |
24693 | jghali | 800 | ocgGroups[a]->setState(OptionalContentGroup::On); |
17448 | fschmid | 801 | } |
802 | } |
||
24693 | jghali | 803 | pdfDoc->displayPage(dev.get(), firstPage, hDPI, vDPI, zeroRotate, useMediaBox, crop, printing, nullptr, nullptr, dev->annotations_callback, dev.get()); |
16729 | fschmid | 804 | } |
805 | } |
||
24693 | jghali | 806 | |
807 | m_pdfDoc = nullptr; |
||
16729 | fschmid | 808 | } |
24693 | jghali | 809 | pdfDoc.reset(); |
16729 | fschmid | 810 | } |
24693 | jghali | 811 | globalParams.reset(); |
16729 | fschmid | 812 | |
813 | // qDebug() << "converting finished"; |
||
24455 | jghali | 814 | // qDebug() << "Imported" << m_elements.count() << "Elements"; |
16729 | fschmid | 815 | |
24455 | jghali | 816 | if (m_elements.count() == 0) |
16729 | fschmid | 817 | { |
24455 | jghali | 818 | for (int i = 0; i < m_importedColors.count(); i++) |
16729 | fschmid | 819 | { |
24455 | jghali | 820 | m_Doc->PageColors.remove(m_importedColors[i]); |
16729 | fschmid | 821 | } |
822 | } |
||
823 | |||
24455 | jghali | 824 | if (m_progressDialog) |
825 | m_progressDialog->close(); |
||
16729 | fschmid | 826 | return true; |
827 | } |
||
828 | |||
18004 | fschmid | 829 | QImage PdfPlug::readPreview(int pgNum, int width, int height, int box) |
17880 | fschmid | 830 | { |
831 | if (!m_pdfDoc) |
||
832 | return QImage(); |
||
24374 | jghali | 833 | |
17880 | fschmid | 834 | double h = m_pdfDoc->getPageMediaHeight(pgNum); |
835 | double w = m_pdfDoc->getPageMediaWidth(pgNum); |
||
836 | double scale = qMin(height / h, width / w); |
||
837 | double hDPI = 72.0 * scale; |
||
838 | double vDPI = 72.0 * scale; |
||
839 | SplashColor bgColor; |
||
840 | bgColor[0] = 255; |
||
841 | bgColor[1] = 255; |
||
842 | bgColor[2] = 255; |
||
25123 | jghali | 843 | SplashOutputDev *dev = new SplashOutputDev(splashModeXBGR8, 4, false, bgColor, true); |
844 | dev->setVectorAntialias(true); |
||
845 | dev->setFreeTypeHinting(true, false); |
||
17880 | fschmid | 846 | dev->startDoc(m_pdfDoc); |
25123 | jghali | 847 | m_pdfDoc->displayPage(dev, pgNum, hDPI, vDPI, 0, true, false, false); |
17880 | fschmid | 848 | SplashBitmap *bitmap = dev->getBitmap(); |
849 | int bw = bitmap->getWidth(); |
||
850 | int bh = bitmap->getHeight(); |
||
851 | SplashColorPtr dataPtr = bitmap->getDataPtr(); |
||
852 | if (QSysInfo::BigEndian == QSysInfo::ByteOrder) |
||
853 | { |
||
854 | uchar c; |
||
855 | int count = bw * bh * 4; |
||
856 | for (int k = 0; k < count; k += 4) |
||
857 | { |
||
858 | c = dataPtr[k]; |
||
859 | dataPtr[k] = dataPtr[k+3]; |
||
860 | dataPtr[k+3] = c; |
||
861 | c = dataPtr[k+1]; |
||
862 | dataPtr[k+1] = dataPtr[k+2]; |
||
863 | dataPtr[k+2] = c; |
||
864 | } |
||
865 | } |
||
866 | // construct a qimage SHARING the raw bitmap data in memory |
||
867 | QImage tmpimg( dataPtr, bw, bh, QImage::Format_ARGB32 ); |
||
868 | QImage image = tmpimg.copy(); |
||
869 | image.setText("XSize", QString("%1").arg(w)); |
||
870 | image.setText("YSize", QString("%1").arg(h)); |
||
18004 | fschmid | 871 | if (box > Media_Box) |
872 | { |
||
873 | QRectF cRect = getCBox(box, pgNum); |
||
22088 | jghali | 874 | QRectF mediaRect = getCBox(0, pgNum); |
875 | cRect.moveTo(cRect.x() - mediaRect.x(), cRect.y() - mediaRect.y()); |
||
18004 | fschmid | 876 | QPainter pp; |
877 | pp.begin(&image); |
||
878 | pp.setBrush(Qt::NoBrush); |
||
22829 | jghali | 879 | pp.setPen(QPen(Qt::red, 3.0)); |
18004 | fschmid | 880 | pp.translate(0, bh); |
881 | pp.scale(scale, -scale); |
||
882 | pp.drawRect(cRect); |
||
883 | pp.end(); |
||
884 | } |
||
17880 | fschmid | 885 | delete dev; |
886 | return image; |
||
887 | } |
||
888 | |||
18004 | fschmid | 889 | QRectF PdfPlug::getCBox(int box, int pgNum) |
890 | { |
||
22741 | jghali | 891 | const PDFRectangle *cBox = nullptr; |
18060 | jghali | 892 | if (box == Media_Box) |
893 | cBox = m_pdfDoc->getPage(pgNum)->getMediaBox(); |
||
894 | else if (box == Bleed_Box) |
||
18004 | fschmid | 895 | cBox = m_pdfDoc->getPage(pgNum)->getBleedBox(); |
896 | else if (box == Trim_Box) |
||
897 | cBox = m_pdfDoc->getPage(pgNum)->getTrimBox(); |
||
898 | else if (box == Crop_Box) |
||
899 | cBox = m_pdfDoc->getPage(pgNum)->getCropBox(); |
||
900 | else if (box == Art_Box) |
||
901 | cBox = m_pdfDoc->getPage(pgNum)->getArtBox(); |
||
902 | QRectF cRect = QRectF(QPointF(cBox->x1, cBox->y1), QPointF(cBox->x2, cBox->y2)).normalized(); |
||
903 | return cRect; |
||
904 | } |
||
905 | |||
25123 | jghali | 906 | QString PdfPlug::UnicodeParsedString(const GooString *s1) |
16729 | fschmid | 907 | { |
908 | if ( !s1 || s1->getLength() == 0 ) |
||
909 | return QString(); |
||
25123 | jghali | 910 | bool isUnicode; |
16729 | fschmid | 911 | int i; |
912 | Unicode u; |
||
913 | QString result; |
||
914 | if ((s1->getChar(0) & 0xff) == 0xfe && (s1->getLength() > 1 && (s1->getChar(1) & 0xff) == 0xff)) |
||
915 | { |
||
25123 | jghali | 916 | isUnicode = true; |
16729 | fschmid | 917 | i = 2; |
918 | result.reserve((s1->getLength() - 2) / 2); |
||
919 | } |
||
920 | else |
||
921 | { |
||
25123 | jghali | 922 | isUnicode = false; |
16729 | fschmid | 923 | i = 0; |
924 | result.reserve(s1->getLength()); |
||
925 | } |
||
926 | while (i < s1->getLength()) |
||
927 | { |
||
928 | if (isUnicode) |
||
929 | { |
||
930 | u = ((s1->getChar(i) & 0xff) << 8) | (s1->getChar(i+1) & 0xff); |
||
931 | i += 2; |
||
932 | } |
||
933 | else |
||
934 | { |
||
935 | u = s1->getChar(i) & 0xff; |
||
936 | ++i; |
||
937 | } |
||
22915 | jghali | 938 | // #15616: imagemagick may write unicode strings incorrectly in PDF |
939 | if (u == 0) |
||
940 | continue; |
||
16729 | fschmid | 941 | result += QChar( u ); |
942 | } |
||
943 | return result; |
||
944 | } |
||
23478 | jghali | 945 | |
946 | QString PdfPlug::UnicodeParsedString(const std::string& s1) |
||
947 | { |
||
948 | if (s1.length() == 0) |
||
949 | return QString(); |
||
25123 | jghali | 950 | bool isUnicode; |
23501 | jghali | 951 | size_t i; |
23478 | jghali | 952 | Unicode u; |
953 | QString result; |
||
954 | if ((s1.at(0) & 0xff) == 0xfe && (s1.length() > 1 && (s1.at(1) & 0xff) == 0xff)) |
||
955 | { |
||
25123 | jghali | 956 | isUnicode = true; |
23478 | jghali | 957 | i = 2; |
958 | result.reserve((s1.length() - 2) / 2); |
||
959 | } |
||
960 | else |
||
961 | { |
||
25123 | jghali | 962 | isUnicode = false; |
23478 | jghali | 963 | i = 0; |
964 | result.reserve(s1.length()); |
||
965 | } |
||
966 | while (i < s1.length()) |
||
967 | { |
||
968 | if (isUnicode) |
||
969 | { |
||
970 | u = ((s1.at(i) & 0xff) << 8) | (s1.at(i+1) & 0xff); |
||
971 | i += 2; |
||
972 | } |
||
973 | else |
||
974 | { |
||
975 | u = s1.at(i) & 0xff; |
||
976 | ++i; |
||
977 | } |
||
978 | // #15616: imagemagick may write unicode strings incorrectly in PDF |
||
979 | if (u == 0) |
||
980 | continue; |
||
981 | result += QChar( u ); |
||
982 | } |
||
983 | return result; |
||
984 | } |