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>
11 KiB
11 KiB
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)
- Estructura documento PDF 1.4
- Paginas (A4, Letter, A3, A5, Legal, custom)
- Texto basico (14 fuentes Type1 built-in)
- Lineas y rectangulos
- Colores RGB, CMYK, Grayscale
- Serializacion correcta
- Refactoring modular
Fase 2 - Sistema de Texto (COMPLETADO)
- cell() - celda con bordes, relleno, alineacion
- multiCell() - texto con word wrap automatico
- ln() - salto de linea
- Alineacion (left, center, right)
- Bordes configurables
Fase 3 - Imagenes (COMPLETADO)
- JPEG embebido (DCT passthrough, sin re-encoding)
- PNG metadata parsing (embedding pendiente por zlib API)
- image() - dibujar imagen en posicion
- imageFit() - escalar manteniendo aspect ratio
Fase 4 - Utilidades (COMPLETADO)
- Table helper (header, row, footer, estilos, alineacion por columna)
- Numeracion de paginas (Pagination.addPageNumbers)
- Headers automaticos (addHeader con linea separadora)
- Footers automaticos (addFooter, addFooterWithLine)
- 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
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
// 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
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
// 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
// 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
// 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
# 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
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