Home | History | Annotate | Download | only in docs
      1 # Getting Started with PDFium
      2 
      3 [TOC]
      4 
      5 This guide walks through some examples of using the PDFium library. For an
      6 example of using PDFium see the [Chromium PDF Plugin][chrome-plugin].
      7 
      8 ## Prerequisites
      9 
     10 You will need the PDFium library on your computer. You can see the
     11 [README](/README.md) for instructions on getting and installing PDFium.
     12 
     13 *** note
     14 You must compile PDFium without both V8 and XFA support for the examples
     15 here to work. V8 can be compiled out by providing
     16 `GYP_DEFINES="pdf_enable_v8=0 pdf_enable_xfa=0" build/gyp_pdfium`.
     17 
     18 See the [V8 Getting Started][pdfium-v8] guide for how to
     19 initialize PDFium when V8 is compiled into the binary.
     20 ***
     21 
     22 ## PDFium Headers
     23 
     24 PDFium's API has been broken up over several headers. You only need to include
     25 the headers for functionality you use in your application. The full set of
     26 headers can be found in the [public/ folder of the repository][pdfium-public].
     27 
     28 In all cases you'll need to include `fpdfview.h` as it defines the needed
     29 methods for initialization and destruction of the library.
     30 
     31 ## Initializing PDFium
     32 
     33 The first step to using PDFium is to initialize the library. Having done so,
     34 you'll need to destroy the library when you're finished. When initializing the
     35 library you provide the `FPDF_LIBRARY_CONFIG` parameters to
     36 `FPDF_InitLibraryWithConfig`.
     37 
     38 ```c
     39 #include <fpdfview.h>
     40 
     41 int main() {
     42   FPDF_LIBRARY_CONFIG config;
     43   config.version = 2;
     44   config.m_pUserFontPaths = NULL;
     45   config.m_pIsolate = NULL;
     46   config.m_v8EmbedderSlot = 0;
     47 
     48   FPDF_InitLibraryWithConfig(&config);
     49 
     50   FPDF_DestroyLibrary();
     51   return 0;
     52 }
     53 ```
     54 
     55 Currently the `config.version` must be set to `2`. `m_pUserFontPaths` can be
     56 used to override the font paths searched by PDFium. If you wish to use your
     57 own font paths pass a `NULL` terminated list of `const char*` paths to use.
     58 
     59 `m_pIsolate` and `m_v8EmbedderSlot` are both used to configure the V8
     60 javascript engine. In the first case, you can provide an isolate through
     61 `m_pIsolate` for PDFium to use to store per-isolate data. Passing `NULL` will
     62 case PDFium to allocate a new isolate. `m_v8EmbedderSlot` is the embedder data
     63 slot to use in the v8::Isolate to store PDFium data. The value must be between
     64 0 and v8::Internals::kNumIsolateDataSlots. Typically, 0 is a good choice.
     65 
     66 For more information on using Javascript see the [V8 Getting Started][pdfium-v8]
     67 guide.
     68 
     69 *** aside
     70 PDFium is built as a set of static libraries. You'll need to specify them all on
     71 the link line in order to compile. My build line was:
     72 
     73 ```
     74 PDF_LIBS="-lpdfium -lfpdfapi -lfxge -lfpdfdoc -lfxcrt -lfx_agg \
     75 -lfxcodec -lfx_lpng -lfx_libopenjpeg -lfx_lcms2 -lfx_freetype -ljpeg \
     76 -lfx_zlib -lfdrm -lpdfwindow -lbigint -lformfiller -ljavascript \
     77 -lfxedit"
     78 PDF_DIR=<path/to/pdfium>
     79 
     80 clang -I $PDF_DIR/public -o init init.c -L $PDF_DIR/out/Debug -lstdc++ -framework AppKit $PDF_LIBS
     81 ```
     82 
     83 The `-framework AppKit` as needed as I'm building on a Mac. Internally PDFium
     84 uses C++, which is why `-lstdc++` is required on the link line.
     85 ***
     86 
     87 ## Loading a Document
     88 
     89 One of the main objects in PDFium is the `FPDF_DOCUMENT`. The object will allow
     90 access to information from PDFs. There are four ways to to create a
     91 `FPDF_DOCUMENT`. `FPDF_CreateNewDocument` will create an empty object which
     92 can be used to create PDFs. For more information see the
     93 [PDF Editing Guide][pdfium-edit-guide].
     94 
     95 Loading an existing document is done in one of three ways: loading from file,
     96 loading from memory, or loading via a custom loader. In all three cases you'll
     97 provide a `FPDF_BYTESTRING` which is the password needed to unlock the PDF, if
     98 encrypted. If the file is not encrypted the password can be `NULL`.
     99 
    100 The two simplest methods are loading from file and loading from memory. To load
    101 from file, you'll provide the name of the file to open, including extension. For
    102 loading from memory you'll provide a data buffer containing the PDF and its
    103 length.
    104 
    105 ```c
    106 FPDF_STRING test_doc = "test_doc.pdf";
    107 FPDF_DOCUMENT doc = FPDF_LoadDocument(test_doc, NULL);
    108 if (!doc) {
    109   return 1;
    110 }
    111 
    112 FPDF_CloseDocument(doc);
    113 
    114 ```
    115 
    116 In all three cases, `FPDF_LoadDocument`, `FPDF_LoadMemDocument`,
    117 `FPDF_LoadCustomDocument` a return of `NULL` indicates an error opening the
    118 document or that the file was not found.
    119 
    120 You can use `FPDF_GetLastError` to determine what went wrong.
    121 
    122 ```c
    123 #include <fpdfview.h>
    124 #include <unistd.h>
    125 #include <stdio.h>
    126 
    127 int main() {
    128   FPDF_LIBRARY_CONFIG config;
    129   config.version = 2;
    130   config.m_pUserFontPaths = NULL;
    131   config.m_pIsolate = NULL;
    132   config.m_v8EmbedderSlot = 0;
    133 
    134   FPDF_InitLibraryWithConfig(&config);
    135 
    136   FPDF_DOCUMENT doc = FPDF_LoadDocument(test_doc, NULL);
    137   if (!doc) {
    138     unsigned long err = FPDF_GetLastError();
    139     fprintf(stderr, "Load pdf docs unsuccessful: ");
    140     switch (err) {
    141       case FPDF_ERR_SUCCESS:
    142         fprintf(stderr, "Success");
    143         break;
    144       case FPDF_ERR_UNKNOWN:
    145         fprintf(stderr, "Unknown error");
    146         break;
    147       case FPDF_ERR_FILE:
    148         fprintf(stderr, "File not found or could not be opened");
    149         break;
    150       case FPDF_ERR_FORMAT:
    151         fprintf(stderr, "File not in PDF format or corrupted");
    152         break;
    153       case FPDF_ERR_PASSWORD:
    154         fprintf(stderr, "Password required or incorrect password");
    155         break;
    156       case FPDF_ERR_SECURITY:
    157         fprintf(stderr, "Unsupported security scheme");
    158         break;
    159       case FPDF_ERR_PAGE:
    160         fprintf(stderr, "Page not found or content error");
    161         break;
    162       default:
    163         fprintf(stderr, "Unknown error %ld", err);
    164     }
    165     fprintf(stderr, ".\n");
    166     goto EXIT;
    167   }
    168 
    169   FPDF_CloseDocument(doc);
    170 EXIT:
    171   FPDF_DestroyLibrary();
    172   return 0;
    173 ```
    174 
    175 While the above are simple, the preferable technique is to use a custom loader.
    176 This makes it possible to load pieces of the document only as needed. This is
    177 useful for loading documents over the network.
    178 
    179 
    180 
    181 
    182 [chrome-plugin]: https://chromium.googlesource.com/chromium/src/+/master/pdf/
    183 [pdfium-public]: https://pdfium.googlesource.com/pdfium/+/master/public/
    184 [pdfium-v8]: /docs/v8-getting-started.md
    185 [pdfium-edit-guide]: /docs/pdfium-edit-guide.md
    186