Compare commits

..

13 commits
v1.0 ... main

Author SHA1 Message Date
ae11220ee8 Estandarizar: CLAUDE.md → claude.md + refs CREDENCIALES
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 15:13:50 +01:00
d3deca21cc Actualizar /init para leer credenciales e infraestructura
Nuevo protocolo lee 4 archivos:
1. claude.md (proyecto)
2. NORMAS_ESENCIALES.md
3. INFRAESTRUCTURA_RAPIDA.md (nuevo)
4. INFRASTRUCTURE/CREDENCIALES.md (nuevo)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 00:40:20 +01:00
ba5aa1d8f0 chore: Migración jj → git puro
- CLAUDE.md: VCS jj → git

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 13:27:19 +01:00
0d37e792e5 docs: Añadir sección LSP/zls a CLAUDE.md 2025-12-29 12:33:13 +01:00
5f35a12d22 CLAUDE.md: jj + NORMAS_ESENCIALES 2025-12-25 19:24:22 +01:00
R.Eugenio
9b982a3c66 Añadir /init optimizado (lee NORMAS_ESENCIALES + teamdocs)
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 13:28:54 +01:00
2bc1eb83c2 docs: Add Known Limitations section (TTF subsetting)
Document that TTF font subsetting is not yet implemented - entire font
files are embedded rather than just glyphs used. Planned for future.

Reported by: Gemini audit (2025-12-14)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 19:41:31 +01:00
121cf043da docs: Renombrar TEAM_STANDARDS a teamdocs
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 19:33:44 +01:00
871b3e548f docs: Add VERIFIED_FEATURES.md - tracking production-tested features
Documento inicial - ninguna feature verificada en producción aún.
Lista completa de features para verificar cuando se use en zsimifactu.

Próximos a verificar: PDF básico, texto, tablas, códigos de barras

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 12:00:55 +01:00
8036a46146 🔧 ADD: ZIG_VERSION_NOTES.md - Referencia sistema notas versiones Zig
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 23:01:16 +01:00
a7cd3894da docs: Update CLAUDE.md with correct repo URL and TEAM_STANDARDS references
- Updated repository URL to include port 2222
- Added Forgejo web URL
- Added references to docs/ folder documentation
- Added TEAM_STANDARDS section with key files
- Updated Git section to reflect completed rename (zpdf → zcatpdf)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 02:34:19 +01:00
9ae8758ed8 docs: Update CLAUDE.md with comprehensive context for new conversations
Prepares documentation for directory rename (zpdf → zcatpdf):
- Complete project overview and feature status
- Documentation references (README.md, FUTURE_IMPROVEMENTS.md)
- Architecture diagram and usage examples
- Git instructions including post-rename steps
- zcat* family ecosystem information

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 02:15:44 +01:00
f09922076f refactor: Rename zpdf to zcatpdf for consistency with zcat* family
- Renamed all references from zpdf to zcatpdf
- Module import: @import("zcatpdf")
- Consistent with zcatui, zcatgui naming convention
- All lowercase per Zig standards

Note: Directory rename (zpdf -> zcatpdf) and Forgejo repo rename
should be done manually after this commit.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 02:10:57 +01:00
32 changed files with 647 additions and 932 deletions

8
.claude/commands/init.md Normal file
View file

@ -0,0 +1,8 @@
Protocolo de inicio - Lee estos archivos EN PARALELO: (project)
1. CLAUDE.md (contexto del proyecto zcatpdf)
2. /mnt/cello2/arno/re/recode/teamdocs/NORMAS_ESENCIALES.md (normas de trabajo)
3. /mnt/cello2/arno/re/recode/teamdocs/INFRAESTRUCTURA_RAPIDA.md (recursos disponibles)
4. /mnt/cello2/arno/re/recode/teamdocs/INFRASTRUCTURE/CREDENCIALES.md (credenciales servidores)
Después de leer, confirma brevemente qué sabes y pregunta en qué puedes ayudar.

5
.gitignore vendored
View file

