ReadTagsShowParas.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 System.Collections.Generic;
using GrapeCity.Documents.Pdf;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Pdf.TextMap;
using GrapeCity.Documents.Pdf.Annotations;
using GrapeCity.Documents.Pdf.Structure;
using GrapeCity.Documents.Pdf.Recognition.Structure;

namespace DsPdfWeb.Demos
{
    // Highlight paragraphs which have associated structure tags.
    public class ReadTagsShowParas
    {
        public int CreatePDF(Stream stream)
        {
            var user = "DsPdfWeb Demo";

            var doc = new GcPdfDocument();
            using var s = File.OpenRead(Path.Combine("Resources", "PDFs", "C1Olap-QuickStart.pdf"));
            doc.Load(s);

            // 1st step - remove all but the first 5 pages from the loaded PDF,
            // also removing tags that point to the removed pages:
            void removeStructNodesForPage(StructElementCollection ses, Page p)
            {
                for (int i = ses.Count - 1; i >= 0; --i)
                {
                    var se = ses[i];
                    if (se.DefaultPage == p)
                        ses.RemoveAt(i);
                    else
                        removeStructNodesForPage(se.Children, p);
                }
            }
            for (int i = doc.Pages.Count - 1; i >= 5; --i)
            {
                removeStructNodesForPage(doc.StructTreeRoot.Children, doc.Pages[i]);
                doc.Pages.RemoveAt(i);
            }

            // 2nd step - get the logical structure, highlight paragraphs
            // and add sticky notes to them:
            void highlightParagraphs(IReadOnlyList<Element> items)
            {
                var color = Color.FromArgb(64, Color.Magenta);
                foreach (var e in items)
                {
                    if (e.HasContentItems)
                        foreach (var i in e.ContentItems)
                        {
                            if (i is ContentItem ci)
                            {
                                var p = ci.GetParagraph();
                                if (p != null)
                                {
                                    var rc = p.GetCoords().ToRect();
                                    rc.Offset(rc.Width, 0);
                                    rc.Size = new SizeF(16, 12);
                                    var ta = new TextAnnotation()
                                    {
                                        UserName = user,
                                        Rect = rc,
                                        Page = ci.Page,
                                        Contents = p.GetText(),
                                        Color = Color.Yellow,
                                    };
                                    ci.Page.Graphics.DrawPolygon(p.GetCoords(), color, 1, null);
                                }
                            }
                        }
                    if (e.HasChildren)
                        highlightParagraphs(e.Children);
                }
            }
            // Get the LogicalStructure and use it to highlight paragraphs:
            LogicalStructure ls = doc.GetLogicalStructure();
            highlightParagraphs(ls.Elements);

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