SimpleTinyPDF 0.52.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package SimpleTinyPDF --version 0.52.0
                    
NuGet\Install-Package SimpleTinyPDF -Version 0.52.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SimpleTinyPDF" Version="0.52.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SimpleTinyPDF" Version="0.52.0" />
                    
Directory.Packages.props
<PackageReference Include="SimpleTinyPDF" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SimpleTinyPDF --version 0.52.0
                    
#r "nuget: SimpleTinyPDF, 0.52.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SimpleTinyPDF@0.52.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SimpleTinyPDF&version=0.52.0
                    
Install as a Cake Addin
#tool nuget:?package=SimpleTinyPDF&version=0.52.0
                    
Install as a Cake Tool

SimpleTinyPDF

An extremely small, zero-dependency PDF generation library for .NET.

SimpleTinyPDF lets you create PDF documents from C# with no external packages. It targets .NET Standard 2.0, so it works with .NET Framework 4.6.1+, .NET Core 2.0+, and .NET 5+. You add pages, draw text, images, shapes, and tables, etc then save. There is no DOM, no layout engine, and no markup language — you position everything in points.

Features

  • Text — single-line, wrapped text boxes, rich text with mixed fonts/sizes/colors, alignment (left, center, right), underline, hyperlinks, opacity
  • Images — JPEG and PNG (with transparency), EXIF auto-orientation, scaling modes (Stretch, Fit, Fill), opacity
  • Tables — styled headers, column alignment, alternate row shading, auto-pagination with repeated headers, CSV import
  • Lists — bullet, numbered, lowercase Roman (i, ii, iii…), and uppercase Roman (I, II, III…); unlimited nesting with per-level style overrides and custom bullet symbols; automatic text wrapping and multi-page flow
  • Shapes — lines, rectangles (stroke and/or fill)
  • Rotation — rotate any text, image, or shape element by an arbitrary angle
  • Bookmarks — hierarchical outline / table of contents
  • Fonts — 14 standard PDF Type 1 fonts (Helvetica, Times, Courier, Symbol, ZapfDingbats) with extended European character support
  • Colors — RGB, CMYK, and grayscale
  • Page sizes — A3, A4, A5, Letter, Legal, custom dimensions, landscape
  • Coordinates — top-down (default) or native PDF bottom-up
  • Metadata — document title and author
  • Zero dependencies — no NuGet packages, no native libraries

Pros and Cons

Use SimpleTinyPDF when you want to:

  • Generate invoices, reports, receipts, or labels from code
  • Avoid pulling in a large dependency tree for simple PDF output
  • Run in constrained environments (Azure Functions, Docker, CI pipelines) without native libraries
  • Ship a self-contained app with no runtime font or image dependencies

Look elsewhere if you need:

  • HTML-to-PDF conversion
  • Fonts beyond the 14 standard PDF fonts (no TrueType/OpenType embedding)
  • Full Unicode or CJK character support
  • Form fields or annotations
  • PDF reading, parsing, or editing
  • Encryption or digital signatures
  • Automatic page layout (headers/footers, page numbers, flowing columns)

Size Comparison

One of SimpleTinyPDF's goals is to stay tiny. Here's how it compares to other popular .NET PDF libraries:

Library NuGet Package Total Footprint vs SimpleTinyPDF Native Binaries?
SimpleTinyPDF ~68 KB ~68 KB 1x No
PDFsharp 6.2.4 ~4.4 MB ~4.5 MB 66x No
iText 9.6.0 ~5.0 MB ~13–15 MB 200x No (BouncyCastle ~8 MB)
QuestPDF 2026.2.4 ~36 MB ~36 MB 530x Yes (bundled Skia)
IronPDF 2026.5 ~19 MB ~250+ MB 3,700x Yes (bundled Chromium)

IronPDF's footprint includes the Chromium rendering engine downloaded at build/runtime. QuestPDF bundles custom Skia native binaries for cross-platform rendering.

API Reference

PdfDocument

The main entry point. Create one, add pages, then save.

var doc = new PdfDocument();
doc.Title = "My Report";
doc.Author = "Jane Doe";

var page = doc.AddPage();                         // A4 by default
var page2 = doc.AddPage(PageSize.Letter);         // US Letter
var page3 = doc.AddPage(PageSize.A4.Landscape()); // A4 landscape
var cover = doc.InsertPage(1);                    // insert at position 1

