poppler/FontInfo.cc | 4 - poppler/FontInfo.h | 2 qt4/src/Doxyfile | 1 qt4/src/poppler-document.cc | 27 +++++-- qt4/src/poppler-fontinfo.cc | 36 ++++++++++ qt4/src/poppler-private.h | 27 ++++++- qt4/src/poppler-qt4.h | 87 ++++++++++++++++++++++++- qt4/tests/check_fonts.cpp | 149 ++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 313 insertions(+), 20 deletions(-)
New commits: commit bdc76dc811a6e4d5fd929bbdc8cd3300aeaea31f Author: Pino Toscano <[email protected]> Date: Tue Jan 6 15:45:37 2009 +0100 [Qt4] apidox improvements for the font functions of Document; mark scanForFonts() as deprecated diff --git a/qt4/src/poppler-qt4.h b/qt4/src/poppler-qt4.h index c7b1ec4..1a7c75e 100644 --- a/qt4/src/poppler-qt4.h +++ b/qt4/src/poppler-qt4.h @@ -883,23 +883,35 @@ QString subject = m_doc->info("Subject"); /** The fonts within the PDF document. + This is a shorthand for getting all the fonts at once. + \note this can take a very long time to run with a large - document. You may wish to use the call below if you have more + document. You may wish to use a FontIterator if you have more than say 20 pages + + \see newFontIterator() */ QList<FontInfo> fonts() const; /** - \overload - + Scans for fonts within the PDF document. \param numPages the number of pages to scan \param fontList pointer to the list where the font information should be placed + \note with this method you can scan for fonts only \em once for each + document; once the end is reached, no more scanning with this method + can be done + \return false if the end of the document has been reached + + \deprecated this function is quite limited in its job (see note), + better use fonts() or newFontIterator() + + \see fonts(), newFontIterator() */ - bool scanForFonts( int numPages, QList<FontInfo> *fontList ) const; + Q_DECL_DEPRECATED bool scanForFonts( int numPages, QList<FontInfo> *fontList ) const; /** Creates a new FontIterator object for font scanning. @@ -912,6 +924,8 @@ QString subject = m_doc->info("Subject"); \param startPage the initial page from which start reading fonts + \see fonts() + \since 0.12 */ FontIterator* newFontIterator( int startPage = 0 ) const; commit 6630e715714161cd803fc064f5d3cf880f42b0a5 Author: Pino Toscano <[email protected]> Date: Tue Jan 6 15:36:19 2009 +0100 tell Doxygen to consider Q_DECL_DEPRECATED as empty diff --git a/qt4/src/Doxyfile b/qt4/src/Doxyfile index cdf57e4..871c37c 100644 --- a/qt4/src/Doxyfile +++ b/qt4/src/Doxyfile @@ -1067,6 +1067,7 @@ INCLUDE_FILE_PATTERNS = # instead of the = operator. PREDEFINED = \ + Q_DECL_DEPRECATED="" \ POPPLER_QT4_EXPORT="" # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then commit d748d430b106580b8be29ca3ec75caf05b55812e Author: Pino Toscano <[email protected]> Date: Tue Jan 6 15:24:25 2009 +0100 [Qt4] Add a FontIterator for iterating through the fonts of the document, page by page. This new iterator class is the new preferred way for getting the fonts of a document in a page-by-page mode. * Document::fonts() is adapted to use it, instead of relying on scanForFonts() * scanForFonts() is ported to FontIterator, but keeping the old behaviour ("i can scan the document only once") * added unit tests for fonts(), scanForFonts() and FontIterator diff --git a/qt4/src/poppler-document.cc b/qt4/src/poppler-document.cc index cf94062..23a1acb 100644 --- a/qt4/src/poppler-document.cc +++ b/qt4/src/poppler-document.cc @@ -181,7 +181,11 @@ namespace Poppler { QList<FontInfo> Document::fonts() const { QList<FontInfo> ourList; - scanForFonts(numPages(), &ourList); + FontIterator it( 0, m_doc ); + while ( it.hasNext() ) + { + ourList += it.next(); + } return ourList; } @@ -192,18 +196,23 @@ namespace Poppler { bool Document::scanForFonts( int numPages, QList<FontInfo> *fontList ) const { - GooList *items = m_doc->m_fontInfoScanner->scan( numPages ); - - if ( NULL == items ) - return false; - - for ( int i = 0; i < items->getLength(); ++i ) { - fontList->append( FontInfo(FontInfoData((::FontInfo*)items->get(i))) ); + if ( !m_doc->m_fontInfoIterator ) + return false; + if ( !m_doc->m_fontInfoIterator->hasNext() ) + return false; + while ( m_doc->m_fontInfoIterator->hasNext() && numPages ) + { + (*fontList) += m_doc->m_fontInfoIterator->next(); + --numPages; } - deleteGooList(items, ::FontInfo); return true; } + FontIterator* Document::newFontIterator( int startPage ) const + { + return new FontIterator( startPage, m_doc ); + } + QByteArray Document::fontData(const FontInfo &fi) const { QByteArray result; diff --git a/qt4/src/poppler-fontinfo.cc b/qt4/src/poppler-fontinfo.cc index 08a80a2..0a8c8de 100644 --- a/qt4/src/poppler-fontinfo.cc +++ b/qt4/src/poppler-fontinfo.cc @@ -110,4 +110,40 @@ FontInfo& FontInfo::operator=( const FontInfo &fi ) return *this; } + +FontIterator::FontIterator( int startPage, DocumentData *dd ) + : d( new FontIteratorData( startPage, dd ) ) +{ +} + +FontIterator::~FontIterator() +{ + delete d; +} + +QList<FontInfo> FontIterator::next() +{ + ++d->currentPage; + + QList<FontInfo> fonts; + GooList *items = d->fontInfoScanner.scan( 1 ); + if ( !items ) + return fonts; + for ( int i = 0; i < items->getLength(); ++i ) { + fonts.append( FontInfo( FontInfoData( ( ::FontInfo* )items->get( i ) ) ) ); + } + deleteGooList( items, ::FontInfo ); + return fonts; +} + +bool FontIterator::hasNext() const +{ + return ( d->currentPage + 1 ) < d->totalPages; +} + +int FontIterator::currentPage() const +{ + return d->currentPage; +} + } diff --git a/qt4/src/poppler-private.h b/qt4/src/poppler-private.h index 941f3d6..fe2e541 100644 --- a/qt4/src/poppler-private.h +++ b/qt4/src/poppler-private.h @@ -90,7 +90,7 @@ namespace Poppler { void init(GooString *ownerPassword, GooString *userPassword) { - m_fontInfoScanner = 0; + m_fontInfoIterator = 0; m_backend = Document::SplashBackend; m_outputDev = 0; paperColor = Qt::white; @@ -114,7 +114,7 @@ namespace Poppler { delete (OptContentModel *)m_optContentModel; delete doc; delete m_outputDev; - delete m_fontInfoScanner; + delete m_fontInfoIterator; count --; if ( count == 0 ) delete globalParams; @@ -179,7 +179,7 @@ namespace Poppler { void fillMembers() { - m_fontInfoScanner = new FontInfoScanner(doc); + m_fontInfoIterator = new FontIterator(0, this); int numEmb = doc->getCatalog()->numEmbeddedFiles(); if (!(0 == numEmb)) { // we have some embedded documents, build the list @@ -195,7 +195,7 @@ namespace Poppler { PDFDoc *doc; QByteArray fileContents; bool locked; - FontInfoScanner *m_fontInfoScanner; + FontIterator *m_fontInfoIterator; Document::RenderBackend m_backend; OutputDev *m_outputDev; QList<EmbeddedFile*> m_embeddedFiles; @@ -243,6 +243,25 @@ namespace Poppler { Ref embRef; }; + class FontIteratorData + { + public: + FontIteratorData( int startPage, DocumentData *dd ) + : fontInfoScanner( dd->doc, startPage ) + , totalPages( dd->doc->getNumPages() ) + , currentPage( qMax( startPage, 0 ) - 1 ) + { + } + + ~FontIteratorData() + { + } + + FontInfoScanner fontInfoScanner; + int totalPages; + int currentPage; + }; + class TextBoxData { public: diff --git a/qt4/src/poppler-qt4.h b/qt4/src/poppler-qt4.h index b8bc152..c7b1ec4 100644 --- a/qt4/src/poppler-qt4.h +++ b/qt4/src/poppler-qt4.h @@ -218,6 +218,56 @@ namespace Poppler { }; + class FontIteratorData; + /** + Iterator for reading the fonts in a document. + + FontIterator provides a Java-style iterator for reading the fonts in a + document. + + You can use it in the following way: + \code +Poppler::FontIterator* it = doc->newFontIterator(); +while (it->hasNext()) { + QList<Poppler::FontInfo> fonts = it->next(); + // do something with the fonts +} + \endcode + */ + class POPPLER_QT4_EXPORT FontIterator { + friend class Document; + friend class DocumentData; + public: + /** + Destructor. + */ + ~FontIterator(); + + /** + Returns the fonts of the current page and then advances the iterator + to the next page. + */ + QList<FontInfo> next(); + + /** + Checks whether there is at least one more page to iterate, ie returns + false when the iterator is beyond the last page. + */ + bool hasNext() const; + + /** + Returns the current page where the iterator is. + */ + int currentPage() const; + + private: + Q_DISABLE_COPY( FontIterator ) + FontIterator( int, DocumentData *dd ); + + FontIteratorData *d; + }; + + class EmbeddedFileData; /** Container class for an embedded file with a PDF document @@ -852,6 +902,21 @@ QString subject = m_doc->info("Subject"); bool scanForFonts( int numPages, QList<FontInfo> *fontList ) const; /** + Creates a new FontIterator object for font scanning. + + The new iterator can be used for reading the font information of the + document, reading page by page. + + The caller is responsible for the returned object, ie it should freed + it when no more useful. + + \param startPage the initial page from which start reading fonts + + \since 0.12 + */ + FontIterator* newFontIterator( int startPage = 0 ) const; + + /** The font data if the font is an embedded one. \since 0.10 diff --git a/qt4/tests/check_fonts.cpp b/qt4/tests/check_fonts.cpp index df5b41a..fdf4be7 100644 --- a/qt4/tests/check_fonts.cpp +++ b/qt4/tests/check_fonts.cpp @@ -2,6 +2,8 @@ #include <poppler-qt4.h> +#include <memory> + class TestFontsData: public QObject { Q_OBJECT @@ -10,8 +12,44 @@ private slots: void checkType1(); void checkType3(); void checkTrueType(); + void checkFontIterator(); + void checkSecondDocumentQuery(); + void checkMultipleIterations(); + void checkScanForFonts(); }; + +QList<Poppler::FontInfo> loadFontsViaIterator( Poppler::Document *doc, int from = 0, int count = -1 ) +{ + int num = count == -1 ? doc->numPages() - from : count; + QList<Poppler::FontInfo> list; + std::auto_ptr< Poppler::FontIterator > it( doc->newFontIterator( from ) ); + while ( it->hasNext() && num ) + { + list += it->next(); + --num; + } + return list; +} + +bool operator==( const Poppler::FontInfo &f1, const Poppler::FontInfo &f2 ) +{ + if ( f1.name() != f2.name() ) + return false; + if ( f1.file() != f2.file() ) + return false; + if ( f1.isEmbedded() != f2.isEmbedded() ) + return false; + if ( f1.isSubset() != f2.isSubset() ) + return false; + if ( f1.type() != f2.type() ) + return false; + if ( f1.typeName() != f2.typeName() ) + return false; + return true; +} + + void TestFontsData::checkNoFonts() { Poppler::Document *doc; @@ -92,6 +130,117 @@ void TestFontsData::checkTrueType() delete doc; } +void TestFontsData::checkFontIterator() +{ + // loading a 1-page document + Poppler::Document *doc; + doc = Poppler::Document::load("../../../test/tests/type3.pdf"); + QVERIFY( doc ); + // loading a 6-pages document + Poppler::Document *doc6 = Poppler::Document::load("../../../test/tests/cropbox.pdf"); + QVERIFY( doc6 ); + + std::auto_ptr< Poppler::FontIterator > it; + + // some tests with the 1-page document: + // - check a default iterator + it.reset( doc->newFontIterator() ); + QVERIFY( it->hasNext() ); + // - check an iterator for negative pages to behave as 0 + it.reset( doc->newFontIterator( -1 ) ); + QVERIFY( it->hasNext() ); + // - check an iterator for pages out of the page limit + it.reset( doc->newFontIterator( 1 ) ); + QVERIFY( !it->hasNext() ); + // - check that it reaches the end after 1 iteration + it.reset( doc->newFontIterator() ); + QVERIFY( it->hasNext() ); + it->next(); + QVERIFY( !it->hasNext() ); + + // some tests with the 6-page document: + // - check a default iterator + it.reset( doc6->newFontIterator() ); + QVERIFY( it->hasNext() ); + // - check an iterator for pages out of the page limit + it.reset( doc6->newFontIterator( 6 ) ); + QVERIFY( !it->hasNext() ); + // - check that it reaches the end after 6 iterations + it.reset( doc6->newFontIterator() ); + QVERIFY( it->hasNext() ); + it->next(); + QVERIFY( it->hasNext() ); + it->next(); + QVERIFY( it->hasNext() ); + it->next(); + QVERIFY( it->hasNext() ); + it->next(); + QVERIFY( it->hasNext() ); + it->next(); + QVERIFY( it->hasNext() ); + it->next(); + QVERIFY( !it->hasNext() ); + + delete doc; + delete doc6; +} + +void TestFontsData::checkSecondDocumentQuery() +{ + Poppler::Document *doc; + doc = Poppler::Document::load("../../../test/tests/type3.pdf"); + QVERIFY( doc ); + + QList<Poppler::FontInfo> listOfFonts = doc->fonts(); + QCOMPARE( listOfFonts.size(), 2 ); + // check we get the very same result when calling fonts() again (#19405) + QList<Poppler::FontInfo> listOfFonts2 = doc->fonts(); + QCOMPARE( listOfFonts, listOfFonts2 ); + + delete doc; +} + +void TestFontsData::checkMultipleIterations() +{ + Poppler::Document *doc; + doc = Poppler::Document::load("../../../test/tests/type3.pdf"); + QVERIFY( doc ); + + QList<Poppler::FontInfo> listOfFonts = loadFontsViaIterator( doc ); + QCOMPARE( listOfFonts.size(), 2 ); + QList<Poppler::FontInfo> listOfFonts2 = loadFontsViaIterator( doc ); + QCOMPARE( listOfFonts, listOfFonts2 ); + + delete doc; +} + +void TestFontsData::checkScanForFonts() +{ + Poppler::Document *doc; + doc = Poppler::Document::load("../../../test/tests/fonts.pdf"); + QVERIFY( doc ); + + QList<Poppler::FontInfo> listOfFonts = doc->fonts(); + QCOMPARE( listOfFonts.size(), 3 ); + // check we get the very same result when gatering fonts using scanForFonts + QList<Poppler::FontInfo> listOfFonts2; + for ( int i = 0; i < doc->numPages(); ++i ) + { + doc->scanForFonts( 1, &listOfFonts2 ); + } + QCOMPARE( listOfFonts, listOfFonts2 ); + + // check doing a second scanForFonts gives no result + QList<Poppler::FontInfo> listOfFonts3; + for ( int i = 0; i < doc->numPages(); ++i ) + { + doc->scanForFonts( 1, &listOfFonts3 ); + } + QVERIFY( listOfFonts3.isEmpty() ); + + delete doc; +} + QTEST_MAIN(TestFontsData) #include "check_fonts.moc" commit b9804542bb50216786dc11ca16efd84304f4b832 Author: Pino Toscano <[email protected]> Date: Tue Jan 6 15:16:53 2009 +0100 Add the possibility to set the first page to scan. The default value is 0 (= first page), so it should be compatible with any usage so far. diff --git a/poppler/FontInfo.cc b/poppler/FontInfo.cc index 060e2c3..13231a5 100644 --- a/poppler/FontInfo.cc +++ b/poppler/FontInfo.cc @@ -35,9 +35,9 @@ #include "PDFDoc.h" #include "FontInfo.h" -FontInfoScanner::FontInfoScanner(PDFDoc *docA) { +FontInfoScanner::FontInfoScanner(PDFDoc *docA, int firstPage) { doc = docA; - currentPage = 1; + currentPage = firstPage + 1; fonts = NULL; fontsLen = fontsSize = 0; visitedXObjects = NULL; diff --git a/poppler/FontInfo.h b/poppler/FontInfo.h index 5072e36..61182ab 100644 --- a/poppler/FontInfo.h +++ b/poppler/FontInfo.h @@ -73,7 +73,7 @@ class FontInfoScanner { public: // Constructor. - FontInfoScanner(PDFDoc *doc); + FontInfoScanner(PDFDoc *doc, int firstPage = 0); // Destructor. ~FontInfoScanner(); _______________________________________________ poppler mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/poppler
