Working with Vector Graphics
PDFDancer allows you to work with vector graphics elements (paths) in PDFs. You can both select existing paths and create new ones - draw lines, shapes, bezier curves, and complex vector graphics.
Selecting Paths
Paths are vector graphics elements in PDFs (lines, shapes, drawings).
- Python
- TypeScript
- Java
from pdfdancer import PDFDancer
with PDFDancer.open("document.pdf") as pdf:
# Get all paths on a specific page
paths = pdf.page(3).select_paths()
# Get paths at specific coordinates
paths_at_point = pdf.page(3).select_paths_at(x=150, y=320)
for path in paths:
print(f"Path ID: {path.internal_id}")
import { PDFDancer } from 'pdfdancer-client-typescript';
const pdf = await PDFDancer.open('document.pdf');
// Get all paths on a specific page
const paths = await pdf.page(3).selectPaths();
// Get paths at specific coordinates
const pathsAtPoint = await pdf.page(3).selectPathsAt(150, 320);
for (const path of paths) {
console.log(`Path ID: ${path.internalId}`);
}
import com.tfc.pdf.pdfdancer.api.PDFDancer;
import com.tfc.pdf.pdfdancer.api.common.model.*;
PDFDancer pdf = PDFDancer.createSession("document.pdf");
// Get all paths on a specific page
List<Path> paths = pdf.page(3).selectPaths();
// Get paths at specific coordinates
List<Path> pathsAtPoint = pdf.page(3).selectPathsAt(150, 320);
for (Path path : paths) {
System.out.println("Path ID: " + path.getInternalId());
}
Understanding Vector Paths
Vector paths in PDFs can represent:
- Lines and curves
- Shapes (rectangles, circles, polygons)
- Complex drawings and diagrams
- Borders and decorative elements
Working with Paths
- Python
- TypeScript
- Java
from pdfdancer import PDFDancer
with PDFDancer.open("document.pdf") as pdf:
# Select paths on a page
paths = pdf.page(1).select_paths()
print(f"Found {len(paths)} paths on page 0")
# You can iterate through paths
for i, path in enumerate(paths):
print(f"Path {i}: {path.internal_id}")
const pdf = await PDFDancer.open('document.pdf');
// Select paths on a page
const paths = await pdf.page(1).selectPaths();
console.log(`Found ${paths.length} paths on page 0`);
// You can iterate through paths
for (const [i, path] of paths.entries()) {
console.log(`Path ${i}: ${path.internalId}`);
}
import com.tfc.pdf.pdfdancer.api.PDFDancer;
PDFDancer pdf = PDFDancer.createSession("document.pdf");
// Select paths on a page
List<Path> paths = pdf.page(1).selectPaths();
System.out.println("Found " + paths.size() + " paths on page 0");
// You can iterate through paths
for (int i = 0; i < paths.size(); i++) {
Path path = paths.get(i);
System.out.println("Path " + i + ": " + path.getInternalId());
}
Drawing Lines
Create straight lines on a page:
- Python
- TypeScript
- Java
from pdfdancer import PDFDancer, Color
with PDFDancer.open("document.pdf") as pdf:
page = pdf.page(1)
# Draw a simple line
page.new_line() \
.from_point(100, 100) \
.to_point(400, 100) \
.stroke_color(Color(0, 0, 0)) \
.stroke_width(2) \
.add()
# Draw a dashed line
page.new_line() \
.from_point(100, 150) \
.to_point(400, 150) \
.stroke_color(Color(255, 0, 0)) \
.stroke_width(1) \
.dash_pattern([5, 3]) \
.add()
pdf.save("output.pdf")
import { PDFDancer, Color } from 'pdfdancer-client-typescript';
const pdf = await PDFDancer.open('document.pdf');
const page = pdf.page(1);
// Draw a simple line
await page.newLine()
.fromPoint(100, 100)
.toPoint(400, 100)
.strokeColor(new Color(0, 0, 0))
.strokeWidth(2)
.apply();
// Draw a dashed line
await page.newLine()
.fromPoint(100, 150)
.toPoint(400, 150)
.strokeColor(new Color(255, 0, 0))
.strokeWidth(1)
.dashPattern([5, 3])
.apply();
await pdf.save('output.pdf');
import com.tfc.pdf.pdfdancer.api.PDFDancer;
import com.tfc.pdf.pdfdancer.api.common.model.*;
PDFDancer pdf = PDFDancer.createSession("document.pdf");
Page page = pdf.page(1);
// Draw a simple line
page.newLine()
.fromPoint(100, 100)
.toPoint(400, 100)
.strokeColor(new Color(0, 0, 0))
.strokeWidth(2)
.add();
// Draw a dashed line
page.newLine()
.fromPoint(100, 150)
.toPoint(400, 150)
.strokeColor(new Color(255, 0, 0))
.strokeWidth(1)
.dashPattern(new int[]{5, 3})
.add();
pdf.save("output.pdf");
Drawing Rectangles
Create rectangles with stroke and fill:
- Python
- TypeScript
- Java
from pdfdancer import PDFDancer, Color
with PDFDancer.open("document.pdf") as pdf:
page = pdf.page(1)
# Draw a stroked rectangle
page.new_rectangle() \
.at_coordinates(100, 200) \
.with_size(200, 100) \
.stroke_color(Color(0, 0, 255)) \
.stroke_width(3) \
.add()
# Draw a filled rectangle
page.new_rectangle() \
.at_coordinates(350, 200) \
.with_size(200, 100) \
.fill_color(Color(255, 200, 0)) \
.add()
# Draw a rectangle with both stroke and fill
page.new_rectangle() \
.at_coordinates(100, 350) \
.with_size(200, 100) \
.stroke_color(Color(0, 0, 0)) \
.stroke_width(2) \
.fill_color(Color(200, 200, 255)) \
.add()
pdf.save("output.pdf")
import { PDFDancer, Color } from 'pdfdancer-client-typescript';
const pdf = await PDFDancer.open('document.pdf');
const page = pdf.page(1);
// Draw a stroked rectangle
await page.newRectangle()
.at(100, 200)
.size(200, 100)
.strokeColor(new Color(0, 0, 255))
.strokeWidth(3)
.apply();
// Draw a filled rectangle
await page.newRectangle()
.at(350, 200)
.size(200, 100)
.fillColor(new Color(255, 200, 0))
.apply();
// Draw a rectangle with both stroke and fill
await page.newRectangle()
.at(100, 350)
.size(200, 100)
.strokeColor(new Color(0, 0, 0))
.strokeWidth(2)
.fillColor(new Color(200, 200, 255))
.apply();
await pdf.save('output.pdf');
import com.tfc.pdf.pdfdancer.api.PDFDancer;
import com.tfc.pdf.pdfdancer.api.common.model.*;
PDFDancer pdf = PDFDancer.createSession("document.pdf");
Page page = pdf.page(1);
// Draw a stroked rectangle
page.newRectangle()
.at(100, 200)
.size(200, 100)
.strokeColor(new Color(0, 0, 255))
.strokeWidth(3)
.add();
// Draw a filled rectangle
page.newRectangle()
.at(350, 200)
.size(200, 100)
.fillColor(new Color(255, 200, 0))
.add();
// Draw a rectangle with both stroke and fill
page.newRectangle()
.at(100, 350)
.size(200, 100)
.strokeColor(new Color(0, 0, 0))
.strokeWidth(2)
.fillColor(new Color(200, 200, 255))
.add();
pdf.save("output.pdf");
Drawing Bezier Curves
Create smooth curves using cubic Bezier curves:
- Python
- TypeScript
- Java
from pdfdancer import PDFDancer, Color
with PDFDancer.open("document.pdf") as pdf:
page = pdf.page(1)
# Draw a bezier curve
page.new_bezier() \
.from_point(100, 100) \
.control_point_1(200, 200) \
.control_point_2(300, 200) \
.to_point(400, 100) \
.stroke_color(Color(0, 128, 0)) \
.stroke_width(2) \
.add()
pdf.save("output.pdf")
import { PDFDancer, Color } from 'pdfdancer-client-typescript';
const pdf = await PDFDancer.open('document.pdf');
const page = pdf.page(1);
// Draw a bezier curve
await page.newBezier()
.startPoint(100, 100)
.controlPoint1(200, 200)
.controlPoint2(300, 200)
.endPoint(400, 100)
.strokeColor(new Color(0, 128, 0))
.strokeWidth(2)
.apply();
await pdf.save('output.pdf');
import com.tfc.pdf.pdfdancer.api.PDFDancer;
import com.tfc.pdf.pdfdancer.api.common.model.*;
PDFDancer pdf = PDFDancer.createSession("document.pdf");
Page page = pdf.page(1);
// Draw a bezier curve
page.newBezier()
.startPoint(100, 100)
.controlPoint1(200, 200)
.controlPoint2(300, 200)
.endPoint(400, 100)
.strokeColor(new Color(0, 128, 0))
.strokeWidth(2)
.add();
pdf.save("output.pdf");
PathBuilder: Programmatic Path Creation
The newPath() method returns a builder that lets you create complex vector paths programmatically. This builder pattern allows you to chain commands to construct shapes, curves, and complex drawings.
In TypeScript SDK v1.0.22+, newPath() returns a PathBuilder instance that provides a fluent API for constructing vector paths. You can also import and use the PathBuilder class directly:
import { PathBuilder } from 'pdfdancer-client-typescript';
Builder Pattern Basics
- Python
- TypeScript
- Java
from pdfdancer import PDFDancer, Color
with PDFDancer.open("document.pdf") as pdf:
# new_path() returns a builder - chain commands and call add()
pdf.page(1).new_path() \
.add_line(Point(100, 100), Point(200, 200)) \
.stroke_color(Color(0, 0, 0)) \
.stroke_width(2) \
.add() # Finalizes and adds the path to the page
import { PDFDancer, Color } from 'pdfdancer-client-typescript';
const pdf = await PDFDancer.open('document.pdf');
// newPath() returns a PathBuilder - chain commands and call apply()
await pdf.page(1).newPath()
.moveTo(100, 100)
.lineTo(200, 200)
.strokeColor(new Color(0, 0, 0))
.strokeWidth(2)
.apply(); // Finalizes and adds the path to the page
import com.pdfdancer.client.rest.*;
PDFDancer pdf = PDFDancer.createSession("document.pdf");
// newPath() returns a builder - chain commands and call add()
pdf.page(1).newPath()
.moveTo(100, 100)
.lineTo(200, 200)
.strokeColor(new Color(0, 0, 0))
.strokeWidth(2)
.add(); // Finalizes and adds the path to the page
Advanced Fill Rules
For complex shapes with overlapping regions, you can control the fill behavior:
- TypeScript
- Python
- Java
// Even-odd fill rule for complex shapes
await pdf.page(1).newPath()
.moveTo(100, 100)
.lineTo(200, 100)
.lineTo(200, 200)
.lineTo(100, 200)
.closePath()
.fillColor(new Color(255, 0, 0))
.evenOddFill(true) // Use even-odd winding rule
.apply();
# Even-odd fill rule supported in Python SDK
# (Check API documentation for current implementation status)
// Even-odd fill rule supported in Java SDK
// (Check API documentation for current implementation status)
The even-odd rule determines whether a point is inside a path by drawing a line from that point to infinity and counting how many times it crosses the path. If the count is odd, the point is inside; if even, it's outside. This is useful for creating shapes with holes or complex overlapping regions.
PathBuilder API Reference
Complete list of PathBuilder methods:
Drawing Commands:
moveTo(x, y)- Move to a point without drawing (sets the current point)lineTo(x, y)- Draw a line from current point to (x, y)bezierTo(cp1x, cp1y, cp2x, cp2y, x, y)- Draw a cubic Bezier curveclosePath()- Draw a line back to the starting point
Styling:
strokeColor(Color)- Set the outline colorfillColor(Color)- Set the fill colorstrokeWidth(number)- Set outline width in pointsdashPattern([on, off, ...])- Set dash pattern for strokes
Advanced:
dashPhase(number)- Set the offset for dash patternsevenOddFill(boolean)- Use even-odd fill rule (TypeScript)
Finalize:
at(pageNumber, x, y)/at(x, y)- Set position and optionally page indexadd()/apply()- Add the path to the document
Python uses snake_case: move_to(), line_to(), stroke_color(), etc.
Drawing Complex Paths
Create complex vector graphics using path commands:
- Python
- TypeScript
- Java
from pdfdancer import PDFDancer, Color, Point
with PDFDancer.open("document.pdf") as pdf:
page = pdf.page(1)
# Draw a complex path (triangle)
page.new_path() \
.add_line(Point(250, 100), Point(350, 250)) \
.add_line(Point(350, 250), Point(150, 250)) \
.add_line(Point(150, 250), Point(250, 100)) \
.stroke_color(Color(128, 0, 128)) \
.stroke_width(3) \
.fill_color(Color(255, 200, 255)) \
.add()
# Draw a path with curves
page.new_path() \
.add_line(Point(100, 400), Point(200, 400)) \
.add_bezier(Point(200, 400), Point(250, 450), Point(300, 450), Point(350, 400)) \
.add_line(Point(350, 400), Point(450, 400)) \
.stroke_color(Color(255, 100, 0)) \
.stroke_width(2) \
.add()
pdf.save("output.pdf")
import { PDFDancer, Color } from 'pdfdancer-client-typescript';
const pdf = await PDFDancer.open('document.pdf');
const page = pdf.page(1);
// Draw a complex path (triangle)
await page.newPath()
.moveTo(250, 100)
.lineTo(350, 250)
.lineTo(150, 250)
.closePath()
.strokeColor(new Color(128, 0, 128))
.strokeWidth(3)
.fillColor(new Color(255, 200, 255))
.apply();
// Draw a path with curves
await page.newPath()
.moveTo(100, 400)
.lineTo(200, 400)
.bezierTo(250, 450, 300, 450, 350, 400)
.lineTo(450, 400)
.strokeColor(new Color(255, 100, 0))
.strokeWidth(2)
.apply();
await pdf.save('output.pdf');
import com.tfc.pdf.pdfdancer.api.PDFDancer;
import com.tfc.pdf.pdfdancer.api.common.model.*;
PDFDancer pdf = PDFDancer.createSession("document.pdf");
Page page = pdf.page(1);
// Draw a complex path (triangle)
page.newPath()
.moveTo(250, 100)
.lineTo(350, 250)
.lineTo(150, 250)
.closePath()
.strokeColor(new Color(128, 0, 128))
.strokeWidth(3)
.fillColor(new Color(255, 200, 255))
.add();
// Draw a path with curves
page.newPath()
.moveTo(100, 400)
.lineTo(200, 400)
.curveTo(250, 450, 300, 450, 350, 400)
.lineTo(450, 400)
.strokeColor(new Color(255, 100, 0))
.strokeWidth(2)
.add();
pdf.save("output.pdf");
Path Commands
Available path commands:
move_to(x, y)/moveTo(x, y)- Move to a point without drawingline_to(x, y)/lineTo(x, y)- Draw a straight line to a pointadd_bezier(...)/bezierTo(cp1x, cp1y, cp2x, cp2y, x, y)/curveTo(...)- Draw a cubic Bezier curveclose_path()/closePath()- Close the current path by drawing a line to the start point
Styling Options
All vector graphics support these styling options:
Stroke (Outline)
stroke_color(Color)/strokeColor(Color)- Set the outline colorstroke_width(number)/strokeWidth(number)- Set the outline width in pointsdash_pattern([on, off, ...])/dashPattern([on, off, ...])- Create dashed lines
Fill
fill_color(Color)/fillColor(Color)- Set the fill color for closed shapes
- Use stroke for outlines and lines
- Use fill for solid shapes
- Use both for outlined shapes with a fill color
- Omit both to create invisible paths (useful for clipping regions)
Next Steps
- Working with Fonts – Use custom fonts in your PDFs
- Details about Positioning – Understand PDF coordinate systems
- Cookbook – See complete working examples