doc.Save("output.pdf");       // save to file
doc.Save(stream);             // write to stream
byte[] bytes = doc.ToArray(); // get as byte array
Property / Method Description
Title Document title (PDF metadata)
Author Document author (PDF metadata)
Pages Read-only list of all pages
PageCount Number of pages
FirstPage / LastPage First or last page (null if empty)
GetPage(int pageNumber) Get a page by 1-based number
GetPageNumber(PdfPage page) Get the 1-based number of a page
AddPage(PageSize) Append a new page (defaults to A4)
InsertPage(int, PageSize) Insert a page at a 1-based position
AddImage(PdfImage) Register an image (deduplicates identical content)
Save(string) / Save(Stream) Write PDF to file or stream
ToArray() Return PDF as a byte array

PdfPage

All drawing happens on a page. Coordinates are in points. By default the coordinate system is top-down (Y=0 is the top of the page). Set CoordinateOrigin to use native PDF bottom-up coordinates instead.

// Default: Y=0 at top, Y increases downward
page.CoordinateOrigin = CoordinateOrigin.TopDown;

// Native PDF: Y=0 at bottom, Y increases upward
page.CoordinateOrigin = CoordinateOrigin.BottomUp;

In BottomUp mode, Y values map directly to PDF coordinates: text Y is the baseline, and rectangle/image Y is the bottom-left corner. Tables (DrawTable) always use top-down layout internally.

Text

page.DrawText("Hello", 50, 50);
page.DrawText("Bold red", 50, 70, PdfFont.HelveticaBold, 14, PdfColor.Red, TextAlignment.Left, underline: true);

// Hyperlink — text becomes clickable
page.DrawText("Visit Example", 50, 90, PdfFont.Helvetica, 12, PdfColor.Blue,
    underline: true, link: "https://example.com");

// Wrapped text box — returns Y position after last line
float nextY = page.DrawTextBox("Long paragraph...", 50, 110, width: 400,
    font: PdfFont.TimesRoman, fontSize: 11, lineSpacing: 1.4f);

// Wrapped text box with hyperlink (each wrapped line is clickable)
float nextY1 = page.DrawTextBox("Click here for full terms and conditions", 50, 160, width: 200,
    link: "https://example.com/terms");

// Rich text (mixed fonts/sizes/colors on one line)
page.DrawRichText(new[] {
    new TextSpan("Normal "),
    new TextSpan("bold", PdfFont.HelveticaBold),
    new TextSpan(" and ", PdfFont.Helvetica, 12, PdfColor.DarkGray),
    new TextSpan("red", PdfFont.Helvetica, 12, PdfColor.Red, underline: true)
}, 50, 200);

// Rich text with hyperlinks — individual spans can be links
page.DrawRichText(new[] {
    new TextSpan("See "),
    new TextSpan("our docs", PdfFont.Helvetica, 12, PdfColor.Blue,
        underline: true, link: "https://docs.example.com"),
    new TextSpan(" for details.")
}, 50, 220);

// Rich text box (mixed formatting with word wrap)
float nextY2 = page.DrawRichTextBox(spans, 50, 240, width: 400);

// Measure text width
float w = page.MeasureText("Hello", PdfFont.Helvetica, 12);

// Rotated text — angle in degrees, clockwise
page.DrawText("Rotated 45°", 300, 100, fontSize: 16, rotation: 45);
page.DrawTextBox("Rotated text box", 300, 200, width: 150, rotation: 90);
Method Returns Description
DrawText(...) void Single line of text
DrawTextBox(...) float Wrapped text; returns Y after last line
DrawRichText(...) void Single line with mixed formatting
DrawRichTextBox(...) float Wrapped mixed-format text
MeasureText(text, font, size) float Width of text in points

TextSpan is used with DrawRichText and DrawRichTextBox for mixed-format text:

new TextSpan("hello")                                          // defaults: Helvetica 12pt black
new TextSpan("bold", PdfFont.HelveticaBold, 14)                // custom font/size
new TextSpan("fancy", PdfFont.TimesItalic, 12, PdfColor.Blue, underline: true, opacity: 0.8f)
new TextSpan("click me", PdfFont.Helvetica, 12, PdfColor.Blue, underline: true,
    link: "https://example.com")                               // hyperlink

TextAlignment: TextAlignment.Left (default), TextAlignment.Center, TextAlignment.Right

Shapes

