diff options
author | ZackaryWelch <welch.zackary@gmail.com> | 2018-04-04 16:55:48 -0400 |
---|---|---|
committer | ZackaryWelch <welch.zackary@gmail.com> | 2018-04-04 16:55:48 -0400 |
commit | 0e00960a81337b407898728e01f44373d0537aab (patch) | |
tree | 44cad19e23e31052e9741c77ec25338d6475b63b /src-qt5 | |
parent | Added support for internal links. Code added for Poppler backend but not enab... (diff) | |
download | lumina-0e00960a81337b407898728e01f44373d0537aab.tar.gz lumina-0e00960a81337b407898728e01f44373d0537aab.tar.bz2 lumina-0e00960a81337b407898728e01f44373d0537aab.zip |
Added propper text annotation handling and changed how links and annotations are shown
Diffstat (limited to 'src-qt5')
-rw-r--r-- | src-qt5/desktop-utils/lumina-pdf/PrintWidget.cpp | 24 | ||||
-rw-r--r-- | src-qt5/desktop-utils/lumina-pdf/PrintWidget.h | 83 | ||||
-rw-r--r-- | src-qt5/desktop-utils/lumina-pdf/Renderer-mupdf.cpp | 86 | ||||
-rw-r--r-- | src-qt5/desktop-utils/lumina-pdf/Renderer-poppler.cpp | 8 | ||||
-rw-r--r-- | src-qt5/desktop-utils/lumina-pdf/Renderer.h | 3 |
5 files changed, 166 insertions, 38 deletions
diff --git a/src-qt5/desktop-utils/lumina-pdf/PrintWidget.cpp b/src-qt5/desktop-utils/lumina-pdf/PrintWidget.cpp index 73e47091..e9a0ed34 100644 --- a/src-qt5/desktop-utils/lumina-pdf/PrintWidget.cpp +++ b/src-qt5/desktop-utils/lumina-pdf/PrintWidget.cpp @@ -224,22 +224,18 @@ void PrintWidget::populateScene() for (int i = 0; i < pages.size(); i++){ scene->removeItem(pages.at(i)); } - for(int i = 0; i < links.size(); i++) { - if(links[i].size() > 0) { - qDeleteAll(links[i]); - links[i].clear(); - } - } - links.clear(); qDeleteAll(pages); pages.clear(); + //links.clear(); + //annots.clear(); int numPages = BACKEND->numPages(); if(BACKEND->hashSize() < numPages){ return; } //nothing to show yet for (int i = 0; i < numPages; i++) { QImage pagePicture = BACKEND->imageHash(i); QSize paperSize = pagePicture.size(); - QList<QGraphicsItem*> linkLocations; + //QList<QGraphicsItem*> linkLocations; + //QList<QGraphicsItem*> annotLocations; if(pagePicture.isNull()) { qDebug() << "NULL IMAGE ON PAGE " << i; @@ -254,9 +250,17 @@ void PrintWidget::populateScene() for(int k = 0; k < BACKEND->linkSize(i); k++) { LinkItem *lItem = new LinkItem(item, BACKEND->linkList(i, k)); lItem->setOpacity(0.1); - linkLocations.append(lItem); + //linkLocations.append(lItem); + } + //qDebug() << "Creating annotations for:" << i; + for(int k = 0; k < BACKEND->annotSize(i); k++) { + AnnotItem *aItem = new AnnotItem(item, BACKEND->annotList(i, k), BACKEND->annotLoc(i, k)); + AnnotZone *aZone = new AnnotZone(item, BACKEND->annotLoc(i, k), aItem); + aItem->setVisible(false); + //annotLocations.append(aItem); } - links.insert(i, linkLocations); + //links.insert(i, linkLocations); + //annots.insert(i, annotLocations); } } } diff --git a/src-qt5/desktop-utils/lumina-pdf/PrintWidget.h b/src-qt5/desktop-utils/lumina-pdf/PrintWidget.h index 3860b011..a95af6fa 100644 --- a/src-qt5/desktop-utils/lumina-pdf/PrintWidget.h +++ b/src-qt5/desktop-utils/lumina-pdf/PrintWidget.h @@ -19,9 +19,56 @@ #include <QStyleOptionGraphicsItem> #include <QtMath> #include <QPageLayout> +#include <QTextDocument> #include "Renderer.h" #include "TextData.h" +class AnnotItem: public QGraphicsItem { +public: + AnnotItem(QGraphicsItem *parent, QList<QString> textData, QRectF loc) : QGraphicsItem(parent), author(textData[0]), text(textData[1]) { + setCacheMode(DeviceCoordinateCache); + QString allText = "Author: " + author + "\n\n" + text; + QTextDocument document; + document.setDefaultFont(QFont("Helvitica", 10, QFont::Normal)); + document.setPageSize(QSize(120, 120)); + document.setHtml(allText); + loc.moveTopLeft(QPointF(loc.center().x(), loc.center().y()+loc.height()/2)); + loc.setSize(document.size()+QSize(10, 10)); + bbox = loc; + } + + QRectF boundingRect() const Q_DECL_OVERRIDE { return bbox; } + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) Q_DECL_OVERRIDE + { + Q_UNUSED(widget); + QString allText = "Author: " + author + "\n\n" + text; + painter->setClipRect(option->exposedRect); + painter->setFont(QFont("Helvitica", 10, QFont::Normal)); + painter->setBrush(QBrush(QColor(255, 255, 177, 255))); + painter->drawRect(bbox); + painter->setPen(QPen(QColor("Black"))); + painter->drawText(bbox, Qt::AlignLeft | Qt::TextWordWrap, allText); + } + +private: + QRectF bbox; + QString author; + QString text; +}; + +class AnnotZone: public QGraphicsItem { +public: + AnnotZone(QGraphicsItem *parent, QRectF _bbox, AnnotItem *_annot) : QGraphicsItem(parent), bbox(_bbox), annot(_annot) { } + QRectF boundingRect() const Q_DECL_OVERRIDE { return bbox; } + AnnotItem* annotation() const { return annot; } + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) Q_DECL_OVERRIDE { Q_UNUSED(widget); Q_UNUSED(painter); Q_UNUSED(option); } + +private: + QRectF bbox; + AnnotItem *annot; +}; + class LinkItem: public QGraphicsItem { public: LinkItem(QGraphicsItem *parent, TextData *_data) : QGraphicsItem(parent), bbox(_data->loc()), data(_data) { @@ -186,24 +233,38 @@ protected: emit resized(); } + void clearItems(QList<QGraphicsItem*> itemList, QGraphicsItem *item) { + foreach(QGraphicsItem *graphicsItem, itemList) { + if(item == graphicsItem) + continue; + if(graphicsItem == dynamic_cast<LinkItem*>(graphicsItem)) + graphicsItem->setOpacity(0.1); + if(graphicsItem == dynamic_cast<AnnotItem*>(graphicsItem)) + graphicsItem->setVisible(false); + } + } + void mouseMoveEvent(QMouseEvent *e) Q_DECL_OVERRIDE { QGraphicsView::mouseMoveEvent(e); - QGraphicsItem *item = scene->itemAt(mapToScene(e->pos()), transform()); - if(item) { - LinkItem *link = dynamic_cast<LinkItem*>(item); - if(link) - link->setOpacity(1); + if(QGraphicsItem *item = scene->itemAt(mapToScene(e->pos()), transform())) { QList<QGraphicsItem*> linkList; + if(item == dynamic_cast<AnnotItem*>(item)) + item = item->parentItem(); + if(PageItem *page = dynamic_cast<PageItem*>(item)) linkList = page->childItems(); else - linkList = link->parentItem()->childItems(); - foreach(QGraphicsItem *linkItem, linkList) { - if(dynamic_cast<LinkItem*>(linkItem) == link) - continue; - dynamic_cast<LinkItem*>(linkItem)->setOpacity(0.1); + linkList = item->parentItem()->childItems(); + + if(LinkItem *link = dynamic_cast<LinkItem*>(item)){ + item->setOpacity(1); + }else if(AnnotZone *annotZone = dynamic_cast<AnnotZone*>(item)){ + annotZone->annotation()->setVisible(true); + item = annotZone->annotation(); } + + clearItems(linkList, item); } } @@ -216,7 +277,7 @@ protected: if(!BACKEND->isExternalLink(page->pageNumber()-1, link->getData()->text())) { BACKEND->handleLink(link->getData()->text()); }else{ - //Handle external link + ExternalLinkDialog } link->setOpacity(0.1); } diff --git a/src-qt5/desktop-utils/lumina-pdf/Renderer-mupdf.cpp b/src-qt5/desktop-utils/lumina-pdf/Renderer-mupdf.cpp index 9b2a43f3..31a07e01 100644 --- a/src-qt5/desktop-utils/lumina-pdf/Renderer-mupdf.cpp +++ b/src-qt5/desktop-utils/lumina-pdf/Renderer-mupdf.cpp @@ -7,6 +7,29 @@ #include <QFuture> #include <QtConcurrent> +class Annot{ + public: + Annot(fz_context *_ctx, pdf_annot *_fzAnnot, char *_text, char *_author, QRectF _loc = QRectF()) : fzAnnot(_fzAnnot), ctx(_ctx), loc(_loc) { + author = (_author) ? QString::fromLocal8Bit(_author) : QString(); + text = (_text) ? QString::fromLocal8Bit(_text) : QString(); + } + + ~Annot() { + fz_drop_annot(ctx, (fz_annot*)fzAnnot); + } + + QString getAuthor() { return author; } + QString getText() { return text; } + QRectF getLoc() { return loc; } + + private: + pdf_annot *fzAnnot; + fz_context *ctx; + QString author; + QString text; + QRectF loc; +}; + class Link { public: Link(fz_context *_ctx, fz_link *_fzLink, char *_uri, int _page, QRectF _loc = QRectF()) : fzLink(_fzLink), ctx(_ctx) { @@ -29,14 +52,15 @@ class Link { class Data { public: - Data(int _pagenum, fz_context *_ctx, fz_display_list *_list, fz_rect _bbox, fz_matrix _ctm, double _sf, fz_link *_link) : pagenumber(_pagenum), ctx(_ctx), list(_list), bbox(_bbox), ctm(_ctm), sf(_sf) { + Data(int _pagenum, fz_context *_ctx, fz_display_list *_list, fz_rect _bbox, fz_matrix _ctm, double _sf, fz_link *_link, QList<Annot*> &_annot) : pagenumber(_pagenum), ctx(_ctx), list(_list), bbox(_bbox), ctm(_ctm), sf(_sf), annotList(_annot) { while(_link) { QRectF rect(sf*_link->rect.x0, sf*_link->rect.y0, sf*(_link->rect.x1 - _link->rect.x0), sf*(_link->rect.y1 - _link->rect.y0)); Link *link = new Link(_ctx, _link, _link->uri, _pagenum, rect); - linkList.push_back(link); + linkList.append(link); _link = _link->next; } + } ~Data() { @@ -44,10 +68,13 @@ class Data { fz_drop_display_list(ctx, list); qDeleteAll(linkList); linkList.clear(); + qDeleteAll(annotList); + annotList.clear(); } int getPage() { return pagenumber; } QList<Link*> getLinkList() { return linkList; } + QList<Annot*> getAnnotList() { return annotList; } fz_context* getContext() { return ctx; } fz_display_list* getDisplayList() { return list; } QRectF getScaledRect() { return QRectF(sf*bbox.x0, sf*bbox.y0, sf*(bbox.x1-bbox.x0), sf*(bbox.y1 - bbox.y0)); } @@ -67,6 +94,7 @@ class Data { fz_matrix ctm; QList<Link*> linkList; double sf; + QList<Annot*> annotList; fz_pixmap *pix; QImage img; @@ -241,6 +269,7 @@ void renderer(Data *data, Renderer *obj) fz_drop_device(ctx, dev); fz_drop_context(ctx); + //qDebug() << "Finished rendering:" << pagenum; emit obj->PageLoaded(pagenum); } @@ -251,10 +280,11 @@ void Renderer::renderPage(int pagenum, QSize DPI, int degrees){ fz_rect bbox; fz_display_list *list; - double pageDPI = 96.0; - double sf = DPI.width() / pageDPI; - fz_scale(&matrix, sf, sf); - fz_pre_rotate(&matrix, degrees); + //double pageDPI = 96.0; + //double sf = DPI.width() / pageDPI; + double sf = 1; + //fz_scale(&matrix, sf, sf); + fz_rotate(&matrix, degrees); fz_page *PAGE = fz_load_page(CTX, DOC, pagenum); fz_bound_page(CTX, PAGE, &bbox); @@ -264,25 +294,35 @@ void Renderer::renderPage(int pagenum, QSize DPI, int degrees){ list = fz_new_display_list(CTX, &bbox); fz_device *dev = fz_new_list_device(CTX, list); fz_run_page(CTX, PAGE, dev, &fz_identity, NULL); - fz_annot *annot = fz_first_annot(CTX, PAGE); - while(annot) { + fz_link *link = fz_load_links(CTX, PAGE); + pdf_annot *_annot = pdf_first_annot(CTX, (pdf_page*)PAGE); + QList<Annot*> annotList; + + //qDebug() << "Starting annotations for:" << pagenum; + while(_annot) { + pdf_run_annot(CTX, _annot, dev, &fz_identity, NULL); fz_rect anotBox; - fz_bound_annot(CTX, annot, &anotBox); - fz_run_annot(CTX, annot, dev, &matrix, NULL); - - QRectF rect(anotBox.x0, anotBox.y0, (anotBox.x1-anotBox.x0), (anotBox.y1 - anotBox.y0)); - qDebug() << "Annotation:" << rect << "at" << pagenum; - annot = fz_next_annot(CTX, annot); + pdf_bound_annot(CTX, _annot, &anotBox); + QRectF rect(sf*anotBox.x0, sf*anotBox.y0, sf*(anotBox.x1-anotBox.x0), sf*(anotBox.y1 - anotBox.y0)); + char *contents = NULL, *author = NULL; + fz_try(CTX) + contents = pdf_copy_annot_contents(CTX, _annot); + fz_catch(CTX) { } + fz_try(CTX) + author = pdf_copy_annot_author(CTX, _annot); + fz_catch(CTX) { } + + Annot *annot = new Annot(CTX, _annot, contents, author, rect); + annotList.append(annot); + _annot = _annot->next; } - fz_link *link = fz_load_links(CTX, PAGE); - fz_close_device(CTX, dev); fz_drop_device(CTX, dev); fz_drop_page(CTX, PAGE); - data = new Data(pagenum, CTX, list, bbox, matrix, sf, link); + data = new Data(pagenum, CTX, list, bbox, matrix, sf, link, annotList); data->setRenderThread(QtConcurrent::run(&renderer, data, this)); } @@ -328,6 +368,18 @@ int Renderer::linkSize(int pagenum) { return dataHash[pagenum]->getLinkList().size(); } +QList<QString> Renderer::annotList(int pagenum, int entry) { + return QList<QString>() << dataHash[pagenum]->getAnnotList()[entry]->getAuthor() << dataHash[pagenum]->getAnnotList()[entry]->getText(); +} + +QRectF Renderer::annotLoc(int pagenum, int entry) { + return dataHash[pagenum]->getAnnotList()[entry]->getLoc(); +} + +int Renderer::annotSize(int pagenum) { + return dataHash[pagenum]->getAnnotList().size(); +} + bool Renderer::isExternalLink(int pagenum, QString text) { QList<Link*> linkList = dataHash[pagenum]->getLinkList(); foreach(Link *link, linkList) { diff --git a/src-qt5/desktop-utils/lumina-pdf/Renderer-poppler.cpp b/src-qt5/desktop-utils/lumina-pdf/Renderer-poppler.cpp index 98a351bd..7354cf38 100644 --- a/src-qt5/desktop-utils/lumina-pdf/Renderer-poppler.cpp +++ b/src-qt5/desktop-utils/lumina-pdf/Renderer-poppler.cpp @@ -190,8 +190,16 @@ TextData* Renderer::linkList(int pageNum, int entry) { return 0; } +QList<QString> Renderer::annotList(int pageNum, int entry) { + return QList<QString>() << QString() << QString(); +} + int Renderer::linkSize(int pageNum) { return linkHash[pageNum].size(); } +int Renderer::annotSize(int pageNum) { return 0; } + +QRectF Renderer::annotLoc(int pageNum, int entry) { return QRectF(); } + bool Renderer::isExternalLink(int pageNum, QString text) { Poppler::Link* trueLink; foreach(QList<Link*> linkArray, linkHash) { diff --git a/src-qt5/desktop-utils/lumina-pdf/Renderer.h b/src-qt5/desktop-utils/lumina-pdf/Renderer.h index cc48b089..4dd3e3b1 100644 --- a/src-qt5/desktop-utils/lumina-pdf/Renderer.h +++ b/src-qt5/desktop-utils/lumina-pdf/Renderer.h @@ -48,6 +48,9 @@ public: void handleLink(QString); TextData *linkList(int, int); int linkSize(int); + QList<QString> annotList(int, int); + int annotSize(int); + QRectF annotLoc(int, int); bool isExternalLink(int, QString); void clearHash(); |