Skip to main content

Details about Positioning

Understanding PDF coordinates is essential for precise content placement. This guide explains how PDF positioning works in PDFDancer.


PDF Coordinate System

PDF uses a Cartesian coordinate system with the origin at the bottom-left corner of the page:

  • X-axis: Increases from left (0) to right
  • Y-axis: Increases from bottom (0) to top
  • Units: PDF points (1 point = 1/72 inch)

Common Page Sizes

  • Letter (US): 612 × 792 points (8.5" × 11")
  • A4: 595 × 842 points (210mm × 297mm)
  • Legal: 612 × 1008 points (8.5" × 14")

Visual Guide to PDF Coordinates

Comprehensive visual guide showing PDF coordinate system with grid, corners labeled, and examples

Visual Asset Needed

Image: positioning-visual-guide.png Shows: Complete PDF page with grid overlay, all four corners annotated with coordinates, common page sizes shown with dimensions, bounding rectangles with labeled properties (x, y, width, height), ruler/scale indicator, and examples of elements at different positions. Details: See /static/img/placeholders/README.md for full specifications.


Understanding Coordinates

from pdfdancer import PDFDancer

with PDFDancer.open("document.pdf") as pdf:
# Bottom-left corner (0, 0)
pdf.new_paragraph() \
.text("Bottom Left") \
.font("Helvetica", 10) \
.at(page_number=1, x=10, y=10) \
.add()

# Top-left corner (for Letter size: 792pt height)
pdf.new_paragraph() \
.text("Top Left") \
.font("Helvetica", 10) \
.at(page_number=1, x=10, y=782) \
.add()

# Center of page (for Letter size: 612×792)
pdf.new_paragraph() \
.text("Center") \
.font("Helvetica", 10) \
.at(page_number=1, x=306, y=396) \
.add()

# Top-right corner
pdf.new_paragraph() \
.text("Top Right") \
.font("Helvetica", 10) \
.at(page_number=1, x=552, y=782) \
.add()

# Bottom-right corner
pdf.new_paragraph() \
.text("Bottom Right") \
.font("Helvetica", 10) \
.at(page_number=1, x=552, y=10) \
.add()

pdf.save("output.pdf")

Working with Position Objects

Position objects help you work with coordinates and bounding rectangles.

from pdfdancer import Position, PositionMode

# Create position at specific coordinates
position = Position.at_page_coordinates(page=0, x=100, y=200)

# Create position with bounding rectangle
position = Position(
page_number=1,
bounding_rect={"x": 100, "y": 200, "width": 50, "height": 30},
mode=PositionMode.INTERSECT
)

# Use position for selection
with PDFDancer.open("document.pdf") as pdf:
paragraphs = pdf.select_paragraphs_at(position)

Bounding Rectangles

Every PDF element has a bounding rectangle that defines its position and size.

from pdfdancer import PDFDancer

with PDFDancer.open("document.pdf") as pdf:
paragraphs = pdf.page(1).select_paragraphs()

for para in paragraphs:
rect = para.position.bounding_rect
print(f"Paragraph at: x={rect['x']}, y={rect['y']}")
print(f" Size: width={rect['width']}, height={rect['height']}")

Visual Example: Bounding Rectangles

Understanding bounding rectangles is crucial for precise element positioning:

Detailed view of bounding rectangle with labeled x, y, width, height properties

Visual Asset Needed

Image: bounding-rect-example.png Shows: Zoomed-in view of a text element or shape with bounding rectangle clearly shown. Label all four properties: x (left edge), y (bottom edge), width, height. Use different colors for each dimension and include actual coordinate values as labels. Details: See /static/img/placeholders/README.md for full specifications.


Common Positioning Patterns

Margins and Safe Areas

from pdfdancer import PDFDancer

# Define margins (in points)
LEFT_MARGIN = 72 # 1 inch
RIGHT_MARGIN = 72 # 1 inch
TOP_MARGIN = 72 # 1 inch
BOTTOM_MARGIN = 72 # 1 inch

PAGE_WIDTH = 612 # Letter width
PAGE_HEIGHT = 792 # Letter height

with PDFDancer.open("document.pdf") as pdf:
# Content within margins
pdf.new_paragraph() \
.text("Safe content area") \
.at(page_number=1, x=LEFT_MARGIN, y=PAGE_HEIGHT - TOP_MARGIN) \
.add()

pdf.save("output.pdf")

Next Steps