page.DrawLine(50, 100, 500, 100, PdfColor.Black, lineWidth: 0.5f);
page.DrawRectangle(50, 110, 200, 80, PdfColor.DarkGray, lineWidth: 1f);
page.DrawFilledRectangle(50, 200, 200, 80, PdfColor.Rgb(230, 240, 255), PdfColor.Black, lineWidth: 0.5f);

// Rotated shapes — angle in degrees, clockwise
page.DrawFilledRectangle(300, 100, 80, 40, PdfColor.Blue, rotation: 45);
page.DrawRectangle(300, 200, 80, 80, PdfColor.Green, lineWidth: 2, rotation: 30);
page.DrawLine(100, 300, 300, 300, PdfColor.Red, lineWidth: 2, rotation: 90);

Images

var logo = PdfImage.FromFile("logo.png");
page.DrawImage(logo, x: 50, y: 30, width: 120, height: 40);
page.DrawImage(logo, x: 50, y: 30, width: 120, height: 40, opacity: 0.5f);
page.DrawImage(logo, x: 50, y: 30, width: 120, height: 40, scaleMode: ImageScaleMode.Fit);

// Rotated image — angle in degrees, clockwise
page.DrawImage(logo, x: 200, y: 100, width: 120, height: 40, rotation: 90);

JPEG and PNG are supported (auto-detected). PNG transparency is preserved. EXIF orientation tags are automatically applied.

The scaleMode parameter controls how the image is scaled to fit the target rectangle:

Mode Aspect Ratio Description
Stretch (default) Ignored Fills the entire area exactly; image may be distorted
Fit Preserved Scales to fit inside the area; image is centered with possible letterboxing
Fill Preserved Scales to cover the entire area; image is centered and overflow is clipped

Rotation

All drawing methods (DrawText, DrawRichText, DrawTextBox, DrawRichTextBox, DrawImage, DrawLine, DrawRectangle, DrawFilledRectangle) accept an optional rotation parameter:

  • Angle is in degrees, clockwise (matching CSS convention)
  • Origin is the element's (x, y) position
  • Default is 0 (no rotation)
// Watermark-style diagonal text
page.DrawText("DRAFT", 300, 400, PdfFont.HelveticaBold, 72,
    PdfColor.Rgb(200, 200, 200), TextAlignment.Center, opacity: 0.3f, rotation: -45);

Tables

float endY = page.DrawTable(table, x: 50, y: 200, bottomMargin: 50);

Tables that exceed the page height automatically continue on new pages with repeated headers. By default, continuation pages start the table at the same Y position as the first page. Use continuationY to start higher on subsequent pages:

// Table starts at y=300 on page 1, but at y=50 on continuation pages
page.DrawTable(table, x: 50, y: 300, continuationY: 50);

Lists

DrawList renders a hierarchical list and returns a (PdfPage page, float y) tuple indicating where rendering ended, so you can continue drawing below it — including on a different page if the list overflowed.

var items = new[]
{
    new ListItem("Introduction"),
    new ListItem("Installation",
        new ListItem("Windows"),
        new ListItem("macOS"),
        new ListItem("Linux")),
    new ListItem("Configuration")
};

// Bullet list (default)
var (nextPage, nextY) = page.DrawList(items, x: 50, y: 100, width: 450);

// Numbered list
var (nextPage, nextY) = page.DrawList(items, x: 50, y: 100, width: 450,
    style: ListStyle.Numbered);

// Lowercase Roman numerals (i, ii, iii…)
var (nextPage, nextY) = page.DrawList(items, x: 50, y: 100, width: 450,
    style: ListStyle.RomanLower);

// Uppercase Roman numerals (I, II, III…)
var (nextPage, nextY) = page.DrawList(items, x: 50, y: 100, width: 450,
    style: ListStyle.RomanUpper);

// Multi-page list — automatically flows to new pages
var (lastPage, endY) = page.DrawList(items, x: 50, y: 100, width: 450,
    bottomMargin: 50, continuationY: 50);

Each item can override the style and bullet symbol used for its children:

var items = new[]
{
    // Children use numbered style
    new ListItem("Chapter 1", ListStyle.Numbered,
        new ListItem("Section 1.1"),
        new ListItem("Section 1.2")),

    // Children use Roman numerals with a custom bullet symbol at the next level
    new ListItem("Chapter 2", ListStyle.RomanUpper,
        new ListItem("Part I", ListStyle.RomanLower,
            new ListItem("Sub-part a"))),
};

