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>
372 lines
11 KiB
Markdown
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*
|