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 = 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 { x, y, width, height } properties.

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 = 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),
});

drawSvgPath(pathData, options?)

Draw an SVG path on the page. Useful for icons, logos, and vector graphics.

ParamTypeDefaultDescription
pathDatastringrequiredSVG path d attribute string
[options]DrawSvgPathOptions
[options.x]number0X position
[options.y]number0Y position
[options.scale]number1Scale factor
[options.flipY]booleantrueFlip Y-axis (SVG to PDF coordinates)
[options.color]ColorblackFill color
[options.borderColor]ColorStroke color
[options.borderWidth]number1Stroke width
[options.opacity]number1Fill opacity
[options.borderOpacity]number1Stroke opacity
[options.windingRule]"nonzero" | "evenodd""nonzero"Fill rule for overlapping paths
[options.lineCap]LineCapLine cap style
[options.lineJoin]LineJoinLine join style
[options.dashArray]number[]Dash pattern

All SVG path commands are supported: M, L, H, V, C, S, Q, T, A, Z (and lowercase relative variants).

// Simple filled triangle
page.drawSvgPath("M 0 0 L 50 0 L 25 40 Z", {
  x: 100,
  y: 700,
  color: rgb(1, 0, 0),
});

// Stroked icon (Lucide-style)
page.drawSvgPath("M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3...", {
  x: 50,
  y: 600,
  scale: 2,
  borderColor: rgb(0.9, 0.2, 0.2),
  borderWidth: 2,
});

// Path with hole (even-odd fill)
page.drawSvgPath("M 0 0 L 80 0 L 80 80 L 0 80 Z M 20 20 L 60 20 L 60 60 L 20 60 Z", {
  x: 200,
  y: 500,
  color: rgb(0, 0, 1),
  windingRule: "evenodd",
});

Coordinate System: By default, flipY: true transforms SVG coordinates (Y increases downward) to PDF coordinates (Y increases upward). Set flipY: false when paths are already in PDF coordinate space.


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 = 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)Cubic bezier curve
quadraticCurveTo(cpx, cpy, x, y)Quadratic bezier curve
appendSvgPath(pathData, options?)Append SVG path commands
close()Close the path
fill(options)Fill the path
stroke(options)Stroke the path
fillAndStroke(options)Fill and stroke

Using appendSvgPath:

The appendSvgPath method lets you mix SVG path commands with PathBuilder methods:

// Mix PathBuilder methods with SVG path data
page
  .drawPath()
  .moveTo(50, 500)
  .lineTo(100, 500)
  .appendSvgPath("l 30 -30 l 30 30", { flipY: false }) // relative SVG
  .lineTo(200, 500)
  .stroke({ borderColor: rgb(0, 0, 0) });

Options for appendSvgPath:

OptionTypeDefaultDescription
flipYbooleanfalseFlip Y-axis for SVG paths
scalenumber1Scale factor
translateXnumber0X translation after transform
translateYnumber0Y translation after transform

Note: Unlike drawSvgPath(), the appendSvgPath() method defaults to flipY: false since PathBuilder operates in PDF coordinates.


Low-Level Drawing

For advanced graphics operations, PDFPage provides methods to emit raw operators and register resources. See Low-Level Drawing for detailed usage.

drawOperators(operators)

Emit raw PDF operators to the page content stream.

ParamTypeDescription
operatorsOperator[]Array of operators to emit
import { ops } from "@libpdf/core";

page.drawOperators([
  ops.pushGraphicsState(),
  ops.concatMatrix(1, 0, 0, 1, 100, 200),
  ops.setNonStrokingRGB(1, 0, 0),
  ops.rectangle(0, 0, 50, 50),
  ops.fill(),
  ops.popGraphicsState(),
]);

The caller is responsible for valid operator sequences. Invalid sequences may produce corrupted PDFs.


registerFont(font)

Register a font resource and return its operator name.

ParamTypeDescription
fontEmbeddedFont | Standard14FontNameFont to register

Returns: string - Resource name (e.g., "F0")

