# plutobook **Repository Path**: yangyangdevel/plutobook ## Basic Information - **Project Name**: plutobook - **Description**: No description available - **Primary Language**: Unknown - **License**: MPL-2.0 - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-15 - **Last Updated**: 2026-07-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README [![Actions](https://img.shields.io/github/actions/workflow/status/plutoprint/plutobook/main.yml)](https://github.com/plutoprint/plutobook/actions) [![Releases](https://img.shields.io/github/v/release/plutoprint/plutobook)](https://github.com/plutoprint/plutobook/releases) [![License](https://img.shields.io/github/license/plutoprint/plutobook)](https://github.com/plutoprint/plutobook/blob/main/LICENSE) [![Sponsors](https://img.shields.io/github/sponsors/plutoprint)](https://github.com/sponsors/plutoprint) [![Packages](https://repology.org/badge/tiny-repos/plutobook.svg)](https://repology.org/project/plutobook/versions) > Prefer Python? Try [PlutoPrint](https://github.com/plutoprint/plutoprint) — a Python library built on PlutoBook for easy paged HTML rendering. # PlutoBook PlutoBook is a robust HTML rendering library tailored for paged media. It takes HTML or XML as input, applies CSS stylesheets, and lays out elements across one or more pages, which can then be rendered as Bitmap images or PDF documents. > [!NOTE] > PlutoBook implements its own rendering engine and does **not** depend on rendering engines like Chromium, WebKit, or Gecko. > The engine is designed to be robust, lightweight, and memory-efficient, leveraging modern C++ features such as [`std::pmr::monotonic_buffer_resource`](https://en.cppreference.com/w/cpp/memory/monotonic_buffer_resource) to minimize memory fragmentation and optimize allocation performance. **Testimonial** > *"PlutoBook is incredibly fast and lightweight. In my invoicing app (built in 2010), I replaced headless Chrome with PlutoBook and saw at least a **10× speed improvement** and **10× lower memory usage**, while achieving similar output quality."* > — **Nikola Radovanović** --- ## Basic Usage This example creates a PDF from inline HTML using **plutobook**. It sets up a book with A4 page size and **narrow margins** (36 points or 0.5 inches on all sides), then writes the output to `hello.pdf`. ```cpp #include static const char kHTMLContent[] = R"HTML( Magnum Scopulum Corallinum

Magnum Scopulum Corallinum

Magnum Scopulum Corallinum

Magnum Scopulum Corallinum est maximum systema scopulorum corallinorum in mundo, quod per plus quam 2,300 chiliometra oram septentrionalem-orientalem Australiae extenditur. Ex milibus scopulorum individualium et centenis insularum constat, e spatio videri potest et inter mirabilia naturalia mundi numeratur.

Domus est incredibili diversitati vitae marinae, cum plus quam 1,500 speciebus piscium, 400 generibus corallii, et innumerabilibus aliis organismis. Partem vitalem agit in salute oecosystematis marini conservanda et sustentat victum communitatum litoralium per otium et piscationem.

Quamquam pulchritudinem ac significationem oecologicam praebet, Magnum Scopulum Corallinum minas continenter patitur ex mutatione climatis, pollutione, et nimia piscatione. Eventus albi corallii ex temperaturis marinis crescentibus magnam partem scopuli nuper laeserunt. Conatus conservatorii toto orbe suscipiuntur ad hunc magnificum oecosystema subaquaneum tuendum et restaurandum.

)HTML"; int main() { plutobook::Book book(plutobook::PageSize::A4, plutobook::PageMargins::Narrow); book.loadHtml(kHTMLContent); book.writeToPdf("hello.pdf"); return 0; } ```
Equivalent in C ```c #include static const char kHTMLContent[] = "\n" "\n" "\n" " \n" " Magnum Scopulum Corallinum\n" " \n" "\n" "\n" "

Magnum Scopulum Corallinum

\n" " \"Magnum\n" "

Magnum Scopulum Corallinum est maximum systema scopulorum corallinorum in mundo, quod per plus quam 2,300 chiliometra oram septentrionalem-orientalem Australiae extenditur. Ex milibus scopulorum individualium et centenis insularum constat, e spatio videri potest et inter mirabilia naturalia mundi numeratur.

\n" "

Domus est incredibili diversitati vitae marinae, cum plus quam 1,500 speciebus piscium, 400 generibus corallii, et innumerabilibus aliis organismis. Partem vitalem agit in salute oecosystematis marini conservanda et sustentat victum communitatum litoralium per otium et piscationem.

\n" "

Quamquam pulchritudinem ac significationem oecologicam praebet, Magnum Scopulum Corallinum minas continenter patitur ex mutatione climatis, pollutione, et nimia piscatione. Eventus albi corallii ex temperaturis marinis crescentibus magnam partem scopuli nuper laeserunt. Conatus conservatorii toto orbe suscipiuntur ad hunc magnificum oecosystema subaquaneum tuendum et restaurandum.

\n" "\n" "\n"; int main() { plutobook_t* book = plutobook_create( PLUTOBOOK_PAGE_SIZE_A4, PLUTOBOOK_PAGE_MARGINS_NARROW, PLUTOBOOK_MEDIA_TYPE_PRINT ); plutobook_load_html(book, kHTMLContent, -1, "", "", ""); plutobook_write_to_pdf(book, "hello.pdf"); plutobook_destroy(book); return 0; } ```
Example output:

hello.pdf

--- ## Page Rendering PlutoBook supports precise page-level rendering, allowing individual pages to be drawn onto different canvas types, including bitmap canvases and PDF outputs. For custom rendering workflows, it integrates directly with Cairo, enabling advanced use cases like drawing onto custom surfaces or embedding within existing rendering pipelines. This page-specific approach improves efficiency by avoiding full document processing and is well-suited for previews, selective exports, and on-demand rendering. This example loads [**Alice’s Adventures in Wonderland**](https://www.gutenberg.org/ebooks/11) from Project Gutenberg, renders the first three pages as PNG images, and also exports them as a PDF. ```cpp #include #include int main() { // Create a plutobook instance with A4 page size, narrow margins, and print media type plutobook::Book book(plutobook::PageSize::A4, plutobook::PageMargins::Narrow, plutobook::MediaType::Print); // Load the HTML content from file book.loadUrl("Alice’s Adventures in Wonderland.html"); // Get page size in points and convert to pixel dimensions const plutobook::PageSize& pageSize = book.pageSize(); int pageWidth = std::ceil(pageSize.width() / plutobook::units::px); int pageHeight = std::ceil(pageSize.height() / plutobook::units::px); // Create a canvas to render pages as images plutobook::ImageCanvas canvas(pageWidth, pageHeight); // Render the first 3 pages to PNG files for(int pageIndex = 0; pageIndex < 3; ++pageIndex) { auto filename = "page-" + std::to_string(pageIndex + 1) + ".png"; // Clear the canvas to white before rendering each page canvas.clearSurface(1, 1, 1, 1); // Render the page onto the canvas book.renderPage(canvas, pageIndex); // Save the canvas to a PNG file canvas.writeToPng(filename); } // Export pages 1 to 3 (inclusive) to PDF with step=1 (every page in order) book.writeToPdf("Alice’s Adventures in Wonderland.pdf", 1, 3, 1); return 0; } ```
Equivalent in C ```c #include #include #include int main() { // Create a plutobook instance with A4 page size, narrow margins, and print media type plutobook_t* book = plutobook_create( PLUTOBOOK_PAGE_SIZE_A4, PLUTOBOOK_PAGE_MARGINS_NARROW, PLUTOBOOK_MEDIA_TYPE_PRINT ); // Load the HTML content from file plutobook_load_url(book, "Alice’s Adventures in Wonderland.html", "", ""); // Get page size in points and convert to pixel dimensions plutobook_page_size_t page_size = plutobook_get_page_size(book); int page_width = (int)ceilf(page_size.width / PLUTOBOOK_UNITS_PX); int page_height = (int)ceilf(page_size.height / PLUTOBOOK_UNITS_PX); // Create a canvas to render pages as images plutobook_canvas_t* canvas = plutobook_image_canvas_create( page_width, page_height, PLUTOBOOK_IMAGE_FORMAT_ARGB32 ); // Render the first 3 pages to PNG files for(int page_index = 0; page_index < 3; ++page_index) { char filename[64]; sprintf(filename, "page-%d.png", page_index + 1); // Clear the canvas to white before rendering each page plutobook_canvas_clear_surface(canvas, 1, 1, 1, 1); // Render the page onto the canvas plutobook_render_page(book, canvas, page_index); // Save the canvas to a PNG file plutobook_image_canvas_write_to_png(canvas, filename); } // Export pages 1 to 3 (inclusive) to PDF with step=1 (every page in order) plutobook_write_to_pdf_range(book, "Alice’s Adventures in Wonderland.pdf", 1, 3, 1); // Clean up resources plutobook_canvas_destroy(canvas); plutobook_destroy(book); return 0; } ```
Example output: | `page-1.png` | `page-2.png` | `page-3.png` | | --- | --- | --- | | ![page-1](https://github.com/user-attachments/assets/c9c26c07-e283-487e-a2e8-ab77c79bdbb5) | ![page-2](https://github.com/user-attachments/assets/43bdf6dc-21fc-427f-a9c6-e54510b88fbd) | ![page-3](https://github.com/user-attachments/assets/6bff4046-7877-4a89-9723-920bdb5799c0) | --- ## Document Rendering PlutoBook supports full-document rendering, drawing the entire content flow as a single continuous layout. This is ideal for generating scrollable previews, long-form visual exports, or cases where the overall structure needs to be viewed or processed at once. It also supports rendering specific rectangular regions of the document, which is useful for partial redraws or focused exports. Both full and partial rendering are available across all supported canvas types, including bitmap outputs, PDF surfaces, and Cairo contexts. The example below demonstrates how to perform a full-document render of an HTML file into a bitmap image. The document's actual rendered dimensions are measured first, and then a canvas of that size is created to ensure the entire layout is captured without clipping. Finally, the rendered result is saved as a PNG image.
Explore Life Through Moments.html ```html Explore Life Through Moments

Nature

Relax in the beauty of untouched landscapes and flourishing greenery. Nature inspires and calms the mind.

Nature

City Life

Discover the energy and excitement of urban environments. Cities pulse with opportunity and culture.

City

Adventure

Seek new horizons with every journey. Adventure is about embracing the unknown and living boldly.

Adventure
```
```cpp #include #include int main() { // Define a custom page size in pixel units used as the viewport for layout const plutobook::PageSize pageSize(1800 * plutobook::units::px, 600 * plutobook::units::px); // Create a plutobook instance with the custom page size, no page margins, and screen media type plutobook::Book book(pageSize, plutobook::PageMargins::None, plutobook::MediaType::Screen); // Load the HTML content from file with a custom user style book.loadUrl("Explore Life Through Moments.html", /*userStyle=*/"body { border: 1px solid gray }"); // Compute the full document dimensions after layout int width = std::ceil(book.documentWidth()); int height = std::ceil(book.documentHeight()); // Create a canvas large enough to render the entire document at once plutobook::ImageCanvas canvas(width, height); // Render the full document content to the canvas book.renderDocument(canvas); // Export the rendered canvas to a PNG file canvas.writeToPng("Explore Life Through Moments.png"); return 0; } ```
Equivalent in C ```c #include #include int main() { // Define a custom page size in pixel units used as the viewport for layout const plutobook_page_size_t page_size = {1800 * PLUTOBOOK_UNITS_PX, 600 * PLUTOBOOK_UNITS_PX}; // Create a plutobook instance with the custom page size, no page margins, and screen media type plutobook_t* book = plutobook_create(page_size, PLUTOBOOK_PAGE_MARGINS_NONE, PLUTOBOOK_MEDIA_TYPE_SCREEN); // Load the HTML content from file with a custom user style plutobook_load_url(book, "Explore Life Through Moments.html", /*user_style=*/"body { border: 1px solid gray }", ""); // Compute the full document dimensions after layout int width = (int)ceilf(plutobook_get_document_width(book)); int height = (int)ceilf(plutobook_get_document_height(book)); // Create a canvas large enough to render the entire document at once plutobook_canvas_t* canvas = plutobook_image_canvas_create(width, height, PLUTOBOOK_IMAGE_FORMAT_ARGB32); // Render the full document content to the canvas plutobook_render_document(book, canvas); // Export the rendered canvas to a PNG file plutobook_image_canvas_write_to_png(canvas, "Explore Life Through Moments.png"); // Clean up resources plutobook_canvas_destroy(canvas); plutobook_destroy(book); return 0; } ```
Example output: Explore Life Through Moments.png --- ## Features **PlutoBook** is a high-performance document renderer designed for static layout and print-ready output. It supports a broad set of modern web standards, including most of `CSS 3` and parts of `CSS 4`, with input from `HTML5`, `XHTML`, `SVG`, and common image formats like `JPG`, `PNG`, `WEBP`, `GIF`, `BMP`, and `TGA`. Output can be saved directly to `PDF`, image files, or any format supported by `Cairo` (e.g. `SVG`, `PostScript`). It includes robust support for international text layout via `ICU` and `HarfBuzz`, including Arabic, Hebrew, Hindi, and more. Emoji rendering (bitmap and vector) is fully supported. Font handling is powered by `Fontconfig` and `FreeType`, enabling access to all installed system fonts and major font formats. PlutoBook supports `file:` and `data:` URLs out of the box. Remote resources over `http`, `https`, and `ftp` are supported via `libcurl`, and you can plug in a custom fetcher for full control over resource loading. For a full breakdown of supported features, see [`FEATURES.md`](FEATURES.md): * [Fonts](FEATURES.md#fonts) * [Color](FEATURES.md#color) * [Backgrounds and Borders](FEATURES.md#backgrounds-and-borders) * [Outlines](FEATURES.md#outlines) * [Box Model](FEATURES.md#box-model) * [Box Sizing](FEATURES.md#box-sizing) * [Display](FEATURES.md#display) * [Positioning](FEATURES.md#positioning) * [Floats](FEATURES.md#floats) * [Lists and Counters](FEATURES.md#lists-and-counters) * [Counter Styles](FEATURES.md#counter-styles) * [Tables](FEATURES.md#tables) * [Multiple Columns](FEATURES.md#multiple-columns) * [Flexible Box](FEATURES.md#flexible-box) * [Custom Properties](FEATURES.md#custom-properties) * [Logical Properties](FEATURES.md#logical-properties) * [Values and Units](FEATURES.md#values-and-units) * [Transforms](FEATURES.md#transforms) * [Media Queries](FEATURES.md#media-queries) * [Paged Media](FEATURES.md#paged-media) * [Scalable Vector Graphics](FEATURES.md#scalable-vector-graphics) --- ## Roadmap PlutoBook is designed to grow into a powerful, flexible tool for static HTML rendering and high-quality print output. The following features are not yet available, but they are part of our long-term vision: * **JavaScript Support:** We plan to embed a lightweight JavaScript engine (like Duktape or QuickJS) so authors can use `