LibPDF

PDFPage

Page class for accessing dimensions, drawing content, and extracting text.

PDFPage

The PDFPage class represents a single page in a PDF document. It provides access to page properties, drawing operations, and text extraction.

const pdf = await PDF.load(bytes);
const page = await pdf.getPage(0);
if (!page) throw new Error("Page not found");

console.log(`Size: ${page.width} x ${page.height}`);
console.log(`Rotation: ${page.rotation}`);

Properties

ref

The page reference (for low-level operations).

Type: PdfRef (readonly)


dict

The page dictionary (for low-level operations).

Type: PdfDict (readonly)


index

The page index (0-based).

Type: number (readonly)


width

Page width in points (accounting for rotation).

Type: number (readonly)

const width = page.width; // e.g., 612 for US Letter

height

Page height in points (accounting for rotation).

Type: number (readonly)

const height = page.height; // e.g., 792 for US Letter

rotation

Page rotation in degrees (0, 90, 180, or 270).

Type: 0 | 90 | 180 | 270 (readonly)

if (page.rotation === 90) {
  console.log("Page is rotated 90 degrees clockwise");
}

isLandscape

Whether the page is in landscape orientation.

Type: boolean (readonly)


isPortrait

Whether the page is in portrait orientation.

Type: boolean (readonly)


Page Boxes

PDF pages have multiple "boxes" defining different regions. Each returns a Rectangle with { x1, y1, x2, y2 } coordinates.

getMediaBox()

Get the MediaBox (page boundary). Falls back to US Letter if not defined.

Returns: Rectangle


getCropBox()

Get the CropBox (visible region). Falls back to MediaBox if not defined.

Returns: Rectangle


getBleedBox()

Get the BleedBox (printing bleed area). Falls back to CropBox if not defined.

Returns: Rectangle


getTrimBox()

Get the TrimBox (intended dimensions after trimming). Falls back to CropBox if not defined.

Returns: Rectangle


getArtBox()

Get the ArtBox (meaningful content area). Falls back to CropBox if not defined.

Returns: Rectangle


setRotation(degrees)

Set the page rotation.

ParamTypeDescription
degrees0 | 90 | 180 | 270Rotation in degrees
page.setRotation(90);

Text Drawing

drawText(text, options?)

Draw text on the page.

ParamTypeDefaultDescription
textstringrequiredText to draw
[options]DrawTextOptions
[options.x]number0X position from left
[options.y]number0Y position from bottom
[options.font]string | EmbeddedFont"Helvetica"Font to use
[options.size]number12Font size in points
[options.color]ColorblackText color
[options.opacity]number1Opacity (0-1)
[options.maxWidth]numberEnable word wrapping
[options.lineHeight]numbersize * 1.2Line height
[options.alignment]"left" | "center" | "right" | "justify""left"Text alignment
[options.rotate]RotationRotation options
// Simple text
page.drawText("Hello, World!", {
  x: 50,
  y: 700,
  size: 24,
  color: rgb(0, 0, 0),
});

// With embedded font
const font = await pdf.embedFont(fontBytes);
page.drawText("Custom Font", {
  x: 50,
  y: 650,
  font,
  size: 18,
});

// Multiline with wrapping
page.drawText(longText, {
  x: 50,
  y: 600,
  maxWidth: 500,
  lineHeight: 18,
  alignment: "justify",
});

Standard 14 Fonts (built-in, no embedding required):

Font Name
"Helvetica"
"Helvetica-Bold"
"Helvetica-Oblique"
"Helvetica-BoldOblique"
"Times-Roman"
"Times-Bold"
"Times-Italic"
"Times-BoldItalic"
"Courier"
"Courier-Bold"
"Courier-Oblique"
"Courier-BoldOblique"
"Symbol"
"ZapfDingbats"

Shape Drawing

drawRectangle(options)

Draw a rectangle on the page.

