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

namespace DsPdfWeb.Demos
{
    // This example shows how to strikeout a paragraph starting with a certain phrase
    // ("Several species") using the text markup strikeout annotation.
    public class StrikeoutParagraph
    {
        public int CreatePDF(Stream stream)
        {
            // Load the PDF:
            var doc = new GcPdfDocument();
            using var fs = File.OpenRead(Path.Combine("Resources", "PDFs", "Wetlands.pdf"));
            doc.Load(fs);

            // Strikeout the first paragraph that starts with the words "Several species":
            ITextParagraph para = null;
            foreach (var p in doc.Pages)
            {
                var paras = p.GetTextMap().Paragraphs;
                para = paras.FirstOrDefault(p_ => p_.GetText().StartsWith("Several species"));
                if (para != null)
                    break;
            }
            if (para == null)
                return doc.Pages.Count; // Should not happen.

            // Text markup strikeout annotation:
            var markup = new TextMarkupAnnotation()
            {
                Page = para.Page,
                MarkupType = TextMarkupType.StrikeOut,
                Color = Color.Red
            };

            // Get the coordinates of all text run fragments in the paragraph,
            // and add them to the annotation's area:
            List<Quadrilateral> area = new List<Quadrilateral>();
            foreach (var run in para.Runs)
            {
                foreach (var frag in run)
                {
                    // Note: in v6.0.3 a method ITextRunFragment.GetBounds() was added,
                    // so this code can be replaced with a single 'frag.GetBounds()' call.
                    // Find the text run fragment's index in the containing line:
                    int index = 0;
                    var line = frag.Line;
                    var frags = line.RunFragments;
                    for (int i = 0; i < frags.Count && frags[i] != frag; ++i)
                        index += frags[i].Count;
                    // Add the fragment's bounds (quadrilateral) to the annotation area:
                    area.Add(frag.Line.GetCoords(index, frag.Count));
                }
            }
            markup.Area = area;

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