Text
This example shows how to write headings, paragraphs, and aligned text with rix/pdf.
The example uses the public Rix facade:
#include <rix.hpp>and accesses PDF through:
rix.pdfUse this example when you want to create a PDF with styled text content.
Create the file
mkdir -p ~/rix-pdf-text-example
cd ~/rix-pdf-text-example
touch text.cppAdd:
#include <rix.hpp>
int main()
{
auto doc = rix.pdf.document();
doc.set_title("Rix PDF Text Example");
doc.set_author("Rix");
auto &page = doc.add_page();
auto y = page.y_top();
y = page.heading(
page.x_left(),
y,
"Rix PDF",
1);
y -= 10.0F;
y = page.paragraph(
page.x_left(),
y,
page.content_width(),
"Rix gives Vix C++ projects a unified userland facade. "
"The PDF module keeps the public API simple while the writer internals stay hidden.");
y -= 20.0F;
page.paragraph(
page.x_left(),
y,
page.content_width(),
"This paragraph is centered to show text alignment.",
rixlib::pdf::Align::Center,
rixlib::pdf::TextStyle{
rixlib::pdf::Font::Helvetica,
12.0F,
rixlib::pdf::Color::blue_color()});
auto saved = rix.pdf.save(doc, "rix_pdf_text.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:", "rix_pdf_text.pdf");
return 0;
}Run it:
vix run text.cppIf Rix is not available yet for single-file usage:
vix install -g rix/rix
vix run text.cppThis creates:
rix_pdf_text.pdfWhat this example does
The example creates a PDF document:
auto doc = rix.pdf.document();It sets document metadata:
doc.set_title("Rix PDF Text Example");
doc.set_author("Rix");It adds a page:
auto &page = doc.add_page();It draws a heading:
auto y = page.heading(
page.x_left(),
page.y_top(),
"Rix PDF",
1);It draws a wrapped paragraph:
y = page.paragraph(
page.x_left(),
y,
page.content_width(),
"Rix gives Vix C++ projects a unified userland facade.");Then it saves the file:
auto saved = rix.pdf.save(doc, "rix_pdf_text.pdf");Text coordinates
PDF coordinates are expressed in points.
One inch is 72 points.
The example uses page helpers instead of hardcoded positions:
page.x_left()
page.y_top()
page.content_width()These helpers keep content inside the page margins.
Draw one line of text
Use:
page.text(
page.x_left(),
page.y_top(),
"Hello from rix.pdf");This draws one line at the given X and Y position.
Draw a heading
Use:
auto y = page.heading(
page.x_left(),
page.y_top(),
"Rix PDF",
1);The last argument is the heading level.
Common levels are:
1
2
3
4
5
6heading returns the next Y position after the heading.
This makes it easy to continue below:
y -= 10.0F;Draw a paragraph
Use:
auto y = page.paragraph(
page.x_left(),
page.y_top(),
page.content_width(),
"This paragraph will wrap inside the available content width.");The arguments are:
x position
starting y position
available width
text contentparagraph wraps text and returns the Y position after the paragraph.
Continue below a paragraph
Because paragraph returns the next Y position, you can continue drawing below it:
auto y = page.paragraph(
page.x_left(),
page.y_top(),
page.content_width(),
"First paragraph.");
y -= 20.0F;
page.paragraph(
page.x_left(),
y,
page.content_width(),
"Second paragraph.");This is the normal pattern for multi-section text pages.
Align text
Use Align values:
rixlib::pdf::Align::Left
rixlib::pdf::Align::Center
rixlib::pdf::Align::Right
rixlib::pdf::Align::JustifyExample:
page.paragraph(
page.x_left(),
y,
page.content_width(),
"Centered text",
rixlib::pdf::Align::Center);Draw aligned text on one line
Use text_aligned:
page.text_aligned(
page.x_left(),
page.y_top(),
page.content_width(),
"Centered title",
rixlib::pdf::Align::Center);This is useful for titles, footers, and page labels.
Style text
Use TextStyle when you want to control font, size, color, and line height.
rixlib::pdf::TextStyle{
rixlib::pdf::Font::Helvetica,
12.0F,
rixlib::pdf::Color::blue_color()}Example:
page.paragraph(
page.x_left(),
y,
page.content_width(),
"Blue paragraph",
rixlib::pdf::Align::Left,
rixlib::pdf::TextStyle{
rixlib::pdf::Font::Helvetica,
12.0F,
rixlib::pdf::Color::blue_color()});Common text styles
Use the built-in factories:
rixlib::pdf::TextStyle::normal()
rixlib::pdf::TextStyle::heading()
rixlib::pdf::TextStyle::small()Example:
page.text(
page.x_left(),
page.y_top(),
"Small note",
rixlib::pdf::TextStyle::small());Fonts
Standard PDF fonts are available through rixlib::pdf::Font.
Examples:
rixlib::pdf::Font::Helvetica
rixlib::pdf::Font::HelveticaBold
rixlib::pdf::Font::Times
rixlib::pdf::Font::CourierUse them in a text style:
auto style = rixlib::pdf::TextStyle{
rixlib::pdf::Font::HelveticaBold,
14.0F,
rixlib::pdf::Color::black()};Colors
Use built-in colors:
rixlib::pdf::Color::black()
rixlib::pdf::Color::gray()
rixlib::pdf::Color::blue_color()
rixlib::pdf::Color::red_color()
rixlib::pdf::Color::green_color()Use a hex color:
auto color = rixlib::pdf::Color::from_hex(0x2C3E50);Then:
auto style = rixlib::pdf::TextStyle{
rixlib::pdf::Font::Helvetica,
12.0F,
color};Complete text page example
#include <rix.hpp>
int main()
{
auto doc = rix.pdf.document();
doc.set_title("Text Page")
.set_author("Rix");
auto &page = doc.add_page();
auto y = page.heading(
page.x_left(),
page.y_top(),
"Text Page",
1);
y -= 12.0F;
y = page.paragraph(
page.x_left(),
y,
page.content_width(),
"This is a wrapped paragraph. It uses the content width so text stays inside the page margins.");
y -= 18.0F;
page.text_aligned(
page.x_left(),
y,
page.content_width(),
"Centered line",
rixlib::pdf::Align::Center,
rixlib::pdf::TextStyle{
rixlib::pdf::Font::HelveticaBold,
14.0F,
rixlib::pdf::Color::blue_color()});
auto saved = rix.pdf.save(doc, "text-page.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:", "text-page.pdf");
return 0;
}Run:
vix run text.cppAdd a page number
Use:
page.page_number(1);With total pages:
page.page_number(1, 3);Example:
page.page_number(
1,
1,
page.y_bottom(),
rixlib::pdf::TextStyle::small());Create a simple text PDF with make_text
For the shortest workflow, use:
auto saved = rix.pdf.make_text(
"hello.pdf",
"This file was generated with rix.pdf.make_text.",
"Rix PDF");Complete example:
#include <rix.hpp>
int main()
{
auto saved = rix.pdf.make_text(
"hello.pdf",
"This file was generated with rix.pdf.make_text.",
"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;
}Use make_text for simple text-only PDFs.
Use document() when you need headings, multiple paragraphs, styling, tables, drawings, images, or metadata.
Save the document
Use:
auto saved = rix.pdf.save(doc, "text.pdf");Check errors:
if (saved.failed())
{
rix.debug.eprint(
"pdf error:",
rix.pdf.error.to_string(saved.error()),
saved.error().message());
return 1;
}Write bytes instead of saving
Use:
auto bytes = rix.pdf.write(doc);Example:
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 write for HTTP responses or custom output handling.
Use save for direct file output.
Use in a Vix project
Create a project:
vix new rix-pdf-text --app
cd rix-pdf-textAdd Rix:
vix add rix/rix
vix installMake sure vix.app contains:
deps = [
"rix/rix",
]A minimal vix.app can look like this:
name = "rix-pdf-text"
type = "executable"
standard = "c++20"
output_dir = "bin"
sources = [
"src/main.cpp",
]
include_dirs = [
"include",
"src",
]
deps = [
"rix/rix",
]
packages = [
"vix",
]
links = [
"vix::vix",
]Put the example code in:
src/main.cppBuild and run:
vix build
vix runSingle-file usage
For examples, tests, and quick experiments:
vix run text.cppIf needed:
vix install -g rix/rix
vix run text.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 doc = rix.pdf.document();
auto &page = doc.add_page();
page.text(
page.x_left(),
page.y_top(),
"Hello from rix.pdf");
auto saved = rix.pdf.save(doc, "text.pdf");
return saved.ok() ? 0 : 1;
}When at least one RIX_ENABLE_* macro is defined, only selected modules are mounted.
If you also want debug output:
#define RIX_ENABLE_PDF
#define RIX_ENABLE_DEBUG
#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");
auto saved = rix.pdf.save(doc, "text.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:", "text.pdf");
return 0;
}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>Example:
#include <rix/pdf.hpp>
int main()
{
auto pdf = rixlib::pdf::module();
auto doc = pdf.document();
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(),
"Hello from rix/pdf.");
auto saved = pdf.save(doc, "text.pdf");
return saved.ok() ? 0 : 1;
}The examples in this documentation prefer the public facade:
#include <rix.hpp>and:
rix.pdfCommon mistakes
Forgetting to install Rix
If rix.hpp is not found, install Rix first.
For a project:
vix add rix/rix
vix installFor single-file usage:
vix install -g rix/rixPutting Rix in packages
Wrong:
packages = [
"rix/rix",
]Correct:
deps = [
"rix/rix",
]deps is for Vix Registry packages.
packages is for CMake package discovery.
Forgetting that Y moves downward by subtraction
To draw lower on the page, subtract from Y:
y -= 20.0F;Then draw:
page.text(
page.x_left(),
y,
"Next line");Expecting metadata to be visible
This sets document metadata:
doc.set_title("Rix PDF Text Example");This draws visible text:
page.heading(
page.x_left(),
page.y_top(),
"Rix PDF Text Example",
1);Use both when you want both metadata and visible content.
Calling value() before checking success
Wrong:
auto bytes = rix.pdf.write(doc);
rix.debug.print(bytes.value().size());Correct:
auto bytes = rix.pdf.write(doc);
if (bytes.failed())
{
return 1;
}
rix.debug.print(bytes.value().size());Not checking save errors
Wrong:
rix.pdf.save(doc, "text.pdf");Correct:
auto saved = rix.pdf.save(doc, "text.pdf");
if (saved.failed())
{
rix.debug.eprint(
"pdf error:",
rix.pdf.error.to_string(saved.error()),
saved.error().message());
return 1;
}What you should remember
Create a document:
auto doc = rix.pdf.document();Add a page:
auto &page = doc.add_page();Draw a heading:
auto y = page.heading(
page.x_left(),
page.y_top(),
"Rix PDF",
1);Draw a paragraph:
y = page.paragraph(
page.x_left(),
y,
page.content_width(),
"Text content.");Save:
auto saved = rix.pdf.save(doc, "text.pdf");Check errors:
if (saved.failed())
{
rix.debug.eprint(
"pdf error:",
rix.pdf.error.to_string(saved.error()),
saved.error().message());
}For project usage:
vix add rix/rix
vix installand keep:
deps = [
"rix/rix",
]Next step
Continue with PDF tables.
Next: Tables