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