Phase 1 - Refactoring: - Modular architecture: fonts/, graphics/, objects/, output/ - Fixed Zig 0.15 API changes (ArrayListUnmanaged) - Fixed memory issues in render() Phase 2 - Text System: - cell() with borders, fill, alignment - cellAdvanced() with position control - multiCell() with automatic word wrap - ln() for line breaks - getStringWidth() for text width calculation - Page margins (setMargins, setCellMargin) - Align enum (left, center, right) - Border packed struct New features: - New Pdf API (cleaner than legacy Document) - Document metadata (setTitle, setAuthor, setSubject) - Color: RGB, CMYK, Grayscale support - 52 unit tests passing - New example: text_demo.zig 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
12 KiB
12 KiB
zpdf - Generador PDF para Zig
Ultima actualizacion: 2025-12-08 Lenguaje: Zig 0.15.2 Estado: v0.2 - Sistema de texto completo (cell, multiCell, alignment) 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.2 (Sistema de Texto Completo)
| Componente | Estado | Archivo |
|---|---|---|
| Pdf (API Nueva) | ||
| Pdf init/deinit | OK | src/pdf.zig |
| setTitle, setAuthor, setSubject | OK | src/pdf.zig |
| addPage (with options) | OK | src/pdf.zig |
| output() / render() | OK | src/pdf.zig |
| save() | OK | src/pdf.zig |
| Document (Legacy) | ||
| Document init/deinit | OK | src/root.zig |
| addPage (standard sizes) | OK | src/root.zig |
| render() / saveToFile() | OK | src/root.zig |
| Page | ||
| Page init/deinit | OK | src/page.zig |
| setFont / getFont / getFontSize | OK | src/page.zig |
| setFillColor / setStrokeColor / setTextColor | OK | src/page.zig |
| setLineWidth | OK | src/page.zig |
| setXY / setX / setY / getX / getY | OK | src/page.zig |
| setMargins / setCellMargin | OK | src/page.zig |
| drawText | OK | src/page.zig |
| writeText | OK | src/page.zig |
| cell() | OK | src/page.zig |
| cellAdvanced() | OK | src/page.zig |
| multiCell() | OK | src/page.zig |
| ln() | OK | src/page.zig |
| getStringWidth() | OK | src/page.zig |
| getEffectiveWidth() | OK | src/page.zig |
| drawLine | OK | src/page.zig |
| drawRect / fillRect / drawFilledRect | OK | src/page.zig |
| rect (with RenderStyle) | OK | src/page.zig |
| Types | ||
| PageSize enum (A4, Letter, A3, A5, Legal) | OK | src/objects/base.zig |
| Orientation enum (portrait, landscape) | 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 (left, center, right) | OK | src/page.zig |
| Border packed struct | OK | src/page.zig |
| CellPosition enum | OK | src/page.zig |
| ContentStream | OK | src/content_stream.zig |
| OutputProducer | OK | src/output/producer.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 |
| Total | 52 | 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 (cells, tables, multiCell) | 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 nueva)
│ ├── page.zig # Page + sistema de texto
│ ├── content_stream.zig # Content stream (operadores PDF)
│ ├── fonts/
│ │ ├── mod.zig # Exports de fonts
│ │ └── type1.zig # 14 fuentes Type1 + metricas
│ ├── graphics/
│ │ ├── mod.zig # Exports de graphics
│ │ └── color.zig # Color (RGB, CMYK, Gray)
│ ├── objects/
│ │ ├── mod.zig # Exports de objects
│ │ └── base.zig # PageSize, Orientation, Unit
│ └── output/
│ ├── mod.zig # Exports de output
│ └── producer.zig # OutputProducer (serializa PDF)
├── examples/
│ ├── hello.zig # Ejemplo basico
│ ├── invoice.zig # Factura ejemplo
│ └── text_demo.zig # Demo sistema de texto
└── docs/
├── PLAN_MAESTRO_ZPDF.md
├── ARQUITECTURA_FPDF2.md
└── ARQUITECTURA_ZPDF.md
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 (separar en archivos)
- Arreglar errores Zig 0.15 (ArrayListUnmanaged)
Fase 2 - Sistema de Texto (COMPLETADO)
- cell() - celda con bordes, relleno, alineacion
- cellAdvanced() - cell con control de posicion
- multiCell() - texto con word wrap automatico
- ln() - salto de linea
- getStringWidth() - ancho de texto
- Alineacion (left, center, right)
- Bordes configurables (Border packed struct)
- Margenes de pagina
- 18 tests para sistema de texto
Fase 3 - Imagenes (PENDIENTE)
- JPEG embebido
- PNG embebido (con alpha)
- Escalado y posicionamiento
- Aspect ratio preservation
Fase 4 - Utilidades (PENDIENTE)
- Helper para tablas
- Numeracion de paginas
- Headers/footers automaticos
- Links/URLs
Fase 5 - Avanzado (FUTURO)
- Fuentes TTF embebidas
- Compresion de streams (zlib)
- Bookmarks/outline
- Forms (campos rellenables)
API Actual
API Nueva (Pdf)
const zpdf = @import("zpdf");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
// Crear documento
var doc = zpdf.Pdf.init(allocator, .{
.page_size = .a4,
.orientation = .portrait,
});
defer doc.deinit();
// Metadatos
doc.setTitle("Mi Documento");
doc.setAuthor("zpdf");
// Agregar pagina
var page = try doc.addPage(.{});
// Configurar fuente y posicion
try page.setFont(.helvetica_bold, 24);
page.setXY(50, 800);
page.setMargins(50, 50, 50);
// cell() - celda simple
try page.cell(0, 30, "Titulo", zpdf.Border.none, .center, false);
page.ln(35);
// Tabla con cells
try page.setFont(.helvetica, 12);
page.setFillColor(zpdf.Color.light_gray);
try page.cell(150, 20, "Columna 1", zpdf.Border.all, .center, true);
try page.cell(150, 20, "Columna 2", zpdf.Border.all, .center, true);
page.ln(null);
// multiCell - texto con word wrap
const texto_largo = "Este es un texto largo que se ajustara automaticamente...";
try page.multiCell(400, null, texto_largo, zpdf.Border.all, .left, false);
// Guardar
try doc.save("documento.pdf");
}
API Legacy (Document)
const pdf = @import("zpdf");
var doc = pdf.Document.init(allocator);
defer doc.deinit();
var page = try doc.addPage(.a4);
try page.setFont(.helvetica_bold, 24);
try page.drawText(50, 750, "Titulo");
try doc.saveToFile("documento.pdf");
Sistema de Texto
// cell(width, height, text, border, align, fill)
// width=0 extiende hasta margen derecho
// width=null ajusta al ancho del texto
try page.cell(100, 20, "Hello", Border.all, .left, false);
try page.cell(0, 20, "Full width", Border.none, .center, true);
// cellAdvanced - control de posicion despues de la celda
try page.cellAdvanced(100, 20, "A", Border.all, .left, false, .right); // mover a la derecha
try page.cellAdvanced(100, 20, "B", Border.all, .left, false, .next_line); // nueva linea
try page.cellAdvanced(100, 20, "C", Border.all, .left, false, .below); // debajo (mismo X)
// multiCell - word wrap automatico
try page.multiCell(200, 15, "Texto largo que se ajusta automaticamente al ancho especificado.", Border.all, .left, true);
// ln(height) - salto de linea
page.ln(20); // salto de 20 puntos
page.ln(null); // salto del tamano de fuente actual
// getStringWidth - ancho del texto
const width = page.getStringWidth("Hello World");
Bordes
const Border = packed struct {
left: bool,
top: bool,
right: bool,
bottom: bool,
};
Border.none // sin bordes
Border.all // todos los bordes
Border{ .left = true, .bottom = true } // bordes especificos
Border.fromInt(0b1111) // desde entero (LTRB)
Alineacion
const Align = enum { left, center, right };
try page.cell(100, 20, "Left", Border.all, .left, false);
try page.cell(100, 20, "Center", Border.all, .center, false);
try page.cell(100, 20, "Right", Border.all, .right, false);
Colores
// Predefinidos
zpdf.Color.black
zpdf.Color.white
zpdf.Color.red
zpdf.Color.green
zpdf.Color.blue
zpdf.Color.light_gray
zpdf.Color.medium_gray
// RGB (0-255)
zpdf.Color.rgb(41, 98, 255)
// Hex
zpdf.Color.hex(0xFF8000)
// CMYK (0.0-1.0)
zpdf.Color.cmyk(0.0, 1.0, 1.0, 0.0)
// Grayscale (0.0-1.0)
zpdf.Color.gray(0.5)
Comandos
# Zig path
ZIG=/mnt/cello2/arno/re/recode/zig/zig-0.15.2/zig-x86_64-linux-0.15.2/zig
# Compilar
$ZIG build
# Tests
$ZIG build test
# Ejecutar ejemplos
$ZIG build && ./zig-out/bin/hello
$ZIG build && ./zig-out/bin/invoice
$ZIG build && ./zig-out/bin/text_demo
Fuentes Type1 Built-in
PDF incluye 14 fuentes estandar que no necesitan embeber:
| Familia | Variantes |
|---|---|
| Helvetica | helvetica, helvetica_bold, helvetica_oblique, helvetica_bold_oblique |
| Times | times_roman, times_bold, times_italic, times_bold_italic |
| Courier | courier, courier_bold, courier_oblique, courier_bold_oblique |
| Otros | symbol, zapf_dingbats |
Tamanos de Pagina
| Nombre | Puntos | Milimetros |
|---|---|---|
| A4 | 595 x 842 | 210 x 297 |
| A3 | 842 x 1191 | 297 x 420 |
| A5 | 420 x 595 | 148 x 210 |
| Letter | 612 x 792 | 216 x 279 |
| Legal | 612 x 1008 | 216 x 356 |
Equipo y Metodologia
Normas de Trabajo Centralizadas
IMPORTANTE: Todas las normas de trabajo estan en:
/mnt/cello2/arno/re/recode/TEAM_STANDARDS/
Control de Versiones
# Remote
git remote: git@git.reugenio.com:reugenio/zpdf.git
# Branches
main # Codigo estable
Historial de Desarrollo
2025-12-08 - v0.2 (Sistema de Texto Completo)
- Refactoring modular completo (fonts/, graphics/, objects/, output/)
- Arreglados errores Zig 0.15 (ArrayListUnmanaged API)
- Sistema de texto completo:
- cell() con bordes, relleno, alineacion
- cellAdvanced() con control de posicion
- multiCell() con word wrap automatico
- ln() para saltos de linea
- getStringWidth() para calcular anchos
- Margenes de pagina configurables
- Nueva API Pdf (mas limpia que Document legacy)
- 52 tests unitarios pasando
- Nuevo ejemplo: text_demo.zig
2025-12-08 - v0.1 (Core Funcional)
- Estructura inicial del proyecto
- Document, Page, Color, Font, PageSize types
- Texto con 14 fuentes Type1 standard
- Graficos: lineas, rectangulos (stroke, fill, both)
- Colores RGB
- Serializacion PDF 1.4 correcta
- 6 tests unitarios pasando
- Ejemplos: hello.zig, invoice.zig funcionales
Referencias
- fpdf2 (Python): https://github.com/py-pdf/fpdf2 - Fuente principal
- 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.2 - 2025-12-08