zcatpdf/examples/text_demo.zig
reugenio 2996289953 feat: v0.2 - Complete text system (cell, multiCell, alignment)
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>
2025-12-08 19:46:30 +01:00

182 lines
6 KiB
Zig

//! Text System Demo - Demonstrates cell(), multiCell(), alignment, etc.
const std = @import("std");
const pdf = @import("zpdf");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
std.debug.print("zpdf - Text System Demo\n", .{});
var doc = pdf.Pdf.init(allocator, .{});
defer doc.deinit();
doc.setTitle("Text System Demo");
doc.setAuthor("zpdf");
var page = try doc.addPage(.{});
// Set initial position at top of page with margins
page.setMargins(50, 50, 50);
page.setXY(50, 800);
// Title
try page.setFont(.helvetica_bold, 24);
page.setFillColor(pdf.Color.rgb(41, 98, 255));
try page.cell(0, 30, "Text System Demo", pdf.Border.none, .center, false);
page.ln(35);
// Section 1: Basic cells
try page.setFont(.helvetica_bold, 14);
page.setFillColor(pdf.Color.black);
try page.cell(0, 20, "1. Basic Cells", pdf.Border.none, .left, false);
page.ln(25);
try page.setFont(.helvetica, 12);
// Row of cells with different alignments
page.setFillColor(pdf.Color.rgb(230, 230, 230));
try page.cell(150, 20, "Left aligned", pdf.Border.all, .left, true);
try page.cell(150, 20, "Center", pdf.Border.all, .center, true);
try page.cell(150, 20, "Right aligned", pdf.Border.all, .right, true);
page.ln(25);
// Section 2: Colored cells
try page.setFont(.helvetica_bold, 14);
page.setFillColor(pdf.Color.black);
try page.cell(0, 20, "2. Colored Cells", pdf.Border.none, .left, false);
page.ln(25);
try page.setFont(.helvetica, 12);
page.setFillColor(pdf.Color.rgb(255, 200, 200));
try page.cell(100, 20, "Red", pdf.Border.all, .center, true);
page.setFillColor(pdf.Color.rgb(200, 255, 200));
try page.cell(100, 20, "Green", pdf.Border.all, .center, true);
page.setFillColor(pdf.Color.rgb(200, 200, 255));
try page.cell(100, 20, "Blue", pdf.Border.all, .center, true);
page.setFillColor(pdf.Color.rgb(255, 255, 200));
try page.cell(100, 20, "Yellow", pdf.Border.all, .center, true);
page.ln(30);
// Section 3: MultiCell with word wrap
try page.setFont(.helvetica_bold, 14);
page.setFillColor(pdf.Color.black);
try page.cell(0, 20, "3. MultiCell with Word Wrap", pdf.Border.none, .left, false);
page.ln(25);
try page.setFont(.helvetica, 11);
page.setFillColor(pdf.Color.rgb(245, 245, 245));
const long_text =
\\This is a demonstration of the multiCell function in zpdf.
\\It automatically wraps text to fit within the specified width.
\\
\\You can include explicit line breaks using backslash-n, and the
\\text will flow naturally within the cell boundaries. This is
\\useful for paragraphs, descriptions, and any longer text content.
;
try page.multiCell(450, null, long_text, pdf.Border.all, .left, true);
page.ln(10);
// Section 4: Table-like structure
try page.setFont(.helvetica_bold, 14);
page.setFillColor(pdf.Color.black);
try page.cell(0, 20, "4. Table Structure", pdf.Border.none, .left, false);
page.ln(25);
// Table header
try page.setFont(.helvetica_bold, 11);
page.setFillColor(pdf.Color.rgb(41, 98, 255));
page.setTextColor(pdf.Color.white);
try page.cell(150, 20, "Product", pdf.Border.all, .center, true);
try page.cell(100, 20, "Quantity", pdf.Border.all, .center, true);
try page.cell(100, 20, "Price", pdf.Border.all, .center, true);
try page.cell(100, 20, "Total", pdf.Border.all, .center, true);
page.ln(null);
// Table rows
try page.setFont(.helvetica, 11);
page.setTextColor(pdf.Color.black);
const products = [_]struct { name: []const u8, qty: []const u8, price: []const u8, total: []const u8 }{
.{ .name = "Widget A", .qty = "10", .price = "5.00", .total = "50.00" },
.{ .name = "Widget B", .qty = "5", .price = "12.50", .total = "62.50" },
.{ .name = "Widget C", .qty = "3", .price = "25.00", .total = "75.00" },
};
for (products, 0..) |product, i| {
if (i % 2 == 0) {
page.setFillColor(pdf.Color.white);
} else {
page.setFillColor(pdf.Color.rgb(245, 245, 245));
}
try page.cell(150, 18, product.name, pdf.Border.all, .left, true);
try page.cell(100, 18, product.qty, pdf.Border.all, .center, true);
try page.cell(100, 18, product.price, pdf.Border.all, .right, true);
try page.cell(100, 18, product.total, pdf.Border.all, .right, true);
page.ln(null);
}
// Total row
try page.setFont(.helvetica_bold, 11);
page.setFillColor(pdf.Color.rgb(230, 230, 230));
try page.cell(350, 20, "TOTAL", pdf.Border.all, .right, true);
try page.cell(100, 20, "187.50", pdf.Border.all, .right, true);
page.ln(30);
// Section 5: Different fonts
try page.setFont(.helvetica_bold, 14);
page.setFillColor(pdf.Color.black);
try page.cell(0, 20, "5. Font Showcase", pdf.Border.none, .left, false);
page.ln(25);
const fonts = [_]pdf.Font{
.helvetica,
.helvetica_bold,
.helvetica_oblique,
.times_roman,
.times_bold,
.times_italic,
.courier,
.courier_bold,
};
const font_names = [_][]const u8{
"Helvetica",
"Helvetica Bold",
"Helvetica Oblique",
"Times Roman",
"Times Bold",
"Times Italic",
"Courier",
"Courier Bold",
};
for (fonts, 0..) |font, i| {
try page.setFont(font, 11);
page.setFillColor(pdf.Color.black);
try page.cell(200, 16, font_names[i], pdf.Border.none, .left, false);
page.ln(null);
}
// Footer
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);
// Save
const filename = "text_demo.pdf";
try doc.save(filename);
std.debug.print("Created: {s}\n", .{filename});
std.debug.print("Done!\n", .{});
}