[poppler] 4 commits - poppler/FontInfo.cc poppler/FontInfo.h qt4/src qt4/tests

Pino Toscano pino at kemper.freedesktop.org
Tue Jan 6 06:47:06 PST 2009


 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 <pino at kde.org>
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 <pino at kde.org>
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 <pino at kde.org>
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 <pino at kde.org>
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();
 


More information about the poppler mailing list