ParamTypeDefaultDescription
options.xnumberrequiredX position
options.ynumberrequiredY position
options.widthnumberrequiredRectangle width
options.heightnumberrequiredRectangle height
[options.color]ColorFill color
[options.borderColor]ColorBorder color
[options.borderWidth]number1Border width
[options.borderDashArray]number[]Dash pattern
[options.opacity]number1Fill opacity
[options.borderOpacity]number1Border opacity
[options.cornerRadius]numberRounded corners
[options.rotate]RotationRotation
// Filled rectangle
page.drawRectangle({
  x: 50,
  y: 500,
  width: 200,
  height: 100,
  color: rgb(0.95, 0.95, 0.95),
});

// Stroked with rounded corners
page.drawRectangle({
  x: 50,
  y: 350,
  width: 200,
  height: 100,
  borderColor: rgb(0, 0, 0),
  borderWidth: 2,
  cornerRadius: 10,
});

drawLine(options)

Draw a line on the page.

ParamTypeDefaultDescription
options.start{ x: number, y: number }requiredStart point
options.end{ x: number, y: number }requiredEnd point
[options.color]ColorblackLine color
[options.thickness]number1Line thickness
[options.opacity]number1Opacity
[options.dashArray]number[]Dash pattern
[options.lineCap]LineCap"butt"Line cap style
page.drawLine({
  start: { x: 50, y: 500 },
  end: { x: 550, y: 500 },
  color: rgb(0, 0, 0),
  thickness: 1,
});

// Dashed line
page.drawLine({
  start: { x: 50, y: 450 },
  end: { x: 550, y: 450 },
  dashArray: [5, 3],
});

drawCircle(options)

Draw a circle on the page.

ParamTypeDefaultDescription
options.xnumberrequiredCenter X
options.ynumberrequiredCenter Y
options.radiusnumberrequiredRadius
[options.color]ColorFill color
[options.borderColor]ColorBorder color
[options.borderWidth]number1Border width
[options.opacity]number1Fill opacity
[options.borderOpacity]number1Border opacity
page.drawCircle({
  x: 300,
  y: 400,
  radius: 50,
  color: rgb(1, 0, 0),
  borderColor: rgb(0, 0, 0),
  borderWidth: 2,
});

drawEllipse(options)

Draw an ellipse on the page.

ParamTypeDefaultDescription
options.xnumberrequiredCenter X
options.ynumberrequiredCenter Y
options.xRadiusnumberrequiredHorizontal radius
options.yRadiusnumberrequiredVertical radius
[options.color]ColorFill color
[options.borderColor]ColorBorder color
[options.borderWidth]number1Border width
[options.opacity]number1Fill opacity
[options.borderOpacity]number1Border opacity
[options.rotate]RotationRotation
page.drawEllipse({
  x: 300,
  y: 400,
  xRadius: 100,
  yRadius: 50,
  color: rgb(0, 0, 1),
});

Image Drawing

drawImage(image, options?)

Draw an image on the page.

ParamTypeDefaultDescription
imagePDFImagerequiredEmbedded image
[options]DrawImageOptions
[options.x]number0X position
[options.y]number0Y position
[options.width]numbernaturalTarget width
[options.height]numbernaturalTarget height
[options.opacity]number1Opacity
[options.rotate]RotationRotation

If only width or height is specified, aspect ratio is preserved.

const image = await pdf.embedImage(jpegBytes);

// Draw at natural size
page.drawImage(image, { x: 50, y: 500 });

// Scale to width
page.drawImage(image, { x: 50, y: 400, width: 200 });

// With rotation
page.drawImage(image, {
  x: 300,
  y: 400,
  width: 100,
  height: 100,
  rotate: { angle: 45 },
});

Embedded Page Drawing

drawPage(embedded, options?)

Draw an embedded page (Form XObject) onto this page.

ParamTypeDefaultDescription
embeddedPDFEmbeddedPagerequiredEmbedded page
[options]DrawPageOptions
[options.x]number0X position
[options.y]number0Y position
[options.scale]number1Uniform scale
[options.width]numberTarget width (overrides scale)
[options.height]numberTarget height (overrides scale)
[options.opacity]number1Opacity
[options.background]booleanfalseDraw behind existing content
const watermarkPdf = await PDF.load(watermarkBytes);
const watermark = await pdf.embedPage(watermarkPdf, 0);

// Center on page
page.drawPage(watermark, {
  x: (page.width - watermark.width) / 2,
  y: (page.height - watermark.height) / 2,
  opacity: 0.5,
});

