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

namespace GcPdfWeb.Samples.Basics
{
    // GcPdf 内でドロップキャップを作成する方法を示します。
    public class DropCap
    {
        public int CreatePDF(Stream stream)
        {
            var doc = new GcPdfDocument();
            var g = doc.NewPage().Graphics;
            const string fontname = "Yu Gothic";
            // テキストを取得し、最初の文字(ドロップキャップ)とそれ以外の部分に分割します。
            var text = Common.Util.getString_ja(1, 0, 1);
            var head = text.Substring(0, 1);
            var tail = text.Substring(1);
            // Times フォントを使用します。
            var font = Font.FromFile(Path.Combine("Resources", "Fonts", "times.ttf"));
            // ドロップキャップのテキストレイアウトします。
            var tlHead = g.CreateTextLayout();
            tlHead.DefaultFormat.FontName = fontname;
            tlHead.DefaultFormat.FontSize = 40;
            tlHead.Append(head);
            tlHead.PerformLayout(true);
            // 残りのテキストのテキストレイアウトします。
            var tlTail = g.CreateTextLayout();
            tlTail.DefaultFormat.Font = font;
            tlTail.DefaultFormat.FontSize = 12;
            // 外周に 1 インチのマージンを持つページ全体を使用します。
            tlTail.MaxWidth = doc.Pages.Last.Size.Width - 72 * 2;
            tlTail.MaxHeight = doc.Pages.Last.Size.Height - 72 * 2;
            tlTail.Append(tail);
            // テキストの本体をレイアウトする前に、ドロップキャップ矩形のサイズと位置を計算し、
            // メインテキストレイアウトの ObjectRects に追加します。
            // これは、外周にメインテキストがフローする長方形のリストです。
            // 
            // 注:ドロップキャップの矩形をメインテキストの左/左に配置するだけで済みますが、
            // ドロップキャップの上端とメインテキストのグリフが整列している方が良いです。 
            // このためには、テキスト境界ボックス内の文字上端のオフセットを計算し、
            // それに応じてドロップキャップの位置を調整(少し上げる)する必要があります。
            // 
            // (この調整のためには、フォントの OS/2 テーブルのバージョン2以上の場合に存在する
            // sCapHeight フィールドが必要です。したがって、それをテストし、CapHeight が利用できない
            // 場合はこのステップをスキップする必要があります)
            float dy = 0;
            if (font.CapHeight != -1)
            {
                // ドロップキャップのフォントサイズの Em 四角内の上のスペースと残りのテキストの
                // フォントサイズの差に等しい量だけ、ドロップキャップの位置を上に移動します。
                float k = tlHead.DefaultFormat.FontSize * tlHead.Resolution * tlHead.FontScaleFactor / (font.UnitsPerEm * 72);
                dy = (font.HorizontalAscender - font.CapHeight) * k;
                k /= tlHead.DefaultFormat.FontSize;
                k *= tlTail.DefaultFormat.FontSize;
                dy -= (font.HorizontalAscender - font.SmallXHeight) * k;
            }
            // 外周にメインテキストがフローする矩形を指定します。
            tlTail.ObjectRects = new List<ObjectRect>() { new ObjectRect(0, -dy, tlHead.ContentWidth * 1.2f, tlHead.ContentHeight) };
            // 今すぐメインテキストをレイアウトします。
            tlTail.PerformLayout(true);
            // すべてを描画します。
            g.DrawTextLayout(tlHead, new PointF(72, 72 - dy));
            g.DrawTextLayout(tlTail, new PointF(72, 72));
            // PDF ドキュメントを保存します。
            doc.Save(stream);
            return doc.Pages.Count;
        }
    }
}