File indexing completed on 2024-05-12 16:06:43
0001 /* 0002 SPDX-FileCopyrightText: 2005 Albert Astals Cid <aacid@kde.org> 0003 SPDX-FileCopyrightText: 2006-2007 Pino Toscano <pino@kde.org> 0004 SPDX-FileCopyrightText: 2006-2007 Tobias Koenig <tokoe@kde.org> 0005 0006 Work sponsored by the LiMux project of the city of Munich: 0007 SPDX-FileCopyrightText: 2017 Klarälvdalens Datakonsult AB a KDAB Group company <info@kdab.com> 0008 0009 SPDX-License-Identifier: GPL-2.0-or-later 0010 */ 0011 0012 #include "generator_kimgio.h" 0013 0014 #include <QBuffer> 0015 #include <QFile> 0016 #include <QImageReader> 0017 #include <QMimeDatabase> 0018 #include <QMimeType> 0019 #include <QPainter> 0020 #include <QPrinter> 0021 0022 #include <KAboutData> 0023 #include <KActionCollection> 0024 #include <KLocalizedString> 0025 #include <QAction> 0026 #include <QIcon> 0027 0028 #ifdef WITH_KEXIV 0029 #include <kexiv2/kexiv2.h> 0030 #endif 0031 0032 #include <core/page.h> 0033 0034 OKULAR_EXPORT_PLUGIN(KIMGIOGenerator, "libokularGenerator_kimgio.json") 0035 0036 KIMGIOGenerator::KIMGIOGenerator(QObject *parent, const QVariantList &args) 0037 : Generator(parent, args) 0038 { 0039 setFeature(ReadRawData); 0040 setFeature(Threaded); 0041 setFeature(TiledRendering); 0042 setFeature(PrintNative); 0043 setFeature(PrintToFile); 0044 setFeature(SwapBackingFile); 0045 } 0046 0047 KIMGIOGenerator::~KIMGIOGenerator() 0048 { 0049 } 0050 0051 bool KIMGIOGenerator::loadDocument(const QString &fileName, QVector<Okular::Page *> &pagesVector) 0052 { 0053 QFile f(fileName); 0054 if (!f.open(QFile::ReadOnly)) { 0055 Q_EMIT error(i18n("Unable to load document: %1", f.errorString()), -1); 0056 return false; 0057 } 0058 return loadDocumentInternal(f.readAll(), fileName, pagesVector); 0059 } 0060 0061 bool KIMGIOGenerator::loadDocumentFromData(const QByteArray &fileData, QVector<Okular::Page *> &pagesVector) 0062 { 0063 return loadDocumentInternal(fileData, QString(), pagesVector); 0064 } 0065 0066 bool KIMGIOGenerator::loadDocumentInternal(const QByteArray &fileData, const QString &fileName, QVector<Okular::Page *> &pagesVector) 0067 { 0068 QBuffer buffer; 0069 buffer.setData(fileData); 0070 buffer.open(QIODevice::ReadOnly); 0071 0072 QImageReader reader(&buffer, QImageReader::imageFormat(&buffer)); 0073 reader.setAutoDetectImageFormat(true); 0074 if (!reader.read(&m_img)) { 0075 if (!m_img.isNull()) { 0076 Q_EMIT warning(i18n("This document appears malformed. Here is a best approximation of the document's intended appearance."), -1); 0077 } else { 0078 Q_EMIT error(i18n("Unable to load document: %1", reader.errorString()), -1); 0079 return false; 0080 } 0081 } 0082 QMimeDatabase db; 0083 auto mime = db.mimeTypeForFileNameAndData(fileName, fileData); 0084 docInfo.set(Okular::DocumentInfo::MimeType, mime.name()); 0085 0086 #ifdef WITH_KEXIV 0087 // Apply transformations dictated by Exif metadata 0088 KExiv2Iface::KExiv2 exifMetadata; 0089 if (exifMetadata.loadFromData(fileData)) { 0090 exifMetadata.rotateExifQImage(m_img, exifMetadata.getImageOrientation()); 0091 } 0092 #endif 0093 0094 pagesVector.resize(1); 0095 0096 Okular::Page *page = new Okular::Page(0, m_img.width(), m_img.height(), Okular::Rotation0); 0097 pagesVector[0] = page; 0098 0099 return true; 0100 } 0101 0102 KIMGIOGenerator::SwapBackingFileResult KIMGIOGenerator::swapBackingFile(QString const & /*newFileName*/, QVector<Okular::Page *> & /*newPagesVector*/) 0103 { 0104 // NOP: We don't actually need to do anything because all data has already 0105 // been loaded in RAM 0106 return SwapBackingFileNoOp; 0107 } 0108 0109 bool KIMGIOGenerator::doCloseDocument() 0110 { 0111 m_img = QImage(); 0112 0113 return true; 0114 } 0115 0116 QImage KIMGIOGenerator::image(Okular::PixmapRequest *request) 0117 { 0118 // perform a smooth scaled generation 0119 if (request->isTile()) { 0120 const QRect srcRect = request->normalizedRect().geometry(m_img.width(), m_img.height()); 0121 const QRect destRect = request->normalizedRect().geometry(request->width(), request->height()); 0122 0123 QImage destImg(destRect.size(), QImage::Format_RGB32); 0124 destImg.fill(Qt::white); 0125 0126 QPainter p(&destImg); 0127 p.setRenderHint(QPainter::SmoothPixmapTransform); 0128 p.drawImage(destImg.rect(), m_img, srcRect); 0129 0130 return destImg; 0131 } else { 0132 int width = request->width(); 0133 int height = request->height(); 0134 if (request->page()->rotation() % 2 == 1) { 0135 qSwap(width, height); 0136 } 0137 0138 return m_img.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); 0139 } 0140 } 0141 0142 Okular::Document::PrintError KIMGIOGenerator::print(QPrinter &printer) 0143 { 0144 QPainter p(&printer); 0145 0146 QImage image(m_img); 0147 0148 if ((image.width() > printer.width()) || (image.height() > printer.height())) { 0149 image = image.scaled(printer.width(), printer.height(), Qt::KeepAspectRatio, Qt::SmoothTransformation); 0150 } 0151 0152 p.drawImage(0, 0, image); 0153 0154 return Okular::Document::NoPrintError; 0155 } 0156 0157 Okular::DocumentInfo KIMGIOGenerator::generateDocumentInfo(const QSet<Okular::DocumentInfo::Key> &keys) const 0158 { 0159 Q_UNUSED(keys); 0160 0161 return docInfo; 0162 } 0163 0164 #include "generator_kimgio.moc"