MarkupPerWord.cs
// 
// このコードは、DioDocs for PDF のサンプルの一部として提供されています。
// © MESCIUS inc. All rights reserved.
// 
using System;
using System.IO;
using System.Drawing;
using GrapeCity.Documents.Pdf;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Pdf.Annotations;
using System.Collections.Generic;
using GrapeCity.Documents.Pdf.TextMap;
using GrapeCity.Documents.Common;

namespace DsPdfWeb.Demos
{
    // このサンプルでは、PDF ドキュメント内の2つの単語をすべて検索し、テキストマークアップ注釈の
    // ハイライトを使用して、2つの単語をそれぞれ別の色で強調表示する方法を紹介しています。
    // このコードのポイント:
    // - 各単語に対して別々の FindText() メソッドを使用しています。検索を高速化するために、
    //   各ページでテキストマップをキャッシュし、それを2つの FindText() 呼び出しの際に再利用しています。
    //   単語2つを検索する場合、速度向上はわずかですが、大量の単語を検索する場合(例えば、
    //   WordIndex のサンプルのように、単語を検索して単語インデックスを作成する場合など)には、
    //   大きな効果が期待できます。
    // - 2つの単語をそれぞれ別の色で強調表示するために、各ページで単語ごとに
    //   1つのテキストマークアップ注釈を作成しています。
    public class MarkupPerWord
    {
        public int CreatePDF(Stream stream)
        {
            const string word0 = "JavaScript";
            const string word1 = "framework";

            // PDF を読み込みます。
            var doc = new GcPdfDocument();
            using var fs = File.OpenRead(Path.Combine("Resources", "PDFs", "CompleteJavaScriptBook.pdf"));
            doc.Load(fs);

            // 検索する単語に対応する FindTextParams を作成します。
            var ft0 = new FindTextParams(word0, wholeWord: false, matchCase: false, regex: false);
            var ft1 = new FindTextParams(word1, wholeWord: false, matchCase: false, regex: false);

            // ページ上の単語を検索してハイライトします。
            // 各ページのテキストマップをキャッシュして、2つの検索に再利用します。
            foreach (var p in doc.Pages)
            {
                // 最初の単語を検索してハイライトします。
                var textMap = p.GetTextMap();
                TextMarkupAnnotation markup0 = null;
                List<Quadrilateral> area0 = null;
                textMap.FindText(ft0, fp_ => {
                    markup0 ??= new TextMarkupAnnotation()
                    {
                        Subject = word0,
                        Page = doc.Pages[fp_.PageIndex],
                        MarkupType = TextMarkupType.Highlight,
                        Color = Color.Cyan
                    };
                    area0 ??= new List<Quadrilateral>();
                    foreach (var b in fp_.Bounds)
                        area0.Add(b);
                });
                if (markup0 != null)
                    markup0.Area = area0;

                // 2番目の単語を検索してハイライトします。
                TextMarkupAnnotation markup1 = null;
                List<Quadrilateral> area1 = null;
                textMap.FindText(ft1, fp_ => {
                    markup1 ??= new TextMarkupAnnotation()
                    {
                        Subject = word1,
                        Page = doc.Pages[fp_.PageIndex],
                        MarkupType = TextMarkupType.Highlight,
                        Color = Color.Fuchsia
                    };
                    area1 ??= new List<Quadrilateral>();
                    foreach (var b in fp_.Bounds)
                        area1.Add(b);
                });
                if (markup1 != null)
                    markup1.Area = area1;
            }

            // PDF ドキュメントを保存します。
            doc.Save(stream);
            return doc.Pages.Count;
        }
    }
}