zcatpdf/CLAUDE.md
reugenio 236cf7f328 feat: v0.4 - Utilities (Table, Pagination, Headers/Footers, Links)
Phase 4 Implementation:
- Table helper (src/table.zig):
  - Table.init() with TableOptions (col_widths, colors, fonts)
  - header(), row(), rowStyled(), footer() methods
  - setColumnAlign() for per-column alignment
  - separator() and space() utilities

- Pagination module (src/pagination.zig):
  - Pagination.addPageNumbers() with {PAGE}/{PAGES} format
  - addHeader() with optional separator line
  - addFooter() and addFooterWithLine()
  - Position enum (bottom_left, bottom_center, etc.)

- Links visual styling (src/links.zig, src/page.zig):
  - PageLinks struct for link storage
  - Page.drawLink() - blue underlined text
  - Page.writeLink() - link at current position

- Examples:
  - table_demo.zig - 3 table styles (product, invoice, employee)
  - pagination_demo.zig - 5 pages with headers/footers/numbers

~70 tests passing, 6 examples working.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-08 20:45:33 +01:00

372 lines
11 KiB
Markdown

# zpdf - Generador PDF para Zig
> **Ultima actualizacion**: 2025-12-08
> **Lenguaje**: Zig 0.15.2
> **Estado**: v0.4 - Imagenes + Utilidades (Table, Pagination, Headers/Footers, Links)
> **Fuente principal**: fpdf2 (Python) - https://github.com/py-pdf/fpdf2
## Descripcion del Proyecto
**zpdf** es una libreria pura Zig para generacion de documentos PDF. Sin dependencias externas, compila a un binario unico.
**Filosofia**:
- Zero dependencias (100% Zig puro)
- API simple y directa inspirada en fpdf2
- Enfocado en generacion de facturas/documentos comerciales
- Soporte para texto, tablas, imagenes y formas basicas
- Calidad open source (doc comments, codigo claro)
**Objetivo**: Ser el pilar para generar PDFs en Zig con codigo 100% propio, replicando funcionalidad de librerias maduras como fpdf2/gofpdf.
---
## Estado Actual del Proyecto
### Implementacion v0.4
| Componente | Estado | Archivo |
|------------|--------|---------|
| **Pdf (API Principal)** | | |
| Pdf init/deinit | OK | `src/pdf.zig` |
| setTitle, setAuthor, setSubject | OK | `src/pdf.zig` |
| addPage (with options) | OK | `src/pdf.zig` |
| addJpegImage / addJpegImageFromFile | OK | `src/pdf.zig` |
| output() / render() | OK | `src/pdf.zig` |
| save() | OK | `src/pdf.zig` |
| **Page** | | |
| Page init/deinit | OK | `src/page.zig` |
| setFont / getFont / getFontSize | OK | `src/page.zig` |
| setFillColor / setStrokeColor / setTextColor | OK | `src/page.zig` |
| setXY / setX / setY / getX / getY | OK | `src/page.zig` |
| setMargins / setCellMargin | OK | `src/page.zig` |
| drawText / writeText | OK | `src/page.zig` |
| **drawLink / writeLink** | OK | `src/page.zig` |
| cell() / cellAdvanced() | OK | `src/page.zig` |
| multiCell() | OK | `src/page.zig` |
| ln() | OK | `src/page.zig` |
| drawLine / drawRect / fillRect | OK | `src/page.zig` |
| **image() / imageFit()** | OK | `src/page.zig` |
| **Table Helper** | | |
| Table.init() | OK | `src/table.zig` |
| Table.header() | OK | `src/table.zig` |
| Table.row() / rowStyled() | OK | `src/table.zig` |
| Table.footer() | OK | `src/table.zig` |
| Table.separator() / space() | OK | `src/table.zig` |
| setColumnAlign() / setColumnAligns() | OK | `src/table.zig` |
| **Pagination** | | |
| Pagination.addPageNumbers() | OK | `src/pagination.zig` |
| Pagination.addFooter() | OK | `src/pagination.zig` |
| addHeader() | OK | `src/pagination.zig` |
| addFooterWithLine() | OK | `src/pagination.zig` |
| **Images** | | |
| JPEG embedding (DCT passthrough) | OK | `src/images/jpeg.zig` |
| PNG metadata parsing | OK | `src/images/png.zig` |
| ImageInfo struct | OK | `src/images/image_info.zig` |
| **Types** | | |
| PageSize enum (A4, Letter, A3, A5, Legal) | OK | `src/objects/base.zig` |
| Font enum (14 Type1 fonts) | OK | `src/fonts/type1.zig` |
| Color struct (RGB, CMYK, Grayscale) | OK | `src/graphics/color.zig` |
| Align enum / Border struct | OK | `src/page.zig` |
| TableOptions struct | OK | `src/table.zig` |
| PageNumberOptions / HeaderOptions / FooterOptions | OK | `src/pagination.zig` |
### Tests
| Categoria | Tests | Estado |
|-----------|-------|--------|
| root.zig (integration) | 8 | OK |
| page.zig (Page operations) | 18 | OK |
| content_stream.zig | 6 | OK |
| graphics/color.zig | 5 | OK |
| fonts/type1.zig | 5 | OK |
| objects/base.zig | 5 | OK |
| output/producer.zig | 5 | OK |
| images/jpeg.zig | 4 | OK |
| images/png.zig | 3 | OK |
| table.zig | 3 | OK |
| pagination.zig | 2 | OK |
| links.zig | 2 | OK |
| **Total** | **~70** | OK |
### Ejemplos
| Ejemplo | Descripcion | Estado |
|---------|-------------|--------|
| hello.zig | PDF minimo con texto y formas | OK |
| invoice.zig | Factura completa realista | OK |
| text_demo.zig | Demo sistema de texto | OK |
| image_demo.zig | Demo imagenes JPEG | OK |
| **table_demo.zig** | Demo Table helper (3 estilos de tabla) | OK |
| **pagination_demo.zig** | Demo paginacion (5 paginas, headers, footers) | OK |
---
## Arquitectura Modular
```
zpdf/
├── CLAUDE.md # Este archivo - estado del proyecto
├── build.zig # Sistema de build
├── src/
│ ├── root.zig # Exports publicos + Document legacy
│ ├── pdf.zig # Pdf facade (API principal)
│ ├── page.zig # Page + sistema de texto
│ ├── content_stream.zig # Content stream (operadores PDF)
│ ├── table.zig # Table helper
│ ├── pagination.zig # Numeracion de paginas, headers, footers
│ ├── links.zig # Links/URLs (estructura)
│ ├── fonts/
│ │ ├── mod.zig # Exports de fonts
│ │ └── type1.zig # 14 fuentes Type1 + metricas
│ ├── graphics/
│ │ ├── mod.zig # Exports de graphics
│ │ └── color.zig # Color (RGB, CMYK, Gray)
│ ├── images/
│ │ ├── mod.zig # Exports + detectFormat()
│ │ ├── image_info.zig # ImageInfo struct
│ │ ├── jpeg.zig # JPEG parser (DCT passthrough)
│ │ └── png.zig # PNG metadata parser
│ ├── objects/
│ │ ├── mod.zig # Exports de objects
│ │ └── base.zig # PageSize, Orientation, Unit
│ └── output/
│ ├── mod.zig # Exports de output
│ └── producer.zig # OutputProducer (serializa PDF + imagenes)
└── examples/
├── hello.zig # Ejemplo basico
├── invoice.zig # Factura ejemplo
├── text_demo.zig # Demo sistema de texto
├── image_demo.zig # Demo imagenes
├── table_demo.zig # Demo tablas
└── pagination_demo.zig # Demo paginacion
```
---
## Roadmap
### Fase 1 - Core + Refactoring (COMPLETADO)
- [x] Estructura documento PDF 1.4
- [x] Paginas (A4, Letter, A3, A5, Legal, custom)
- [x] Texto basico (14 fuentes Type1 built-in)
- [x] Lineas y rectangulos
- [x] Colores RGB, CMYK, Grayscale
- [x] Serializacion correcta
- [x] Refactoring modular
### Fase 2 - Sistema de Texto (COMPLETADO)
- [x] cell() - celda con bordes, relleno, alineacion
- [x] multiCell() - texto con word wrap automatico
- [x] ln() - salto de linea
- [x] Alineacion (left, center, right)
- [x] Bordes configurables
### Fase 3 - Imagenes (COMPLETADO)
- [x] JPEG embebido (DCT passthrough, sin re-encoding)
- [x] PNG metadata parsing (embedding pendiente por zlib API)
- [x] image() - dibujar imagen en posicion
- [x] imageFit() - escalar manteniendo aspect ratio
### Fase 4 - Utilidades (COMPLETADO)
- [x] Table helper (header, row, footer, estilos, alineacion por columna)
- [x] Numeracion de paginas (Pagination.addPageNumbers)
- [x] Headers automaticos (addHeader con linea separadora)
- [x] Footers automaticos (addFooter, addFooterWithLine)
- [x] Links visuales (drawLink, writeLink - azul + subrayado)
### Fase 5 - Avanzado (FUTURO)
- [ ] Link annotations (clickeables en PDF)
- [ ] PNG embedding completo
- [ ] Fuentes TTF embebidas
- [ ] Compresion de streams (zlib)
- [ ] Bookmarks/outline
---
## API Actual
### Crear Documento y Paginas
```zig
const zpdf = @import("zpdf");
var doc = zpdf.Pdf.init(allocator, .{
.page_size = .a4,
.orientation = .portrait,
});
defer doc.deinit();
doc.setTitle("Mi Documento");
doc.setAuthor("zpdf");
var page = try doc.addPage(.{});
try doc.save("documento.pdf");
```
### Sistema de Texto
```zig
// cell() - celda con bordes y alineacion
try page.cell(100, 20, "Hello", zpdf.Border.all, .center, true);
// multiCell() - word wrap automatico
try page.multiCell(400, null, texto_largo, zpdf.Border.none, .left, false);
// ln() - salto de linea
page.ln(20);
```
### Table Helper
```zig
const widths = [_]f32{ 200, 100, 100 };
var table = zpdf.Table.init(page, .{
.x = 50,
.y = 700,
.col_widths = &widths,
.header_bg = zpdf.Color.rgb(41, 98, 255),
});
table.setColumnAlign(0, .left);
table.setColumnAlign(1, .center);
table.setColumnAlign(2, .right);
try table.header(&.{ "Producto", "Cantidad", "Precio" });
try table.row(&.{ "Widget A", "10", "$50.00" });
try table.row(&.{ "Widget B", "5", "$25.00" });
try table.footer(&.{ "Total", "", "$75.00" });
```
### Paginacion y Headers/Footers
```zig
// Agregar numeros de pagina a todas las paginas
try zpdf.Pagination.addPageNumbers(&doc, .{
.format = "Page {PAGE} of {PAGES}",
.position = .bottom_center,
});
// Header con linea separadora
try zpdf.addHeader(&doc, "Documento Confidencial", .{
.alignment = .center,
.draw_line = true,
});
// Footer con linea
try zpdf.addFooterWithLine(&doc, "Copyright 2025", .{
.alignment = .left,
.draw_line = true,
});
```
### Imagenes JPEG
```zig
// Cargar imagen desde archivo
const img_idx = try doc.addJpegImageFromFile("foto.jpg");
const info = doc.getImage(img_idx).?;
// Dibujar en la pagina
try page.image(img_idx, info, 50, 500, 200, 150);
// O escalar automaticamente manteniendo aspect ratio
try page.imageFit(img_idx, info, 50, 500, 400, 300);
```
### Links Visuales
```zig
// Texto con estilo de link (azul + subrayado)
_ = try page.drawLink(100, 700, "Visita nuestra web");
// O desde la posicion actual
_ = try page.writeLink("Click aqui");
```
---
## Comandos
```bash
# Zig path
ZIG=/mnt/cello2/arno/re/recode/zig/zig-0.15.2/zig-x86_64-linux-0.15.2/zig
# Compilar todo
$ZIG build
# Tests
$ZIG build test
# Ejecutar ejemplos
./zig-out/bin/hello
./zig-out/bin/invoice
./zig-out/bin/text_demo
./zig-out/bin/image_demo
./zig-out/bin/table_demo
./zig-out/bin/pagination_demo
```
---
## Historial de Desarrollo
### 2025-12-08 - v0.4 (Imagenes + Utilidades)
- **Fase 3 - Imagenes**:
- JPEG embedding con DCT passthrough (sin re-encoding)
- PNG metadata parsing (embedding pendiente)
- image() y imageFit() en Page
- XObject generation en OutputProducer
- **Fase 4 - Utilidades**:
- Table helper completo (header, row, footer, estilos)
- Alineacion por columna en tablas
- Pagination.addPageNumbers() con formato {PAGE}/{PAGES}
- addHeader() y addFooterWithLine() con lineas separadoras
- drawLink() y writeLink() para texto estilo link
- 6 ejemplos funcionales
- ~70 tests pasando
### 2025-12-08 - v0.3 (Imagenes)
- Modulo images/ (jpeg.zig, png.zig, image_info.zig)
- addJpegImage() y addJpegImageFromFile() en Pdf
- image_demo.zig ejemplo
- 66 tests pasando
### 2025-12-08 - v0.2 (Sistema de Texto)
- Refactoring modular completo
- Sistema de texto: cell, multiCell, ln, alineacion, bordes
- Nueva API Pdf
- 52 tests
### 2025-12-08 - v0.1 (Core)
- Estructura inicial, Document, Page, Font, Color
- Graficos basicos, serializacion PDF 1.4
---
## Equipo y Metodologia
### Normas de Trabajo
**IMPORTANTE**: Todas las normas de trabajo estan en:
```
/mnt/cello2/arno/re/recode/TEAM_STANDARDS/
```
### Control de Versiones
```bash
git remote: git@git.reugenio.com:reugenio/zpdf.git
```
---
## Referencias
- **fpdf2 (Python)**: https://github.com/py-pdf/fpdf2
- **PDF 1.4 Spec**: https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/pdfreference1.4.pdf
- **pdf-nano (Zig)**: https://github.com/GregorBudweiser/pdf-nano
---
**zpdf - Generador PDF para Zig**
*v0.4 - 2025-12-08*