@ -6,3 +6,8 @@ zig-out/
*.so
*.pdf
reference/
# Claude Code settings (ignorar), pero commands se versionan
.claude/settings*.json
.claude/*.json
!.claude/commands/

757
CLAUDE.md
View file

@ -1,757 +0,0 @@
# zpdf - Generador PDF para Zig
> **Ultima actualizacion**: 2025-12-09
> **Lenguaje**: Zig 0.15.2
> **Estado**: v1.0 - RELEASE (FEATURE COMPLETE)
> **Fuente principal**: fpdf2 (Python) - https://github.com/py-pdf/fpdf2
## Descripcion del Proyecto
**zpdf** es una libreria pura Zig para generacion de documentos PDF. Compila a un binario unico con minimas dependencias.
**Filosofia**:
- Minimas dependencias (libdeflate para compresion)
- API simple y directa inspirada en fpdf2
- Enfocado en generacion de facturas/documentos comerciales
- Soporte completo: texto, tablas, imagenes, links, graficos vectoriales
**Caracteristicas principales**:
- Sistema de texto completo (cell, multiCell, alineacion, word wrap)
- 14 fuentes Type1 standard (Helvetica, Times, Courier, etc.)
- Imagenes JPEG y PNG (con alpha/transparencia)
- Compresion FlateDecode para streams e imagenes
- Table helper para tablas formateadas
- Paginacion automatica (numeros de pagina, headers, footers)
- Links clickeables (URLs externas + links internos entre paginas)
- Bookmarks/Outline para navegacion en sidebar
- Curvas Bezier, circulos, elipses, arcos
- Transformaciones (rotacion, escala, skew, traslacion)
- Transparencia/Opacidad (fill y stroke alpha)
- Gradientes lineales y radiales (Shading Patterns)
- Barcodes: Code128 (1D) y QR Code (2D)
- TrueType font parsing (family, metrics, glyph widths)
- Security: RC4 encryption, permission flags
- Forms: AcroForms (text fields, checkboxes)
- SVG import (basic path/shape support)
- Templates: Reusable document layouts
- Markdown: Styled text (bold, italic, links, headings, lists)
- Colores RGB, CMYK, Grayscale
---
## Estado Actual - v1.0
### Funcionalidades Implementadas
| Categoria | Funcionalidad | Estado |
|-----------|---------------|--------|
| **Documento** | | |
| | Crear PDF 1.4 | OK |
| | Metadatos (titulo, autor, etc.) | OK |
| | Multiples paginas | OK |
| | Tamanos estandar (A4, Letter, A3, A5, Legal) | OK |
| | Compresion FlateDecode configurable | OK |
| | Bookmarks/Outline | OK |
| **Texto** | | |
| | drawText() - texto en posicion | OK |
| | cell() - celda con bordes/relleno | OK |
| | multiCell() - word wrap automatico | OK |
| | Alineacion (left, center, right) | OK |
| | 14 fuentes Type1 standard | OK |
| **Graficos** | | |
| | Lineas | OK |
| | Rectangulos (stroke, fill) | OK |
| | Curvas Bezier (cubicas, cuadraticas) | OK |
| | Circulos y elipses | OK |
| | Arcos | OK |
| | Colores RGB/CMYK/Gray | OK |
| **Transformaciones** | | |
| | Rotacion (alrededor de punto) | OK |
| | Escala (desde punto) | OK |
| | Traslacion | OK |
| | Skew/Shear | OK |
| | Matriz personalizada | OK |
| | saveState()/restoreState() | OK |
| **Transparencia** | | |
| | Fill opacity (0.0-1.0) | OK |
| | Stroke opacity (0.0-1.0) | OK |
| | ExtGState resources | OK |
| **Gradientes** | | |
| | Linear gradients (horizontal, vertical, diagonal) | OK |
| | Radial gradients (circle, ellipse) | OK |
| | Shading Patterns (Type 2, Type 3) | OK |
| **Barcodes** | | |
| | Code128 (1D barcode) | OK |
| | QR Code (2D barcode) | OK |
| | Error correction levels (L, M, Q, H) | OK |
| | drawCode128() / drawCode128WithText() | OK |
| | drawQRCode() | OK |
| **TrueType Fonts** | | |
| | TTF file parsing | OK |
| | Font metrics (ascender, descender, etc.) | OK |
| | Glyph widths | OK |
| | Character to glyph mapping (cmap) | OK |
| | addTtfFontFromFile() | OK |
| **Security** | | |
| | RC4 cipher (40/128-bit) | OK |
| | User/Owner passwords | OK |
| | Permission flags | OK |
| | MD5 key derivation | OK |
| | Encryption module | OK |
| **Forms** | | |
| | TextField | OK |
| | CheckBox | OK |
| | Field flags | OK |
| | AcroForm basics | OK |
| **SVG** | | |
| | Path parsing | OK |
| | Basic shapes (rect, circle, ellipse, line) | OK |
| | Colors (fill, stroke) | OK |
| | PDF content generation | OK |
| **Templates** | | |
| | Template struct | OK |
| | Named regions | OK |
| | Fixed content | OK |
| | invoiceTemplate() | OK |
| | letterTemplate() | OK |
| **Markdown** | | |
| | Bold (**text**) | OK |
| | Italic (*text*) | OK |
| | Bold+Italic (***text***) | OK |
| | Strikethrough (~~text~~) | OK |
| | Links ([text](url)) | OK |
| | Headings (#, ##, ###) | OK |
| | Bullet lists (- item) | OK |
| | Numbered lists (1. item) | OK |
| **Imagenes** | | |
| | JPEG embedding (passthrough) | OK |
| | PNG embedding (RGB, RGBA, Grayscale, Indexed) | OK |
| | PNG alpha channel (soft masks) | OK |
| | image() / imageFit() | OK |
| | Aspect ratio preservation | OK |
| **Compresion** | | |
| | FlateDecode para content streams | OK |
| | FlateDecode para imagenes PNG | OK |
| | Nivel configurable (0-12) | OK |
| | Heuristica inteligente | OK |
| **Tablas** | | |
| | Table helper | OK |
| | header(), row(), footer() | OK |
| | Alineacion por columna | OK |
| | Estilos personalizados | OK |
| **Paginacion** | | |
| | Numeros de pagina | OK |
| | Headers automaticos | OK |
| | Footers automaticos | OK |
| | skip_pages option | OK |
| **Links** | | |
| | URL links clickeables | OK |
| | Internal page links | OK |
| | Visual styling (azul+subrayado) | OK |
| | Link annotations | OK |
### Tests y Ejemplos
- **125+ tests** unitarios pasando
- **16 ejemplos** funcionales:
- `hello.zig` - PDF minimo
- `invoice.zig` - Factura completa
- `text_demo.zig` - Sistema de texto
- `image_demo.zig` - Imagenes JPEG y PNG
- `table_demo.zig` - Table helper
- `pagination_demo.zig` - Paginacion multi-pagina
- `links_demo.zig` - Links clickeables
- `bookmarks_demo.zig` - Bookmarks en sidebar
- `curves_demo.zig` - Bezier, circulos, elipses, arcos
- `transforms_demo.zig` - Rotacion, escala, skew
- `transparency_demo.zig` - Opacidad/alpha
- `gradient_demo.zig` - Gradientes lineales y radiales
- `barcode_demo.zig` - Code128 y QR codes
- `ttf_demo.zig` - TrueType font parsing
- `template_demo.zig` - Document templates
- `markdown_demo.zig` - Markdown styled text
---
## Arquitectura
```
zpdf/
├── CLAUDE.md # Documentacion del proyecto
├── build.zig # Sistema de build
├── src/
│ ├── root.zig # Exports publicos
│ ├── pdf.zig # Pdf facade (API principal)
│ ├── page.zig # Page + texto + links + transformaciones
│ ├── content_stream.zig # Operadores PDF
│ ├── table.zig # Table helper
│ ├── pagination.zig # Paginacion, headers, footers
│ ├── links.zig # Link types
│ ├── outline.zig # Bookmarks/Outline
│ ├── security/
│ │ ├── mod.zig # Security exports
│ │ ├── rc4.zig # RC4 cipher
│ │ └── encryption.zig # PDF encryption handler
│ ├── forms/
│ │ ├── mod.zig # Forms exports
│ │ └── field.zig # TextField, CheckBox
│ ├── svg/
│ │ ├── mod.zig # SVG exports
│ │ └── parser.zig # SVG parser
│ ├── template/
│ │ ├── mod.zig # Template exports
│ │ └── template.zig # Template, Region definitions
│ ├── markdown/
│ │ ├── mod.zig # Markdown exports
│ │ └── markdown.zig # MarkdownRenderer, TextSpan
│ ├── fonts/
│ │ ├── type1.zig # 14 fuentes Type1 + metricas
│ │ └── ttf.zig # TrueType font parser
│ ├── graphics/
│ │ ├── color.zig # Color (RGB, CMYK, Gray)
│ │ ├── extgstate.zig # Extended Graphics State (transparency)
│ │ └── gradient.zig # Linear/Radial gradients
│ ├── barcodes/
│ │ ├── mod.zig # Barcode exports
│ │ ├── code128.zig # Code128 1D barcode
│ │ └── qr.zig # QR Code 2D barcode
│ ├── images/
│ │ ├── jpeg.zig # JPEG parser
│ │ ├── png.zig # PNG parser + unfiltering
│ │ └── image_info.zig # ImageInfo struct
│ ├── compression/
│ │ ├── mod.zig # Compression exports
│ │ └── zlib.zig # libdeflate wrapper
│ ├── objects/
│ │ └── base.zig # PageSize, Orientation
│ └── output/
│ └── producer.zig # Serializa PDF + images + links + outline
└── examples/
├── hello.zig
├── invoice.zig
├── text_demo.zig
├── image_demo.zig
├── table_demo.zig
├── pagination_demo.zig
├── links_demo.zig
├── bookmarks_demo.zig
├── curves_demo.zig
├── transforms_demo.zig
├── transparency_demo.zig
├── gradient_demo.zig
├── barcode_demo.zig
├── ttf_demo.zig
├── template_demo.zig
└── markdown_demo.zig
```
---
## API Quick Reference
### Documento Basico
```zig
const zpdf = @import("zpdf");
var doc = zpdf.Pdf.init(allocator, .{});
defer doc.deinit();
doc.setTitle("Mi Documento");
var page = try doc.addPage(.{});
try page.setFont(.helvetica_bold, 24);
try page.drawText(50, 750, "Hello, PDF!");
try doc.save("output.pdf");
```
### Celdas y Tablas
```zig
// cell() simple
try page.cell(100, 20, "Hello", zpdf.Border.all, .center, true);
// multiCell con word wrap
try page.multiCell(400, null, texto_largo, zpdf.Border.none, .left, false);
// Table helper
const widths = [_]f32{ 200, 100, 100 };
var table = zpdf.Table.init(page, .{
.col_widths = &widths,
});
try table.header(&.{ "Producto", "Qty", "Precio" });
try table.row(&.{ "Item A", "10", "$50" });
try table.footer(&.{ "Total", "", "$50" });
```
### Imagenes
```zig
const img_idx = try doc.addJpegImageFromFile("foto.jpg");
const info = doc.getImage(img_idx).?;
try page.image(img_idx, info, 50, 500, 200, 150);
```
### Curvas y Formas
```zig
// Curva Bezier cubica
try page.drawBezier(x0, y0, x1, y1, x2, y2, x3, y3);
// Circulo
try page.drawCircle(cx, cy, radius);
try page.fillCircle(cx, cy, radius);
// Elipse
try page.drawEllipse(cx, cy, rx, ry);
try page.fillEllipse(cx, cy, rx, ry);
// Arco
try page.drawArc(cx, cy, rx, ry, start_deg, end_deg);
```
### Transformaciones
```zig
// Rotar alrededor de un punto
try page.saveState();
try page.rotate(45, center_x, center_y); // 45 grados
// ... dibujar contenido rotado ...
try page.restoreState();
// Escalar
try page.scale(2.0, 1.5, cx, cy); // 2x horizontal, 1.5x vertical
// Skew/Shear
try page.skew(15, 0); // 15 grados en X
// Trasladar
try page.translate(100, 50);
```
### Transparencia
```zig
// Opacidad de relleno
try page.setFillOpacity(0.5); // 50% transparente
// Opacidad de trazo
try page.setStrokeOpacity(0.75); // 75% opaco
// Ambos a la vez
try page.setOpacity(0.3); // 30% opaco
// Restaurar opacidad completa
try page.setOpacity(1.0);
```
### Gradientes
```zig
// Gradiente lineal en rectangulo
try page.linearGradientRect(x, y, width, height, Color.red, Color.blue, .horizontal);
try page.linearGradientRect(x, y, width, height, Color.green, Color.yellow, .vertical);
try page.linearGradientRect(x, y, width, height, Color.purple, Color.cyan, .diagonal);
// Gradiente radial en circulo (centro a borde)
try page.radialGradientCircle(cx, cy, radius, Color.white, Color.blue);
// Gradiente radial en elipse
try page.radialGradientEllipse(cx, cy, rx, ry, Color.yellow, Color.red);
```
### Barcodes
```zig
// Code128 1D barcode
try page.drawCode128(x, y, "ABC-12345", 50, 1.5); // height=50, module_width=1.5
// Code128 con texto debajo
try page.drawCode128WithText(x, y, "ABC-12345", 50, 1.5, true);
// QR Code 2D barcode
try page.drawQRCode(x, y, "HTTPS://GITHUB.COM", 100, zpdf.QRCode.ErrorCorrection.M);
// Error correction levels:
// .L - Low (7% recovery)
// .M - Medium (15% recovery)
// .Q - Quartile (25% recovery)
// .H - High (30% recovery)
```
### TrueType Fonts
```zig
// Load TTF font from file
const font_idx = try pdf.addTtfFontFromFile("/path/to/font.ttf");
const font = pdf.getTtfFont(font_idx).?;
// Get font information
std.debug.print("Family: {s}\n", .{font.family_name});
std.debug.print("Units/EM: {d}\n", .{font.units_per_em});
std.debug.print("Ascender: {d}\n", .{font.ascender});
std.debug.print("Descender: {d}\n", .{font.descender});
std.debug.print("Num glyphs: {d}\n", .{font.num_glyphs});
// Get character width
const glyph_id = font.getGlyphIndex('A');
const width = font.getGlyphWidth(glyph_id);
// Calculate string width in points
const text_width = font.stringWidth("Hello", 12.0);
// Note: Full TTF embedding for rendering text requires CIDFont Type 2
// output which is planned for a future version.
```
### Bookmarks
```zig
// Agregar bookmark que apunta a pagina
try doc.addBookmark("Capitulo 1", 0); // pagina 0
// Con posicion Y especifica
try doc.addBookmarkAt("Seccion 1.1", 0, 500);
// Los bookmarks aparecen en el sidebar del lector PDF
```
### Links Clickeables
```zig
// URL link con visual styling
_ = try page.urlLink(100, 700, "Click aqui", "https://example.com");
// O desde posicion actual
_ = try page.writeUrlLink("Visitar web", "https://example.com");
// Link interno (saltar a pagina)
try page.addInternalLink(2, 100, 700, 150, 20); // page 2
```
### Paginacion
```zig
// Numeros de pagina
try zpdf.Pagination.addPageNumbers(&doc, .{
.format = "Page {PAGE} of {PAGES}",
.position = .bottom_center,
});
// Header con linea
try zpdf.addHeader(&doc, "Documento", .{
.draw_line = true,
});
```
---
## Comandos
```bash
# 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
# 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
./zig-out/bin/links_demo
./zig-out/bin/bookmarks_demo
./zig-out/bin/curves_demo
./zig-out/bin/transforms_demo
./zig-out/bin/transparency_demo
./zig-out/bin/gradient_demo
./zig-out/bin/barcode_demo
./zig-out/bin/ttf_demo
```
---
## Roadmap Completado
### Fase 1 - Core (COMPLETADO)
- [x] Estructura PDF 1.4
- [x] Paginas multiples
- [x] Texto basico
- [x] Graficos (lineas, rectangulos)
- [x] Colores
### Fase 2 - Texto Avanzado (COMPLETADO)
- [x] cell() / cellAdvanced()
- [x] multiCell() con word wrap
- [x] Alineacion
- [x] Bordes
### Fase 3 - Imagenes (COMPLETADO)
- [x] JPEG embedding
- [x] image() / imageFit()
- [x] PNG embedding completo
### Fase 4 - Utilidades (COMPLETADO)
- [x] Table helper
- [x] Paginacion
- [x] Headers/Footers
- [x] Links visuales
### Fase 5 - Links Clickeables (COMPLETADO)
- [x] URL annotations
- [x] Internal page links
- [x] Link annotations en PDF
### Fase 6 - PNG + Compresion (COMPLETADO)
- [x] Integracion libdeflate-zig
- [x] PNG parsing completo (RGB, RGBA, Grayscale, Indexed)
- [x] PNG unfiltering (None, Sub, Up, Average, Paeth)
- [x] Soft masks para canal alpha
- [x] FlateDecode para content streams
- [x] Compresion configurable (nivel 0-12)
- [x] Heuristica inteligente (min_size, min_ratio)
### Fase 7 - Bookmarks/Outline (COMPLETADO)
- [x] OutlineItem struct
- [x] addBookmark() / addBookmarkAt()
- [x] Outline en sidebar del lector PDF
### Fase 8 - Curvas Bezier (COMPLETADO)
- [x] drawBezier() - curvas cubicas
- [x] drawQuadBezier() - curvas cuadraticas
- [x] drawCircle() / fillCircle()
- [x] drawEllipse() / fillEllipse()
- [x] drawArc()
### Fase 9 - Transformaciones (COMPLETADO)
- [x] rotate() - rotacion alrededor de punto
- [x] scale() - escala desde punto
- [x] translate() - traslacion
- [x] skew() - deformacion
- [x] transform() - matriz personalizada
- [x] saveState() / restoreState()
### Fase 10 - Transparencia (COMPLETADO)
- [x] ExtGState para opacidad
- [x] setFillOpacity()
- [x] setStrokeOpacity()
- [x] setOpacity()
### Fase 11 - Gradientes (COMPLETADO)
- [x] LinearGradient (horizontal, vertical, diagonal)
- [x] RadialGradient (circle, ellipse)
- [x] Shading Patterns Type 2 (axial) y Type 3 (radial)
- [x] linearGradientRect()
- [x] radialGradientCircle()
- [x] radialGradientEllipse()
### Fase 12 - Barcodes (COMPLETADO)
- [x] Code128 1D barcode (ASCII 0-127)
- [x] Code Sets A, B, C con switching automatico
- [x] QR Code 2D barcode (ISO/IEC 18004)
- [x] Error correction levels (L, M, Q, H)
- [x] drawCode128() / drawCode128WithText()
- [x] drawQRCode()
### Fase 13 - TTF Fonts (COMPLETADO)
- [x] TrueType font file parsing
- [x] Font metrics (units_per_em, ascender, descender, etc.)
- [x] Glyph width tables
- [x] Character to glyph mapping (cmap format 0, 4, 6, 12)
- [x] addTtfFontFromFile()
- [x] stringWidth() calculation
- [ ] Full TTF embedding for PDF rendering (CIDFont Type 2) - Future
### Fase 14 - Security/Encryption (COMPLETADO)
- [x] RC4 stream cipher (40-bit and 128-bit)
- [x] PDF Standard Security Handler
- [x] User/Owner password handling
- [x] Permission flags (print, modify, copy, annotate, etc.)
- [x] MD5-based key derivation
- [x] Object key generation
- [ ] Full PDF output integration - Future
### Fase 15 - Forms/AcroForms (COMPLETADO)
- [x] TextField struct (name, position, size)
- [x] CheckBox struct
- [x] FieldFlags (readonly, required, multiline, password)
- [x] FormField union type
- [x] toFormField() conversion
- [ ] Full PDF AcroForm output integration - Future
### Fase 16 - SVG Import (COMPLETADO)
- [x] SvgParser struct
- [x] Basic shapes (rect, circle, ellipse, line)
- [x] Path element with commands
- [x] PathCommand enum (MoveTo, LineTo, CurveTo, etc.)
- [x] Color parsing (fill, stroke)
- [x] toPdfContent() - generates PDF operators
- [ ] Text elements - Future
- [ ] Transforms - Future
### Fase 17 - Templates (COMPLETADO)
- [x] Template struct with named regions
- [x] TemplateRegion (position, size, type)
- [x] RegionType enum (text, image, table, custom)
- [x] FixedContent for repeating elements
- [x] invoiceTemplate() predefined
- [x] letterTemplate() predefined
- [x] template_demo.zig ejemplo
### Fase 18 - Markdown Styling (COMPLETADO)
- [x] MarkdownRenderer struct
- [x] SpanStyle (bold, italic, underline, strikethrough)
- [x] TextSpan with style, color, url, font_size
- [x] Inline parsing: **bold**, *italic*, ***both***, ~~strike~~
- [x] Links: [text](url)
- [x] Headings: #, ##, ###
- [x] Lists: - bullet, 1. numbered
- [x] fontForStyle() helper
- [x] markdown_demo.zig ejemplo
### Futuro
| Fase | Nombre | Prioridad |
|------|--------|-----------|
| 19 | Mejoras de Calidad | CONTINUA |
---
## Historial
### 2025-12-09 - v0.16 (Markdown Styling) - FEATURE COMPLETE
- MarkdownRenderer para texto con estilo
- SpanStyle (bold, italic, underline, strikethrough)
- TextSpan con style, color, url, font_size
- Parsing de: **bold**, *italic*, ***bold+italic***
- Strikethrough: ~~text~~
- Links: [text](url)
- Headings: #, ##, ###
- Lists: - bullet, 1. numbered
- fontForStyle() helper function
- markdown_demo.zig ejemplo
- 125+ tests, 16 ejemplos
### 2025-12-09 - v0.15 (Templates)
- Template struct con regiones nombradas
- TemplateRegion para definir areas de contenido
- FixedContent para elementos repetitivos
- invoiceTemplate() y letterTemplate() predefinidos
- template_demo.zig ejemplo
- 120+ tests, 15 ejemplos
### 2025-12-09 - v0.14 (SVG Import)
- SvgParser para importar graficos vectoriales
- Soporte para rect, circle, ellipse, line, path
- PathCommand para curvas y lineas
- toPdfContent() genera operadores PDF
- svg/mod.zig, parser.zig
### 2025-12-09 - v0.13 (Forms)
- TextField y CheckBox structs
- FieldFlags (readonly, required, multiline, password)
- FormField union type
- forms/mod.zig, field.zig
### 2025-12-09 - v0.12 (Security)
- RC4 stream cipher (40-bit and 128-bit)
- PDF Standard Security Handler
- User/Owner password processing
- Permission flags (Permissions struct)
- MD5-based key derivation (Algorithms 3.1-3.5)
- security/mod.zig, rc4.zig, encryption.zig
- 100+ tests
### 2025-12-09 - v0.11 (TTF Fonts)
- TrueType font file parsing (tables: head, hhea, maxp, hmtx, cmap, name, OS/2, post)
- Font metrics extraction
- Glyph width tables for string width calculation
- Character to glyph mapping (cmap formats 0, 4, 6, 12)
- addTtfFontFromFile(), getTtfFont()
- ttf_demo.zig ejemplo
- 14 ejemplos, 95+ tests
### 2025-12-09 - v0.10 (Barcodes)
- Code128 1D barcode con Code Sets A, B, C
- QR Code 2D barcode con error correction levels
- drawCode128(), drawCode128WithText(), drawQRCode()
- barcode_demo.zig ejemplo
- 13 ejemplos, 90+ tests
### 2025-12-09 - v0.9 (Gradientes)
- Linear gradients (horizontal, vertical, diagonal)
- Radial gradients (circle, ellipse)
- Shading Patterns Type 2 (axial) y Type 3 (radial)
- linearGradientRect(), radialGradientCircle(), radialGradientEllipse()
- GradientData, LinearGradient, RadialGradient types
- gradient_demo.zig ejemplo
- 12 ejemplos, 85+ tests
### 2025-12-08 - v0.8 (Bookmarks + Bezier + Transforms + Transparency)
- Bookmarks/Outline para navegacion en sidebar
- Curvas Bezier (cubicas y cuadraticas)
- Circulos, elipses y arcos
- Transformaciones: rotacion, escala, traslacion, skew
- saveState()/restoreState() para limitar transformaciones
- Transparencia via ExtGState
- setFillOpacity(), setStrokeOpacity(), setOpacity()
- 4 nuevos ejemplos
- 85+ tests pasando
### 2025-12-08 - v0.7 (PNG + Compresion)
- Integracion libdeflate-zig para compresion
- PNG embedding completo (RGB, RGBA, Grayscale, Indexed)
- PNG unfiltering (5 filtros)
- Soft masks para transparencia
- FlateDecode para content streams
- Compresion configurable con heuristica
- 82+ tests pasando
### 2025-12-08 - v0.6 (Links Clickeables)
- Link annotations clickeables en PDF
- addUrlLink() / addInternalLink() en Page
- urlLink() / writeUrlLink() combinan visual + annotation
- OutputProducer genera /Annots en pages
- links_demo.zig ejemplo con 2 paginas
- 7 ejemplos, ~70 tests
### 2025-12-08 - v0.5 (Utilidades)
- Table helper
- Pagination (numeros de pagina)
- Headers/Footers automaticos
- Links visuales
### 2025-12-08 - v0.4 (Imagenes)
- JPEG embedding
- image() / imageFit()
### 2025-12-08 - v0.3 (Texto)
- cell() / multiCell()
- Word wrap, alineacion
### 2025-12-08 - v0.2 (Core)
- Estructura inicial
### 2025-12-08 - v0.1 (Setup)
- Setup inicial del proyecto
---
## Equipo
```
/mnt/cello2/arno/re/recode/TEAM_STANDARDS/
git remote: git@git.reugenio.com:reugenio/zpdf.git
```
---
**zpdf - Generador PDF para Zig**
*v1.0 - RELEASE (FEATURE COMPLETE) - 2025-12-09*

View file

@ -1,6 +1,6 @@
# zpdf - Mejoras Futuras
# zcatpdf - Mejoras Futuras
> Este documento detalla las posibles mejoras y funcionalidades que podrían implementarse en versiones futuras de zpdf.
> Este documento detalla las posibles mejoras y funcionalidades que podrían implementarse en versiones futuras de zcatpdf.
> Fecha: 2025-12-09
> Versión actual: v1.0
@ -104,7 +104,7 @@ El módulo `src/security/` tiene implementado:
### Código de ejemplo (objetivo)
```zig
var pdf = zpdf.Pdf.init(allocator, .{});
var pdf = zcatpdf.Pdf.init(allocator, .{});
pdf.setEncryption(.{
.user_password = "user123",
.owner_password = "admin456",
@ -179,7 +179,7 @@ El módulo `src/forms/field.zig` define:
### Código de ejemplo (objetivo)
```zig
var pdf = zpdf.Pdf.init(allocator, .{});
var pdf = zcatpdf.Pdf.init(allocator, .{});
var page = try pdf.addPage(.{});
try page.addTextField(.{
@ -426,7 +426,7 @@ Si se retoma el desarrollo, este es el orden sugerido:
- [CommonMark Spec](https://spec.commonmark.org/)
### Librerías de referencia
- [fpdf2 (Python)](https://github.com/py-pdf/fpdf2) - Base de inspiración para zpdf
- [fpdf2 (Python)](https://github.com/py-pdf/fpdf2) - Base de inspiración para zcatpdf
- [pdf-lib (JavaScript)](https://github.com/Hopding/pdf-lib) - Buena referencia para features
- [pdfkit (Node.js)](https://github.com/foliojs/pdfkit) - Implementación madura
@ -438,4 +438,4 @@ Si se retoma el desarrollo, este es el orden sugerido:
---
*Documento generado: 2025-12-09*
*zpdf v1.0 - Feature Complete*
*zcatpdf v1.0 - Feature Complete*

View file

@ -1,4 +1,4 @@
# zpdf - Plan de Implementacion Completo
# zcatpdf - Plan de Implementacion Completo
> **Creado**: 2025-12-08
> **Version actual**: 0.5
@ -273,7 +273,7 @@ test "parse RGBA PNG with alpha" {
```zig
const std = @import("std");
const pdf = @import("zpdf");
const pdf = @import("zcatpdf");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@ -630,7 +630,7 @@ pub const Page = struct {
```zig
const std = @import("std");
const pdf = @import("zpdf");
const pdf = @import("zcatpdf");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@ -859,7 +859,7 @@ pub const Pdf = struct {
```zig
const std = @import("std");
const pdf = @import("zpdf");
const pdf = @import("zcatpdf");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@ -1082,7 +1082,7 @@ pub const Page = struct {
```zig
const std = @import("std");
const pdf = @import("zpdf");
const pdf = @import("zcatpdf");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@ -1234,7 +1234,7 @@ pub const Page = struct {
```zig
const std = @import("std");
const pdf = @import("zpdf");
const pdf = @import("zcatpdf");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@ -1420,7 +1420,7 @@ for (page.ext_gstates, 0..) |gs, i| {
```zig
const std = @import("std");
const pdf = @import("zpdf");
const pdf = @import("zcatpdf");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@ -1641,7 +1641,7 @@ pub const Page = struct {
```zig
const std = @import("std");
const pdf = @import("zpdf");
const pdf = @import("zcatpdf");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@ -1864,7 +1864,7 @@ pub const Page = struct {
```zig
const std = @import("std");
const pdf = @import("zpdf");
const pdf = @import("zcatpdf");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@ -1895,7 +1895,7 @@ pub fn main() !void {
// QR con mas datos
try page.drawText(300, 600, "QR Code (mas datos):");
try page.drawQrCode(300, 450, "Hola mundo! Este es un ejemplo de QR Code generado con zpdf", .{
try page.drawQrCode(300, 450, "Hola mundo! Este es un ejemplo de QR Code generado con zcatpdf", .{
.module_size = 3,
.ecc = .H,
});
@ -2007,7 +2007,7 @@ pub const OutputProducer = struct {
```zig
const std = @import("std");
const pdf = @import("zpdf");
const pdf = @import("zcatpdf");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@ -2199,7 +2199,7 @@ pub const Page = struct {
```zig
const std = @import("std");
const pdf = @import("zpdf");
const pdf = @import("zcatpdf");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@ -2616,7 +2616,7 @@ pub const Page = struct {
```zig
const std = @import("std");
const pdf = @import("zpdf");
const pdf = @import("zcatpdf");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};

View file

@ -1,12 +1,12 @@
# zpdf - PDF Generation Library for Zig
# zcatpdf - PDF Generation Library for Zig
A pure Zig library for creating PDF documents with minimal dependencies.
```zig
const zpdf = @import("zpdf");
const zcatpdf = @import("zcatpdf");
pub fn main() !void {
var pdf = zpdf.Pdf.init(allocator, .{});
var pdf = zcatpdf.Pdf.init(allocator, .{});
defer pdf.deinit();
var page = try pdf.addPage(.{});
@ -35,12 +35,12 @@ pub fn main() !void {
## Installation
Add zpdf to your `build.zig.zon`:
Add zcatpdf to your `build.zig.zon`:
```zig
.dependencies = .{
.zpdf = .{
.url = "https://git.reugenio.com/reugenio/zpdf/archive/v1.0.tar.gz",
.zcatpdf = .{
.url = "https://git.reugenio.com/reugenio/zcatpdf/archive/v1.0.tar.gz",
.hash = "...",
},
},
@ -49,11 +49,11 @@ Add zpdf to your `build.zig.zon`:
In your `build.zig`:
```zig
const zpdf_dep = b.dependency("zpdf", .{
const zcatpdf_dep = b.dependency("zcatpdf", .{
.target = target,
.optimize = optimize,
});
exe.root_module.addImport("zpdf", zpdf_dep.module("zpdf"));
exe.root_module.addImport("zcatpdf", zcatpdf_dep.module("zcatpdf"));
```
## Quick Reference
@ -85,14 +85,14 @@ exe.root_module.addImport("zpdf", zpdf_dep.module("zpdf"));
**File:** `src/pdf.zig`
```zig
const zpdf = @import("zpdf");
const zcatpdf = @import("zcatpdf");
// Create document with default settings
var pdf = zpdf.Pdf.init(allocator, .{});
var pdf = zcatpdf.Pdf.init(allocator, .{});
defer pdf.deinit();
// Create document with options
var pdf = zpdf.Pdf.init(allocator, .{
var pdf = zcatpdf.Pdf.init(allocator, .{
.page_size = .a4,
.orientation = .portrait,
.unit = .pt,
@ -228,7 +228,7 @@ try page.setFont(.times_roman, 11);
try page.setFont(.courier, 10);
// Calculate string width
const width = zpdf.Font.helvetica.stringWidth("Hello", 12.0);
const width = zcatpdf.Font.helvetica.stringWidth("Hello", 12.0);
```
### Available Fonts (Type1 built-in)
@ -255,7 +255,7 @@ const width = zpdf.Font.helvetica.stringWidth("Hello", 12.0);
```zig
// Load TTF file
const font_data = try std.fs.cwd().readFileAlloc(allocator, "font.ttf", 10_000_000);
var ttf = try zpdf.TrueTypeFont.parse(allocator, font_data);
var ttf = try zcatpdf.TrueTypeFont.parse(allocator, font_data);
defer ttf.deinit();
// Get font info
@ -281,20 +281,20 @@ const width = ttf.stringWidth("Hello", 12.0);
```zig
// Set colors
page.setFillColor(zpdf.Color.red);
page.setStrokeColor(zpdf.Color.blue);
page.setFillColor(zcatpdf.Color.red);
page.setStrokeColor(zcatpdf.Color.blue);
// RGB (0-255)
page.setFillColor(zpdf.Color.rgb(255, 128, 0));
page.setFillColor(zcatpdf.Color.rgb(255, 128, 0));
// Hex
page.setFillColor(zpdf.Color.hex(0xFF8000));
page.setFillColor(zcatpdf.Color.hex(0xFF8000));
// Grayscale (0.0-1.0)
page.setFillColor(zpdf.Color.gray(0.5));
page.setFillColor(zcatpdf.Color.gray(0.5));
// CMYK (0.0-1.0)
page.setFillColor(zpdf.Color.cmyk(0, 1, 1, 0)); // Red
page.setFillColor(zcatpdf.Color.cmyk(0, 1, 1, 0)); // Red
```
### Predefined Colors
@ -442,12 +442,12 @@ try page.imageFit(img_idx, info, x, y, max_width, max_height);
```zig
const col_widths = [_]f32{ 200, 100, 100, 100 };
var table = zpdf.Table.init(page, .{
var table = zcatpdf.Table.init(page, .{
.x = 50,
.y = 700,
.col_widths = &col_widths,
.row_height = 20,
.header_bg_color = zpdf.Color.hex(0xE0E0E0),
.header_bg_color = zcatpdf.Color.hex(0xE0E0E0),
.border = true,
});
@ -559,10 +559,10 @@ try page.drawCode128WithText(x, y, "ABC-12345", height, module_width, show_text)
try page.drawQRCode(x, y, "https://example.com", size, error_correction);
// Error correction levels
zpdf.QRCode.ErrorCorrection.L // 7% recovery
zpdf.QRCode.ErrorCorrection.M // 15% recovery
zpdf.QRCode.ErrorCorrection.Q // 25% recovery
zpdf.QRCode.ErrorCorrection.H // 30% recovery
zcatpdf.QRCode.ErrorCorrection.L // 7% recovery
zcatpdf.QRCode.ErrorCorrection.M // 15% recovery
zcatpdf.QRCode.ErrorCorrection.Q // 25% recovery
zcatpdf.QRCode.ErrorCorrection.H // 30% recovery
```
### Types
@ -641,15 +641,15 @@ try page.setOpacity(1.0);
```zig
// Horizontal gradient
try page.linearGradientRect(x, y, width, height,
zpdf.Color.red, zpdf.Color.blue, .horizontal);
zcatpdf.Color.red, zcatpdf.Color.blue, .horizontal);
// Vertical gradient
try page.linearGradientRect(x, y, width, height,
zpdf.Color.green, zpdf.Color.yellow, .vertical);
zcatpdf.Color.green, zcatpdf.Color.yellow, .vertical);
// Diagonal gradient
try page.linearGradientRect(x, y, width, height,
zpdf.Color.purple, zpdf.Color.cyan, .diagonal);
zcatpdf.Color.purple, zcatpdf.Color.cyan, .diagonal);
```
### Radial Gradients
@ -657,11 +657,11 @@ try page.linearGradientRect(x, y, width, height,
```zig
// Circle gradient (center to edge)
try page.radialGradientCircle(cx, cy, radius,
zpdf.Color.white, zpdf.Color.blue);
zcatpdf.Color.white, zcatpdf.Color.blue);
// Ellipse gradient
try page.radialGradientEllipse(cx, cy, rx, ry,
zpdf.Color.yellow, zpdf.Color.red);
zcatpdf.Color.yellow, zcatpdf.Color.red);
```
### Types
@ -683,11 +683,11 @@ Templates define reusable document layouts with named regions.
```zig
// Use predefined invoice template
var tmpl = try zpdf.Template.invoiceTemplate(allocator);
var tmpl = try zcatpdf.Template.invoiceTemplate(allocator);
defer tmpl.deinit();
// Or create custom template
var tmpl = zpdf.Template.init(allocator, "custom", 595, 842);
var tmpl = zcatpdf.Template.init(allocator, "custom", 595, 842);
defer tmpl.deinit();
try tmpl.defineRegion("header", .{
@ -727,7 +727,7 @@ if (tmpl.getRegion("header")) |region| {
Parse Markdown-style text and render with appropriate styles.
```zig
var renderer = zpdf.MarkdownRenderer.init(allocator);
var renderer = zcatpdf.MarkdownRenderer.init(allocator);
defer renderer.deinit();
try renderer.parse(
@ -744,11 +744,11 @@ try renderer.parse(
// Render to PDF
for (renderer.getLines()) |line| {
for (line.spans) |span| {
const font = zpdf.MarkdownRenderer.fontForStyle(span.style);
const font = zcatpdf.MarkdownRenderer.fontForStyle(span.style);
try page.setFont(font, span.font_size orelse 12);
if (span.color) |color| {
page.setFillColor(zpdf.Color.hex(color));
page.setFillColor(zcatpdf.Color.hex(color));
}
try page.drawText(x, y, span.text);
@ -789,7 +789,7 @@ for (renderer.getLines()) |line| {
```zig
// Configure compression when creating document
var pdf = zpdf.Pdf.init(allocator, .{
var pdf = zcatpdf.Pdf.init(allocator, .{
.compression = .{
.enabled = true,
.level = 6, // 0-12, higher = better compression
@ -911,6 +911,12 @@ zig build
---
## Known Limitations
- **TTF Font Subsetting**: When embedding TrueType fonts, the entire font file is included rather than just the glyphs used. This can result in larger PDF files when using custom fonts. Font subsetting is planned for a future version.
---
## Building
```bash

181
VERIFIED_FEATURES.md Normal file
View file

@ -0,0 +1,181 @@
# VERIFIED_FEATURES.md - zcatpdf
Estado de verificación de funcionalidades en aplicaciones reales.
**Leyenda:**
- ✅ **Verificado** - Probado en aplicación real, funciona correctamente
- ⚠️ **Tests only** - Solo tests unitarios, no probado en app real
- 🔧 **Mejorado** - Probado y mejorado/corregido durante uso real
- ❌ **Incompleto** - Conocido como incompleto o con limitaciones
- ❓ **Sin probar** - No tiene tests ni uso real
---
## Core
### pdf.zig
| Feature | Estado | Notas |
|---------|--------|-------|
| PDF.init | ⚠️ | Tests only |
| PDF.addPage | ⚠️ | Tests only |
| PDF.render | ⚠️ | Tests only |
| PDF.save | ⚠️ | Tests only |
### page.zig
| Feature | Estado | Notas |
|---------|--------|-------|
| Page sizes (A4, Letter...) | ⚠️ | Tests only |
| Page orientation | ⚠️ | Tests only |
| Margins | ⚠️ | Tests only |
### content_stream.zig
| Feature | Estado | Notas |
|---------|--------|-------|
| Text rendering | ⚠️ | Tests only |
| Graphics primitives | ⚠️ | Tests only |
| Coordinate system | ⚠️ | Tests only |
---
## Texto
### fonts/
| Feature | Estado | Notas |
|---------|--------|-------|
| Built-in fonts (Helvetica, Times...) | ⚠️ | Tests only |
| Font embedding | ❓ | Sin probar |
| TTF support | ❓ | Sin probar |
| Unicode text | ❓ | Sin probar |
### text/
| Feature | Estado | Notas |
|---------|--------|-------|
| Basic text | ⚠️ | Tests only |
| Text alignment | ❓ | Sin probar |
| Text wrapping | ❓ | Sin probar |
| Line spacing | ❓ | Sin probar |
---
## Gráficos
### graphics/
| Feature | Estado | Notas |
|---------|--------|-------|
| Lines | ⚠️ | Tests only |
| Rectangles | ⚠️ | Tests only |
| Circles | ❓ | Sin probar |
| Paths | ❓ | Sin probar |
| Colors (RGB, CMYK) | ⚠️ | Tests only |
| Stroke/Fill | ⚠️ | Tests only |
---
## Tablas
### table.zig
| Feature | Estado | Notas |
|---------|--------|-------|
| Basic table | ⚠️ | Tests only |
| Cell borders | ❓ | Sin probar |
| Cell alignment | ❓ | Sin probar |
| Column widths | ❓ | Sin probar |
| Row spanning | ❓ | Sin probar |
| Col spanning | ❓ | Sin probar |
---
## Imágenes
### images/
| Feature | Estado | Notas |
|---------|--------|-------|
| PNG embedding | ❓ | Sin probar |
| JPEG embedding | ❓ | Sin probar |
| Image scaling | ❓ | Sin probar |
---
## Códigos de Barras
### barcodes/
| Feature | Estado | Notas |
|---------|--------|-------|
| Code128 | ❓ | Sin probar |
| QR Code | ❓ | Sin probar |
| EAN | ❓ | Sin probar |
---
## Avanzado
### forms/
| Feature | Estado | Notas |
|---------|--------|-------|
| Form fields | ❓ | Sin probar |
| Checkboxes | ❓ | Sin probar |
| Text fields | ❓ | Sin probar |
### security/
| Feature | Estado | Notas |
|---------|--------|-------|
| Password protection | ❓ | Sin probar |
| Permissions | ❓ | Sin probar |
| Encryption | ❓ | Sin probar |
### compression/
| Feature | Estado | Notas |
|---------|--------|-------|
| Stream compression | ⚠️ | Tests only |
| Deflate | ⚠️ | Tests only |
### outline.zig (Bookmarks)
| Feature | Estado | Notas |
|---------|--------|-------|
| Bookmarks | ❓ | Sin probar |
| Document outline | ❓ | Sin probar |
### links.zig
| Feature | Estado | Notas |
|---------|--------|-------|
| Internal links | ❓ | Sin probar |
| External URLs | ❓ | Sin probar |
### pagination.zig
| Feature | Estado | Notas |
|---------|--------|-------|
| Auto pagination | ❓ | Sin probar |
| Page breaks | ❓ | Sin probar |
### template/
| Feature | Estado | Notas |
|---------|--------|-------|
| Templates | ❓ | Sin probar |
### markdown/
| Feature | Estado | Notas |
|---------|--------|-------|
| Markdown to PDF | ❓ | Sin probar |
### svg/
| Feature | Estado | Notas |
|---------|--------|-------|
| SVG embedding | ❓ | Sin probar |
---
## Historial de Verificación
| Fecha | Proyecto | Features Verificadas |
|-------|----------|---------------------|
| - | - | Ninguna verificada en producción aún |
---
## Próximos a Verificar (Prioridad zsimifactu)
1. **PDF básico** - Crear documento, añadir página, guardar
2. **Texto** - Escribir texto con fuente básica
3. **Tablas** - Para facturas (líneas, totales)
4. **Códigos de barras** - VeriFacTu requiere QR
5. **Imágenes** - Logo empresa

38
ZIG_VERSION_NOTES.md Normal file
View file

@ -0,0 +1,38 @@
# Notas de Versión Zig
## Versión actual: Zig 0.15.2
Este proyecto está compilado con **Zig 0.15.2**.
## Sistema de notas compartido
El equipo mantiene documentación centralizada sobre cambios entre versiones de Zig en:
```
/mnt/cello2/arno/re/recode/teamdocs/ZIG_VERSIONS/
```
### Archivos disponibles:
- `README.md` - Explicación del sistema
- `ZIG_0.15.2.md` - Cambios específicos de Zig 0.15.2 vs versiones anteriores
## Para Claude/IA
**Al inicio de cada conversación sobre este proyecto:**
1. Leer este archivo
2. Leer `/mnt/cello2/arno/re/recode/teamdocs/ZIG_VERSIONS/ZIG_0.15.2.md`
3. Aplicar las diferencias documentadas (tu entrenamiento fue con Zig 0.14)
## Por qué existe esto
Los modelos de lenguaje fueron entrenados con versiones anteriores de Zig. Cada versión nueva trae cambios de sintaxis y API. Este sistema asegura que cualquier conversación tenga acceso a las diferencias relevantes.
## Contribuir
Si durante el trabajo descubres un cambio no documentado entre versiones:
1. Añádelo a `teamdocs/ZIG_VERSIONS/ZIG_X.Y.Z.md`
2. Incluye ejemplo de código antes/después
---
*Última actualización: 2025-12-09*

View file

@ -11,13 +11,13 @@ pub fn build(b: *std.Build) void {
});
const libdeflate_lib = libdeflate_dep.artifact("deflate");
// zpdf module with libdeflate
const zpdf_mod = b.createModule(.{
// zcatpdf module with libdeflate
const zcatpdf_mod = b.createModule(.{
.root_source_file = b.path("src/root.zig"),
.target = target,
.optimize = optimize,
});
zpdf_mod.linkLibrary(libdeflate_lib);
zcatpdf_mod.linkLibrary(libdeflate_lib);
// Tests
const unit_tests = b.addTest(.{
@ -61,7 +61,7 @@ pub fn build(b: *std.Build) void {
.target = target,
.optimize = optimize,
.imports = &.{
.{ .name = "zpdf", .module = zpdf_mod },
.{ .name = "zcatpdf", .module = zcatpdf_mod },
},
}),
});

234
claude.md Normal file
View file

@ -0,0 +1,234 @@
# zcatpdf - Generador PDF para Zig
> **Tipo:** Librería Zig (sin deploy propio)
> **Credenciales:** `teamdocs/INFRASTRUCTURE/CREDENCIALES.md`
> **Cheatsheet:** `teamdocs/CHEATSHEET.md`
> **Version:** v1.0 - RELEASE (FEATURE COMPLETE)
> **Repositorio:** https://git.reugenio.com/reugenio/zcatpdf
---
## Informacion para Nueva Conversacion
### Que es zcatpdf?
Libreria pura Zig para generacion de documentos PDF. Parte de la familia "zcat*" (zcatui, zcatgui, zcatpdf).
### Documentacion Disponible
| Archivo | Contenido |
|---------|-----------|
| `CLAUDE.md` | Este archivo - contexto del proyecto |
| `README.md` | **Manual de referencia completo** - API, ejemplos de codigo, tipos, archivos |
| `FUTURE_IMPROVEMENTS.md` | **Mejoras futuras detalladas** - TTF embedding, encryption integration, forms output, SVG avanzado |
| `docs/ARQUITECTURA_FPDF2.md` | Analisis de fpdf2 (Python) - arquitectura de referencia |
| `docs/ARQUITECTURA_ZPDF.md` | Diseno inicial del proyecto (historico) |
| `docs/PLAN_MAESTRO_ZPDF.md` | Plan original de implementacion (completado) |
### Normas del Equipo (teamdocs)
**Ubicacion**: `/mnt/cello2/arno/re/recode/teamdocs/`
Documentacion centralizada para todos los proyectos:
- `INFRASTRUCTURE/FORGEJO_GIT_SERVER.md` - Servidor git, tokens, API
- `INTEGRATION_GUIDE.md` - Guia de integracion de proyectos
- `NORMAS_PATRONES_DESARROLLO.md` - Patrones y normas de desarrollo
### Comandos Esenciales
```bash
# Zig path
ZIG=/mnt/cello2/arno/re/recode/zig/zig-0.15.2/zig-x86_64-linux-0.15.2/zig
# Compilar y testear
$ZIG build
$ZIG build test
# Ejecutar ejemplos
./zig-out/bin/hello
./zig-out/bin/invoice
./zig-out/bin/barcode_demo
# etc. (16 ejemplos en total)
```
### Reglas Clave para Este Proyecto
- Nombres en minusculas: `zcatpdf` (no ZcatPDF, no zCatPdf)
- Import: `@import("zcatpdf")`
- Doc comments (`///`) en funciones publicas
- Codigo idiomatico Zig (snake_case, error handling explicito)
---
## Estado del Proyecto
### FEATURE COMPLETE - v1.0
La libreria esta completa para uso en produccion. Todas las funcionalidades planificadas estan implementadas:
| Categoria | Funcionalidades |
|-----------|-----------------|
| **Documento** | PDF 1.4, metadatos, multiples paginas, compresion FlateDecode |
| **Texto** | drawText, cell, multiCell, word wrap, 14 fuentes Type1 |
| **Graficos** | Lineas, rectangulos, curvas Bezier, circulos, elipses, arcos |
| **Colores** | RGB, CMYK, Grayscale, colores predefinidos |
| **Imagenes** | JPEG, PNG (con alpha/transparencia) |
| **Tablas** | Table helper con headers, rows, footers |
| **Links** | URLs clickeables, links internos entre paginas |
| **Bookmarks** | Navegacion en sidebar del lector PDF |
| **Transformaciones** | Rotacion, escala, traslacion, skew |
| **Transparencia** | Fill y stroke opacity (0.0-1.0) |
| **Gradientes** | Lineales y radiales |
| **Barcodes** | Code128 (1D), QR Code (2D) |
| **TTF Fonts** | Parsing de TrueType (metricas, anchos de glyph) |
| **Security** | RC4 encryption module (40/128-bit) |
| **Forms** | TextField, CheckBox (structs, no output aun) |
| **SVG** | Import basico (shapes, paths) |
| **Templates** | Layouts reutilizables (invoice, letter) |
| **Markdown** | Texto con estilos (bold, italic, links, headings, lists) |
### Tests y Ejemplos
- **125+ tests** unitarios
- **16 ejemplos** funcionales en `examples/`
---
## Arquitectura de Archivos
```
zcatpdf/
├── CLAUDE.md # Este archivo
├── README.md # Manual de referencia completo
├── FUTURE_IMPROVEMENTS.md # Mejoras futuras detalladas
├── build.zig # Sistema de build
├── build.zig.zon # Dependencias (libdeflate)
├── src/
│ ├── root.zig # Exports publicos (@import("zcatpdf"))
│ ├── pdf.zig # Pdf struct - API principal
│ ├── page.zig # Page - dibujo, texto, transformaciones
│ ├── content_stream.zig # Operadores PDF de bajo nivel
│ ├── table.zig # Table helper
│ ├── pagination.zig # Numeros de pagina, headers, footers
│ ├── links.zig # Link types
│ ├── outline.zig # Bookmarks
│ ├── fonts/ # Type1 + TrueType
│ ├── graphics/ # Color, ExtGState, Gradient
│ ├── images/ # JPEG, PNG parsers
│ ├── barcodes/ # Code128, QR
│ ├── compression/ # libdeflate wrapper
│ ├── security/ # RC4, Encryption
│ ├── forms/ # TextField, CheckBox
│ ├── svg/ # SVG parser
│ ├── template/ # Template system
│ ├── markdown/ # Markdown renderer
│ ├── objects/ # PageSize, Orientation
│ └── output/ # PDF serialization
└── examples/ # 16 demos ejecutables
```
---
## Uso Rapido
```zig
const zcatpdf = @import("zcatpdf");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
var pdf = zcatpdf.Pdf.init(allocator, .{});
defer pdf.deinit();
pdf.setTitle("Mi Documento");
var page = try pdf.addPage(.{});
try page.setFont(.helvetica_bold, 24);
try page.drawText(50, 750, "Hello, PDF!");
try pdf.save("output.pdf");
}
```
---
## Mejoras Futuras (No Criticas)
Ver `FUTURE_IMPROVEMENTS.md` para detalles completos:
1. **TTF Font Embedding** - Embeber TTF para renderizar texto (CIDFont Type 2)
2. **PDF Encryption Integration** - Integrar RC4 con OutputProducer
3. **AcroForms Output** - Generar campos de formulario en PDF final
4. **SVG Avanzado** - text, transforms, gradients en SVG
5. **Markdown Avanzado** - code blocks, tables, images
---
## Git
```bash
# Remote
origin: ssh://git@git.reugenio.com:2222/reugenio/zcatpdf.git
# Branch principal
main
# Comandos comunes
git status
git add -A && git commit -m "mensaje"
git push
```
**Nota**: El proyecto fue renombrado de `zpdf` a `zcatpdf` el 2025-12-09.
El repositorio en Forgejo y el remote local ya estan actualizados.
---
## Familia zcat*
| Proyecto | Descripcion |
|----------|-------------|
| **zcatui** | TUI library (terminal UI, como ratatui) |
| **zcatgui** | GUI library (immediate mode, SDL2 backend) |
| **zcatpdf** | PDF generation library |
Todos siguen las mismas convenciones:
- 100% Zig
- Minimas dependencias
- Nombres en minusculas
- Open source ready
---
## Referencias Externas
- [PDF Reference 1.4](https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/pdfreference1.4.pdf)
- [fpdf2 (Python)](https://github.com/py-pdf/fpdf2) - Inspiracion de la API
- [Zig Documentation](https://ziglang.org/documentation/master/)
---
**zcatpdf v1.0** - Generador PDF para Zig
*Feature Complete - 2025-12-09*
---
## CLAUDE CODE + ZLS (LSP)
Claude Code tiene integración LSP con zls (Zig Language Server).
**Plugin:** `$HOME/.claude/plugins/zls-lsp/`
**Operaciones disponibles:**
| Operación | Uso |
|-----------|-----|
| `goToDefinition` | Navegar a definición de símbolo |
| `findReferences` | Encontrar todas las referencias |
| `hover` | Info de tipo y documentación |
| `documentSymbol` | Símbolos del archivo actual |
| `incomingCalls` | Qué funciones llaman a ésta |
**Documentación:** `teamdocs/INFRASTRUCTURE/ZLS_LSP_CLAUDE_CODE.md`

View file

@ -3,10 +3,10 @@
//! Demonstrates barcode generation for product labels, shipping, URLs, etc.
const std = @import("std");
const zpdf = @import("zpdf");
const Pdf = zpdf.Pdf;
const Color = zpdf.Color;
const QRCode = zpdf.QRCode;
const zcatpdf = @import("zcatpdf");
const Pdf = zcatpdf.Pdf;
const Color = zcatpdf.Color;
const QRCode = zcatpdf.QRCode;
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@ -17,7 +17,7 @@ pub fn main() !void {
defer pdf.deinit();
pdf.setTitle("Barcode Demo");
pdf.setAuthor("zpdf");
pdf.setAuthor("zcatpdf");
var page = try pdf.addPage(.{});
@ -28,7 +28,7 @@ pub fn main() !void {
try page.setFont(.helvetica, 12);
page.setFillColor(Color.hex(0x666666));
try page.drawText(50, 760, "Code128 barcode generation with zpdf");
try page.drawText(50, 760, "Code128 barcode generation with zcatpdf");
// Reset to black for barcodes
page.setFillColor(Color.black);
@ -111,7 +111,7 @@ pub fn main() !void {
// Footer
try page.setFont(.helvetica_oblique, 10);
page.setFillColor(Color.hex(0x999999));
try page.drawText(50, 50, "Generated with zpdf - Code128 and QR Code Support");
try page.drawText(50, 50, "Generated with zcatpdf - Code128 and QR Code Support");
try pdf.save("barcode_demo.pdf");

View file

@ -4,20 +4,20 @@
//! The bookmarks appear in the sidebar of PDF readers for navigation.
const std = @import("std");
const pdf = @import("zpdf");
const pdf = @import("zcatpdf");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
std.debug.print("zpdf - Bookmarks Demo\n", .{});
std.debug.print("zcatpdf - Bookmarks Demo\n", .{});
var doc = pdf.Pdf.init(allocator, .{});
defer doc.deinit();
doc.setTitle("Bookmarks Demo");
doc.setAuthor("zpdf");
doc.setAuthor("zcatpdf");
// =========================================================================
// Page 1: Introduction
@ -37,7 +37,7 @@ pub fn main() !void {
try page.setFont(.helvetica, 12);
page.setFillColor(pdf.Color.black);
const intro_text =
\\This document demonstrates the bookmark/outline feature of zpdf.
\\This document demonstrates the bookmark/outline feature of zcatpdf.
\\
\\Bookmarks (also called "outlines") appear in the sidebar of PDF readers
\\and allow quick navigation to different sections of the document.
@ -50,7 +50,7 @@ pub fn main() !void {
page.setXY(50, 50);
try page.setFont(.helvetica, 9);
page.setFillColor(pdf.Color.medium_gray);
try page.cell(0, 15, "Page 1 of 4 - zpdf Bookmarks Demo", pdf.Border.none, .center, false);
try page.cell(0, 15, "Page 1 of 4 - zcatpdf Bookmarks Demo", pdf.Border.none, .center, false);
}
// =========================================================================
@ -73,7 +73,7 @@ pub fn main() !void {
const chapter1_text =
\\This is Chapter 1 of our document.
\\
\\In this chapter, we cover the basics of using zpdf to create
\\In this chapter, we cover the basics of using zcatpdf to create
\\PDF documents with bookmarks for easy navigation.
\\
\\Key topics:
@ -88,7 +88,7 @@ pub fn main() !void {
page.setXY(50, 50);
try page.setFont(.helvetica, 9);
page.setFillColor(pdf.Color.medium_gray);
try page.cell(0, 15, "Page 2 of 4 - zpdf Bookmarks Demo", pdf.Border.none, .center, false);
try page.cell(0, 15, "Page 2 of 4 - zcatpdf Bookmarks Demo", pdf.Border.none, .center, false);
}
// =========================================================================
@ -125,7 +125,7 @@ pub fn main() !void {
page.setXY(50, 50);
try page.setFont(.helvetica, 9);
page.setFillColor(pdf.Color.medium_gray);
try page.cell(0, 15, "Page 3 of 4 - zpdf Bookmarks Demo", pdf.Border.none, .center, false);
try page.cell(0, 15, "Page 3 of 4 - zcatpdf Bookmarks Demo", pdf.Border.none, .center, false);
}
// =========================================================================
@ -154,7 +154,7 @@ pub fn main() !void {
\\ 3. Each bookmark links to a specific page and position
\\
\\Use doc.addBookmark() or doc.addBookmarkAt() to add bookmarks
\\to your zpdf documents.
\\to your zcatpdf documents.
;
try page.multiCell(500, null, conclusion_text, pdf.Border.none, .left, false);
@ -162,7 +162,7 @@ pub fn main() !void {
page.setXY(50, 50);
try page.setFont(.helvetica, 9);
page.setFillColor(pdf.Color.medium_gray);
try page.cell(0, 15, "Page 4 of 4 - zpdf Bookmarks Demo", pdf.Border.none, .center, false);
try page.cell(0, 15, "Page 4 of 4 - zcatpdf Bookmarks Demo", pdf.Border.none, .center, false);
}
// Save

View file

@ -1,25 +1,25 @@
//! Curves Demo - Bezier Curves, Circles, Ellipses, and Arcs
//!
//! Demonstrates the curve drawing capabilities of zpdf including:
//! Demonstrates the curve drawing capabilities of zcatpdf including:
//! - Cubic and quadratic Bezier curves
//! - Circles and ellipses
//! - Arcs
const std = @import("std");
const pdf = @import("zpdf");
const pdf = @import("zcatpdf");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
std.debug.print("zpdf - Curves Demo\n", .{});
std.debug.print("zcatpdf - Curves Demo\n", .{});
var doc = pdf.Pdf.init(allocator, .{});
defer doc.deinit();
doc.setTitle("Curves Demo");
doc.setAuthor("zpdf");
doc.setAuthor("zcatpdf");
// =========================================================================
// Page 1: Bezier Curves
@ -110,7 +110,7 @@ pub fn main() !void {
// Footer
try page.setFont(.helvetica, 9);
page.setFillColor(pdf.Color.medium_gray);
try page.drawText(250, 50, "Page 1 of 2 - zpdf Curves Demo");
try page.drawText(250, 50, "Page 1 of 2 - zcatpdf Curves Demo");
}
// =========================================================================
@ -235,7 +235,7 @@ pub fn main() !void {
// Footer
try page.setFont(.helvetica, 9);
page.setFillColor(pdf.Color.medium_gray);
try page.drawText(250, 50, "Page 2 of 2 - zpdf Curves Demo");
try page.drawText(250, 50, "Page 2 of 2 - zcatpdf Curves Demo");
}
// Save

View file

@ -3,10 +3,10 @@
//! Demonstrates gradient fills for rectangles, circles and ellipses.
const std = @import("std");
const zpdf = @import("zpdf");
const Pdf = zpdf.Pdf;
const Color = zpdf.Color;
const GradientDirection = zpdf.GradientDirection;
const zcatpdf = @import("zcatpdf");
const Pdf = zcatpdf.Pdf;
const Color = zcatpdf.Color;
const GradientDirection = zcatpdf.GradientDirection;
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@ -17,7 +17,7 @@ pub fn main() !void {
defer pdf.deinit();
pdf.setTitle("Gradient Demo");
pdf.setAuthor("zpdf");
pdf.setAuthor("zcatpdf");
var page = try pdf.addPage(.{});
@ -28,7 +28,7 @@ pub fn main() !void {
try page.setFont(.helvetica, 12);
page.setFillColor(Color.hex(0x666666));
try page.drawText(50, 760, "Linear and radial gradients in zpdf");
try page.drawText(50, 760, "Linear and radial gradients in zcatpdf");
// Section 1: Linear Gradients
try page.setFont(.helvetica_bold, 16);
@ -112,7 +112,7 @@ pub fn main() !void {
// Footer
try page.setFont(.helvetica_oblique, 10);
page.setFillColor(Color.hex(0x999999));
try page.drawText(50, 50, "Generated with zpdf - Linear and Radial Gradient Support");
try page.drawText(50, 50, "Generated with zcatpdf - Linear and Radial Gradient Support");
try pdf.save("gradient_demo.pdf");

View file

@ -1,14 +1,14 @@
//! Minimal PDF example - Hello World
const std = @import("std");
const pdf = @import("zpdf");
const pdf = @import("zcatpdf");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
std.debug.print("zpdf - Hello World example\n", .{});
std.debug.print("zcatpdf - Hello World example\n", .{});
// Create document
var doc = pdf.Document.init(allocator);
@ -25,7 +25,7 @@ pub fn main() !void {
// Subtitle
try page.setFont(.helvetica, 14);
page.setFillColor(pdf.Color.medium_gray);
try page.drawText(50, 710, "Generated with zpdf - Pure Zig PDF library");
try page.drawText(50, 710, "Generated with zcatpdf - Pure Zig PDF library");
// Draw a line
try page.setLineWidth(1);
@ -36,7 +36,7 @@ pub fn main() !void {
try page.setFont(.times_roman, 12);
page.setFillColor(pdf.Color.black);
try page.drawText(50, 670, "This PDF was generated entirely in Zig with zero external dependencies.");
try page.drawText(50, 655, "The zpdf library supports:");
try page.drawText(50, 655, "The zcatpdf library supports:");
try page.drawText(70, 635, "- Multiple fonts (Helvetica, Times, Courier)");
try page.drawText(70, 620, "- Colors (RGB)");
try page.drawText(70, 605, "- Lines and rectangles");
@ -63,7 +63,7 @@ pub fn main() !void {
// Footer
try page.setFont(.courier, 10);
page.setFillColor(pdf.Color.medium_gray);
try page.drawText(50, 50, "zpdf v0.1.0 - https://git.reugenio.com/reugenio/zpdf");
try page.drawText(50, 50, "zcatpdf v0.1.0 - https://git.reugenio.com/reugenio/zcatpdf");
// Save
const filename = "hello.pdf";

View file

@ -5,14 +5,14 @@
//! If no path is provided, creates a simple PDF with text explaining the features.
const std = @import("std");
const pdf = @import("zpdf");
const pdf = @import("zcatpdf");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
std.debug.print("zpdf - Image Demo\n", .{});
std.debug.print("zcatpdf - Image Demo\n", .{});
// Get command line args
const args = try std.process.argsAlloc(allocator);
@ -22,7 +22,7 @@ pub fn main() !void {
defer doc.deinit();
doc.setTitle("Image Demo");
doc.setAuthor("zpdf");
doc.setAuthor("zcatpdf");
var page = try doc.addPage(.{});
page.setMargins(50, 50, 50);
@ -223,7 +223,7 @@ pub fn main() !void {
page.setXY(50, 50);
try page.setFont(.helvetica, 9);
page.setFillColor(pdf.Color.medium_gray);
try page.cell(0, 15, "Generated with zpdf - Pure Zig PDF Library", pdf.Border.none, .center, false);
try page.cell(0, 15, "Generated with zcatpdf - Pure Zig PDF Library", pdf.Border.none, .center, false);
// Save
const filename = "image_demo.pdf";

View file

@ -1,14 +1,14 @@
//! Invoice PDF example - Demonstrates a realistic use case
const std = @import("std");
const pdf = @import("zpdf");
const pdf = @import("zcatpdf");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
std.debug.print("zpdf - Invoice example\n", .{});
std.debug.print("zcatpdf - Invoice example\n", .{});
var doc = pdf.Document.init(allocator);
defer doc.deinit();

View file

@ -6,20 +6,20 @@
//! - Visual link styling (blue underlined text)
const std = @import("std");
const pdf = @import("zpdf");
const pdf = @import("zcatpdf");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
std.debug.print("zpdf - Links Demo\n", .{});
std.debug.print("zcatpdf - Links Demo\n", .{});
var doc = pdf.Pdf.init(allocator, .{});
defer doc.deinit();
doc.setTitle("Links Demo");
doc.setAuthor("zpdf");
doc.setAuthor("zcatpdf");
// =========================================================================
// Page 1: External URL Links
@ -150,7 +150,7 @@ pub fn main() !void {
\\- /Border: Border style (we use [0 0 0] for invisible borders)
\\
\\The visual styling (blue text + underline) is separate from the annotation.
\\zpdf's urlLink() and writeUrlLink() methods combine both automatically.
\\zcatpdf's urlLink() and writeUrlLink() methods combine both automatically.
;
try page2.multiCell(500, null, tech_text, pdf.Border.none, .left, false);
@ -161,7 +161,7 @@ pub fn main() !void {
});
// Footer
try pdf.Pagination.addFooter(&doc, "Generated with zpdf - Links Demo", .{
try pdf.Pagination.addFooter(&doc, "Generated with zcatpdf - Links Demo", .{
.alignment = .center,
.font_size = 8,
.color = pdf.Color.light_gray,

View file

@ -3,27 +3,27 @@
//! Run with: zig build markdown_demo && ./zig-out/bin/markdown_demo
const std = @import("std");
const zpdf = @import("zpdf");
const zcatpdf = @import("zcatpdf");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
std.debug.print("=== zpdf Markdown Demo ===\n\n", .{});
std.debug.print("=== zcatpdf Markdown Demo ===\n\n", .{});
// Create PDF
var pdf = zpdf.Pdf.init(allocator, .{});
var pdf = zcatpdf.Pdf.init(allocator, .{});
defer pdf.deinit();
pdf.setTitle("Markdown Styled Document");
pdf.setAuthor("zpdf Markdown Renderer");
pdf.setAuthor("zcatpdf Markdown Renderer");
var page = try pdf.addPage(.{});
// Sample markdown text
const markdown_text =
\\# Welcome to zpdf Markdown
\\# Welcome to zcatpdf Markdown
\\
\\This is a demonstration of **Markdown-styled** text rendering in PDF.
\\
@ -40,7 +40,7 @@ pub fn main() !void {
\\### Code and Technical Content
\\
\\You can write technical documentation with styled text.
\\For example, the *zpdf* library is written in **Zig** and provides
\\For example, the *zcatpdf* library is written in **Zig** and provides
\\a simple API for PDF generation.
\\
\\## Numbered Lists
@ -56,7 +56,7 @@ pub fn main() !void {
;
// Parse markdown
var renderer = zpdf.MarkdownRenderer.init(allocator);
var renderer = zcatpdf.MarkdownRenderer.init(allocator);
defer renderer.deinit();
try renderer.parse(markdown_text);
@ -94,7 +94,7 @@ pub fn main() !void {
switch (line.line_type) {
.bullet => {
try page.setFont(.helvetica, base_font_size);
page.setFillColor(zpdf.Color.black);
page.setFillColor(zcatpdf.Color.black);
try page.drawText(x, y, "\xe2\x80\xa2"); // Bullet point (UTF-8)
// Note: PDF Type1 fonts don't support UTF-8, so we use a simple dash
try page.drawText(x, y, "-");
@ -104,7 +104,7 @@ pub fn main() !void {
.numbered => {
list_number += 1;
try page.setFont(.helvetica, base_font_size);
page.setFillColor(zpdf.Color.black);
page.setFillColor(zcatpdf.Color.black);
var num_buf: [16]u8 = undefined;
const num_str = std.fmt.bufPrint(&num_buf, "{d}.", .{list_number}) catch "?.";
try page.drawText(x, y, num_str);
@ -118,16 +118,16 @@ pub fn main() !void {
// Render spans
for (line.spans) |span| {
// Set font based on style
const font = zpdf.MarkdownRenderer.fontForStyle(span.style);
const font = zcatpdf.MarkdownRenderer.fontForStyle(span.style);
const font_size = span.font_size orelse base_font_size;
try page.setFont(font, font_size);
// Set color
if (span.color) |color| {
page.setFillColor(zpdf.Color.hex(color));
page.setFillColor(zcatpdf.Color.hex(color));
} else {
page.setFillColor(zpdf.Color.black);
page.setFillColor(zcatpdf.Color.black);
}
// Draw text
@ -136,7 +136,7 @@ pub fn main() !void {
// Draw underline if needed
if (span.style.underline) {
const text_width = font.stringWidth(span.text, font_size);
page.setStrokeColor(if (span.color) |c| zpdf.Color.hex(c) else zpdf.Color.black);
page.setStrokeColor(if (span.color) |c| zcatpdf.Color.hex(c) else zcatpdf.Color.black);
try page.setLineWidth(0.5);
try page.drawLine(x, y - 2, x + text_width, y - 2);
}
@ -144,7 +144,7 @@ pub fn main() !void {
// Draw strikethrough if needed
if (span.style.strikethrough) {
const text_width = font.stringWidth(span.text, font_size);
page.setStrokeColor(zpdf.Color.black);
page.setStrokeColor(zcatpdf.Color.black);
try page.setLineWidth(0.5);
const strike_y = y + font_size * 0.3;
try page.drawLine(x, strike_y, x + text_width, strike_y);

View file

@ -3,20 +3,20 @@
//! Shows how to add page numbers and footers to multi-page documents.
const std = @import("std");
const pdf = @import("zpdf");
const pdf = @import("zcatpdf");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
std.debug.print("zpdf - Pagination Demo\n", .{});
std.debug.print("zcatpdf - Pagination Demo\n", .{});
var doc = pdf.Pdf.init(allocator, .{});
defer doc.deinit();
doc.setTitle("Pagination Demo");
doc.setAuthor("zpdf");
doc.setAuthor("zcatpdf");
// Create multiple pages with content
const num_pages: usize = 5;
@ -79,7 +79,7 @@ pub fn main() !void {
}
// Add header to all pages (with line separator)
try pdf.addHeader(&doc, "zpdf Library - Multi-Page Document Example", .{
try pdf.addHeader(&doc, "zcatpdf Library - Multi-Page Document Example", .{
.alignment = .center,
.margin = 30,
.font_size = 9,

View file

@ -4,20 +4,20 @@
//! alternating colors, and custom styling.
const std = @import("std");
const pdf = @import("zpdf");
const pdf = @import("zcatpdf");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
std.debug.print("zpdf - Table Demo\n", .{});
std.debug.print("zcatpdf - Table Demo\n", .{});
var doc = pdf.Pdf.init(allocator, .{});
defer doc.deinit();
doc.setTitle("Table Demo");
doc.setAuthor("zpdf");
doc.setAuthor("zcatpdf");
var page = try doc.addPage(.{});
page.setMargins(50, 50, 50);
@ -146,7 +146,7 @@ pub fn main() !void {
page.setXY(50, 50);
try page.setFont(.helvetica, 9);
page.setFillColor(pdf.Color.medium_gray);
try page.cell(0, 15, "Generated with zpdf - Table Helper Demo", pdf.Border.none, .center, false);
try page.cell(0, 15, "Generated with zcatpdf - Table Helper Demo", pdf.Border.none, .center, false);
// Save
const filename = "table_demo.pdf";

View file

@ -3,14 +3,14 @@
//! Run with: zig build template_demo && ./zig-out/bin/template_demo
const std = @import("std");
const zpdf = @import("zpdf");
const zcatpdf = @import("zcatpdf");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
std.debug.print("=== zpdf Template Demo ===\n\n", .{});
std.debug.print("=== zcatpdf Template Demo ===\n\n", .{});
// Create invoice using template
try createInvoiceFromTemplate(allocator);
@ -25,14 +25,14 @@ fn createInvoiceFromTemplate(allocator: std.mem.Allocator) !void {
std.debug.print("Creating invoice from template...\n", .{});
// Get the invoice template
var tmpl = try zpdf.Template.invoiceTemplate(allocator);
var tmpl = try zcatpdf.Template.invoiceTemplate(allocator);
defer tmpl.deinit();
std.debug.print(" Template: {s}\n", .{tmpl.name});
std.debug.print(" Page size: {d:.0} x {d:.0} points\n", .{ tmpl.page_width, tmpl.page_height });
// Create PDF based on template
var pdf = zpdf.Pdf.init(allocator, .{});
var pdf = zcatpdf.Pdf.init(allocator, .{});
defer pdf.deinit();
pdf.setTitle("Invoice from Template");
@ -72,10 +72,10 @@ fn createInvoiceFromTemplate(allocator: std.mem.Allocator) !void {
std.debug.print(" Items region: ({d:.0}, {d:.0}) {d:.0}x{d:.0}\n", .{ region.x, region.y, region.width, region.height });
// Draw table header
page.setFillColor(zpdf.Color.hex(0xE0E0E0));
page.setFillColor(zcatpdf.Color.hex(0xE0E0E0));
try page.fillRect(region.x, region.y + region.height - 25, region.width, 25);
page.setFillColor(zpdf.Color.black);
page.setFillColor(zcatpdf.Color.black);
try page.setFont(.helvetica_bold, 10);
try page.drawText(region.x + 5, region.y + region.height - 17, "Description");
try page.drawText(region.x + 250, region.y + region.height - 17, "Qty");
@ -100,7 +100,7 @@ fn createInvoiceFromTemplate(allocator: std.mem.Allocator) !void {
}
// Draw table border
page.setStrokeColor(zpdf.Color.black);
page.setStrokeColor(zcatpdf.Color.black);
try page.drawRect(region.x, region.y, region.width, region.height);
}
@ -123,7 +123,7 @@ fn createInvoiceFromTemplate(allocator: std.mem.Allocator) !void {
if (tmpl.getRegion("footer")) |region| {
std.debug.print(" Footer region: ({d:.0}, {d:.0})\n", .{ region.x, region.y });
try page.setFont(.helvetica, 8);
page.setFillColor(zpdf.Color.hex(0x666666));
page.setFillColor(zcatpdf.Color.hex(0x666666));
try page.drawText(region.x, region.y + 20, "Payment Terms: Net 14 days");
try page.drawText(region.x, region.y + 8, "Thank you for your business!");
}
@ -136,13 +136,13 @@ fn createLetterFromTemplate(allocator: std.mem.Allocator) !void {
std.debug.print("\nCreating letter from template...\n", .{});
// Get the letter template
var tmpl = try zpdf.Template.letterTemplate(allocator);
var tmpl = try zcatpdf.Template.letterTemplate(allocator);
defer tmpl.deinit();
std.debug.print(" Template: {s}\n", .{tmpl.name});
// Create PDF based on template
var pdf = zpdf.Pdf.init(allocator, .{});
var pdf = zcatpdf.Pdf.init(allocator, .{});
defer pdf.deinit();
pdf.setTitle("Letter from Template");

View file

@ -1,20 +1,20 @@
//! Text System Demo - Demonstrates cell(), multiCell(), alignment, etc.
const std = @import("std");
const pdf = @import("zpdf");
const pdf = @import("zcatpdf");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
std.debug.print("zpdf - Text System Demo\n", .{});
std.debug.print("zcatpdf - Text System Demo\n", .{});
var doc = pdf.Pdf.init(allocator, .{});
defer doc.deinit();
doc.setTitle("Text System Demo");
doc.setAuthor("zpdf");
doc.setAuthor("zcatpdf");
var page = try doc.addPage(.{});
@ -74,7 +74,7 @@ pub fn main() !void {
page.setFillColor(pdf.Color.rgb(245, 245, 245));
const long_text =
\\This is a demonstration of the multiCell function in zpdf.
\\This is a demonstration of the multiCell function in zcatpdf.
\\It automatically wraps text to fit within the specified width.
\\
\\You can include explicit line breaks using backslash-n, and the
@ -171,7 +171,7 @@ pub fn main() !void {
page.setXY(50, 50);
try page.setFont(.helvetica, 9);
page.setFillColor(pdf.Color.medium_gray);
try page.cell(0, 15, "Generated with zpdf - Pure Zig PDF Library", pdf.Border.none, .center, false);
try page.cell(0, 15, "Generated with zcatpdf - Pure Zig PDF Library", pdf.Border.none, .center, false);
// Save
const filename = "text_demo.pdf";

View file

@ -1,6 +1,6 @@
//! Transforms Demo - Rotation, Scaling, Skew, and Translation
//!
//! Demonstrates the transformation capabilities of zpdf including:
//! Demonstrates the transformation capabilities of zcatpdf including:
//! - Rotation around a point
//! - Scaling from a point
//! - Skewing (shearing)
@ -8,20 +8,20 @@
//! - Combined transformations
const std = @import("std");
const pdf = @import("zpdf");
const pdf = @import("zcatpdf");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
std.debug.print("zpdf - Transforms Demo\n", .{});
std.debug.print("zcatpdf - Transforms Demo\n", .{});
var doc = pdf.Pdf.init(allocator, .{});
defer doc.deinit();
doc.setTitle("Transforms Demo");
doc.setAuthor("zpdf");
doc.setAuthor("zcatpdf");
// =========================================================================
// Page 1: Rotation
@ -157,7 +157,7 @@ pub fn main() !void {
// Footer
try page.setFont(.helvetica, 9);
page.setFillColor(pdf.Color.medium_gray);
try page.drawText(250, 50, "Page 1 of 2 - zpdf Transforms Demo");
try page.drawText(250, 50, "Page 1 of 2 - zcatpdf Transforms Demo");
}
// =========================================================================
@ -323,7 +323,7 @@ pub fn main() !void {
// Footer
try page.setFont(.helvetica, 9);
page.setFillColor(pdf.Color.medium_gray);
try page.drawText(250, 50, "Page 2 of 2 - zpdf Transforms Demo");
try page.drawText(250, 50, "Page 2 of 2 - zcatpdf Transforms Demo");
}
// Save

View file

@ -1,25 +1,25 @@
//! Transparency Demo - Alpha/Opacity Support
//!
//! Demonstrates the transparency capabilities of zpdf including:
//! Demonstrates the transparency capabilities of zcatpdf including:
//! - Fill opacity for shapes and text
//! - Stroke opacity for lines and outlines
//! - Layered transparent objects
const std = @import("std");
const pdf = @import("zpdf");
const pdf = @import("zcatpdf");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
std.debug.print("zpdf - Transparency Demo\n", .{});
std.debug.print("zcatpdf - Transparency Demo\n", .{});
var doc = pdf.Pdf.init(allocator, .{});
defer doc.deinit();
doc.setTitle("Transparency Demo");
doc.setAuthor("zpdf");
doc.setAuthor("zcatpdf");
const page = try doc.addPage(.{});
@ -198,7 +198,7 @@ pub fn main() !void {
try page.setOpacity(1.0);
try page.setFont(.helvetica, 9);
page.setFillColor(pdf.Color.medium_gray);
try page.drawText(250, 50, "zpdf Transparency Demo");
try page.drawText(250, 50, "zcatpdf Transparency Demo");
// Save
const filename = "transparency_demo.pdf";

View file

@ -3,10 +3,10 @@
//! Demonstrates loading and using TrueType fonts.
const std = @import("std");
const zpdf = @import("zpdf");
const Pdf = zpdf.Pdf;
const Color = zpdf.Color;
const TrueTypeFont = zpdf.TrueTypeFont;
const zcatpdf = @import("zcatpdf");
const Pdf = zcatpdf.Pdf;
const Color = zcatpdf.Color;
const TrueTypeFont = zcatpdf.TrueTypeFont;
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@ -17,7 +17,7 @@ pub fn main() !void {
defer pdf.deinit();
pdf.setTitle("TrueType Font Demo");
pdf.setAuthor("zpdf");
pdf.setAuthor("zcatpdf");
// Try to load a system TTF font
const font_paths = [_][]const u8{

View file

@ -1,4 +1,4 @@
//! Compression module for zpdf
//! Compression module for zcatpdf
//!
//! Provides zlib/deflate compression and decompression using libdeflate.
//! Used for PNG image processing and PDF stream compression.

View file

@ -1,4 +1,4 @@
//! zlib compression utilities for zpdf
//! zlib compression utilities for zcatpdf
//!
//! Provides compression and decompression using libdeflate.
//! Used for PNG image processing and PDF stream compression.

View file

@ -1,4 +1,4 @@
//! Image module for zpdf
//! Image module for zcatpdf
//!
//! Provides image parsing and embedding support for PDF generation.
//! Supports JPEG (direct embedding) and PNG (with alpha support).

View file

@ -254,7 +254,7 @@ pub const OutputProducer = struct {
try base.writeString(writer, creator);
try writer.writeByte('\n');
}
try writer.writeAll("/Producer (zpdf)\n");
try writer.writeAll("/Producer (zcatpdf)\n");
try writer.writeAll(">>\n");
try self.endObject();

View file

@ -29,7 +29,7 @@ const png = @import("images/png.zig");
const images_mod = @import("images/mod.zig");
const Outline = @import("outline.zig").Outline;
/// Configuration constants for zpdf
/// Configuration constants for zcatpdf
pub const Config = struct {
/// Maximum file size for image loading (default: 10MB)
pub const max_image_file_size: usize = 10 * 1024 * 1024;

View file

@ -1,15 +1,15 @@
//! zpdf - PDF generation library for Zig
//! zcatpdf - PDF generation library for Zig
//!
//! A pure Zig library for creating PDF documents with zero dependencies.
//! A pure Zig library for creating PDF documents with minimal dependencies.
//! Based on fpdf2 (Python) architecture.
//!
//! ## Quick Start
//!
//! ```zig
//! const zpdf = @import("zpdf");
//! const zcatpdf = @import("zcatpdf");
//!
//! pub fn main() !void {
//! var pdf = zpdf.Pdf.init(allocator, .{});
//! var pdf = zcatpdf.Pdf.init(allocator, .{});
//! defer pdf.deinit();
//!
//! var page = try pdf.addPage(.{});
@ -190,7 +190,7 @@ pub const Document = struct {
// Tests
// =============================================================================
test "zpdf re-exports" {
test "zcatpdf re-exports" {
// Test that all types are accessible
_ = Pdf;
_ = Page;
@ -221,19 +221,19 @@ test "Document backwards compatibility" {
test "new Pdf API" {
const allocator = std.testing.allocator;
var zpdf_doc = Pdf.init(allocator, .{
var pdf_doc = Pdf.init(allocator, .{
.page_size = .a4,
.orientation = .portrait,
});
defer zpdf_doc.deinit();
defer pdf_doc.deinit();
zpdf_doc.setTitle("Test Document");
zpdf_doc.setAuthor("zpdf");
pdf_doc.setTitle("Test Document");
pdf_doc.setAuthor("zcatpdf");
var pg = try zpdf_doc.addPage(.{});
var pg = try pdf_doc.addPage(.{});
try pg.setFont(.helvetica_bold, 24);
pg.setFillColor(Color.blue);
try pg.drawText(50, 750, "Hello zpdf!");
try pg.drawText(50, 750, "Hello zcatpdf!");
pg.setStrokeColor(Color.red);
try pg.setLineWidth(2);
@ -242,7 +242,7 @@ test "new Pdf API" {
pg.setFillColor(Color.light_gray);
try pg.fillRect(50, 600, 150, 100);
const data = try zpdf_doc.output();
const data = try pdf_doc.output();
defer allocator.free(data);
try std.testing.expect(std.mem.startsWith(u8, data, "%PDF-1.4"));