RedactLinks.cs
//
// This code is part of Document Solutions for PDF demos.
// Copyright (c) MESCIUS inc. All rights reserved.
//
using System.IO;
using System.Drawing;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using GrapeCity.Documents.Pdf;
using GrapeCity.Documents.Pdf.Annotations;
using GrapeCity.Documents.Pdf.TextMap;
using GrapeCity.Documents.Pdf.AcroForms;
using GrapeCity.Documents.Pdf.Actions;
using GrapeCity.Documents.Common;
using System.Linq;

namespace DsPdfWeb.Demos
{
    // This sample shows how to find and remove all links to a certain URL from a PDF.
    // The code first finds all link annotations with ActionURI pointing to the URL
    // that needs to be removed, then uses redact to erase all content within the found link areas.
    // Red overlay is used by the redacts to visualize the erased areas.
    //
    // The PDF used by this sample, but with links intact, can be seen in the FindAndHighlight sample.
    public class RedactLinks
    {
        public int CreatePDF(Stream stream)
        {
            // Load the PDF with links that need to be remove:
            var doc = new GcPdfDocument();
            using var fs = File.OpenRead(Path.Combine("Resources", "PDFs", "fendo-13-1005722.pdf"));
            doc.Load(fs);

            // Remove all links containing this string:
            const string targetUrl = "frontiersin.org";

            // Find all relevant link annotations:
            var linkAnnotations = new HashSet<LinkAnnotation>();
            foreach (var page in doc.Pages)
            {
                foreach (var a in page.Annotations)
                {
                    if (a is LinkAnnotation la && la.Action is ActionURI actUri)
                    {
                        if (!string.IsNullOrEmpty(actUri.URI) && actUri.URI.Contains(targetUrl))
                        {
                            linkAnnotations.Add(la);
                        }
                    }
                }
            }
            // Loop through the found links, add redact annotations for each:
            foreach (var la in linkAnnotations)
            {
                foreach (var page in la.Pages)
                {
                    // We must make a copy of page.Annotations to be able to add redact annotations in a foreach loop:
                    var annots = page.Annotations.Where(a_ => a_ == la).ToList();
                    foreach (var a in annots)
                    {
                        page.Annotations.Add(new RedactAnnotation()
                        {
                            Rect = la.Rect,
                            OverlayFillColor = Color.Red
                        });
                    }
                }
            }
            // Apply the redacts:
            doc.Redact();

            // Done:
            doc.Save(stream);
            return doc.Pages.Count;
        }
    }
}