zcatpdf/examples/transparency_demo.zig
reugenio 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

209 lines
7 KiB
Zig

//! Transparency Demo - Alpha/Opacity Support
//!
//! 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("zcatpdf");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
std.debug.print("zcatpdf - Transparency Demo\n", .{});
var doc = pdf.Pdf.init(allocator, .{});
defer doc.deinit();
doc.setTitle("Transparency Demo");
doc.setAuthor("zcatpdf");
const page = try doc.addPage(.{});
// Title
try page.setFont(.helvetica_bold, 24);
page.setFillColor(pdf.Color.rgb(41, 98, 255));
try page.drawText(50, 780, "Transparency / Alpha");
try page.setFont(.helvetica, 11);
page.setFillColor(pdf.Color.black);
try page.drawText(50, 755, "Demonstrating fill and stroke opacity using ExtGState");
// =========================================================================
// Fill Opacity Examples
// =========================================================================
try page.setFont(.helvetica_bold, 14);
page.setFillColor(pdf.Color.black);
try page.drawText(50, 710, "Fill Opacity:");
// Draw overlapping squares with different opacities
const base_x: f32 = 80;
const base_y: f32 = 550;
const size: f32 = 100;
// First layer - red square (fully opaque)
page.setFillColor(pdf.Color.rgb(255, 0, 0));
try page.fillRect(base_x, base_y, size, size);
// Second layer - green square (75% opacity)
page.setFillColor(pdf.Color.rgb(0, 255, 0));
try page.setFillOpacity(0.75);
try page.fillRect(base_x + 40, base_y + 30, size, size);
// Third layer - blue square (50% opacity)
page.setFillColor(pdf.Color.rgb(0, 0, 255));
try page.setFillOpacity(0.5);
try page.fillRect(base_x + 80, base_y + 60, size, size);
// Labels
try page.setOpacity(1.0); // Reset to fully opaque
try page.setFont(.helvetica, 9);
page.setFillColor(pdf.Color.dark_gray);
try page.drawText(base_x, base_y - 15, "Overlapping (100%, 75%, 50%)");
// Individual opacity examples
const opacities = [_]f32{ 1.0, 0.75, 0.5, 0.25, 0.1 };
var x: f32 = 280;
for (opacities) |opacity| {
try page.setFillOpacity(opacity);
page.setFillColor(pdf.Color.rgb(128, 0, 128)); // Purple
try page.fillRect(x, base_y + 30, 60, 60);
try page.setOpacity(1.0); // Reset for label
try page.setFont(.helvetica, 9);
page.setFillColor(pdf.Color.dark_gray);
var buf: [32]u8 = undefined;
const label = std.fmt.bufPrint(&buf, "{d}%", .{@as(u32, @intFromFloat(opacity * 100))}) catch "??";
try page.drawText(x + 20, base_y + 10, label);
x += 70;
}
// =========================================================================
// Stroke Opacity Examples
// =========================================================================
try page.setOpacity(1.0);
try page.setFont(.helvetica_bold, 14);
page.setFillColor(pdf.Color.black);
try page.drawText(50, 500, "Stroke Opacity:");
try page.setLineWidth(8);
page.setStrokeColor(pdf.Color.rgb(220, 20, 60)); // Crimson
x = 80;
for (opacities) |opacity| {
try page.setStrokeOpacity(opacity);
try page.drawLine(x, 420, x + 80, 420);
try page.setOpacity(1.0);
try page.setFont(.helvetica, 9);
page.setFillColor(pdf.Color.dark_gray);
var buf: [32]u8 = undefined;
const label = std.fmt.bufPrint(&buf, "{d}%", .{@as(u32, @intFromFloat(opacity * 100))}) catch "??";
try page.drawText(x + 20, 400, label);
x += 100;
}
// =========================================================================
// Combined Fill and Stroke Opacity
// =========================================================================
try page.setOpacity(1.0);
try page.setFont(.helvetica_bold, 14);
page.setFillColor(pdf.Color.black);
try page.drawText(50, 370, "Combined Fill + Stroke Opacity:");
try page.setLineWidth(4);
x = 80;
const fill_opacities = [_]f32{ 1.0, 0.5, 0.25 };
const stroke_opacities = [_]f32{ 1.0, 0.5, 0.25 };
for (fill_opacities, stroke_opacities) |fill_op, stroke_op| {
page.setFillColor(pdf.Color.rgb(100, 149, 237)); // Cornflower blue
page.setStrokeColor(pdf.Color.rgb(0, 0, 139)); // Dark blue
try page.setFillOpacity(fill_op);
try page.setStrokeOpacity(stroke_op);
try page.drawFilledRect(x, 280, 80, 60);
try page.setOpacity(1.0);
try page.setFont(.helvetica, 8);
page.setFillColor(pdf.Color.dark_gray);
var buf: [32]u8 = undefined;
const label = std.fmt.bufPrint(&buf, "f:{d}% s:{d}%", .{
@as(u32, @intFromFloat(fill_op * 100)),
@as(u32, @intFromFloat(stroke_op * 100)),
}) catch "??";
try page.drawText(x, 265, label);
x += 120;
}
// =========================================================================
// Transparent Text
// =========================================================================
try page.setOpacity(1.0);
try page.setFont(.helvetica_bold, 14);
page.setFillColor(pdf.Color.black);
try page.drawText(50, 230, "Transparent Text:");
// Background rectangle
page.setFillColor(pdf.Color.rgb(255, 215, 0)); // Gold
try page.fillRect(80, 130, 450, 70);
// Overlapping text with different opacities
try page.setFont(.helvetica_bold, 48);
page.setFillColor(pdf.Color.rgb(255, 0, 0));
try page.setFillOpacity(1.0);
try page.drawText(100, 150, "ZPDF");
page.setFillColor(pdf.Color.rgb(0, 128, 0));
try page.setFillOpacity(0.6);
try page.drawText(150, 160, "ZPDF");
page.setFillColor(pdf.Color.rgb(0, 0, 255));
try page.setFillOpacity(0.3);
try page.drawText(200, 170, "ZPDF");
// =========================================================================
// Transparent Circles (Venn diagram style)
// =========================================================================
try page.setOpacity(1.0);
try page.setFont(.helvetica_bold, 14);
page.setFillColor(pdf.Color.black);
try page.drawText(350, 230, "Overlapping Circles:");
try page.setFillOpacity(0.5);
page.setFillColor(pdf.Color.rgb(255, 0, 0));
try page.fillCircle(420, 170, 50);
page.setFillColor(pdf.Color.rgb(0, 255, 0));
try page.fillCircle(460, 170, 50);
page.setFillColor(pdf.Color.rgb(0, 0, 255));
try page.fillCircle(440, 130, 50);
// Footer
try page.setOpacity(1.0);
try page.setFont(.helvetica, 9);
page.setFillColor(pdf.Color.medium_gray);
try page.drawText(250, 50, "zcatpdf Transparency Demo");
// Save
const filename = "transparency_demo.pdf";
try doc.save(filename);
std.debug.print("Created: {s} ({d} pages)\n", .{ filename, doc.pageCount() });
std.debug.print("Done!\n", .{});
}