const font = pdf.embedFont(fontBytes);
const fontName = page.registerFont(font);

page.drawOperators([
  ops.beginText(),
  ops.setFont(fontName, 12),
  ops.moveText(100, 700),
  ops.showText("Hello"),
  ops.endText(),
]);

registerImage(image)

Register an image resource and return its operator name.

ParamTypeDescription
imagePDFImageEmbedded image

Returns: string - Resource name (e.g., "Im0")

const image = pdf.embedImage(imageBytes);
const imageName = page.registerImage(image);

page.drawOperators([
  ops.pushGraphicsState(),
  ops.concatMatrix(100, 0, 0, 100, 200, 500),
  ops.paintXObject(imageName),
  ops.popGraphicsState(),
]);

registerShading(shading)

Register a shading (gradient) resource and return its operator name.

ParamTypeDescription
shadingPDFShadingShading resource

Returns: string - Resource name (e.g., "Sh0")

const gradient = pdf.createAxialShading({...});
const shadingName = page.registerShading(gradient);

page.drawOperators([
  ops.pushGraphicsState(),
  ops.rectangle(50, 50, 100, 100),
  ops.clip(),
  ops.endPath(),
  ops.paintShading(shadingName),
  ops.popGraphicsState(),
]);

registerPattern(pattern)

Register a pattern resource and return its operator name.

ParamTypeDescription
patternPDFPatternPattern resource

Returns: string - Resource name (e.g., "P0")

import { ColorSpace } from "@libpdf/core";

const pattern = pdf.createTilingPattern({...});
const patternName = page.registerPattern(pattern);

page.drawOperators([
  ops.setNonStrokingColorSpace(ColorSpace.Pattern),
  ops.setNonStrokingColorN(patternName),
  ops.rectangle(100, 100, 200, 200),
  ops.fill(),
]);

registerExtGState(state)

Register an extended graphics state and return its operator name.

ParamTypeDescription
statePDFExtGStateGraphics state

Returns: string - Resource name (e.g., "GS0")

const gs = pdf.createExtGState({
  fillOpacity: 0.5,
  blendMode: "Multiply",
});
const gsName = page.registerExtGState(gs);

page.drawOperators([
  ops.pushGraphicsState(),
  ops.setGraphicsState(gsName),
  ops.setNonStrokingRGB(1, 0, 0),
  ops.rectangle(100, 100, 50, 50),
  ops.fill(),
  ops.popGraphicsState(),
]);

registerXObject(xobject)

Register a Form XObject or embedded page and return its operator name.

ParamTypeDescription
xobjectPDFFormXObject | PDFEmbeddedPageXObject to register

Returns: string - Resource name (e.g., "Fm0")

const stamp = pdf.createFormXObject({...});
const stampName = page.registerXObject(stamp);

page.drawOperators([
  ops.pushGraphicsState(),
  ops.concatMatrix(1, 0, 0, 1, 200, 700),
  ops.paintXObject(stampName),
  ops.popGraphicsState(),
]);

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
page.drawField(nameField, {
  x: 100,
  y: 700,
  width: 200,
  height: 24,
});

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

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

Annotations

PDFPage provides methods for adding and retrieving PDF annotations such as highlights, links, sticky notes, shapes, stamps, and freehand drawings.

See the Annotations documentation for the complete API reference.

// Add a highlight
page.addHighlightAnnotation({
  rect: { x: 100, y: 700, width: 200, height: 14 },
  color: rgb(1, 1, 0),
});

// Get all annotations
const annotations = page.getAnnotations();

// Get specific types
const highlights = page.getHighlightAnnotations();
const links = page.getLinkAnnotations();

Text Extraction

extractText(options?)

Extract all text content from the page.

ParamTypeDescription
[options]ExtractTextOptionsExtraction options

Returns: PageText

const pageText = 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: TextMatch[]

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

// Regex search
const placeholders = 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 {
  x: number; // Left x coordinate
  y: number; // Bottom y coordinate
  width: number; // Width
  height: number; // Height
}

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