diff --git a/gui/previewgenerator.cpp b/gui/previewgenerator.cpp new file mode 100644 index 0000000..7d4c891 --- /dev/null +++ b/gui/previewgenerator.cpp @@ -0,0 +1 @@ +#include "previewgenerator.h" diff --git a/gui/previewgenerator.h b/gui/previewgenerator.h new file mode 100644 index 0000000..51019a0 --- /dev/null +++ b/gui/previewgenerator.h @@ -0,0 +1,17 @@ +#ifndef PREVIEWGENERATOR_H +#define PREVIEWGENERATOR_H +#include +#include +#include "previewresult.h" +#include "renderconfig.h" + +class PreviewGenerator +{ + public: + virtual PreviewResult *generate(RenderConfig config, QString documentPath, unsigned int page) = 0; + virtual ~PreviewGenerator() + { + } +}; + +#endif // PREVIEWGENERATOR_H diff --git a/gui/previewgeneratormapfunctor.cpp b/gui/previewgeneratormapfunctor.cpp new file mode 100644 index 0000000..ef08e8d --- /dev/null +++ b/gui/previewgeneratormapfunctor.cpp @@ -0,0 +1,44 @@ +#include "previewgeneratormapfunctor.h" +#include "previewgeneratorpdf.h" + +PreviewGeneratorMapFunctor::PreviewGeneratorMapFunctor() +{ + generator[GeneratorIndex::PDF] = new PreviewGeneratorPdf(); +} + +PreviewGenerator *PreviewGeneratorMapFunctor::getGenerator(QString filePath) +{ + /* Dirty, but that's all we have at this point */ + if(filePath.endsWith(".pdf")) + { + return generator[GeneratorIndex::PDF]; + } + return nullptr; +} + +PreviewGeneratorMapFunctor::~PreviewGeneratorMapFunctor() +{ + for(int i = GeneratorIndex::PDF; i < GeneratorIndex::LAST_DUMMY; i++) + { + // delete generator[i]; + generator[i] = nullptr; + } +} + +void PreviewGeneratorMapFunctor::setRenderConfig(RenderConfig config) +{ + this->renderConfig = config; +} + +QSharedPointer PreviewGeneratorMapFunctor::operator()(const QSharedPointer &renderResult) +{ + PreviewGenerator *previewGenerator = getGenerator(renderResult->getDocumentPath()); + if(previewGenerator == nullptr) + { + return QSharedPointer(); + } + auto preview = + previewGenerator->generate(this->renderConfig, renderResult->getDocumentPath(), renderResult->getPage()); + + return QSharedPointer(preview); +} diff --git a/gui/previewgeneratormapfunctor.h b/gui/previewgeneratormapfunctor.h new file mode 100644 index 0000000..9097b8c --- /dev/null +++ b/gui/previewgeneratormapfunctor.h @@ -0,0 +1,32 @@ +#ifndef PREVIEWGENERATORMAPFUNCTOR_H +#define PREVIEWGENERATORMAPFUNCTOR_H + +#include "renderconfig.h" +#include "previewgenerator.h" + +class PreviewGeneratorMapFunctor +{ + + private: + enum GeneratorIndex + { + PDF = 0, + LAST_DUMMY + }; + RenderConfig renderConfig; + PreviewGenerator *generator[LAST_DUMMY]; + PreviewGenerator *getGenerator(QString filePath); + + public: + typedef QSharedPointer result_type; + + PreviewGeneratorMapFunctor(); + + ~PreviewGeneratorMapFunctor(); + + void setRenderConfig(RenderConfig config); + + QSharedPointer operator()(const QSharedPointer &renderResult); +}; + +#endif // PREVIEWGENERATORMAPFUNCTOR_H diff --git a/gui/previewgeneratorpdf.cpp b/gui/previewgeneratorpdf.cpp new file mode 100644 index 0000000..092d5c6 --- /dev/null +++ b/gui/previewgeneratorpdf.cpp @@ -0,0 +1,59 @@ +#include +#include + +#include "previewgeneratorpdf.h" + +static QMutex cacheMutex; + +Poppler::Document *PreviewGeneratorPdf::document(QString path) +{ + if(documentcache.contains(path)) + { + return documentcache.value(path); + } + Poppler::Document *result = Poppler::Document::load(path); + if(result == nullptr) + { + // TODO: some kind of user feedback would be nice + return nullptr; + } + result->setRenderHint(Poppler::Document::TextAntialiasing); + QMutexLocker locker(&cacheMutex); + documentcache.insert(path, result); + locker.unlock(); + return result; +} + +PreviewResult *PreviewGeneratorPdf::generate(RenderConfig config, QString documentPath, unsigned int page) +{ + PreviewResultPdf *result = new PreviewResultPdf(documentPath, page); + + Poppler::Document *doc = document(documentPath); + if(doc == nullptr) + { + return result; + } + if(doc->isLocked()) + { + return result; + } + int p = (int)page - 1; + if(p < 0) + { + p = 0; + } + Poppler::Page *pdfPage = doc->page(p); + QImage img = pdfPage->renderToImage(config.scaleX, config.scaleY); + for(QString &word : config.wordsToHighlight) + { + QList rects = pdfPage->search(word, Poppler::Page::SearchFlag::IgnoreCase); + for(QRectF &rect : rects) + { + QPainter painter(&img); + painter.scale(config.scaleX / 72.0, config.scaleY / 72.0); + painter.fillRect(rect, QColor(255, 255, 0, 64)); + } + } + result->previewImage = img; + return result; +} diff --git a/gui/previewgeneratorpdf.h b/gui/previewgeneratorpdf.h new file mode 100644 index 0000000..29bd586 --- /dev/null +++ b/gui/previewgeneratorpdf.h @@ -0,0 +1,24 @@ +#ifndef PREVIEWGENERATORPDF_H +#define PREVIEWGENERATORPDF_H +#include +#include "previewgenerator.h" +#include "previewresultpdf.h" + +class PreviewGeneratorPdf : public PreviewGenerator +{ + protected: + QHash documentcache; + Poppler::Document *document(QString path); + + public: + using PreviewGenerator::PreviewGenerator; + + PreviewResult *generate(RenderConfig config, QString documentPath, unsigned int page); + + ~PreviewGeneratorPdf() + { + qDeleteAll(documentcache); + } +}; + +#endif // PREVIEWGENERATORPDF_H