PDF Quick Start
This page shows the fastest way to create a PDF file with rix/pdf.
The examples use the public Rix facade:
#include <rix.hpp>and access PDF through:
rix.pdfrix/pdf is useful when a Vix.cpp or Rix project needs to generate simple PDF documents, reports, tables, or text files from C++.
What you will build
You will create a small C++ file that:
creates a PDF document
adds one page
writes text
saves the document to disk
checks save errors
runs with vix runThe output file will be:
hello.pdfCreate a working folder
Create a small folder in your home directory:
mkdir -p ~/rix-pdf-quick-start
cd ~/rix-pdf-quick-start
touch pdf.cppAdd the example
Open:
pdf.cppAdd:
#include <rix.hpp>
int main()
{
auto doc = rix.pdf.document();
auto &page = doc.add_page();
page.text(
page.x_left(),
page.y_top(),
"Hello from rix.pdf");
page.text(
page.x_left(),
page.y_top() - 30.0F,
"This PDF was generated through the unified Rix facade.");
auto saved = rix.pdf.save(doc, "hello.pdf");
if (saved.failed())
{
rix.debug.eprint(
"pdf error:",
rix.pdf.error.to_string(saved.error()),
saved.error().message());
return 1;
}
rix.debug.print("created:", "hello.pdf");
return 0;
}Run the file
Run:
vix run pdf.cppIf Rix is not available yet for single-file usage:
vix install -g rix/rix
vix run pdf.cppExpected output
The terminal output should look like this:
created: hello.pdfThe folder should now contain:
pdf.cpp
hello.pdfOpen hello.pdf with your normal PDF viewer.
Create a document
The first step is to create a document:
auto doc = rix.pdf.document();A document owns pages and metadata.
It does not write itself to disk automatically.
You save it later with:
rix.pdf.save(doc, "hello.pdf");Add a page
Add a page with:
auto &page = doc.add_page();The returned page is the drawing surface.
You use it to add text, paragraphs, headings, tables, drawings, and images.
Write text
Use:
page.text(x, y, value);Example:
page.text(
page.x_left(),
page.y_top(),
"Hello from rix.pdf");page.x_left() gives the left content position inside margins.
page.y_top() gives the top content position inside margins.
Add another line
To draw another line lower on the page, subtract from the Y position:
page.text(
page.x_left(),
page.y_top() - 30.0F,
"Second line");PDF coordinates use points.
One point is 1/72 inch.
Save the document
Save with:
auto saved = rix.pdf.save(doc, "hello.pdf");Always check the result:
if (saved.failed())
{
rix.debug.eprint(
"pdf error:",
rix.pdf.error.to_string(saved.error()),
saved.error().message());
return 1;
}save returns a status object.
It does not throw for normal PDF errors.
Fastest helper: make_text
For a very small text PDF, use:
auto saved = rix.pdf.make_text(
"hello.pdf",
"Hello from rix.pdf",
"Rix PDF");Complete example:
#include <rix.hpp>
int main()
{
auto saved = rix.pdf.make_text(
"hello.pdf",
"Hello from rix.pdf",
"Rix PDF");
if (saved.failed())
{
rix.debug.eprint(
"pdf error:",
rix.pdf.error.to_string(saved.error()),
saved.error().message());
return 1;
}
rix.debug.print("created:", "hello.pdf");
return 0;
}Run:
vix run pdf.cppUse make_text when you only need a simple text document.
Use document() when you need pages, headings, tables, drawings, images, or metadata.
Add a title and paragraph
For a more document-like PDF:
#include <rix.hpp>
int main()
{
auto doc = rix.pdf.document();
doc.set_title("Rix PDF Quick Start");
doc.set_author("Rix");
auto &page = doc.add_page();
auto y = page.heading(
page.x_left(),
page.y_top(),
"Rix PDF",
1);
y -= 10.0F;
page.paragraph(
page.x_left(),
y,
page.content_width(),
"Rix PDF lets C++ applications create simple generated documents "
"through the unified Rix facade.");
auto saved = rix.pdf.save(doc, "quick-start.pdf");
if (saved.failed())
{
rix.debug.eprint(
"pdf error:",
rix.pdf.error.to_string(saved.error()),
saved.error().message());
return 1;
}
rix.debug.print("created:", "quick-start.pdf");
return 0;
}Run:
vix run pdf.cppAdd a small table
Tables are useful for reports.
#include <rix.hpp>
int main()
{
auto doc = rix.pdf.document();
doc.set_title("Rix PDF Table");
auto &page = doc.add_page();
auto y = page.heading(
page.x_left(),
page.y_top(),
"Project table",
1);
y -= 20.0F;
rixlib::pdf::Table table;
table.set_column_widths({
160.0F,
160.0F,
160.0F});
table.add_header({
"Name",
"Language",
"Project"});
table.add_row({
"Ada",
"C++",
"Rix"});
table.add_row({
"Gaspard",
"C++",
"Vix.cpp"});
page.table(
page.x_left(),
y,
table);
auto saved = rix.pdf.save(doc, "table.pdf");
if (saved.failed())
{
rix.debug.eprint(
"pdf error:",
rix.pdf.error.to_string(saved.error()),
saved.error().message());
return 1;
}
rix.debug.print("created:", "table.pdf");
return 0;
}Run:
vix run pdf.cppAdd metadata
Metadata is written into the PDF info dictionary.
auto doc = rix.pdf.document();
doc.set_title("Rix PDF Metadata")
.set_author("Rix")
.set_subject("PDF generation")
.set_keywords("rix,pdf,vix,cpp");Use metadata for generated reports and files that need a readable title or author.
Write bytes instead of saving
Use write when you want the PDF bytes in memory:
auto bytes = rix.pdf.write(doc);
if (bytes.failed())
{
rix.debug.eprint(
"pdf error:",
rix.pdf.error.to_string(bytes.error()),
bytes.error().message());
return 1;
}
rix.debug.print("pdf bytes:", bytes.value().size());Use:
rix.pdf.save(doc, "output.pdf");when you want a file.
Use:
rix.pdf.write(doc);when another part of your application will handle the bytes.
Use in a Vix project
Create a Vix application:
vix new pdf-quick-start --app
cd pdf-quick-startAdd Rix:
vix add rix/rix
vix installIn vix.app, make sure Rix is listed under deps:
deps = [
"rix/rix",
]A small vix.app can look like this:
name = "pdf-quick-start"
type = "executable"
standard = "c++20"
output_dir = "bin"
sources = [
"src/main.cpp",
]
include_dirs = [
"include",
"src",
]
deps = [
"rix/rix",
]
packages = [
"vix",
]
links = [
"vix::vix",
]Then use PDF in src/main.cpp:
#include <rix.hpp>
int main()
{
auto saved = rix.pdf.make_text(
"hello.pdf",
"Hello from rix.pdf",
"Rix PDF");
if (saved.failed())
{
rix.debug.eprint(
"pdf error:",
rix.pdf.error.to_string(saved.error()),
saved.error().message());
return 1;
}
rix.debug.print("created:", "hello.pdf");
return 0;
}Build and run:
vix build
vix runSingle-file usage
For small scripts, examples, and experiments:
vix run pdf.cppIf Rix is installed globally for single-file usage:
vix install -g rix/rix
vix run pdf.cppFor project usage, prefer:
vix add rix/rix
vix installand keep the dependency in vix.app:
deps = [
"rix/rix",
]Use only PDF with the facade
If you want the rix.* facade style but only want PDF mounted, define the feature macro before including rix.hpp:
#define RIX_ENABLE_PDF
#include <rix.hpp>
int main()
{
auto saved = rix.pdf.make_text(
"hello.pdf",
"Hello from rix.pdf",
"Rix PDF");
return saved.ok() ? 0 : 1;
}When at least one RIX_ENABLE_* macro is defined, only selected modules are mounted.
Use the independent package
For independent usage, install:
vix add rix/pdf
vix installIn vix.app:
deps = [
"rix/pdf",
]Then include:
#include <rix/pdf.hpp>Use this style when a project only needs PDF and does not need the full unified Rix facade.
For most application documentation, prefer:
#include <rix.hpp>Common mistakes
Forgetting to save the document
Wrong:
auto doc = rix.pdf.document();
doc.add_page();Correct:
auto saved = rix.pdf.save(doc, "hello.pdf");Not checking errors
Wrong:
rix.pdf.save(doc, "hello.pdf");Better:
auto saved = rix.pdf.save(doc, "hello.pdf");
if (saved.failed())
{
rix.debug.eprint(
"pdf error:",
rix.pdf.error.to_string(saved.error()),
saved.error().message());
return 1;
}Saving to an empty path
This fails:
rix.pdf.save(doc, "");Use a real output path:
rix.pdf.save(doc, "hello.pdf");Drawing outside the visible page
This can make content invisible:
page.text(0.0F, -50.0F, "Hidden text");Use page helpers:
page.x_left()
page.y_top()
page.content_width()Forgetting deps
For a Vix project, do not put Rix packages in packages.
Use:
deps = [
"rix/rix",
]packages is for CMake package discovery.
deps is for Vix Registry packages.
What you should remember
Create a document:
auto doc = rix.pdf.document();Add a page:
auto &page = doc.add_page();Write text:
page.text(
page.x_left(),
page.y_top(),
"Hello from rix.pdf");Save:
auto saved = rix.pdf.save(doc, "hello.pdf");Check errors:
if (saved.failed())
{
rix.debug.eprint(
"pdf error:",
rix.pdf.error.to_string(saved.error()),
saved.error().message());
}Use make_text for the fastest simple PDF:
rix.pdf.make_text(
"hello.pdf",
"Hello from rix.pdf",
"Rix PDF");For a Vix project, install Rix:
vix add rix/rix
vix installand use:
deps = [
"rix/rix",
]Next step
Learn how to create a PDF document.
Next: Create Document