Building PDFs with the Core API
The core Docotic.Pdf API provides full control over PDF creation. It lets you draw text, images, and vector graphics on canvases provided by PDF pages, XObjects, and tiling patterns.
You control every coordinate and every drawing operation, and this gives you maximum control over the layout of your PDF pages. For graphics-heavy or custom‑layout documents where precision matters, this level of control is indispensable.
With the Core API, you can also add annotations, form fields, layers, bookmarks, and more to the created PDFs. The API is the most flexible and powerful way to create PDFs in .NET provided by Docotic.Pdf.

See the article that outlines every method for creating PDFs if you want a broader overview of all approaches available in Docotic.Pdf, including those beyond the Core API.
Before you begin
Before you start working with the Core API, set up your environment by installing Docotic.Pdf and requesting a license key.
Install Docotic.Pdf
To create PDF documents in C# or VB.NET, start by installing the library from NuGet.
Install-Package BitMiracle.Docotic.Pdf
If you prefer to install the library manually, download the ZIP archive with the library binaries,
unpack it, and add a reference from your project to the BitMiracle.Docotic.Pdf.dll.
Get a license key
A license key is required to use the library. To try the library, request a free time-limited license key by filling out the form on the Docotic.Pdf download page.
Basic PDF creation examples
This section provides basic examples that demonstrate how to create PDF documents with the Core API, first in C# and then in VB.NET.
How to create PDF in C#
Now that you have installed Docotic.Pdf and obtained a license key, it is easy to create a PDF with the Core API.
BitMiracle.Docotic.LicenseManager.AddLicenseData("PUT-LICENSE-HERE");
using var pdf = new PdfDocument();
pdf.Save("empty.pdf");
The code shows how to create an empty PDF file. The first line adds a license key. Without a
license, you will get an exception on the line that instantiates a PdfDocument. The last line
saves the document to a PDF file.
The internal structure of the created file depends on the save options. In this example, the code
uses the Save method overload that saves with the default options. To understand what these
defaults do and when you may want to adjust them, see the section on save
options.
To honor programming tradition, the second example demonstrates a Hello, world! created with the Core API.
using var pdf = new PdfDocument();
var page = pdf.Pages[0];
page.Canvas.DrawString(50, 50, "Hello, world!");
pdf.Save("hello.pdf");
The code places the classic phrase on the canvas of the first page in the document, starting at the explicitly specified position. The line uses the default font and the default font size. Continue reading for additional information on working with PDF canvas.
Using VB.NET to create PDF
VB.NET code to create a PDF looks very similar to the code from the previous section.
Using pdf As New PdfDocument()
Dim page = pdf.Pages(0)
page.Canvas.DrawString(50, 50, "Hello, world!")
pdf.Save("hello.pdf")
End Using
The previous section, which includes a C# example, explains what the code does and how it works.
Working with PDF canvas
To change a canvas in a PDF document, use the Canvas API. It is a subset of the Core API.
The Canvas API uses an absolute positioning model. You choose the coordinates, and the canvas draws exactly where you tell it. The coordinate system places the origin in the top-left corner of the page. Coordinates increase to the right along the X-axis and downward along the Y-axis.
(0,0) ──► X
│
│
▼
Y
Drawing text
In the PdfCanvas class, Docotic.Pdf provides two primary methods for rendering text: DrawString
and DrawText. Both methods use the current canvas font, so it is recommended to set the font you
need before drawing any text.
Using DrawString
DrawString always draws a single line of text. The method starts drawing from the current text position of the canvas unless you use an overload with explicit coordinates. Some overloads let you specify additional options that control how the line of text is drawn.
You already saw a simple example of DrawString in the Hello, world! snippet. Here is another
example that uses string‑drawing options to
underline text.
using var pdf = new PdfDocument();
var canvas = pdf.Pages[0].Canvas;
canvas.DrawString(50, 50, "This text is underlined", new PdfStringDrawingOptions
{
Underline = true,
});
pdf.Save("underlined-text.pdf");
Using DrawText
DrawText can render multiple lines of text within specified rectangle. The method handles line breaks and clips text that does not fit into the allowed space. The text-drawing options define the horizontal and vertical alignment of text and other aspects of how the text is positioned and rendered.
Here is how to draw text in a PDF using C#:
using var pdf = new PdfDocument();
const string LongString = "Lorem ipsum dolor sit amet, consectetur adipisicing elit";
var multiLineOptions = new PdfTextDrawingOptions(new PdfRectangle(70, 70, 40, 150))
{
HorizontalAlignment = PdfTextAlign.Left,
VerticalAlignment = PdfVerticalAlign.Top
};
var canvas = pdf.Pages[0].Canvas;
canvas.DrawText(LongString, multiLineOptions);
pdf.Save("drawtext.pdf");
For fine‑tuning text appearance, you can adjust the following canvas properties:
- character spacing
- word spacing
- text scaling
- text rise (baseline shift)
- rendering mode (fill, stroke, fill and stroke, and others)
For practical examples of text‑related methods and properties, consult the Text sample group.
Adding and using fonts
Unless you are fine with the default Helvetica font, you should add the fonts you need to the PDF to ensure that your text appears exactly as intended.
Docotic.Pdf can add Type1, TrueType, Compact Font Format (CFF), and OpenType fonts from:
- the collection of system‑installed fonts
- external files and streams
In addition, you can use the 14 built‑in Type1 fonts, available in any PDF viewer.
To use a font in your PDF, create a PdfFont object by using the CreateFont or
CreateFontFromFile method of the corresponding PdfDocument object. Then assign the font to the
canvas before drawing text. It is also a good idea to set the font size.
using var pdf = new PdfDocument();
var canvas = pdf.Pages[0].Canvas;
var font = pdf.CreateFont("NSimSun");
canvas.Font = font;
canvas.FontSize = 14;
canvas.DrawString(10, 50, "Olá. 你好. Hello, Unicode!");
font.RemoveUnusedGlyphs();
pdf.Save("unicode-text.pdf");
The font must contain glyphs for all characters in the text you are trying to draw. Otherwise, you
will get a CannotShowTextException. Use PdfFont.ContainsGlyphsForText to verify that the font
contains all required glyphs.
Unicode support depends on the font type. Type 1 fonts support only the Latin character set and encoding, with one exception. The built-in Symbol and ZapfDingbats fonts provide mathematical, Greek, and decorative symbols.
TrueType, CFF, and OpenType fonts usually support Unicode, but they may not include glyphs for all Unicode characters.
Docotic.Pdf tries to embed as few font bytes as possible to keep the output PDF small. However,
when a document uses fonts with many glyphs, the resulting file may still be relatively large. Use
PdfFont.RemoveUnusedGlyphs to minimize the number of bytes added by embedded fonts.
Calculating text dimensions
Because the Canvas API uses absolute positioning, it is often necessary to know how much space a
piece of text will occupy before you draw it. This is especially important when you output text in
several takes, such as splitting long strings, aligning text precisely, or avoiding overlaps with
other content. The PdfCanvas class provides several methods that help you measure text using the
currently selected font and font size.
Use PdfCanvas.MeasureText to obtain both the width and height of a string as it would appear on
the canvas. Typical use cases include:
- determining whether text fits into a given area
- calculating line breaks manually
- positioning text blocks relative to each other
For cases where you are centering or right-aligning text and only need the horizontal extent, use
PdfCanvas.GetTextWidth. To know the height of a line of text for the current font, use
PdfCanvas.GetTextHeight.
Drawing images
To draw an image on a PDF canvas, create a PdfImage object first and then draw that object using
the PdfCanvas.DrawImage method.
Here is how to add an image to a PDF in C#:
using var pdf = new PdfDocument();
var canvas = pdf.Pages[0].Canvas;
var image = pdf.CreateImage("image.png");
canvas.DrawImage(image, 10, 50);
pdf.Save("image.pdf");
The code creates an image object by using the CreateImage method of the corresponding
PdfDocument object and draws the image on the canvas of the first page.
Read about creating PDFs from images for details on supported image formats and more advanced image‑to‑PDF techniques.
Using vector graphics
Docotic.Pdf lets you draw straight lines, Bezier curves, and common geometric shapes directly on a
PDF canvas by using the methods of the PdfCanvas class. Use methods beginning with Draw (for
example, DrawLineTo, DrawCircle, DrawRectangle) to place visible marks on the canvas.
Lines and curves are rendered using the current pen, defined
through PdfCanvas.Pen, which specifies stroke color, width, and other drawing properties.
Depending on the drawing mode, shapes can be stroked, filled, or stroked and then filled. The
current brush, accessed through PdfCanvas.Brush, is used to
fill the interior of shapes.
using var pdf = new PdfDocument();
var canvas = pdf.Pages[0].Canvas;
canvas.DrawCircle(new PdfPoint(60, 100), 40);
canvas.DrawRectangle(
new PdfRectangle(300, 60, 110, 70),
PdfDrawMode.Fill);
canvas.CurrentPosition = new PdfPoint(150, 90);
canvas.DrawCurveTo(new PdfPoint(180, 60), new PdfPoint(230, 120), new PdfPoint(250, 90));
pdf.Save("curve-and-shapes.pdf");
Every PDF canvas maintains a graphics state, which includes the pen, brush, font, and current
positions. Use SaveState to preserve the current state and RestoreState to revert to a previous
state. Besides reverting temporary transformations and similar changes, restoring state is the only
way to remove clipping once applied.
Graphics paths let you build complex shapes from lines, curves, and simpler shapes without drawing
them immediately. Use Append methods such as AppendLineTo or AppendRectangle to add segments
to the current path. Paths do not produce visible output until you explicitly fill or stroke them.
You can use any constructed graphics path as a clipping region to restrict subsequent drawing operations. Clipping remains active until the graphics state is restored.
Practical, runnable examples of working with vector graphics are available in the Graphics section of the sample repository.
Setting colors and transparency
You can change stroke and fill colors through the pen and brush of a PDF canvas. To do this, use
PdfPen.Color and PdfBrush.Color.

