Show
Ignore:
Timestamp:
04/17/06 07:28:50 (3 years ago)
Author:
jordi
Message:

Since version 0.5.0 and up doesn't support the old Xpdf header files and because the CairoOutputDev?.h file is not installed on version 0.5.1, I now use Poppler's glib wrapper for PDF loading.

The glib wrapper needs an URI instead of a filename (why?), so the path to the file must be specified as an absolute path to be able to convert it to an URI (file:///dir1/dir2/file.pdf). This also means that the tests files had to be changed to use absolute paths. I added a function (that I'll change to a common utils source) that transform the filename to an absolute path.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/PDFDocument.cxx

    r73 r78  
    1717 
    1818#include <config.h> 
    19  
    20 // Poppler headers. 
    21 #include <goo/GooList.h> 
    22 #include <PDFDoc.h> 
    23 #include <CairoOutputDev.h> 
    24 #include <ErrorCodes.h> 
    25 #include <GlobalParams.h> 
    26 #include <PDFDocEncoding.h> 
    27 #include <Outline.h> 
    28 #include <Link.h> 
    29  
     19#include <time.h> 
     20#include <glib/poppler.h> 
    3021#include "epdfview.h" 
    3122 
     
    3324 
    3425// Constants. 
    35 static const gint CAIRO_BYTES_PER_PIXEL = 4; 
     26static const gint PIXBUF_BITS_PER_SAMPLE = 8; 
     27static const gint DATE_LENGTH = 100; 
    3628 
    3729// Forward declarations. 
    38 static gchar *getDictionaryString (Object &object, const gchar *key); 
    39 static gchar *getDictionaryDate (Object &object, const gchar *key); 
    40 static gboolean hasUnicodeMarker (GooString *string); 
    41 static PageLayout convertPageLayout (Catalog::PageLayout pageLayout); 
    42 static PageMode convertPageMode (Catalog::PageMode pageMode); 
     30static PageLayout convertPageLayout (gint pageLayout); 
     31static PageMode convertPageMode (gint pageMode); 
    4332 
    4433/// 
     
    4938{ 
    5039    m_Document = NULL; 
    51     m_OutputDevice = NULL; 
    5240} 
    5341 
     
    5745PDFDocument::~PDFDocument () 
    5846{ 
    59     delete m_Document; 
    60     delete m_OutputDevice; 
     47    if ( NULL != m_Document ) 
     48    { 
     49        g_object_unref (G_OBJECT (m_Document)); 
     50    } 
    6151} 
    6252 
     
    6959PDFDocument::isLoaded () 
    7060{ 
    71     return (NULL != m_Document && m_Document->isOk ()); 
     61    return (NULL != m_Document); 
    7262} 
    7363 
     
    7767/// Tries to open the PDF file @a filename using the password in @a password. 
    7868/// 
    79 /// @param filename The name of the file name to open. 
     69/// @param filename The name of the file name to open. It must be an absolute 
     70///                 path. 
    8071/// @param password The password to use to open @a filename. 
    8172/// @param error Location to store the error occurring or NULL to ignore  
     
    9081    g_assert (NULL != filename && "Tried to load a NULL file name"); 
    9182 
    92     // The Poppler library has a GLOBAL file for parameters. 
    93     // If this file isn't loaded then weird error happens. 
    94     if ( NULL == globalParams ) 
    95     { 
    96         globalParams = new GlobalParams ("/etc/xpdfrc"); 
    97     } 
    98  
    99     GooString *filename_g = new GooString (filename); 
    100     GooString *password_g = NULL; 
    101     if (NULL != password ) 
    102     { 
    103         password_g = new GooString (password); 
     83    gchar *filename_uri = g_filename_to_uri (filename, NULL, error); 
     84    if ( NULL == filename_uri ) 
     85    { 
     86        return FALSE; 
    10487    } 
    10588    // Try to open the PDF document. 
    106     PDFDoc *newDocument = new PDFDoc (filename_g, password_g, password_g); 
    107     delete password_g; 
    108     // The filename_g can't be deleted as PDFDoc saves the reference. 
    109     // deleting it will cause trouble when deleting the newDocument. 
    110  
     89    GError *loadError = NULL; 
     90    PopplerDocument *newDocument =  
     91        poppler_document_new_from_file (filename_uri, password, &loadError); 
     92    g_free (filename_uri); 
    11193    // Check if the document couldn't be opened successfully and why. 
    112     if ( !newDocument->isOk() ) 
    113     { 
    114         DocumentError errorCode = (DocumentError)newDocument->getErrorCode (); 
    115         delete newDocument; 
     94    if ( NULL == newDocument ) 
     95    { 
     96        // Popller's glib wrapper passes the Poppler error code unless the 
     97        // error is that the file is encrypted. We want to set our own 
     98        // error code in this case. 
     99        DocumentError errorCode = DocumentErrorNone; 
     100        if ( POPPLER_ERROR == loadError->domain ) 
     101        { 
     102            errorCode = DocumentErrorEncrypted;  
     103        } 
     104        else 
     105        { 
     106            // OK, the glib's wrapper don't pass the error code directly 
     107            // from Poppler. Instead returns G_FILE_ERROR_FAILED and a  
     108            // non translated string. 
     109            // Maybe I'm wrong (very probable) but that's a wrong way. 
     110            // So I'm reading the error code from the error string... 
     111            sscanf (loadError->message, "Failed to load document (error %d)",  
     112                    (gint *)&errorCode); 
     113        } 
     114        g_error_free (loadError); 
     115        // Get our error message. 
    116116        gchar *errorMessage = IDocument::getErrorMessage (errorCode); 
    117117        g_set_error (error,  
     
    124124    } 
    125125    
    126     setFileName (filename); 
     126    // Set the used filename and password to let the user reload the 
     127    // document. 
     128    setFileName (filename);     
    127129    setPassword (password); 
    128     delete m_Document; 
     130    if ( NULL != m_Document ) 
     131    { 
     132        g_object_unref (G_OBJECT (m_Document)); 
     133        m_Document = NULL; 
     134    } 
    129135    m_Document = newDocument; 
    130136    // Load the document's information and outline. 
    131137    loadMetadata (); 
    132     Outline *outline = m_Document->getOutline (); 
     138    PopplerIndexIter *outline = poppler_index_iter_new (m_Document); 
    133139    m_Outline = new DocumentOutline (); 
    134     setOutline (m_Outline, outline->getItems ()); 
     140    setOutline (m_Outline, outline); 
    135141    // Set the current rotation angle and zoom level. 
    136142    setRotation (0); 
    137143    setZoom (1.0f); 
    138     // Set the output device. 
    139     delete m_OutputDevice; 
    140     m_OutputDevice = new CairoOutputDev (); 
    141     m_OutputDevice->startDoc (m_Document->getXRef ()); 
    142144 
    143145    return TRUE; 
     
    158160    g_assert (NULL != m_Document && "The document has not been loaded."); 
    159161 
    160     // Retrieve the document's meta data dictionary. 
    161     Object dictionary; 
    162     m_Document->getDocInfo (&dictionary); 
    163  
    164     gchar *value = NULL; 
    165     // Author 
    166     value = getDictionaryString (dictionary, "Author"); 
    167     setAuthor (value); 
    168     g_free (value); 
    169     // Creation date. 
    170     value = getDictionaryDate (dictionary, "CreationDate"); 
    171     setCreationDate (value); 
    172     g_free (value); 
    173     // Creator 
    174     value = getDictionaryString (dictionary, "Creator"); 
    175     setCreator (value); 
    176     g_free (value); 
    177     // PDF Format 
    178     value = g_strdup_printf ("PDF-%.2g", m_Document->getPDFVersion ()); 
    179     setFormat (value); 
    180     g_free (value); 
    181     // Keywords 
    182     value = getDictionaryString (dictionary, "Keywords"); 
    183     setKeywords (value); 
    184     g_free (value); 
    185     // Is linearised 
    186     setLinearized (m_Document->isLinearized ()); 
    187     // Modified date 
    188     value = getDictionaryDate (dictionary, "ModDate"); 
    189     setModifiedDate (value); 
    190     g_free (value); 
    191     // Producer 
    192     value = getDictionaryString (dictionary, "Producer"); 
    193     setProducer (value); 
    194     g_free (value); 
    195     // Subject 
    196     value = getDictionaryString (dictionary, "Subject"); 
    197     setSubject (value); 
    198     g_free (value); 
    199     // Title 
    200     value = getDictionaryString (dictionary, "Title"); 
    201     setTitle (value); 
    202     g_free (value); 
    203  
    204     // For the page mode and layout we need the catalog, not the 
    205     // dictionary. 
    206     Catalog *catalog = m_Document->getCatalog (); 
    207     setPageLayout (convertPageLayout (catalog->getPageLayout ())); 
    208     setPageMode (convertPageMode (catalog->getPageMode ())); 
     162 
     163    gchar *author = NULL; 
     164    GTime creationDate; 
     165    gchar *creator = NULL; 
     166    gchar *format = NULL; 
     167    gchar *keywords = NULL; 
     168    PopplerPageLayout layout = POPPLER_PAGE_LAYOUT_UNSET; 
     169    gchar *linearized = NULL; 
     170    GTime modDate; 
     171    PopplerPageMode mode = POPPLER_PAGE_MODE_UNSET; 
     172    gchar *producer = NULL; 
     173    gchar *subject = NULL; 
     174    gchar *title = NULL; 
     175    
     176    g_object_get (m_Document, 
     177            "author", &author, 
     178            "creation-date", &creationDate, 
     179            "creator", &creator, 
     180            "format", &format, 
     181            "keywords", &keywords, 
     182            "page-layout", &layout, 
     183            "linearized", &linearized, 
     184            "mod-date", &modDate, 
     185            "page-mode", &mode, 
     186            "producer", &producer, 
     187            "subject", &subject, 
     188            "title", &title, 
     189            NULL); 
     190    setAuthor (author); 
     191    if ( 0 < creationDate ) 
     192    { 
     193        struct tm *tmpTime = localtime ((const time_t *)&creationDate); 
     194        gchar *date = g_strnfill (DATE_LENGTH + 1, 0); 
     195        strftime (date, DATE_LENGTH, "%Y-%m-%d %H:%M:%S", tmpTime); 
     196        setCreationDate (date); 
     197    } 
     198    else 
     199    { 
     200        setCreationDate (NULL); 
     201    } 
     202    setCreator (creator); 
     203    setFormat (format); 
     204    setKeywords (keywords); 
     205    setLinearized (linearized); 
     206    if ( 0 < modDate ) 
     207    { 
     208        struct tm *tmpTime = localtime ((const time_t *)&modDate); 
     209        gchar *date = g_strnfill (DATE_LENGTH + 1, 0); 
     210        strftime (date, DATE_LENGTH, "%Y-%m-%d %H:%M:%S", tmpTime); 
     211        setModifiedDate (date); 
     212    } 
     213    else 
     214    { 
     215        setModifiedDate (NULL); 
     216    } 
     217    setProducer (producer); 
     218    setSubject (subject); 
     219    setTitle (title); 
     220 
     221    // For the page mode and layout we need the enumerator value 
     222    GEnumValue *pageLayout = g_enum_get_value ( 
     223            (GEnumClass *)g_type_class_peek (POPPLER_TYPE_PAGE_LAYOUT), layout); 
     224    setPageLayout (convertPageLayout (pageLayout->value)); 
     225    GEnumValue *pageMode = g_enum_get_value ( 
     226            (GEnumClass *)g_type_class_peek (POPPLER_TYPE_PAGE_MODE), mode); 
     227    setPageMode (convertPageMode (pageMode->value)); 
    209228 
    210229    // Get the number of pages and set the current to the first. 
    211     setNumPages (m_Document->getNumPages ()); 
     230    setNumPages (poppler_document_get_n_pages (m_Document)); 
    212231    goToFirstPage (); 
    213232} 
     
    222241///                call must be set to the root DocumentOutline. 
    223242/// @param childrenList The list of children for to set to @a outline. 
    224 ///                     The first line must be a call to the getItems() 
    225 ///                     function from the PDF's outline. 
     243///                     The first line must be the returned valued of 
     244///                     poppler_index_iter_new(). 
    226245/// 
    227246void 
    228 PDFDocument::setOutline (DocumentOutline *outline, GooList *childrenList) 
     247PDFDocument::setOutline (DocumentOutline *outline,  
     248                         PopplerIndexIter *childrenList) 
    229249{ 
    230250    if ( NULL != childrenList ) 
    231251    { 
    232         int numChildren = childrenList->getLength (); 
    233         for ( int childIndex = 0 ; childIndex < numChildren ; childIndex++ ) 
     252        do 
    234253        { 
    235             OutlineItem *item = (OutlineItem *)childrenList->get (childIndex); 
    236             // Get the title, create the new child outline and set the 
    237             // title to it. 
    238             gchar *title = g_ucs4_to_utf8 (item->getTitle (), 
    239                                            item->getTitleLength (),  
    240                                            NULL, NULL, NULL); 
    241             DocumentOutline *child = new DocumentOutline (); 
    242             child->setParent (outline); 
    243             child->setTitle (title); 
    244             g_free (title); 
    245             /// Get the page destination. 
    246             gint destination = 1; 
    247             LinkAction *action = item->getAction (); 
    248             if ( NULL != action && actionGoTo == action->getKind () && 
    249                  action->isOk () ) 
     254            PopplerAction *action =  
     255                poppler_index_iter_get_action (childrenList); 
     256            if ( POPPLER_ACTION_GOTO_DEST == action->type ) 
    250257            { 
    251                 LinkDest *linkDestination = NULL; 
    252                 GooString *namedDest = ((LinkGoTo *)action)->getNamedDest (); 
    253                 // getNamedDest() or getDest() will return NULL, just need to 
    254                 // find which one. 
    255                 if ( NULL != namedDest ) 
    256                 { 
    257                     linkDestination = m_Document->findDest (namedDest); 
    258                 } 
    259                 else 
    260                 { 
    261                     linkDestination = ((LinkGoTo *)action)->getDest (); 
    262                 } 
    263                 if ( NULL != linkDestination && linkDestination->isOk () ) 
    264                 { 
    265                     if ( linkDestination->isPageRef () ) 
    266                     { 
    267                         Ref pageReference = linkDestination->getPageRef (); 
    268                         destination = m_Document->findPage (pageReference.num, 
    269                                                             pageReference.gen); 
    270                     } 
    271                     else 
    272                     { 
    273                         destination = linkDestination->getPageNum (); 
    274                     } 
    275                 } // if ( linkDestination->isOk () ) 
    276             } // if ( NULL != action ... ) 
    277             child->setDestination (destination); 
    278             outline->addChild (child); 
    279             // Add the child's children, if any. 
    280             if ( item->hasKids () ) 
    281             { 
    282                 // I need to open the outline because if it's not 
    283                 // open then the getKids() function would return NULL. 
    284                 item->open (); 
    285                 setOutline (child, item->getKids ()); 
     258                PopplerActionGotoDest *actionGoTo =  
     259                    (PopplerActionGotoDest *)action; 
     260                DocumentOutline *child = new DocumentOutline (); 
     261                child->setParent (outline); 
     262                child->setTitle (actionGoTo->title); 
     263                PopplerDest *destination = actionGoTo->dest; 
     264                child->setDestination (destination->page_num); 
     265                outline->addChild (child); 
     266                PopplerIndexIter *childIter =  
     267                    poppler_index_iter_get_child (childrenList); 
     268                setOutline (child, childIter); 
    286269            } 
    287         } // for ( int childIndex = 0 ; ... )        
    288     } // if ( NULL != childrenList ) 
    289 } 
    290  
    291 /// 
    292 /// @brief Gets the string value from a document's dictionary. 
    293 /// 
    294 /// Retrieves the string value of @a key inside the dictionary @a directory. The 
    295 /// dictionary must be an Object retrieved by calling Poppler's getDocInfo() 
    296 /// function. 
    297 /// 
    298 /// @param object The object retrieved by calling Poppler's getDocInfo(). 
    299 /// @param key The key's name to retrieve it's value. 
    300 /// 
    301 /// @return The string value of @a key or an empty string if it couldn't  
    302 ///         be retrieved. 
    303 ///         The returned string must be freed by calling g_free(). 
    304 /// 
    305 gchar * 
    306 getDictionaryString (Object &object, const gchar *key) 
    307 { 
    308     gchar *result = NULL; 
    309     if (object.isDict ()) 
    310     { 
    311         Dict *dictionary = object.getDict (); 
    312         Object value; 
    313         if ( !dictionary->lookup ((gchar *)key, &value)->isString () ) 
    314         { 
    315             value.free ();             
    316             result = g_strdup (""); 
    317         } 
    318         else 
    319         { 
    320             GooString *value_g = value.getString (); 
    321             if ( hasUnicodeMarker (value_g) ) 
    322             { 
    323                 // Convert the string skipping the Unicode marker, 
    324                 // which is 2 bytes long (UTF-16BE). 
    325                 result = g_convert (value_g->getCString () + 2, 
    326                                     value_g->getLength () - 2, 
    327                                     "UTF-8", "UTF-16BE", NULL, NULL, NULL); 
    328             } 
    329             else 
    330             { 
    331                 // Otherwise we need to get each character in the document's 
    332                 // encoding, transform it to UCS4 and finally transform to 
    333                 // UTF-8. 
    334                 int stringLength = value_g->getLength (); 
    335                 gunichar *ucs4_tmp = g_new (gunichar, stringLength + 1); 
    336                 for ( int pos = 0 ; pos < stringLength ; pos++) 
    337                 { 
    338                     ucs4_tmp[pos] =  
    339                         pdfDocEncoding[(unsigned char)value_g->getChar(pos)]; 
    340                 } 
    341                 ucs4_tmp[stringLength] = 0; 
    342                 result = g_ucs4_to_utf8 (ucs4_tmp, -1, NULL, NULL, NULL); 
    343             } 
    344             value.free (); 
    345         } 
    346     } 
    347     else 
    348     { 
    349         result = g_strdup (""); 
    350     } 
    351  
    352     g_assert (NULL != result && "The result is NULL!");     
    353     return result; 
    354 } 
    355  
    356 /// 
    357 /// @brief Gets the date value from a document's dictionary. 
    358 /// 
    359 /// Retrieves the string value of @a key inside the dictionary @a directory. The 
    360 /// dictionary must be an Object retrieved by calling Poppler's getDocInfo() 
    361 /// function. 
    362 /// 
    363 /// @param object The object retrieved by calling Poppler's getDocInfo(). 
    364 /// @param key The key's name to retrieve it's value. 
    365 /// 
    366 /// @return The string value of @a key or an empty string if it couldn't  
    367 ///         be retrieved. 
    368 ///         The returned string must be freed by calling g_free(). 
    369 /// 
    370 gchar * 
    371 getDictionaryDate (Object &object, const gchar *key) 
    372 { 
    373     gchar *result = NULL; 
    374     if ( object.isDict () ) 
    375     { 
    376         Dict *dictionary = object.getDict (); 
    377         Object value; 
    378         if ( !dictionary->lookup ((gchar *)key, &value)->isString () ) 
    379         { 
    380             value.free (); 
    381             result = g_strdup (""); 
    382         } 
    383         else 
    384         { 
    385             GooString *value_g = value.getString (); 
    386             gchar *dateString = NULL; 
    387             if ( hasUnicodeMarker (value_g) ) 
    388             { 
    389                 // Copy the string skipping the two-bytes long 
    390                 // Unicode marker. 
    391                 dateString = g_convert (value_g->getCString () + 2, 
    392                                         value_g->getLength () - 2, 
    393                                         "UTF-8", "UTF-16BE", NULL, NULL, NULL); 
    394             } 
    395             else 
    396             { 
    397                 dateString = g_strndup (value_g->getCString (), 
    398                                         value_g->getLength ()); 
    399             } 
    400             value.free (); 
    401  
    402             // Set PDF Reference 1.3, Section 3.8.2 for PDF Date representation. 
    403             gchar *oldDate = dateString; 
    404             if ( 'D' == dateString[0] && ':' == dateString[1] ) 
    405             { 
    406                 dateString += 2; 
    407             } 
    408             int year; 
    409             int month; 
    410             int day; 
    411             int hour; 
    412             int minute;  
    413             int second; 
    414  
    415             int scannedItems = sscanf (dateString, "%4d%2d%2d%2d%2d%2d", 
    416                     &year, &month, &day, &hour, &minute, &second); 
    417             g_free (oldDate); 
    418             if ( 6 != scannedItems ) 
    419             { 
    420                 result = g_strdup (""); 
    421             } 
    422             else 
    423             { 
    424                 result = g_strdup_printf ("%04d-%02d-%02d %02d:%02d:%02d",  
    425                                           year, month, day, hour, minute, 
    426                                           second); 
    427             } 
    428         }       
    429     } 
    430     else 
    431     { 
    432         result = g_strdup (""); 
    433     } 
    434     g_assert ( result != NULL && "The result is NULL."); 
    435     return result; 
    436 } 
    437  
    438 /// 
    439 /// @brief Checks if a GooString has the Unicode marker. 
    440 /// 
    441 /// I really don't know, but it seems that some PDF files has UTF-16BE 
    442 /// strings. This function just tests if the string has this BOM (Binary 
    443 /// Order Marker), which is 0xfeff for Big Endian and 0xfffe for Little Endian. 
    444 /// 
    445 /// @param string The string to check if has the Unicode marker. 
    446 /// 
    447 /// @return TRUE if the GooString has the Unicode marker, FALSE otherwise. 
    448 /// 
    449 gboolean 
    450 hasUnicodeMarker (GooString *string) 
    451 { 
    452     return ((string->getChar (0) & 0xff) == 0xfe && 
    453             (string->getChar (1) & 0xff) == 0xff ); 
    454 } 
    455  
    456 /// 
    457 /// @brief Gets the document's page layout from Poppler's catalog. 
    458 /// 
    459 /// @param pageLayout Is the page layout that Poppler's catalog gives. 
     270        }  
     271        while ( poppler_index_iter_next (childrenList) ); 
     272 
     273        poppler_index_iter_free (childrenList); 
     274    } 
     275} 
     276 
     277/// 
     278/// @brief Gets the document's page layout from Poppler's page layout. 
     279/// 
     280/// @param pageLayout Is the page layout that Poppler's glib wrapper gives. 
    460281/// 
    461282/// @return The PageLayout based on @a pageLayout. 
    462283/// 
    463284PageLayout 
    464 convertPageLayout (Catalog::PageLayout pageLayout) 
     285convertPageLayout (gint pageLayout) 
    465286{ 
    466287    PageLayout layout = PageLayoutUnset; 
    467288    switch (pageLayout) 
    468289    { 
    469         case Catalog::pageLayoutSinglePage: 
     290        case POPPLER_PAGE_LAYOUT_SINGLE_PAGE: 
    470291            layout = PageLayoutSinglePage; 
    471292            break; 
    472         case Catalog::pageLayoutOneColumn: 
     293        case POPPLER_PAGE_LAYOUT_ONE_COLUMN: 
    473294            layout = PageLayoutOneColumn; 
    474295            break; 
    475         case Catalog::pageLayoutTwoColumnLeft: 
     296        case POPPLER_PAGE_LAYOUT_TWO_COLUMN_LEFT: 
    476297            layout = PageLayoutTwoColumnLeft; 
    477298            break; 
    478         case Catalog::pageLayoutTwoColumnRight: 
     299        case POPPLER_PAGE_LAYOUT_TWO_COLUMN_RIGHT: 
    479300            layout = PageLayoutTwoColumnRight; 
    480301            break; 
    481         case Catalog::pageLayoutTwoPageLeft: 
     302        case POPPLER_PAGE_LAYOUT_TWO_PAGE_LEFT: 
    482303            layout = PageLayoutTwoPageLeft; 
    483304            break; 
    484         case Catalog::pageLayoutTwoPageRight: 
     305        case POPPLER_PAGE_LAYOUT_TWO_PAGE_RIGHT: 
    485306            layout = PageLayoutTwoPageRight; 
    486307            break; 
    487         case Catalog::pageLayoutNone: 
     308        case POPPLER_PAGE_LAYOUT_UNSET: 
    488309        default: 
    489310            layout = PageLayoutUnset; 
     
    501322/// 
    502323PageMode 
    503 convertPageMode (Catalog::PageMode pageMode) 
     324convertPageMode (gint pageMode) 
    504325{ 
    505326    PageMode mode = PageModeUnset; 
    506327    switch (pageMode) 
    507328    { 
    508         case Catalog::pageModeOutlines: 
     329        case POPPLER_PAGE_MODE_USE_OUTLINES: 
    509330            mode = PageModeOutlines; 
    510331            break; 
    511         case Catalog::pageModeThumbs: 
     332        case POPPLER_PAGE_MODE_USE_THUMBS: 
    512333            mode = PageModeThumbs; 
    513334            break; 
    514         case Catalog::pageModeFullScreen: 
     335        case POPPLER_PAGE_MODE_FULL_SCREEN: 
    515336            mode = PageModeFullScreen; 
    516337            break; 
    517         case Catalog::pageModeOC: 
     338        case POPPLER_PAGE_MODE_USE_OC: 
    518339            mode = PageModeOC; 
    519340            break; 
    520         case Catalog::pageModeAttach: 
     341        case POPPLER_PAGE_MODE_USE_ATTACHMENTS: 
    521342            mode = PageModeAttach; 
    522343            break; 
    523         case Catalog::pageModeNone: 
     344        case POPPLER_PAGE_MODE_NONE: 
     345        case POPPLER_PAGE_MODE_UNSET: 
    524346        default: 
    525347            mode = PageModeUnset; 
     
    545367    g_assert (NULL != height && "Tried to save the page's height to NULL."); 
    546368 
    547     Catalog *catalog = m_Document->getCatalog (); 
    548     Page *page = catalog->getPage (getCurrentPageNum ()); 
     369    PopplerPage *page = poppler_document_get_page (m_Document, 
     370                                                   getCurrentPageNum () - 1); 
    549371 
    550372    gdouble pageWidth; 
     
    552374    // Check which rotation has the document's page to know what is width 
    553375    // and what is height. 
    554     gint rotate = page->getRotate () + getRotation (); 
     376    gint rotate = getRotation (); 
    555377    if ( 90 == rotate || 270 == rotate ) 
    556378    { 
    557         pageWidth = page->getCropHeight (); 
    558         pageHeight = page->getCropWidth (); 
     379        poppler_page_get_size (page, &pageHeight, &pageWidth); 
    559380    } 
    560381    else  
    561382    { 
    562         pageWidth = page->getCropWidth (); 
    563         pageHeight = page->getCropHeight (); 
     383        poppler_page_get_size (page, &pageWidth, &pageHeight); 
    564384    } 
    565385 
     
    589409    renderedPage->newPage (width, height); 
    590410 
    591     // Now get the page to render and prepare the output device. 
    592     Catalog *catalog = m_Document->getCatalog (); 
    593     Page *page = catalog->getPage (getCurrentPageNum ()); 
    594      
    595     // Prepare the output device. 
    596     gint cairoRowStride = width * CAIRO_BYTES_PER_PIXEL; 
    597     gint cairoSize = cairoRowStride * height; 
    598     guchar *cairoData = new guchar[cairoSize]; 
    599     memset (cairoData, 0xff, cairoSize); 
    600     cairo_surface_t *cairoSurface =  
    601         cairo_image_surface_create_for_data (cairoData, CAIRO_FORMAT_RGB24, 
    602                                               width, height, cairoRowStride); 
    603     m_OutputDevice->setSurface (cairoSurface); 
    604