//! Links Demo - Demonstrates clickable URL links in PDFs //! //! Shows how to create: //! - Clickable URL links (external websites) //! - Internal page links (jump to page) //! - Visual link styling (blue underlined text) 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 - Links Demo\n", .{}); var doc = pdf.Pdf.init(allocator, .{}); defer doc.deinit(); doc.setTitle("Links Demo"); doc.setAuthor("zcatpdf"); // ========================================================================= // Page 1: External URL Links // ========================================================================= var page1 = try doc.addPage(.{}); page1.setMargins(50, 50, 50); // Title try page1.setFont(.helvetica_bold, 24); page1.setFillColor(pdf.Color.rgb(41, 98, 255)); page1.setXY(50, 780); try page1.cell(0, 30, "Clickable Links Demo", pdf.Border.none, .center, false); page1.ln(50); // Description try page1.setFont(.helvetica, 12); page1.setFillColor(pdf.Color.black); const desc = \\This PDF demonstrates clickable links. When you view this in a PDF reader, \\you can click on the blue underlined text to open URLs in your browser. ; try page1.multiCell(500, null, desc, pdf.Border.none, .left, false); page1.ln(30); // Section: External Links try page1.setFont(.helvetica_bold, 16); page1.setFillColor(pdf.Color.rgb(51, 51, 51)); try page1.cell(0, 25, "External URL Links", pdf.Border.none, .left, false); page1.ln(30); try page1.setFont(.helvetica, 12); page1.setFillColor(pdf.Color.black); // Link 1: Example website try page1.cell(0, 18, "Visit the example website: ", pdf.Border.none, .left, false); _ = try page1.writeUrlLink("https://example.com", "https://example.com"); page1.ln(25); // Link 2: GitHub try page1.cell(0, 18, "Check out Zig on GitHub: ", pdf.Border.none, .left, false); _ = try page1.writeUrlLink("Zig Language", "https://github.com/ziglang/zig"); page1.ln(25); // Link 3: Email try page1.cell(0, 18, "Send us an email: ", pdf.Border.none, .left, false); _ = try page1.writeUrlLink("contact@example.com", "mailto:contact@example.com"); page1.ln(40); // Section: Internal Links try page1.setFont(.helvetica_bold, 16); page1.setFillColor(pdf.Color.rgb(51, 51, 51)); try page1.cell(0, 25, "Internal Page Links", pdf.Border.none, .left, false); page1.ln(30); try page1.setFont(.helvetica, 12); page1.setFillColor(pdf.Color.black); try page1.cell(0, 18, "Click to jump to: ", pdf.Border.none, .left, false); // Internal link to page 2 const link_text = "Page 2 - More Information"; const link_width = try page1.drawLink(page1.getX(), page1.getY(), link_text); try page1.addInternalLink(1, page1.getX(), page1.getY() - 2, link_width, 16); page1.ln(40); // Information box page1.setFillColor(pdf.Color.rgb(240, 248, 255)); try page1.fillRect(50, page1.getY() - 80, 495, 80); try page1.setFont(.helvetica, 11); page1.setFillColor(pdf.Color.rgb(51, 51, 51)); page1.setXY(60, page1.getY() - 15); const info_text = \\Note: Link clickability depends on your PDF viewer. Most modern viewers \\(Adobe Reader, Preview, Chrome, Firefox) support clickable links. \\The blue underlined styling is visual, while the annotation makes it clickable. ; try page1.multiCell(475, null, info_text, pdf.Border.none, .left, false); // ========================================================================= // Page 2: More Information // ========================================================================= var page2 = try doc.addPage(.{}); page2.setMargins(50, 50, 50); // Title try page2.setFont(.helvetica_bold, 24); page2.setFillColor(pdf.Color.rgb(41, 98, 255)); page2.setXY(50, 780); try page2.cell(0, 30, "Page 2 - More Information", pdf.Border.none, .center, false); page2.ln(50); try page2.setFont(.helvetica, 12); page2.setFillColor(pdf.Color.black); const page2_text = \\You navigated here from a clickable internal link! \\ \\Internal links allow you to create table of contents, cross-references, \\and navigation within your PDF documents. \\ \\The link annotation stores the target page number and the PDF viewer \\handles the navigation when clicked. ; try page2.multiCell(500, null, page2_text, pdf.Border.none, .left, false); page2.ln(30); // Link back to page 1 try page2.cell(0, 18, "Go back to: ", pdf.Border.none, .left, false); const back_text = "Page 1 - Links Demo"; const back_width = try page2.drawLink(page2.getX(), page2.getY(), back_text); try page2.addInternalLink(0, page2.getX(), page2.getY() - 2, back_width, 16); page2.ln(50); // Technical details try page2.setFont(.helvetica_bold, 14); page2.setFillColor(pdf.Color.rgb(51, 51, 51)); try page2.cell(0, 20, "How Links Work in PDF", pdf.Border.none, .left, false); page2.ln(25); try page2.setFont(.helvetica, 11); page2.setFillColor(pdf.Color.black); const tech_text = \\PDF links are implemented using Annotation objects (/Type /Annot /Subtype /Link). \\ \\Each link annotation contains: \\- /Rect: The clickable area coordinates [x1, y1, x2, y2] \\- /A: Action dictionary for URL links (/S /URI /URI "url") \\- /Dest: Destination for internal links (page reference) \\- /Border: Border style (we use [0 0 0] for invisible borders) \\ \\The visual styling (blue text + underline) is separate from the annotation. \\zcatpdf's urlLink() and writeUrlLink() methods combine both automatically. ; try page2.multiCell(500, null, tech_text, pdf.Border.none, .left, false); // Add page numbers try pdf.Pagination.addPageNumbers(&doc, .{ .format = "Page {PAGE} of {PAGES}", .position = .bottom_center, }); // Footer try pdf.Pagination.addFooter(&doc, "Generated with zcatpdf - Links Demo", .{ .alignment = .center, .font_size = 8, .color = pdf.Color.light_gray, }); // Save const filename = "links_demo.pdf"; try doc.save(filename); std.debug.print("Created: {s}\n", .{filename}); std.debug.print("Open in a PDF viewer and click the links!\n", .{}); std.debug.print("Done!\n", .{}); }