// Draw as background
const letterheadPdf = await PDF.load(letterheadBytes);
const letterhead = await pdf.embedPage(letterheadPdf, 0);
page.drawPage(letterhead, { background: true });

Path Drawing

drawPath()

Start building a custom path with a fluent API.

Returns: PathBuilder

// Triangle
page.drawPath()
  .moveTo(100, 100)
  .lineTo(200, 100)
  .lineTo(150, 200)
  .close()
  .fill({ color: rgb(1, 0, 0) });

// Complex shape
page.drawPath()
  .moveTo(50, 50)
  .curveTo(100, 100, 150, 100, 200, 50)
  .lineTo(200, 150)
  .close()
  .fillAndStroke({
    color: rgb(0.9, 0.9, 1),
    borderColor: rgb(0, 0, 1),
  });

PathBuilder Methods:

MethodDescription
moveTo(x, y)Move to point
lineTo(x, y)Draw line to point
curveTo(cp1x, cp1y, cp2x, cp2y, x, y)Bezier curve
quadraticCurveTo(cpx, cpy, x, y)Quadratic curve
close()Close the path
fill(options)Fill the path
stroke(options)Stroke the path
fillAndStroke(options)Fill and stroke

Form Field Drawing

drawField(field, options)

Draw a form field widget on this page.

ParamTypeDescription
fieldFormFieldField to draw
options.xnumberX position
options.ynumberY position
options.widthnumberWidget width
options.heightnumberWidget height
[options.option]stringRadio option value (required for radio groups)

Throws:

  • Error - If field is a signature field
  • Error - If radio group option is missing or invalid
// Text field
await page.drawField(nameField, {
  x: 100,
  y: 700,
  width: 200,
  height: 24,
});

// Checkbox
await page.drawField(agreeCheckbox, {
  x: 100,
  y: 650,
  width: 18,
  height: 18,
});

// Radio group - each option needs its own widget
await page.drawField(paymentRadio, {
  x: 100,
  y: 550,
  width: 16,
  height: 16,
  option: "Credit Card",
});
await page.drawField(paymentRadio, {
  x: 100,
  y: 520,
  width: 16,
  height: 16,
  option: "PayPal",
});

Text Extraction

extractText(options?)

Extract all text content from the page.

ParamTypeDescription
[options]ExtractTextOptionsExtraction options

Returns: Promise<PageText>

const pageText = await page.extractText();
console.log(pageText.text); // Plain text

// Access structured content
for (const line of pageText.lines) {
  console.log(`Line at y=${line.baseline}: "${line.text}"`);
}

PageText Structure:

interface PageText {
  pageIndex: number;
  width: number;
  height: number;
  text: string;          // Plain text
  lines: TextLine[];     // Structured lines
}

interface TextLine {
  text: string;
  baseline: number;
  spans: TextSpan[];
}

findText(query, options?)

Search for text on the page.

ParamTypeDescription
querystring | RegExpSearch query
[options]FindTextOptions
[options.caseSensitive]booleanCase-sensitive matching
[options.wholeWord]booleanMatch whole words only

Returns: Promise<TextMatch[]>

// String search
const matches = await page.findText("invoice");
for (const match of matches) {
  console.log(`Found at:`, match.bbox);
}

// Regex search
const placeholders = await page.findText(/\{\{\s*\w+\s*\}\}/g);

TextMatch Structure:

interface TextMatch {
  text: string;
  pageIndex: number;
  bbox: { x: number; y: number; width: number; height: number };
}

Types

Rectangle

interface Rectangle {
  x1: number;  // Left
  y1: number;  // Bottom
  x2: number;  // Right
  y2: number;  // Top
}

Color

Colors can be created with helper functions:

import { rgb, cmyk, grayscale } from "@libpdf/core";

const red = rgb(1, 0, 0);
const cyan = cmyk(1, 0, 0, 0);
const gray = grayscale(0.5);

Rotation

interface Rotation {
  angle: number;  // Degrees
  origin?: { x: number; y: number };  // Rotation center
}

LineCap

type LineCap = "butt" | "round" | "square";

LineJoin

type LineJoin = "miter" | "round" | "bevel";

On this page