Supported device‑dependent color spaces include Gray, RGB, and CMYK, represented by PdfGrayColor,
PdfRgbColor, and PdfCmykColor.
using var pdf = new PdfDocument();
var canvas = pdf.Pages[0].Canvas;
canvas.Pen.Color = new PdfRgbColor(30, 60, 160);
canvas.Pen.Width = 3;
canvas.Brush.Color = new PdfCmykColor(0, 20, 5, 0);
canvas.DrawRectangle(
new PdfRectangle(50, 50, 100, 40),
PdfDrawMode.FillAndStroke);
pdf.Save("fill-and-stroke-colors.pdf");
Docotic.Pdf supports CIE‑based, device‑independent color spaces, including L*a*b* colors and ICC‑based calibrated colors. The Core API also supports spot colors and separation color spaces for workflows that require custom inks or channel‑specific output.
The sample code below demonstrates how to create Lab colors, profile‑based colors, and spot colors. To run the example, first download the ICC profile it uses.
using var pdf = new PdfDocument();
var canvas = pdf.Pages[0].Canvas;
var labColorSpace = new PdfLabColorSpace(pdf, [0.5, 1, 0.5]);
canvas.Pen.Color = new PdfLabColor(labColorSpace, 50, -50, 50);
canvas.Pen.Width = 3;
var rgbProfile = pdf.CreateColorProfile("AdobeCompat-v2.icc");
canvas.Brush.Color = new PdfRgbColor(rgbProfile, 210, 105, 30);
canvas.DrawRectangle(
new PdfRectangle(50, 50, 100, 40),
PdfDrawMode.FillAndStroke);
var tintTransform = new PdfExponentialFunction(
pdf, 1, [0d, 0, 0, 0], [0, 0.8, 0.73, 0.25], [0d, 1]);
var separationColorSpace = new PdfSeparationColorSpace(
pdf, "BLOODRED", new PdfCmykColorSpace(), tintTransform);
canvas.Pen.Color = new PdfSpotColor(1.0, separationColorSpace);
canvas.DrawCircle(new PdfPoint(100, 70), 60);
pdf.Save("using-special-colors.pdf");
You can also stroke and fill shapes using tiling patterns. A pattern is defined by a pattern cell drawn on its own canvas. Two types exist:
- Colored patterns. Their cells define its own colors.
- Uncolored patterns. Their cells are tinted by the pen/brush color at use time.
To use a pattern, create one by using CreateColoredPattern or CreateUncoloredPattern of the
corresponding PdfDocument object. Then apply the pattern via PdfPen.Pattern and/or
PdfBrush.Pattern. Check the sample code for creating and using patterns in the
sample repository.
Semi‑transparent colors let you draw shapes, text, and images with varying opacity. Use
PdfPen.Opacity and PdfBrush.Opacity to produce translucent colors.
In addition, blend modes control how transparent content
interacts with what's beneath it. To change the blend mode of a canvas, use PdfCanvas.BlendMode.
Adding and customizing pages
Docotic.Pdf exposes the PdfDocument.Pages collection, which you can use to manage all pages in a
document. In the PdfDocument class, there are two primary methods that allow you to add new
pages: AddPage and InsertPage.
Use AddPage() to append a new page at the end of the document. To insert a page at any position,
use InsertPage(index). Both methods return the newly created PdfPage instance.
Every new page has the default size of 595 x 842 user space units. It's the size of an A4 sheet. In most cases, the user space unit in PDF is 1/72 of an inch. Or, to put it differently, one user space unit equals one pixel when the resolution of the page is 72 pixels per inch.
You can change the size of a page at any time by setting its width and/or height to a specific number of user space units.
using var pdf = new PdfDocument();
var page = pdf.Pages[0];
page.Width = 600;
page.Height = 800;
Another option is to use one of the predefined sizes:
page.Size = PdfPaperSize.Ledger;
It's also possible to change page orientation from portrait to landscape, and to rotate a page by 90°, 180°, or 270° clockwise.
page.Orientation = PdfPaperOrientation.Landscape;
page.Rotation = PdfRotation.Rotate180;
Beyond setting page width, height, or a predefined size, it is also possible to adjust the page size together with cropping or resizing the existing content.
Reusing content with XObjects
A PDF XObject is a container with vector graphics, images, and text. Each XObject has its own canvas, so you can create XObjects as complex as regular PDF pages.
XObjects are similar to vector images. You can reuse the same object on multiple pages without recreating the content or inflating the size of the document. You can scale and rotate such objects without introducing visual artefacts. Because of these qualities, XObjects are ideal for repeated elements such as logos, illustrations, backgrounds, watermarks, and other recurring graphics.
Creating and using XObjects
To create an XObject, use the PdfDocument.CreateXObject method. Change the width and height of
the object, if necessary. Then fill the canvas with text, images, and graphics in the same way as a
regular page canvas.
Use the PdfCanvas.DrawXObject method in your C# or VB.NET code to add the XObject to other
canvases. Note that you can draw XObjects on canvases provided by both pages and other XObjects.
Here is C# code that creates an XObject with an illustration and draws the illustration on two pages.
using var pdf = new PdfDocument();
var xobj = pdf.CreateXObject();
var options = new PdfTextDrawingOptions(new PdfRectangle(0, 0, 100, 50))
{
HorizontalAlignment = PdfTextAlign.Center,
VerticalAlignment = PdfVerticalAlign.Center,
};
xobj.Canvas.FontSize = 16;
xobj.Canvas.DrawText("Company Logo", options);
xobj.Canvas.DrawRectangle(options.Bounds);
var page1 = pdf.Pages[0];
page1.Canvas.DrawXObject(xobj, 100, 100);
var page2 = pdf.AddPage();
page2.Canvas.DrawXObject(xobj, 200, 200);
pdf.Save("using-xobjects.pdf");
Transforming pages with XObjects
XObjects also enable scenarios that go beyond simple reuse of graphics. One common example is combining two existing PDF pages into a single, larger page. By turning each source page into an XObject, you can draw them side by side on a new canvas, effectively creating a merged two-page spread. This approach gives you full control over positioning, spacing, and scaling, making it easy to build comparison layouts, book spreads, or multi‑page previews.
The same technique can be applied when you need to resize PDF pages. Instead of redrawing or reconstructing the content, you can create an XObject from the original page and draw it scaled to the new size. This allows you to shrink oversized pages, enlarge small ones, or normalize a mixed‑size document with minimal effort.
Scope and constraints of the Core API
The Core API offers precise, low‑level control over PDF creation, but it does not provide any automatic layout features. There are no built‑in margins, headers, footers, or page‑breaking logic, and all content must be positioned manually. Text measurement and splitting across pages are responsibilities left entirely to your code, making this the most manual approach to creating PDFs.
Automatic layout, including support for tables, paragraphs, and page breaking, is available through the higher‑level Layout API.
Conclusion
The core Docotic.Pdf API provides full control over PDF creation. It lets you draw text, images, and vector graphics on canvases provided by PDF pages, XObjects, and tiling patterns.
The API is designed for scenarios that require precise, low‑level control: you position every element explicitly, manage text measurement and page splitting yourself, and manipulate graphics state, colors, and transparency directly.
Overall, the Core API is the most flexible tool for building PDFs when precision and control are the priority.