1# Getting Started with PDFium
2
3[TOC]
4
5This guide walks through some examples of using the PDFium library. For an
6example of using PDFium see the [Chromium PDF Plugin][chrome-plugin].
7
8## Prerequisites
9
10You 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
14You must compile PDFium without both V8 and XFA support for the examples
15here to work. V8 can be compiled out by providing
16`GYP_DEFINES="pdf_enable_v8=0 pdf_enable_xfa=0" build/gyp_pdfium`.
17
18See the [V8 Getting Started][pdfium-v8] guide for how to
19initialize PDFium when V8 is compiled into the binary.
20***
21
22## PDFium Headers
23
24PDFium's API has been broken up over several headers. You only need to include
25the headers for functionality you use in your application. The full set of
26headers can be found in the [public/ folder of the repository][pdfium-public].
27
28In all cases you'll need to include `fpdfview.h` as it defines the needed
29methods for initialization and destruction of the library.
30
31## Initializing PDFium
32
33The first step to using PDFium is to initialize the library. Having done so,
34you'll need to destroy the library when you're finished. When initializing the
35library you provide the `FPDF_LIBRARY_CONFIG` parameters to
36`FPDF_InitLibraryWithConfig`.
37
38```c
39#include <fpdfview.h>
40
41int 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
55Currently the `config.version` must be set to `2`. `m_pUserFontPaths` can be
56used to override the font paths searched by PDFium. If you wish to use your
57own 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
60javascript 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
62case PDFium to allocate a new isolate. `m_v8EmbedderSlot` is the embedder data
63slot to use in the v8::Isolate to store PDFium data. The value must be between
640 and v8::Internals::kNumIsolateDataSlots. Typically, 0 is a good choice.
65
66For more information on using Javascript see the [V8 Getting Started][pdfium-v8]
67guide.
68
69*** aside
70PDFium is built as a set of static libraries. You'll need to specify them all on
71the link line in order to compile. My build line was:
72
73```
74PDF_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"
78PDF_DIR=<path/to/pdfium>
79
80clang -I $PDF_DIR/public -o init init.c -L $PDF_DIR/out/Debug -lstdc++ -framework AppKit $PDF_LIBS
81```
82
83The `-framework AppKit` as needed as I'm building on a Mac. Internally PDFium
84uses C++, which is why `-lstdc++` is required on the link line.
85***
86
87## Loading a Document
88
89One of the main objects in PDFium is the `FPDF_DOCUMENT`. The object will allow
90access to information from PDFs. There are four ways to to create a
91`FPDF_DOCUMENT`. `FPDF_CreateNewDocument` will create an empty object which
92can be used to create PDFs. For more information see the
93[PDF Editing Guide][pdfium-edit-guide].
94
95Loading an existing document is done in one of three ways: loading from file,
96loading from memory, or loading via a custom loader. In all three cases you'll
97provide a `FPDF_BYTESTRING` which is the password needed to unlock the PDF, if
98encrypted. If the file is not encrypted the password can be `NULL`.
99
100The two simplest methods are loading from file and loading from memory. To load
101from file, you'll provide the name of the file to open, including extension. For
102loading from memory you'll provide a data buffer containing the PDF and its
103length.
104
105```c
106FPDF_STRING test_doc = "test_doc.pdf";
107FPDF_DOCUMENT doc = FPDF_LoadDocument(test_doc, NULL);
108if (!doc) {
109  return 1;
110}
111
112FPDF_CloseDocument(doc);
113
114```
115
116In all three cases, `FPDF_LoadDocument`, `FPDF_LoadMemDocument`,
117`FPDF_LoadCustomDocument` a return of `NULL` indicates an error opening the
118document or that the file was not found.
119
120You 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
127int 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);
170EXIT:
171  FPDF_DestroyLibrary();
172  return 0;
173```
174
175While the above are simple, the preferable technique is to use a custom loader.
176This makes it possible to load pieces of the document only as needed. This is
177useful 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