To use a custom bullet symbol from Symbol or ZapfDingbats, pass a TextSpan as the bullet:

// Custom top-level bullet
var (nextPage, nextY) = page.DrawList(items, x: 50, y: 100, width: 450,
    bullet: new TextSpan("»", PdfFont.Helvetica));

// Per-level custom symbols via ChildrenBullet
new ListItem("Top item", ListStyle.Bullet, new TextSpan("‣", PdfFont.Helvetica),
    new ListItem("Child item"))
Parameter Default Description
items required Array of ListItem to render
x required Left edge in points
y required Top of first item in points
width required Available width for text wrapping
style Bullet Bullet, Numbered, RomanLower, or RomanUpper
bottomMargin 0 Distance from page bottom before a new page is added
font Helvetica Font for item text and numbered markers
fontSize 12 Font size in points
lineSpacing 1.2 Line spacing multiplier
color Black Text and marker color
bullet Bullet symbol (used when style is Bullet)
startNumber 1 Starting counter value (numbered/Roman styles)
indentPerLevel 20 Horizontal indent per nesting level in points
continuationY same as y Y position on continuation pages

PdfTable

Build tables with a fluent API or import from CSV.

var table = new PdfTable(100, 200, 100, 100)  // column widths in points
    .SetHeaders("ID", "Description", "Qty", "Price")
    .AddRow("1001", "Widget", "5", "$12.50")
    .AddRow("1002", "Gadget", "2", "$24.00");

table.SetColumnAlignment(2, TextAlignment.Right);
table.SetColumnAlignment(3, TextAlignment.Right);
table.AlternateRowShading = true;
Property Default Description
HeaderFont HelveticaBold Font for header row
HeaderFontSize 10 Font size for header row
CellFont Helvetica Font for body cells
CellFontSize 10 Font size for body cells
HeaderBackground LightGray Header row background color
HeaderTextColor Black Header text color
BorderColor Black Border color
BorderWidth 0.5 Border line width in points
CellPadding 4 Padding inside cells in points
TextColor Black Body text color
AlternateRowShading false Enable zebra-stripe rows
AlternateRowColor RGB(0.95, 0.95, 0.95) Alternate row background
LineSpacing 1.2 Line spacing multiplier for cell text

CSV import:

var table = PdfTable.FromCsv("data.csv");
var table = PdfTable.FromCsv("data.csv", firstRowIsHeader: true, delimiter: ',',
    columnWidths: new float[] { 80, 200, 80, 80 });
var table = PdfTable.FromCsvString(csvContent, totalWidth: 500);

PdfImage

var img = PdfImage.FromFile("photo.jpg");
var img = PdfImage.FromBytes(byteArray);
var img = PdfImage.FromStream(stream);

int w = img.PixelWidth;   // display width (EXIF-adjusted)
int h = img.PixelHeight;  // display height (EXIF-adjusted)

PdfColor

var c1 = PdfColor.Rgb(51, 102, 204);        // 0-255 integers
var c2 = PdfColor.Rgb(0.2f, 0.4f, 0.8f);    // 0.0-1.0 floats
var c3 = PdfColor.Cmyk(1f, 0f, 0f, 0f);     // CMYK
var c4 = PdfColor.Gray(0.5f);               // grayscale

Predefined colors:

Name Value Color Space
Black K=1 CMYK
White 255, 255, 255 RGB
Red 255, 0, 0 RGB
Green 0, 255, 0 RGB
Blue 0, 0, 255 RGB
Yellow Y=1 CMYK
Cyan C=1 CMYK
Magenta M=1 CMYK
Orange 255, 165, 0 RGB
Purple 128, 0, 128 RGB
Pink 255, 192, 203 RGB
Brown 139, 69, 19 RGB
Gold 255, 215, 0 RGB
Navy 0, 0, 128 RGB
Teal 0, 128, 128 RGB
Maroon 128, 0, 0 RGB
Olive 128, 128, 0 RGB
Coral 255, 127, 80 RGB
Crimson 220, 20, 60 RGB
Indigo 75, 0, 130 RGB
Silver 192, 192, 192 RGB
MediumGray 128, 128, 128 RGB
LightGray 212, 212, 212 RGB
DarkGray 84, 84, 84 RGB

PageSize

Predefined: PageSize.A4, A3, A5, Letter, Legal

var landscape = PageSize.A4.Landscape();
var custom = new PageSize(400, 600);  // width x height in points

Bookmarks

