# Advanced PDF Text Positioning & Page Analysis Tools

This document provides comprehensive documentation for the new PDF analysis tools that enable precise text positioning and intelligent watermark placement.

## 📋 Table of Contents

- [Overview](#overview)
- [Tool 1: analyze-pdf-page](#tool-1-analyze-pdf-page)
- [Tool 2: detect-text-position](#tool-2-detect-text-position)
- [Use Cases](#use-cases)
- [Technical Details](#technical-details)
- [Examples](#examples)

---

## Overview

Two new powerful tools have been added to the PDF MCP Server:

1. **`analyze-pdf-page`** - Extracts page dimensions, margins, and layout information
2. **`detect-text-position`** - Detects precise text positions with OCR-level accuracy

These tools enable:
- ✅ Accurate element positioning in PDFs
- ✅ Intelligent watermark placement that avoids text
- ✅ Content-aware PDF operations
- ✅ Understanding PDF page layout and structure

---

## Tool 1: analyze-pdf-page

### Description

Analyzes a PDF page to extract comprehensive layout information including dimensions, margins, and page boxes. Essential for understanding page layout before adding watermarks, headers, footers, or other elements.

### Input Schema

```typescript
{
  filePath: string;       // Path to the PDF file (required)
  pageNumber?: number;    // Page number to analyze (1-indexed, default: 1)
}
```

**File Path Formats Supported:**
- Full path: `/Users/username/Downloads/document.pdf`
- Filename only: `document.pdf` (searches common folders)
- Relative path: `./document.pdf` or `../folder/document.pdf`
- file:// URI: `file:///path/to/document.pdf`

### Output Schema

```typescript
{
  filePath: string;              // Path to the analyzed PDF file
  pageNumber: number;            // Page number analyzed (1-indexed)
  dimensions: {
    width: number;               // Page width in points
    height: number;              // Page height in points
    rotation: number;            // Page rotation in degrees (0, 90, 180, 270)
    inchDimensions: {
      width: number;             // Page width in inches
      height: number;            // Page height in inches
    };
    mmDimensions: {
      width: number;             // Page width in millimeters
      height: number;            // Page height in millimeters
    };
  };
  margins: {
    top: number;                 // Top margin in points
    bottom: number;              // Bottom margin in points
    left: number;                // Left margin in points
    right: number;               // Right margin in points
    detected: boolean;           // Whether margins were detected from content
  };
  mediaBox: {
    x: number;                   // MediaBox X coordinate
    y: number;                   // MediaBox Y coordinate
    width: number;               // MediaBox width
    height: number;              // MediaBox height
  };
  cropBox?: {                    // Optional: visible page area
    x: number;
    y: number;
    width: number;
    height: number;
  };
}
```

### Example Usage

```javascript
// Analyze first page of a PDF
const result = await analyze-pdf-page({
  filePath: "document.pdf",
  pageNumber: 1
});

console.log(`Page dimensions: ${result.dimensions.width} x ${result.dimensions.height} points`);
console.log(`Page size: ${result.dimensions.inchDimensions.width}" x ${result.dimensions.inchDimensions.height}"`);
console.log(`Margins: T:${result.margins.top} B:${result.margins.bottom} L:${result.margins.left} R:${result.margins.right}`);
```

---

## Tool 2: detect-text-position

### Description

Detects precise text positions in a PDF page using advanced text extraction algorithms powered by PDF.js. Returns an array of text items with exact bounding boxes, font information, and coordinates for each text element.

### Input Schema

```typescript
{
  filePath: string;         // Path to the PDF file (required)
  pageNumber?: number;      // Page number to analyze (1-indexed, default: 1)
  searchQuery?: string;     // Optional: filter text items by content
  maxResults?: number;      // Optional: maximum number of results to return
}
```

### Output Schema

```typescript
{
  filePath: string;                // Path to the analyzed PDF file
  pageNumber: number;              // Page number analyzed (1-indexed)
  textItems: Array<{
    text: string;                  // The text content
    fontName: string;              // Font name used for this text
    fontSize: number;              // Font size in points
    bounds: {
      x: number;                   // X coordinate of top-left corner
      y: number;                   // Y coordinate of top-left corner
      width: number;               // Width of the bounding box
      height: number;              // Height of the bounding box
    };
    transform: number[];           // PDF transformation matrix [a, b, c, d, e, f]
    direction: number;             // Text direction in degrees (0=horizontal, 90=vertical)
  }>;
  totalTextItems: number;          // Total number of text items found
  pageDimensions: {
    width: number;                 // Page width in points
    height: number;                // Page height in points
    rotation: number;              // Page rotation
    inchDimensions: { width: number; height: number; };
    mmDimensions: { width: number; height: number; };
  };
  searchQuery?: string;            // Search query used (if filtering was applied)
  filtered: boolean;               // Whether results were filtered
}
```

### Example Usage

#### Basic Text Extraction

```javascript
// Extract all text positions from a page
const result = await detect-text-position({
  filePath: "document.pdf",
  pageNumber: 1
});

console.log(`Found ${result.totalTextItems} text items`);

result.textItems.forEach((item, index) => {
  console.log(`${index + 1}. "${item.text}"`);
  console.log(`   Position: (${item.bounds.x}, ${item.bounds.y})`);
  console.log(`   Size: ${item.bounds.width} x ${item.bounds.height}`);
  console.log(`   Font: ${item.fontName} @ ${item.fontSize}pt`);
});
```

#### Search for Specific Text

```javascript
// Find all text items containing "watermark"
const result = await detect-text-position({
  filePath: "document.pdf",
  pageNumber: 1,
  searchQuery: "watermark"
});

console.log(`Found ${result.totalTextItems} items matching "${result.searchQuery}"`);
```

#### Limit Results

```javascript
// Get only the first 10 text items
const result = await detect-text-position({
  filePath: "document.pdf",
  pageNumber: 1,
  maxResults: 10
});
```

---

## Use Cases

### 1. Intelligent Watermark Placement

Use text position data to place watermarks intelligently, avoiding overlap with important text:

```javascript
// Step 1: Detect text positions
const textResult = await detect-text-position({
  filePath: "document.pdf",
  pageNumber: 1
});

// Step 2: Find clear areas (no text)
// You can use the utility function findOptimalWatermarkPositions
// from text-position-utils.ts

// Step 3: Add watermark at optimal position
const watermarkResult = await add-pdf-watermark({
  filePath: "document.pdf",
  text: "CONFIDENTIAL",
  position: "custom",
  x: optimalX,  // From step 2
  y: optimalY,
  opacity: 0.3
});
```

### 2. Page Layout Analysis

Understand page layout before making modifications:

```javascript
// Analyze page structure
const pageAnalysis = await analyze-pdf-page({
  filePath: "document.pdf",
  pageNumber: 1
});

// Use dimensions for calculations
const safeAreaWidth = pageAnalysis.dimensions.width - 
                      pageAnalysis.margins.left - 
                      pageAnalysis.margins.right;

const safeAreaHeight = pageAnalysis.dimensions.height - 
                       pageAnalysis.margins.top - 
                       pageAnalysis.margins.bottom;

console.log(`Safe content area: ${safeAreaWidth} x ${safeAreaHeight} points`);
```

### 3. Text-Aware Content Addition

Add headers/footers or annotations that respect existing text:

```javascript
// Get text positions
const textData = await detect-text-position({
  filePath: "document.pdf",
  pageNumber: 1
});

// Find the highest text position
const highestText = Math.max(...textData.textItems.map(item => item.bounds.y));

// Add header above all text
const headerY = highestText + 50; // 50 points above highest text
```

### 4. Content Analysis

Analyze document structure and content distribution:

```javascript
// Get all text with font information
const textData = await detect-text-position({
  filePath: "document.pdf",
  pageNumber: 1
});

// Find headers (large font sizes)
const headers = textData.textItems.filter(item => item.fontSize > 18);

// Find body text
const bodyText = textData.textItems.filter(item => item.fontSize <= 14);

console.log(`Headers: ${headers.length}`);
console.log(`Body paragraphs: ${bodyText.length}`);
```

---

## Technical Details

### Algorithms Used

#### Page Analysis (`analyze-pdf-page`)

- **Library**: pdf-lib
- **Method**: Direct page inspection using PDF.js internal APIs
- **Accuracy**: Exact page dimensions from PDF specification
- **Margins**: Estimated based on standard page sizes (Letter, A4, Legal)

**Standard Margin Estimates:**
- Letter (8.5" x 11"): 1 inch (72 points) on all sides
- A4 (210mm x 297mm): ~25mm (71 points) on all sides
- Other sizes: 10% of page dimensions (max 72 points)

#### Text Position Detection (`detect-text-position`)

- **Library**: PDF.js (Mozilla)
- **Method**: `getTextContent()` API with transformation matrices
- **Accuracy**: Character-level precision
- **Features**:
  - Exact text coordinates
  - Bounding box calculations
  - Font metadata extraction
  - Rotation and transformation support

**Transformation Matrix Format:**
```
[a, b, c, d, e, f]
where:
  a, d = scaling factors
  b, c = rotation/skew factors
  e, f = translation (x, y position)
```

### Coordinate System

PDFs use a coordinate system with the origin (0,0) at the **bottom-left** corner:

```
(0, height) ┌─────────────────┐ (width, height)
            │                 │
            │   PDF PAGE      │
            │                 │
       (0,0)└─────────────────┘ (width, 0)
```

### Unit Conversions

- **1 point** = 1/72 inch
- **1 inch** = 72 points = 25.4 millimeters
- **1 millimeter** = 2.83465 points

**Common Page Sizes:**
- Letter: 612 x 792 points (8.5" x 11")
- A4: 595 x 842 points (210mm x 297mm)
- Legal: 612 x 1008 points (8.5" x 14")

---

## Examples

### Complete Workflow: Smart Watermarking

```javascript
// 1. Analyze the page
const pageInfo = await analyze-pdf-page({
  filePath: "report.pdf",
  pageNumber: 1
});

console.log(`Analyzing page: ${pageInfo.dimensions.width} x ${pageInfo.dimensions.height} points`);

// 2. Detect text positions
const textInfo = await detect-text-position({
  filePath: "report.pdf",
  pageNumber: 1
});

console.log(`Found ${textInfo.totalTextItems} text elements`);

// 3. Calculate optimal watermark position
// (avoiding all text bounding boxes)

let watermarkX = pageInfo.dimensions.width / 2;
let watermarkY = pageInfo.dimensions.height / 2;

// Check for overlaps and adjust position
for (const textItem of textInfo.textItems) {
  const textBox = textItem.bounds;
  
  // If watermark would overlap this text, move it
  if (watermarkX >= textBox.x && watermarkX <= textBox.x + textBox.width &&
      watermarkY >= textBox.y && watermarkY <= textBox.y + textBox.height) {
    // Move watermark to bottom-right corner instead
    watermarkX = pageInfo.dimensions.width - 200;
    watermarkY = 100;
    break;
  }
}

// 4. Add watermark at optimal position
const result = await add-pdf-watermark({
  filePath: "report.pdf",
  text: "DRAFT",
  position: "custom",
  x: watermarkX,
  y: watermarkY,
  fontSize: 48,
  opacity: 0.2,
  rotation: -45,
  color: { r: 0.7, g: 0.7, b: 0.7 }
});

console.log(`Watermark added: ${result.outputPath}`);
```

---

## Performance Considerations

### Page Analysis
- **Speed**: Very fast (~10-50ms per page)
- **Memory**: Minimal (< 5MB per page)
- **Scalability**: Can analyze 1000+ pages efficiently

### Text Position Detection
- **Speed**: Moderate (~50-200ms per page depending on text density)
- **Memory**: Moderate (10-50MB per page depending on content)
- **Scalability**: Best for on-demand analysis of specific pages
- **Tip**: Use `maxResults` to limit data for large documents

---

## Troubleshooting

### Issue: "Invalid page number"
**Solution**: Ensure page numbers are 1-indexed (first page = 1, not 0)

### Issue: "File not found"
**Solution**: Check file path. Use absolute paths or ensure file is in common folders (Downloads, Documents)

### Issue: Text position detection returns empty array
**Solution**: 
- PDF may contain images of text (not actual text)
- Try OCR preprocessing if needed
- Check if PDF is a scanned document

### Issue: Margins seem incorrect
**Solution**: 
- Margins are estimated for standard page sizes
- Use text position detection to find actual content boundaries
- Calculate custom margins from text bounding boxes

---

## Related Documentation

- [Watermark Tool Documentation](./EXAMPLES.md#watermarks)
- [Header/Footer Tool Documentation](./EXAMPLES.md#headers-and-footers)
- [Complete Usage Guide](./USAGE_GUIDE.md)
- [API Reference](./README.md)

---

## Support

For issues, questions, or feature requests related to these tools, please:
1. Check the troubleshooting section above
2. Review the examples in this documentation
3. Open an issue on GitHub with detailed information

---

**Version**: 2.1.0  
**Last Updated**: October 30, 2025  
**Tools Added**: `analyze-pdf-page`, `detect-text-position`
