A week before release, legal asks which license covers the pdfium.dll in your installer and whether it forces you to publish source. It does not. PDFium uses a permissive BSD-style license that allows closed-source commercial redistribution if its notices ship with your app; PDFium Component, the Delphi wrapper, carries a separate losLab commercial license
What remains is bookkeeping. The engine DLL is a bundle of open-source libraries compiled together, the optional V8 build adds more of them, and the commercial license for the Delphi code sits on another layer entirely. This article is not legal advice; it lays out what the shipped files say, what we found inside the bundled binaries, and a packaging routine you can hand to an auditor
What does the PDFium license actually require?
For a binary-only Delphi product, the PDFium BSD license asks for three things. Your documentation or other materials shipped with the program must reproduce the PDFium copyright notice, the list of conditions and the warranty disclaimer. Source redistributions must keep the same notice in the source files, which only matters if you ship PDFium source. And neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote your product without specific prior written permission. Notice what is absent: no obligation to release your own source, no copyleft reaching into the executable that loads the DLL, no runtime fee, no registration
The file that ships with PDFium Component as DLLs\PDFium-LICENSE deserves a full read, because the top of it is misleading if you stop early. The first block is the BSD text under the line Copyright 2014 The PDFium Authors. Scroll past the disclaimer and the file also carries the full Apache License 2.0 text. Apache 2.0 is permissive too and allows closed-source sale, but its redistribution section adds conditions of its own: recipients get a copy of the license, attribution notices from any NOTICE file are carried forward, and modified files are marked as changed. Section 6 withholds trademark rights, which lines up with the BSD endorsement clause. Ship both halves together. A one-line credit that paraphrases the BSD part and drops the Apache text leaves half the file behind
What else is compiled into pdfium.dll?
A pdfium.dll is PDFium plus everything PDFium links statically, and each of those libraries has its own license text. The DLLs bundled with PDFium Component come from the pdfium-binaries project, which DLLs\Readme.txt names as the build source; the version resource on the Win64 DLL reads ProductName pdfium, CompanyName Google Inc. and FileDescription PDFium (compiled by github.com/bblanchon). When we scanned the bundled Win64 pdfium.dll for embedded identification strings, it reported libjpeg-turbo version 3.1.0, OpenJPEG error messages, ICU data tables (icudt78l) and Skia drawing classes. The upstream PDFium source tree records the license of each vendored library in a README.pdfium file, and an upstream checkout gives the picture below. Versions shift with every PDFium roll, so treat the license names as the stable part and collect each license text at the revision your build actually used
| Component | Role in the engine | License |
|---|---|---|
| PDFium | Parsing, rendering, forms, text | BSD-3-Clause with Apache-2.0 text (PDFium-LICENSE) |
| FreeType | Font loading and glyph rasterization | FreeType License (FTL), credit required in documentation |
| libjpeg-turbo | DCT (JPEG) image decoding | IJG License and Modified (3-clause) BSD License, IJG credit required for binary-only distribution |
| Little CMS | ICC color management | MIT |
| OpenJPEG | JPEG 2000 (JPXDecode) images | BSD-2-Clause |
| Anti-Grain Geometry 2.3 | Vector rasterizer for the AGG renderer | MIT |
| zlib, ICU | Flate streams, Unicode data | Chromium dependencies under their own permissive licenses |
FreeType and the Independent JPEG Group are the two credits most often missed, because each asks for a sentence in your documentation rather than a file in your package. The FTL requires distribution documentation to state that the software is based in part on the work of the FreeType Team, and it offers a preferred wording: Portions of this software are copyright © <year> The FreeType Project (www.freetype.org). All rights reserved., with the year taken from the FreeType version you ship. The IJG License, which libjpeg-turbo carries, says that when only executable code is distributed, the accompanying documentation must state that "this software is based in part on the work of the Independent JPEG Group". Put both sentences in the readme, help file or manual that ships with the product. Little CMS, OpenJPEG and AGG want their copyright and permission notices preserved, which a consolidated notices file handles
Does the V8 build pdfium.v8.dll change the picture?
The V8 build carries more code and therefore more notices. The bundled pdfium.v8.dll is 34,308,608 bytes on Win64 against 10,052,608 for the plain pdfium.dll, and scanning it turned up V8 runtime symbols plus libtiff and libpng entry points that the plain DLL lacks; the XFA image codecs use them. V8 has a BSD-style license of its own, and libtiff and libpng each have a short permissive license, so all three join the notices file of any package that ships pdfium.v8.dll. Whether you ship it depends on your documents. PDFium Component selects pdfium.v8.dll when you set EnableV8Engine before the library loads, and also when the first document a process opens carries XFA markers. An application that may meet XFA forms should therefore ship the V8 build with its notices, and the piece on detecting XFA forms and extracting XFA packets shows how to tell which documents those are. One that only renders ordinary AcroForm PDFs can leave the 34 MB file out
PDFium license versus the PDFium Component license
Two licenses apply, and they never merge. The open-source PDFium license governs pdfium.dll and pdfium.v8.dll, whoever compiled them. The PDFium Component license from losLab governs the Object Pascal source, or the precompiled DCU units, that you compile into your executable. According to the purchase page, every tier grants royalty-free deployment in unlimited applications within the selected developer scope, a perpetual right to use the purchased version, and one year of updates and email support. Single covers one developer. Small Business covers up to five developers in one company, and Enterprise every developer in one company. The Installation guide adds that compiled applications need no additional runtime licenses
Royalty-free describes the losLab side only: no per-copy fee goes to losLab, while the notice duties of the open-source engine keep traveling with the DLL. Optional providers follow the same rule. A deployment that adds the Tesseract OCR provider, OpenSSL outside Windows or a separate LittleCMS color provider adds each binary's license text to the package, taken from that provider's own distribution. If you are still choosing a project layout, the PDFium Component getting started guide for Delphi and Lazarus shows where the DLLs folder sits relative to your executable
Packaging checklist for pdfium.dll redistribution
Install the engine into your own application tree and keep every license file beside the binary it describes. LoadPDFiumDll, the loader in PDFium Component, looks for the DLLs\Win32 or DLLs\Win64 tree in the application folder or one of its parent folders, followed by a bare Win32 or Win64 folder, the executable folder and the Windows system directory; if all of those miss, Windows applies its standard DLL search order. On a development machine that breadth hides packaging mistakes. The CopyDLLs.bat script in the component package can copy the DLLs into System32 and SysWOW64 for running demos, and a leftover DLLs tree in a parent build folder resolves just as quietly. Either one can satisfy the loader on your machine while the customer package lacks the file. The article on deploying the PDFium DLL and diagnosing load failures covers the error codes you see when the tree is wrong. The checklist:
- Ship DLLs\PDFium-LICENSE unchanged at the root of the DLLs tree, where the component package keeps it, so the BSD and Apache texts reach every recipient exactly as published
- Add a ThirdPartyNotices.txt beside the executable listing PDFium and every bundled library with its copyright line and full license text, assembled from the upstream sources of the build you ship
- Credit FreeType and the Independent JPEG Group in the documentation that ships with the product, and, for visibility, in the About box as well
- Keep the Google name out of marketing copy; describing the product as using the open-source PDFium engine is factual and avoids anything resembling endorsement
- Include pdfium.v8.dll and its V8, libtiff and libpng notices only in editions that open XFA forms
- Have the installer copy license files under the same component flags as the DLLs, so a custom install that adds the engine always adds its notices
Showing PDFium credits in a Delphi About box
A credits screen should show the component version, the engine file the process actually loaded, and the notices text. The obvious source for an engine version is the DLL version resource, but on the bundled DLLs FileVersion and ProductVersion both read 0.0.0.0. FPDF_GetFileVersion answers a different question: it returns the PDF version of an open document, and PDFium Component wraps it as TPdf.GetPdfVersion. What the component exposes is PdfComponentVersion for its own release number, and the PDFiumLibrary module handle, from which GetModuleFileName yields the full path of the DLL in use. A path ending in pdfium.v8.dll tells support at a glance which build a customer runs
uses
Winapi.Windows, System.SysUtils, System.Classes, System.IOUtils,
Vcl.Forms, PDFium;
// Full path of the PDFium runtime this process bound, or a reason
function LoadedPdfiumFile: string;
var
Buffer: array[0..MAX_PATH] of Char;
Count: DWORD;
begin
try
PDFium.LoadLibrary; // Winapi.Windows declares a LoadLibrary too
except
on E: Exception do
Exit('(not loaded: ' + E.Message + ')');
end;
// Qualify Loaded: inside a form method a bare Loaded is TComponent.Loaded
if not PDFium.Loaded then
Exit('(not loaded)');
Count := GetModuleFileName(PDFiumLibrary, Buffer, Length(Buffer));
SetString(Result, Buffer, Count);
end;
procedure TAboutForm.FormCreate(Sender: TObject);
var
Credits: TStringBuilder;
NoticeFile: string;
begin
NoticeFile := TPath.Combine(ExtractFilePath(Application.ExeName),
'ThirdPartyNotices.txt');
Credits := TStringBuilder.Create;
try
Credits.AppendLine('PDF engine: PDFium Component ' + PdfComponentVersion);
Credits.AppendLine('PDFium runtime: ' + LoadedPdfiumFile);
Credits.AppendLine('This software is based in part on the work of the FreeType Team');
Credits.AppendLine('This software is based in part on the work of the Independent JPEG Group');
Credits.AppendLine;
if FileExists(NoticeFile) then
Credits.Append(TFile.ReadAllText(NoticeFile, TEncoding.UTF8))
else
Credits.AppendLine('Third-party notices: ' + NoticeFile);
MemoCredits.Text := Credits.ToString;
finally
Credits.Free;
end;
end;
The call is written PDFium.LoadLibrary because Winapi.Windows exports a LoadLibrary of its own. Loaded is qualified for a similar reason: TComponent declares a Loaded method, so inside a form or TPdf method the bare name binds to that method, and the component source itself writes PDFium.Loaded. The second routine belongs behind a hidden command-line switch of the packaged build. It resolves the engine path with LoadPDFiumDll, which computes the location without loading anything, and the StartsText test flags any runtime found outside the application folder, whether in System32 or in a parent folder's DLLs tree. Wire it into the release pipeline before the installer is signed, so a missing notices file stops the build
uses
System.SysUtils, System.Classes, System.StrUtils, System.IOUtils, PDFium;
// Run as MyApp.exe --check-redist from the staged install folder
function CheckPdfiumRedistributables(Problems: TStrings): Boolean;
var
AppDir, DllFile, DllDir, DllsRoot, Notices: string;
begin
AppDir := IncludeTrailingPathDelimiter(GetApplicationPath);
Notices := AppDir + 'ThirdPartyNotices.txt';
DllFile := LoadPDFiumDll; // resolves the path; nothing is loaded
DllDir := ExtractFilePath(DllFile);
if (DllDir = '') or not FileExists(DllFile) then
Problems.Add(BuildDllName(EnableV8Engine) + ' not found in the application tree')
else if not StartsText(AppDir, DllFile) then
Problems.Add('Runtime resolved outside the application folder: ' + DllFile);
// PDFium-LICENSE sits at the DLLs root, one level above Win32 / Win64
if DllDir <> '' then
begin
DllsRoot := ExtractFilePath(ExcludeTrailingPathDelimiter(DllDir));
if not FileExists(DllDir + 'PDFium-LICENSE') and
not FileExists(DllsRoot + 'PDFium-LICENSE') then
Problems.Add('PDFium-LICENSE missing near ' + DllFile);
end;
if not FileExists(Notices) then
Problems.Add('ThirdPartyNotices.txt missing in ' + AppDir)
else if FileExists(DllDir + BuildDllName(True)) and
not ContainsText(TFile.ReadAllText(Notices, TEncoding.UTF8), 'V8') then
Problems.Add('pdfium.v8.dll ships but the notices do not mention V8');
Result := Problems.Count = 0;
end;
With these pieces in place, the answer to legal is a short packet: PDFium-LICENSE as shipped, the notices file, the documentation credits page, and the losLab license terms for the Delphi layer. To try the routine before buying, download the evaluation package from the PDFium Component product page, copy its DLLs folder into a staging tree beside a test build, and run the check routine there; each line it reports is one item to close before your own release