Add bookmarks (outlines) that appear in the PDF viewer's navigation panel. Bookmarks can be nested to create a hierarchical table of contents.

// Top-level bookmarks
var ch1 = doc.AddBookmark("Chapter 1", page1);
var ch2 = doc.AddBookmark("Chapter 2", page2);

// Nested bookmarks — point to a specific Y position on the page
ch1.AddBookmark("Installation", page1, y: 150);
ch1.AddBookmark("Configuration", page1, y: 350);

// Deeper nesting
var advanced = ch2.AddBookmark("Advanced Topics", page3);
advanced.AddBookmark("Performance Tuning", page3, y: 200);
Method Description
PdfDocument.AddBookmark(title, page, y?) Add a top-level bookmark. Returns the bookmark for nesting children.
PdfBookmark.AddBookmark(title, page, y?) Add a child bookmark under this one.

When y is omitted the bookmark fits the entire page. When y is provided the viewer scrolls to that vertical position (in the page's coordinate system).

Invoice example output

using SimpleTinyPDF;

var doc = new PdfDocument { Title = "Invoice #1042" };
var page = doc.AddPage(PageSize.Letter);

// Company logo
var logo = PdfImage.FromFile("company-logo.png");
page.DrawImage(logo, 50, 40, 150, 50);

// Company info (right-aligned)
page.DrawText("Acme Corp", 562, 40, PdfFont.HelveticaBold, 14, alignment: TextAlignment.Right);
page.DrawText("123 Main Street, Springfield", 562, 58, PdfFont.Helvetica, 9,
    PdfColor.DarkGray, TextAlignment.Right);
page.DrawText("Tel: (555) 123-4567", 562, 70, PdfFont.Helvetica, 9,
    PdfColor.DarkGray, TextAlignment.Right);

// Divider
page.DrawLine(50, 100, 562, 100, PdfColor.LightGray, 1f);

// Invoice title
page.DrawText("INVOICE", 50, 120, PdfFont.HelveticaBold, 24, PdfColor.Rgb(51, 51, 51));

// Invoice details
page.DrawText("Invoice #: 1042", 50, 160, PdfFont.Helvetica, 10);
page.DrawText("Date: April 16, 2026", 50, 175, PdfFont.Helvetica, 10);
page.DrawText("Due: May 16, 2026", 50, 190, PdfFont.Helvetica, 10);

// Bill to
page.DrawText("Bill To:", 350, 160, PdfFont.HelveticaBold, 10);
page.DrawText("John Smith", 350, 175, PdfFont.Helvetica, 10);
page.DrawText("456 Oak Avenue", 350, 190, PdfFont.Helvetica, 10);
page.DrawText("Shelbyville, IL 62565", 350, 205, PdfFont.Helvetica, 10);

// Line items table
var table = new PdfTable(240, 80, 80, 112)
    .SetHeaders("Description", "Quantity", "Unit Price", "Amount")
    .AddRow("Web Development Services", "40 hrs", "$75.00", "$3,000.00")
    .AddRow("UI/UX Design", "16 hrs", "$85.00", "$1,360.00")
    .AddRow("Hosting Setup", "1", "$200.00", "$200.00");

table.SetColumnAlignment(1, TextAlignment.Center);
table.SetColumnAlignment(2, TextAlignment.Right);
table.SetColumnAlignment(3, TextAlignment.Right);
table.HeaderBackground = PdfColor.Rgb(51, 51, 51);
table.HeaderTextColor = PdfColor.White;
table.AlternateRowShading = true;

float tableEndY = page.DrawTable(table, 50, 240);

// Totals
float totalsX = 370;
float totalsY = tableEndY + 15;
page.DrawText("Subtotal:", totalsX, totalsY, PdfFont.Helvetica, 10);
page.DrawText("$4,560.00", 562, totalsY, PdfFont.Helvetica, 10, alignment: TextAlignment.Right);
page.DrawText("Tax (8%):", totalsX, totalsY + 18, PdfFont.Helvetica, 10);
page.DrawText("$364.80", 562, totalsY + 18, PdfFont.Helvetica, 10, alignment: TextAlignment.Right);
page.DrawLine(totalsX, totalsY + 34, 562, totalsY + 34, PdfColor.Black, 0.5f);
page.DrawText("Total Due:", totalsX, totalsY + 42, PdfFont.HelveticaBold, 12);
page.DrawText("$4,924.80", 562, totalsY + 42, PdfFont.HelveticaBold, 12, alignment: TextAlignment.Right);

// Footer note
page.DrawText("Payment is due within 30 days. Thank you for your business!",
    306, 720, PdfFont.HelveticaOblique, 9, PdfColor.DarkGray, TextAlignment.Center);

doc.Save("invoice-1042.pdf");

Example: CSV to Table Report

CSV report example output

using SimpleTinyPDF;

// Suppose "sales-data.csv" contains:
//   Region,Product,Q1,Q2,Q3,Q4
//   North,Widgets,1200,1350,1100,1500
//   South,Widgets,980,1050,1200,1180
//   ...

var doc = new PdfDocument { Title = "Quarterly Sales Report" };
var page = doc.AddPage(PageSize.Letter.Landscape());

// Report header
page.DrawText("Quarterly Sales Report", 50, 40, PdfFont.HelveticaBold, 20);
page.DrawText("Generated: April 16, 2026", 50, 65, PdfFont.Helvetica, 10, PdfColor.DarkGray);
page.DrawLine(50, 85, 742, 85, PdfColor.LightGray, 1f);

// Import CSV directly into a table
var table = PdfTable.FromCsv("sales-data.csv",
    firstRowIsHeader: true,
    columnWidths: new float[] { 100, 120, 90, 90, 90, 90 });

// Style it
table.HeaderBackground = PdfColor.Rgb(0, 51, 102);
table.HeaderTextColor = PdfColor.White;
table.HeaderFont = PdfFont.HelveticaBold;
table.HeaderFontSize = 11;
table.CellFont = PdfFont.Helvetica;
table.CellFontSize = 10;
table.AlternateRowShading = true;
table.AlternateRowColor = PdfColor.Rgb(235, 241, 250);
table.CellPadding = 6;

// Right-align the numeric columns
table.SetColumnAlignment(2, TextAlignment.Right);
table.SetColumnAlignment(3, TextAlignment.Right);
table.SetColumnAlignment(4, TextAlignment.Right);
table.SetColumnAlignment(5, TextAlignment.Right);

// Draw — if the data has many rows, it will automatically
// continue on new pages with the header row repeated.
// Use continuationY to start the table higher on subsequent pages.
page.DrawTable(table, 50, 100, bottomMargin: 50, continuationY: 50);

doc.Save("sales-report.pdf");

Font Limitations

SimpleTinyPDF uses the 14 standard PDF Type 1 fonts. These fonts are built into every PDF viewer and require no embedding, which keeps the library simple and output files small.

Available font families:

Family Variants
Helvetica Regular, Bold, Oblique, BoldOblique
Times Roman, Bold, Italic, BoldItalic
Courier Regular, Bold, Oblique, BoldOblique
Symbol (symbol characters)
ZapfDingbats (decorative symbols)

Character support:

  • Full WinAnsiEncoding coverage (standard Latin characters, digits, punctuation)
  • Extended European characters including Polish, Czech, Slovak, and Hungarian diacritics (e.g. ą, ć, ę, ł, ň, ř, š, ž, ő, ű)
  • Characters not in the supported set are replaced with a fallback; they will not cause an error but may not render as expected

What is not supported:

  • Custom font embedding (TrueType, OpenType, WOFF)
  • CJK characters (Chinese, Japanese, Korean)
  • Arabic, Hebrew, or other right-to-left scripts
  • Emoji

If your project requires custom fonts or broad Unicode support, consider a full-featured PDF library such as QuestPDF, iTextSharp, or PdfSharp.

Version History

Version Date Changes
0.52 May 2026 Add hierarchical lists with nesting, text wrapping, multi-page flow, and four list styles (Bullet, Numbered, RomanLower, RomanUpper)
0.51 May 2026 Add rotation support for text, images, and shapes
0.50 April 2026 Initial beta release

Development Notes

This library was written as an exploration of what my increasingly good friend Claude could acomplish. I continue to be amazed at what generative AI can do.

Sample image assets in the tests project are taken from https://www.publicdomainpictures.net/

License

MIT

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.60.0 57 6/11/2026
0.58.0 76 6/5/2026
0.57.0 100 5/31/2026
0.56.0 92 5/30/2026
0.55.0 123 5/22/2026
0.54.0 108 5/22/2026
0.53.0 100 5/14/2026
0.52.0 104 5/10/2026
0.51.0 101 5/7/2026
0.5.0 100 5/4/2026