From c74934c822e6870151f511b1438de202136369c2 Mon Sep 17 00:00:00 2001 From: Felix Kauselmann <2039670+selmf@users.noreply.github.com> Date: Tue, 18 Oct 2016 00:48:56 +0200 Subject: [PATCH] Add support for pdfium --- YACReader/YACReader.pro | 11 +- YACReaderLibrary/YACReaderLibrary.pro | 142 ++++++++++++++------------ YACReaderLibrary/library_creator.cpp | 102 +++++++++--------- common/comic.cpp | 20 +++- common/comic.h | 14 +-- common/pdf_comic.cpp | 81 +++++++++++++++ common/pdf_comic.h | 45 +++++--- 7 files changed, 268 insertions(+), 147 deletions(-) create mode 100644 common/pdf_comic.cpp diff --git a/YACReader/YACReader.pro b/YACReader/YACReader.pro index bace4826..f53b9fdd 100644 --- a/YACReader/YACReader.pro +++ b/YACReader/YACReader.pro @@ -58,9 +58,17 @@ win32 { } unix:!macx{ - +!CONFIG(pdfium){ INCLUDEPATH += /usr/include/poppler/qt5 LIBS += -L/usr/lib -lpoppler-qt5 +} else { + DEFINES += "USE_PDFIUM" + INCLUDEPATH += /usr/include/pdfium + LIBS += -L/usr/lib/pdfium -Wl,--start-group -lpdfium -lfpdfapi -lfxge -lfpdfdoc \ + -lfxcrt -lfx_agg -lfxcodec -lfx_lpng -lfx_libopenjpeg -lfx_lcms2 -ljpeg \ + -lfx_zlib -lfdrm -lfxedit -lformfiller -lpdfwindow -lpdfium -lbigint -ljavascript \ + -lfxedit -Wl,--end-group -lfreetype +} !CONFIG(no_opengl) { LIBS += -lGLU @@ -172,6 +180,7 @@ SOURCES += ../common/comic.cpp \ ../common/library_item.cpp \ yacreader_local_client.cpp \ ../common/http_worker.cpp \ + ../common/pdf_comic.cpp \ ../common/yacreader_global.cpp \ ../common/yacreader_global_gui.cpp \ ../common/exit_check.cpp \ diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro index 25a3b6d4..c247823a 100644 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ b/YACReaderLibrary/YACReaderLibrary.pro @@ -46,9 +46,18 @@ win32 { } unix:!macx{ - -INCLUDEPATH += /usr/include/poppler/qt5 -LIBS += -L/usr/lib -lpoppler-qt5 +!CONFIG(pdfium) { + INCLUDEPATH += /usr/include/poppler/qt5 + LIBS += -L/usr/lib -lpoppler-qt5 + } + else { + DEFINES += "USE_PDFIUM" + INCLUDEPATH += /usr/include/pdfium + LIBS += -L/usr/lib/pdfium -Wl,--start-group -lpdfium -lfpdfapi -lfxge -lfpdfdoc \ + -lfxcrt -lfx_agg -lfxcodec -lfx_lpng -lfx_libopenjpeg -lfx_lcms2 -ljpeg \ + -lfx_zlib -lfdrm -lfxedit -lformfiller -lpdfwindow -lpdfium -lbigint -ljavascript \ + -lfxedit -Wl,--end-group -lfreetype + } !CONFIG(no_opengl) { LIBS += -lGLU @@ -161,69 +170,70 @@ HEADERS += comic_flow.h \ } SOURCES += comic_flow.cpp \ - create_library_dialog.cpp \ - library_creator.cpp \ - library_window.cpp \ - main.cpp \ - add_library_dialog.cpp \ - rename_library_dialog.cpp \ - properties_dialog.cpp \ - options_dialog.cpp \ - export_library_dialog.cpp \ - import_library_dialog.cpp \ - package_manager.cpp \ - bundle_creator.cpp \ - export_comics_info_dialog.cpp \ - import_comics_info_dialog.cpp \ - server_config_dialog.cpp \ - comic_flow_widget.cpp \ - db_helper.cpp \ - ./db/data_base_management.cpp \ - ./db/folder_item.cpp \ - ./db/folder_model.cpp \ - ./db/comic_model.cpp \ - ./db/comic_item.cpp \ - ../common/comic_db.cpp \ - ../common/folder.cpp \ - ../common/library_item.cpp \ - ../common/comic.cpp \ - ../common/bookmarks.cpp \ - ../common/pictureflow.cpp \ - ../common/custom_widgets.cpp \ - ../common/qnaturalsorting.cpp \ - ../common/onstart_flow_selection_dialog.cpp \ - no_libraries_widget.cpp \ - import_widget.cpp \ - yacreader_local_server.cpp \ - yacreader_main_toolbar.cpp \ - comics_remover.cpp \ - ../common/http_worker.cpp \ - ../common/yacreader_global.cpp \ - ../common/yacreader_global_gui.cpp \ - yacreader_libraries.cpp \ - ../common/exit_check.cpp \ - comics_view.cpp \ - classic_comics_view.cpp \ - empty_folder_widget.cpp \ - no_search_results_widget.cpp \ - comic_files_manager.cpp \ - db/reading_list_model.cpp \ - db/reading_list_item.cpp \ - yacreader_folders_view.cpp \ - yacreader_reading_lists_view.cpp \ - add_label_dialog.cpp \ - yacreader_history_controller.cpp \ - yacreader_navigation_controller.cpp \ - empty_label_widget.cpp \ - empty_container_info.cpp \ - empty_special_list.cpp \ - empty_reading_list_widget.cpp \ - ../common/scroll_management.cpp \ - ../common/opengl_checker.cpp \ - yacreader_comics_views_manager.cpp \ - info_comics_view.cpp \ - yacreader_comics_selection_helper.cpp \ - yacreader_comic_info_helper.cpp + create_library_dialog.cpp \ + library_creator.cpp \ + library_window.cpp \ + main.cpp \ + add_library_dialog.cpp \ + rename_library_dialog.cpp \ + properties_dialog.cpp \ + options_dialog.cpp \ + export_library_dialog.cpp \ + import_library_dialog.cpp \ + package_manager.cpp \ + bundle_creator.cpp \ + export_comics_info_dialog.cpp \ + import_comics_info_dialog.cpp \ + server_config_dialog.cpp \ + comic_flow_widget.cpp \ + db_helper.cpp \ + ./db/data_base_management.cpp \ + ./db/folder_item.cpp \ + ./db/folder_model.cpp \ + ./db/comic_model.cpp \ + ./db/comic_item.cpp \ + ../common/comic_db.cpp \ + ../common/folder.cpp \ + ../common/library_item.cpp \ + ../common/comic.cpp \ + ../common/bookmarks.cpp \ + ../common/pictureflow.cpp \ + ../common/custom_widgets.cpp \ + ../common/qnaturalsorting.cpp \ + ../common/onstart_flow_selection_dialog.cpp \ + no_libraries_widget.cpp \ + import_widget.cpp \ + yacreader_local_server.cpp \ + yacreader_main_toolbar.cpp \ + comics_remover.cpp \ + ../common/http_worker.cpp \ + ../common/yacreader_global.cpp \ + ../common/yacreader_global_gui.cpp \ + yacreader_libraries.cpp \ + ../common/exit_check.cpp \ + ../common/pdf_comic.cpp \ + comics_view.cpp \ + classic_comics_view.cpp \ + empty_folder_widget.cpp \ + no_search_results_widget.cpp \ + comic_files_manager.cpp \ + db/reading_list_model.cpp \ + db/reading_list_item.cpp \ + yacreader_folders_view.cpp \ + yacreader_reading_lists_view.cpp \ + add_label_dialog.cpp \ + yacreader_history_controller.cpp \ + yacreader_navigation_controller.cpp \ + empty_label_widget.cpp \ + empty_container_info.cpp \ + empty_special_list.cpp \ + empty_reading_list_widget.cpp \ + ../common/scroll_management.cpp \ + ../common/opengl_checker.cpp \ + yacreader_comics_views_manager.cpp \ + info_comics_view.cpp \ + yacreader_comics_selection_helper.cpp \ + yacreader_comic_info_helper.cpp !CONFIG(no_opengl) { CONFIG(legacy_gl_widget) { diff --git a/YACReaderLibrary/library_creator.cpp b/YACReaderLibrary/library_creator.cpp index 0fa37213..d19b3b0f 100644 --- a/YACReaderLibrary/library_creator.cpp +++ b/YACReaderLibrary/library_creator.cpp @@ -14,7 +14,7 @@ #include "compressed_archive.h" #include "comic.h" - +#include "pdf_comic.h" #include "yacreader_global.h" #include "QsLog.h" @@ -22,18 +22,6 @@ #include using namespace std; -#ifdef Q_OS_MAC - #include "pdf_comic.h" -#else - -#if QT_VERSION >= 0x050000 - #include "poppler-qt5.h" -#else - #include "poppler-qt4.h" -#endif - -#endif - //-------------------------------------------------------------------------------- LibraryCreator::LibraryCreator() :creation(false), partialUpdate(false) @@ -594,8 +582,7 @@ void ThumbnailCreator::create() if(fi.suffix().compare("pdf",Qt::CaseInsensitive) == 0) { - -#ifdef Q_OS_MAC +#if defined Q_OS_MAC && defined USE_PDFKIT MacOSXPDFComic * pdfComic = new MacOSXPDFComic(); if(!pdfComic->openComic(_fileSource)) { @@ -603,40 +590,50 @@ void ThumbnailCreator::create() //QImage p; //p.load(":/images/notCover.png"); //p.save(_target); - return; - } + return; + } +#elif defined USE_PDFIUM + PdfiumComic * pdfComic = new PdfiumComic(); + if(!pdfComic->openComic(_fileSource)) + { + delete pdfComic; + return; + } #else Poppler::Document * pdfComic = Poppler::Document::load(_fileSource); #endif - if (!pdfComic) - { - QLOG_WARN() << "Extracting cover: unable to open PDF file " << _fileSource; - //delete pdfComic; //TODO check if the delete is needed - pdfComic = 0; - //QImage p; - //p.load(":/images/notCover.png"); - //p.save(_target); - return; - } -#ifndef Q_OS_MAC - //poppler only, not mac - if (pdfComic->isLocked()) - { - QLOG_WARN() << "Extracting cover: unable to open PDF file " << _fileSource; - delete pdfComic; - return; - } -#endif - _numPages = pdfComic->numPages(); - if(_numPages >= _coverPage) + + if (!pdfComic) { -#ifdef Q_OS_MAC - { //TODO is this "{" one too much? + QLOG_WARN() << "Extracting cover: unable to open PDF file " << _fileSource; + //delete pdfComic; //TODO check if the delete is needed + pdfComic = 0; + //QImage p; + //p.load(":/images/notCover.png"); + //p.save(_target); + return; + } +#if !defined USE_PDFKIT && !defined USE_PDFIUM + //poppler only, not mac + if (pdfComic->isLocked()) + { + QLOG_WARN() << "Extracting cover: unable to open PDF file " << _fileSource; + delete pdfComic; + return; + } +#endif + _numPages = pdfComic->numPages(); + if(_numPages >= _coverPage) + { +#if defined Q_OS_MAC || defined USE_PDFIUM QImage p = pdfComic->getPage(_coverPage-1); //TODO check if the page is valid + #ifdef USE_PDFKIT + pdfComic->releaseLastPageData(); + #endif #else QImage p = pdfComic->page(_coverPage-1)->renderToImage(72,72); #endif - _cover = p; + _cover = p; if(_target!="") { QImage scaled; @@ -648,22 +645,17 @@ void ThumbnailCreator::create() { scaled = p.scaledToWidth(480,Qt::SmoothTransformation); } - scaled.save(_target,0,75); + scaled.save(_target,0,75); } -#ifdef Q_OS_MAC - } //TODO is this "{" one too much? - pdfComic->releaseLastPageData(); -#endif + else if(_target!="") + { + QLOG_WARN() << "Extracting cover: requested cover index greater than numPages " << _fileSource; + //QImage p; + //p.load(":/images/notCover.png"); + //p.save(_target); + } + delete pdfComic; } - else if(_target!="") - { - QLOG_WARN() << "Extracting cover: requested cover index greater than numPages " << _fileSource; - //QImage p; - //p.load(":/images/notCover.png"); - //p.save(_target); - } - - delete pdfComic; } else { diff --git a/common/comic.cpp b/common/comic.cpp index 7ab2ffe1..fa307f7e 100644 --- a/common/comic.cpp +++ b/common/comic.cpp @@ -769,7 +769,7 @@ bool PDFComic::load(const QString & path, const ComicDB & comic) void PDFComic::process() { -#ifdef Q_OS_MAC +#if defined Q_OS_MAC && defined USE_PDFKIT pdfComic = new MacOSXPDFComic(); if(!pdfComic->openComic(_path)) { @@ -777,8 +777,15 @@ void PDFComic::process() emit errorOpening(); return; } +#elif defined USE_PDFIUM + pdfComic = new PdfiumComic(); + if(!pdfComic->openComic(_path)) + { + delete pdfComic; + emit errorOpening(); + return; + } #else - pdfComic = Poppler::Document::load(_path); if (!pdfComic) { @@ -840,12 +847,15 @@ void PDFComic::process() void PDFComic::renderPage(int page) { -#ifdef Q_OS_MAC +#if defined Q_OS_MAC && defined USE_PDFKIT QImage img = pdfComic->getPage(page); if(!img.isNull()) { pdfComic->releaseLastPageData(); - +#elif defined USE_PDFIUM + QImage img = pdfComic->getPage(page); + if(!img.isNull()) + { #else Poppler::Page* pdfpage = pdfComic->page(page); if (pdfpage) @@ -1080,4 +1090,4 @@ void comic_pages_sort(QList & pageNames, YACReaderPageSortingMode sorti std::sort(pageNames.begin(), pageNames.end()); break; } -} \ No newline at end of file +} diff --git a/common/comic.h b/common/comic.h index bf72b55b..a9a8ef51 100644 --- a/common/comic.h +++ b/common/comic.h @@ -154,14 +154,16 @@ class PDFComic : public Comic Q_OBJECT private: + //pdf -#ifdef Q_OS_MAC - MacOSXPDFComic * pdfComic; -#else + #if defined Q_OS_MAC && defined USE_PDFKIT + MacOSXPDFComic * pdfComic; + #elif defined USE_PDFIUM + PdfiumComic * pdfComic; + #else Poppler::Document * pdfComic; -#endif + #endif void renderPage(int page); - //void run(); public: @@ -183,4 +185,4 @@ class FactoryComic public: static Comic * newComic(const QString & path); }; -#endif \ No newline at end of file +#endif diff --git a/common/pdf_comic.cpp b/common/pdf_comic.cpp new file mode 100644 index 00000000..4cd85501 --- /dev/null +++ b/common/pdf_comic.cpp @@ -0,0 +1,81 @@ +#include "comic.h" +#include "pdf_comic.h" +#ifdef USE_PDFIUM +PdfiumComic::PdfiumComic() +{ + FPDF_InitLibrary(); +} + +PdfiumComic::~PdfiumComic() +{ + if (doc) + { + FPDF_CloseDocument(doc); + } + FPDF_DestroyLibrary(); +} + +bool PdfiumComic::openComic(const QString & path) +{ + doc = FPDF_LoadDocument(path.toStdString().c_str(), NULL); + if (doc) + { + return true; + } + else + { + qDebug() << FPDF_GetLastError(); + return false; + } +} + +void PdfiumComic::closeComic() +{ + FPDF_CloseDocument(doc); +} + +unsigned int PdfiumComic::numPages() +{ + if (doc) + { + return FPDF_GetPageCount(doc); + } + else + { + return 0; //-1? + } +} + +QImage PdfiumComic::getPage(const int page) +{ + QTime time; + time.start(); + QImage image; + FPDF_PAGE pdfpage; + FPDF_BITMAP bitmap; + + pdfpage = FPDF_LoadPage(doc, page); + + if (!pdfpage) + { + qDebug() << FPDF_GetLastError(); + return QImage(); + } + + //TODO: make target DPI configurable + double width = (FPDF_GetPageWidth(pdfpage)/72)*150; + double height = (FPDF_GetPageHeight(pdfpage)/72)*150; + + image = QImage(width, height, QImage::Format_RGB888);// QImage::Format_RGBX8888); + image.fill(0xFFFFFFFF); + + bitmap = FPDFBitmap_CreateEx(image.width(), image.height(), FPDFBitmap_BGR, image.scanLine(0), image.bytesPerLine()); + //TODO: make render flags costumizable + FPDF_RenderPageBitmap(bitmap, pdfpage, 0,0, image.width(), image.height(), 0, (FPDF_REVERSE_BYTE_ORDER | FPDF_LCD_TEXT)); + FPDFBitmap_Destroy(bitmap); + FPDF_ClosePage(pdfpage); + + qDebug()<< "Render time:" << time.elapsed(); + return image; +} +#endif //USE_PDFIUM diff --git a/common/pdf_comic.h b/common/pdf_comic.h index caa3d999..88899c3d 100644 --- a/common/pdf_comic.h +++ b/common/pdf_comic.h @@ -4,24 +4,41 @@ #include #include -#ifdef Q_OS_MAC +#if defined Q_OS_MAC && defined USE_PDFKIT class MacOSXPDFComic { -public: - MacOSXPDFComic(); - ~MacOSXPDFComic(); - bool openComic(const QString & path); - void closeComic(); - unsigned int numPages(); - QImage getPage(const int page); - void releaseLastPageData(); -private: - void * document; - void * lastPageData; -}; + public: + MacOSXPDFComic(); + ~MacOSXPDFComic(); + bool openComic(const QString & path); + void closeComic(); + unsigned int numPages(); + QImage getPage(const int page); + void releaseLastPageData(); + + private: + void * document; + void * lastPageData; + }; +#elif defined USE_PDFIUM +#include + +class PdfiumComic +{ + public: + PdfiumComic(); + ~PdfiumComic(); + bool openComic(const QString & path); + void closeComic(); + unsigned int numPages(); + QImage getPage(const int page); + + private: + FPDF_LIBRARY_CONFIG config; + FPDF_DOCUMENT doc; +}; #else #include "poppler-qt5.h" #endif // Q_OS_MAC - #endif // PDF_COMIC_H