diff --git poppler/PDFDoc.cc poppler/PDFDoc.cc index 631f9a70..524ce66a 100644 --- poppler/PDFDoc.cc +++ poppler/PDFDoc.cc @@ -58,40 +58,41 @@ #include #include #include #include #include #include #include #include #include "goo/glibc.h" #include "goo/gstrtod.h" #include "goo/GooString.h" #include "goo/gfile.h" #include "poppler-config.h" #include "GlobalParams.h" #include "Page.h" #include "Catalog.h" #include "Stream.h" #include "XRef.h" #include "Linearization.h" #include "Link.h" +#include "Gfx.h" #include "OutputDev.h" #include "Error.h" #include "ErrorCodes.h" #include "Lexer.h" #include "Parser.h" #include "SecurityHandler.h" #include "Decrypt.h" #ifndef DISABLE_OUTLINE #include "Outline.h" #endif #include "PDFDoc.h" #include "Hints.h" #include "UTF.h" #ifdef MULTITHREADED # define pdfdocLocker() MutexLocker locker(&mutex) #else # define pdfdocLocker() #endif @@ -538,40 +539,59 @@ void PDFDoc::displayPages(OutputDev *out, int firstPage, int lastPage, } } void PDFDoc::displayPageSlice(OutputDev *out, int page, double hDPI, double vDPI, int rotate, GBool useMediaBox, GBool crop, GBool printing, int sliceX, int sliceY, int sliceW, int sliceH, GBool (*abortCheckCbk)(void *data), void *abortCheckCbkData, GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data), void *annotDisplayDecideCbkData, GBool copyXRef) { if (getPage(page)) getPage(page)->displaySlice(out, hDPI, vDPI, rotate, useMediaBox, crop, sliceX, sliceY, sliceW, sliceH, printing, abortCheckCbk, abortCheckCbkData, annotDisplayDecideCbk, annotDisplayDecideCbkData, copyXRef); } +void PDFDoc::displayAnnot(OutputDev *out, Annot *annot, + double hDPI, double vDPI, int rotate, GBool copyXRef) { + int pageNum = annot->getPageNum(); + PDFRectangle* annotRect = annot->getRect(); + XRef *origXRef = annot->getXRef(); + if (getPage(pageNum) && origXRef) { + PDFRectangle box(annotRect->x1, annotRect->y1, annotRect->x2, annotRect->y2); + XRef *localXRef = (copyXRef) ? origXRef->copy() : origXRef; + Gfx *gfx = new Gfx(this, out, pageNum, getPage(pageNum)->getResourceDict(), + hDPI, vDPI, &box, nullptr, + rotate, nullptr, nullptr, localXRef); + annot->draw(gfx, gFalse); + delete gfx; + if (copyXRef) { + delete localXRef; + } + } +} + Links *PDFDoc::getLinks(int page) { Page *p = getPage(page); if (!p) { return new Links (nullptr); } return p->getLinks(); } void PDFDoc::processLinks(OutputDev *out, int page) { if (getPage(page)) getPage(page)->processLinks(out); } Linearization *PDFDoc::getLinearization() { if (!linearization) { linearization = new Linearization(str); linearizationState = 0; } return linearization; diff --git poppler/PDFDoc.h poppler/PDFDoc.h index 1678d167..22e50a10 100644 --- poppler/PDFDoc.h +++ poppler/PDFDoc.h @@ -166,40 +166,44 @@ public: // Display a range of pages. void displayPages(OutputDev *out, int firstPage, int lastPage, double hDPI, double vDPI, int rotate, GBool useMediaBox, GBool crop, GBool printing, GBool (*abortCheckCbk)(void *data) = NULL, void *abortCheckCbkData = NULL, GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data) = NULL, void *annotDisplayDecideCbkData = NULL); // Display part of a page. void displayPageSlice(OutputDev *out, int page, double hDPI, double vDPI, int rotate, GBool useMediaBox, GBool crop, GBool printing, int sliceX, int sliceY, int sliceW, int sliceH, GBool (*abortCheckCbk)(void *data) = NULL, void *abortCheckCbkData = NULL, GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data) = NULL, void *annotDisplayDecideCbkData = NULL, GBool copyXRef = gFalse); + // Display annotation at origin of the output device + void displayAnnot(OutputDev *out, Annot *annot, + double hDPI, double vDPI, int rotate, GBool copyXRef); + // Find a page, given its object ID. Returns page number, or 0 if // not found. int findPage(int num, int gen) { return catalog->findPage(num, gen); } // Returns the links for the current page, transferring ownership to // the caller. Links *getLinks(int page); // Find a named destination. Returns the link destination, or // NULL if is not a destination. LinkDest *findDest(const GooString *name) { return catalog->findDest(name); } // Process the links for a page. void processLinks(OutputDev *out, int page); #ifndef DISABLE_OUTLINE // Return the outline object. Outline *getOutline(); diff --git qt5/src/poppler-annotation.cc qt5/src/poppler-annotation.cc index 2394ffc5..e6c4554d 100644 --- qt5/src/poppler-annotation.cc +++ qt5/src/poppler-annotation.cc @@ -23,40 +23,41 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ // qt/kde includes #include #include #include #include #include // local includes #include "poppler-annotation.h" #include "poppler-link.h" #include "poppler-qt5.h" #include "poppler-annotation-helper.h" #include "poppler-annotation-private.h" #include "poppler-page-private.h" #include "poppler-private.h" +#include "ArthurOutputDev.h" // poppler includes #include #include #include #include #include #include /* Almost all getters directly query the underlying poppler annotation, with * the exceptions of link, file attachment, sound, movie and screen annotations, * Whose data retrieval logic has not been moved yet. Their getters return * static data set at creation time by findAnnotations */ namespace Poppler { //BEGIN AnnotationUtils implementation Annotation * AnnotationUtils::createAnnotation( const QDomElement & annElement ) { @@ -1564,40 +1565,80 @@ QRectF Annotation::boundary() const return d->boundary; const PDFRectangle * rect = d->pdfAnnot->getRect(); return d->fromPdfRectangle( *rect ); } void Annotation::setBoundary( const QRectF &boundary ) { Q_D( Annotation ); if (!d->pdfAnnot) { d->boundary = boundary; return; } PDFRectangle rect = d->boundaryToPdfRectangle( boundary, flags() ); d->pdfAnnot->setRect(&rect); } +QImage Annotation::renderToImage(double hDPI, double vDPI) const { + Q_D( const Annotation ); + QImage img; + int hints; + + if (!d->pdfAnnot) { + return img; + } + + hints = d->parentDoc->m_hints | Poppler::Document::IgnorePaperColor; + switch(d->parentDoc->m_backend) + { + case Poppler::Document::SplashBackend: + { +#if defined(HAVE_SPLASH) + SplashRenderSetup splashSettings(hints, d->parentDoc->paperColor); + Qt5SplashOutputDev splash_output(splashSettings); + splash_output.startDoc(d->parentDoc->doc); + splash_output.dump(); + d->parentDoc->doc->displayAnnot(splash_output.outputDev(), d->pdfAnnot, hDPI, vDPI, 0, gTrue); + splash_output.dump(); + img = splash_output.getXBGRImage(true); +#endif + break; + } + case Poppler::Document::ArthurBackend: + { + int w = qRound(d->pdfAnnot->getRect()->x2 - d->pdfAnnot->getRect()->x1); + int h = qRound(d->pdfAnnot->getRect()->y2 - d->pdfAnnot->getRect()->y1); + QSize size(w, h); + ImageArthurRenderSetup arthurRenderSetup(0, 0, -1, -1, hDPI, vDPI, size, d->flags, d->parentDoc->paperColor, hints); + QImageDumpingArthurOutputDev arthur_output(arthurRenderSetup); + arthur_output.startDoc(d->parentDoc->doc); + d->parentDoc->doc->displayAnnot(arthur_output.outputDev(), d->pdfAnnot, hDPI, vDPI, 0, gFalse); + img = arthur_output.getImage(); + } + } + return img; +} + Annotation::Style Annotation::style() const { Q_D( const Annotation ); if (!d->pdfAnnot) return d->style; Style s; s.setColor(convertAnnotColor( d->pdfAnnot->getColor() )); const AnnotMarkup *markupann = dynamic_cast(d->pdfAnnot); if (markupann) s.setOpacity( markupann->getOpacity() ); const AnnotBorder *border = d->pdfAnnot->getBorder(); if (border) { if ( border->getType() == AnnotBorder::typeArray ) { const AnnotBorderArray *border_array = static_cast(border); diff --git qt5/src/poppler-annotation.h qt5/src/poppler-annotation.h index a70cbe4f..51a4159d 100644 --- qt5/src/poppler-annotation.h +++ qt5/src/poppler-annotation.h @@ -271,40 +271,51 @@ class POPPLER_QT5_EXPORT Annotation void setFlags( int flags ); /** * Returns this annotation's boundary rectangle in normalized coordinates * * \sa setBoundary(const QRectF&) */ QRectF boundary() const; /** * Sets this annotation's boundary rectangle * * The boundary rectangle is the smallest rectangle that contains the * annotation. * * \warning This property is mandatory: you must always set this. * * \sa boundary(), \ref annotFixedRotation */ void setBoundary( const QRectF &boundary ); + /** + * Renders the annotations into a QImage. + * + * The closed state of the "normal" appearance will be rendered. + * It is drawn onto transparent background. + * Resulting QImage is in Format_ARGB32_Premultiplied format. + * + * \since 0.63 + */ + QImage renderToImage(double hDPI, double vDPI) const; + /** * \short Container class for Annotation style information * * \since 0.20 */ class POPPLER_QT5_EXPORT Style { public: Style(); Style( const Style &other ); Style& operator=( const Style &other ); ~Style(); // appearance properties QColor color() const; // black void setColor(const QColor &color); double opacity() const; // 1.0 void setOpacity(double opacity); // pen properties