//! 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", .{}); }