than_pdf_engine 1.2.0
than_pdf_engine: ^1.2.0 copied to clipboard
than_pdf_engine -> dart package.wrapper cpp langage.pdfium + stb_image_write .
Than PDF Engine #
A lightweight PDF engine for Dart and Flutter built on top of PDFium using Dart FFI .
The engine communicates directly with PDFium through Dart FFI without using a custom C++ wrapper. PDF rendering is handled by PDFium, while image processing and encoding are handled on the Dart side using the image package.
Features #
- Direct PDFium integration through Dart FFI
- No custom C++ wrapper layer
- Open and close PDF documents
- Get PDF page count
- Load individual pages
- Render PDF pages to image data
- Save rendered pages as image files
- Generate PDF thumbnails
- PNG and JPEG image output
- Dart-side image processing and encoding
- Result-based error handling
- Designed for Dart and Flutter applications
Architecture #
The current implementation uses a simple architecture:
┌──────────────────────────┐
│ Dart / Flutter │
├──────────────────────────┤
│ Than PDF Engine │
├──────────────────────────┤
│ Dart FFI │
├──────────────────────────┤
│ PDFium │
└──────────────────────────┘
│
▼
Rendered Pixel Data
│
▼
┌──────────────────────────┐
│ image package │
│ PNG / JPEG encoding │
└──────────────────────────┘
Previous Architecture #
The project previously used a custom C++ wrapper around PDFium:
Dart
│
▼
Dart FFI
│
▼
C++ Wrapper
│
▼
PDFium
The C++ wrapper layer has now been removed.
Current Architecture #
The current implementation communicates with PDFium directly through Dart FFI:
Dart
│
▼
Dart FFI
│
▼
PDFium
│
▼
Rendered Bitmap
│
▼
Dart Image Processing
│
▼
PNG / JPEG
This keeps the native layer small and allows image processing to remain on the Dart side.
Dependencies #
The engine uses pdfium_dart to access the PDFium C API through Dart FFI.
Add the dependency to your pubspec.yaml :
dependencies:
pdfium_dart: ^0.2.5
The project also uses the image package for image processing and encoding.
Why Dart FFI? #
The project originally used a custom C++ wrapper to expose PDFium functionality to Dart.
The current implementation uses Dart FFI directly instead.
This provides several advantages:
- Less native wrapper code
- A simpler architecture
- Fewer C++ APIs to maintain
- Direct access to PDFium functions
- Easier integration with Dart-side image processing
- Better separation between PDF rendering and image encoding
- Easier maintenance of the native layer
PDFium is responsible for PDF parsing and page rendering, while Dart handles the resulting image data.
Related Package #
Looking for a complete Flutter PDF reader built on top of than_pdf_engine ?
Check out t_pdf_reader .
t_pdf_reader uses than_pdf_engine as its core PDF rendering engine and provides a higher-level Flutter PDF reader experience for displaying and interacting with PDF documents.
Basic UsageOpen a PDFLoad a PageRender a PageOpen a DocumentClose the DocumentGenerate PDF ThumbnailsGenerate Thumbnails for Multiple PDFsSave a Page as an ImageLow-Level APIOpen a PDFError HandlingFeaturesArchitectureCurrent ArchitectureImage ProcessingGoals
Image Processing #
PDFium renders a PDF page into a bitmap buffer.
The rendered pixel data is accessed from Dart through FFI and converted into an image using the image package.
PDF Page
│
▼
PDFium Renderer
│
▼
PDFium Bitmap
│
▼
Raw Pixel Buffer
│
▼
Dart FFI
│
▼
image package
│
├── PNG
└── JPEG
This keeps image encoding outside of the PDFium wrapper layer.
Basic Usage #
Open a PDF #
final reader = PdfReaderWorker();
final result = await reader.open('/path/to/document.pdf');
if (result.isErr) {
print('Open error: ${result.unwrapError().status}');
return;
}
Render a Page #
final result = await reader.getImage(0);
if (result.isErr) {
print('Image error: ${result.unwrapError()}');
return;
}
final imageData = result.unwrap();
print(imageData);
Close the Document #
await reader.close();
Low-Level API #
The low-level API can also be used directly when more control over the document and page lifecycle is required.
Open a Document #
final document = PdfDocumentFile();
//final doc = PdfDocumentMem(); //memory bytes
//final doc = PdfDocumentMem64();//memory 64 bytes
final result = document.open('/path/to/document.pdf');
if (result.isErr) {
print(result.unwrapError());
return;
}
print('Pages: ${document.pageCount}');
Load a Page #
final page = PdfPage(document);
final result = page.loadPage(0);
if (result.isErr) {
print(result.unwrapError());
page.close();
return;
}
Save a Page as an Image #
final result = page.saveImageFile('page.png');
if (result.isErr) {
print('Error: ${result.unwrapError()}');
return;
}
Generate PDF Thumbnails #
The engine can also generate thumbnails from PDF documents.
final result = await PdfImageGenerator.instance.generate(
'/path/to/document.pdf',
outPath: '/path/to/output.jpg',
);
if (result.isOk) {
print('Generated: ${result.unwrap()}');
}
Generate Thumbnails for Multiple PDFs #
final dir = Directory('/path/to/pdf');
final outDir = Directory('${dir.path}/gen');
if (!outDir.existsSync()) {
outDir.createSync(recursive: true);
}
for (final file in dir.listSync()) {
final name = file.path.split('/').last;
final parts = name.split('.');
parts.removeLast();
final nameOnly = parts.join('.');
final result = await PdfImageGenerator.instance.generate(
file.path,
outPath: '${outDir.path}/$nameOnly.jpg',
);
if (result.isOk) {
print('Generated: $nameOnly');
}
}
Error Handling #
The project uses a Result<T, E> style API instead of relying entirely on exceptions.
final result = document.open(path);
if (result.isErr) {
final error = result.unwrapError();
print(error);
return;
}
final document = result.unwrap();
This makes errors from the PDFium layer easier to propagate through the Dart API.
Project Structure #
lib/
├── core/
│ ├── high_level_api/
│ │ └── reader/
│ │ └── pdf_reader_worker.dart
│ │
│ ├── low_level_api/
│ │ └── pdf_document.dart
│ │
│ └── types/
│ └── result.dart
│
├── than_pdf_engine.dart
└── than_pdf_engine_bindings_generated.dart
The generated FFI bindings are created from the PDFium C headers and are used directly by the Dart implementation.
Native Dependencies #
The engine depends on PDFium for PDF parsing and page rendering.
Dart FFI is used to access the PDFium C API.
There is no custom C++ PDFium wrapper in the current implementation.
Dart
└── Dart FFI
└── PDFium
Goals #
The main goal of Than PDF Engine is to provide a simple and efficient PDF rendering layer for Dart and Flutter applications without introducing an unnecessary native wrapper layer.
The project focuses on:
- Direct PDFium access
- Minimal native code
- Dart-friendly APIs
- Efficient page rendering
- Image generation
- Flutter integration
- Simple error handling
Status #
This project is currently under active development.
The API may change as more PDFium functionality is exposed through the Dart FFI layer.
License #
License information will be added when the project is ready for release.