ReadTagsShowParas.cs
// 
// このコードは、DioDocs for PDF のサンプルの一部として提供されています。
// © 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
{
    // タグツリーにてタグが付与されている段落をハイライト表示します。
    public class ReadTagsShowParas
    {
        public int CreatePDF(Stream stream)
        {
            var user = "DioDocsDemo";

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

            // 第1ステップ:読み込んだPDFから最初の5ページ以外を削除し、
            // 削除したページを指すタグも削除します。
            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);
            }

            // 第2ステップ:論理構造を取得し、
            // 段落をハイライト表示の上付箋をつけます。
            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);
                }
            }
            // LogicalStructureを取得し、それを使って段落をハイライト表示します。
            LogicalStructure ls = doc.GetLogicalStructure();
            highlightParagraphs(ls.Elements);

            // 終了
            doc.Save(stream);
            return doc.Pages.Count;
        }
    }
}