ユーティリティおよびヘルパークラス
ユーティリティとヘルパークラス
このガイドでは、Aspose.PDF の .NET 用の FOSS が提供する、小規模で特化したヘルパークラスの使用方法を示します。これらのクラスは、セキュリティプリミティブで使用される整数演算、正規表現検索設定、PostScript 関数の評価、外部フォントの検出、ベクトルサブパスの抽出、物理的テキスト測定、バッファリングされたコンテンツストリームの編集、大規模インメモリストリーム、ライブラリバージョンの報告といった一般的な低レベルタスクに利用されます。これらのクラスは単独のエントリーポイントではありませんが、API 全体で高レベルのドキュメント、テキスト、レンダリング操作を支えています。
整数演算ヘルパー
MathExtensions は、ライブラリのセキュリティプリミティブ内部で使用される小さな静的ヘルパーですが、常に非負の結果を返すモジュロ演算が必要な場合に一般的に利用できます。
// Unlike the C# % operator, Mod never returns a negative value.
int wrapped = MathExtensions.Mod(-3, 5); // 2正規表現検索設定
RegexManager は、テキスト検索操作(例: TextFragmentAbsorber)で使用される正規表現エンジンを設定する静的クラスです。MatchTimeout を設定してパターンの実行時間上限を制限し、NonBacktracking を有効にすると、パフォーマンス重視の検索で非バックトラッキング正規表現エンジンを使用できます。
using var doc = Document.Open(pdfBytes);
// Guard against runaway regex patterns.
RegexManager.MatchTimeout = TimeSpan.FromSeconds(5);
RegexManager.NonBacktracking = true;
var absorber = new TextFragmentAbsorber(@"\d{3}-\d{4}", true);
doc.Pages[1].Accept(absorber);PostScript 関数の評価
PostScriptEvaluator は、Type 4 PDF 関数 (PDF32000 §7.10.5) を評価する静的クラスです — PDF に埋め込まれた PostScript 計算プログラムで、いくつかのカラースペースやシェーディング定義で使用されます。
double[] inputs = { 0.5 };
// Evaluate a PostScript calculator program against the input array.
var outputs = PostScriptEvaluator.Evaluate("{ 2 mul }", inputs);外部フォント検索パス
ExternalFontCache は、レンダリングおよび変換時に外部(埋め込みでない)TrueType/OpenType フォントを検索するフォルダーを管理します。シングルトンにアクセスするには Instance を使用し、組み込み検索場所を確認するには GetDefaultFontsFolders を、追加または置換するには SetFontsFolders を使用してください。
var cache = ExternalFontCache.Instance;
var defaultFolders = cache.GetDefaultFontsFolders();
// reset: false appends to the existing search paths instead of replacing them.
cache.SetFontsFolders(new[] { @"C:\Fonts\Custom" }, reset: false);ベクトルサブパスの抽出
GraphicsAbsorber はページを訪れ、描画されたベクトルサブパスを SubPath 要素として抽出します。各要素はそれぞれページ空間のバウンディング Rectangle を持ちます。これは、コンテンツストリームを手作業で解析せずにベクトルアートワークを検査または測定するのに便利です。
using var doc = Document.Open(pdfBytes);
var absorber = new GraphicsAbsorber();
absorber.Visit(doc.Pages[1]);
Console.WriteLine($"Elements found: {absorber.Elements.Count}");
foreach (var element in absorber.Elements)
{
if (element is SubPath subPath)
{
Rectangle bounds = subPath.Rectangle;
Console.WriteLine($"Sub-path bounds: [{bounds.LLX}, {bounds.LLY}, {bounds.URX}, {bounds.URY}]");
}
}物理テキストセグメントの測定
PhysicalTextSegment は、吸収された TextSegment のページ空間への投影です。文字列の測定や解決された TextState を読むには、TextSegment.PhysicalSegment を通じてアクセスしてください。
using var doc = Document.Open(pdfBytes);
var absorber = new TextFragmentAbsorber();
doc.Pages[1].Accept(absorber);
foreach (TextFragment fragment in absorber.TextFragments)
{
foreach (TextSegment segment in fragment.Segments)
{
PhysicalTextSegment physical = segment.PhysicalSegment;
var width = physical.MeasureSegment(segment.StartCharIndex, segment.EndCharIndex, true);
TextState state = physical.TextState;
}
}コンテンツストリーム編集のバッファリング
ContentsAppender は、Page.ContentsAppender を介して到達し、ページのコンテンツストリームの先頭または末尾に前置または追加するオペレーターをバッファリングし、UpdateData で一括してコミットします。
using var doc = Document.Open(pdfBytes);
Page page = doc.Pages[1];
page.ContentsAppender.AppendToBegin(new GSave());
page.ContentsAppender.AppendToEnd(new GRestore());
page.ContentsAppender.UpdateData();大容量インメモリストリーム
OptimizedMemoryStream は、固定サイズのチャンクにデータを格納することで MemoryStream の 2GB 単一配列制限を超えることができる、拡張可能なインメモリストリームです。Stream から派生しているため、通常の読み取り、書き込み、シーク操作をサポートします。
using var stream = new OptimizedMemoryStream();
byte[] buffer = System.Text.Encoding.UTF8.GetBytes("large payload");
stream.Write(buffer, 0, buffer.Length);
bool canSeek = stream.CanSeek;
byte[] allBytes = stream.ToArray();ライブラリ バージョン情報
BuildVersionInfo は、実行時にライブラリの製品名とバージョン番号を公開する静的クラスです — 診断やサポート依頼に便利です。
Console.WriteLine(BuildVersionInfo.Product);
Console.WriteLine(BuildVersionInfo.AssemblyVersion);
Console.WriteLine(BuildVersionInfo.FileVersion);ヒントとベストプラクティス
- 信頼できない、またはユーザー提供のパターンに対して検索を実行する前に
RegexManager.MatchTimeoutを設定し、致命的なバックトラッキングを回避してください。 - デフォルトの検索パスを追加するのではなく完全に置き換えたい場合は、
ExternalFontCache.SetFontsFoldersをreset: trueと共に呼び出してください。 - 2GB を超える可能性のある非常に大きな文書や画像データをバッファリングする場合は、
OptimizedMemoryStreamをMemoryStreamより優先してください。 - バッファされた演算子はその時点までコンテンツストリームにコミットされないため、
ContentsAppender編集のバッチは必ずUpdateData()で終了してください。 GraphicsAbsorber.ElementsにはSubPath以外のGraphicElementインスタンスが含まれる可能性があります。キャストする前に型を確認してください。
よくある問題
| 問題 | 原因 | 修正 |
|---|---|---|
| 正規表現検索が複雑なパターンでハングする | RegexManager にタイムアウトが設定されていません | 実行する前にRegexManager.MatchTimeoutを設定し、TextFragmentAbsorber検索を実行してください |
ContentsAppender からのコンテンツストリーム編集が保存されたファイルに反映されません | UpdateData() が一度も呼び出されませんでした | 最後の AppendToBegin/AppendToEnd 呼び出しの後に UpdateData() を呼び出してください |
| カスタムフォントがレンダリング時に検出されません | フォントフォルダーが登録されていないか、reset: true が期待されるデフォルトをクリアしました | ExternalFontCache.SetFontsFolders を正しいフォルダーリストと reset の値で呼び出してください |
非常に大きな出力をバッファリングする際のOutOfMemoryException | MemoryStream が 2GB の単一配列制限に達しました | 固定サイズのチャンクにデータを格納する OptimizedMemoryStream を使用してください |
FAQ
なぜ MathExtensions.Mod は C# の % 演算子と異なるのですか?
MathExtensions.Mod は常に非負の余りを返しますが、組み込みの % 演算子は被除数が負の場合に負の値を返すことがあります。
正規表現ベースのテキスト検索が長時間実行されるのをどうやって止めることができますか?
正規表現パターンを使用する TextFragmentAbsorber を構築または実行する前に、RegexManager.MatchTimeout を TimeSpan に設定してください。
SetFontsFolders は既存の検索パスを置き換えるのか、追加するのかですか?
それは reset 引数に依存します:現在のフォルダーリストを置き換えるには true を渡し、新しいフォルダーを追加するには false を渡します。
GraphicsAbsorber は実際に何を抽出しますか?
それはページの描画されたベクトルサブパスを SubPath 要素として抽出し、各要素はページ空間のバウンディング Rectangle を持ち、GraphicsAbsorber.Visit を介して行われます。
MemoryStream の代わりに OptimizedMemoryStream を使用すべきなのはいつですか?
バッファされたデータが 2GB に近づくか超える可能性がある場合です。MemoryStream はそのハードリミットを持つ単一の配列で裏付けられているためです。
API Reference の概要
| クラス / メソッド | 説明 |
|---|---|
MathExtensions.Mod | セキュリティプリミティブで使用される非負整数モジュロヘルパー |
RegexManager.MatchTimeout | 正規表現ベースのテキスト検索に適用されるタイムアウト |
RegexManager.NonBacktracking | 非バックトラッキング正規表現エンジンを有効にします |
PostScriptEvaluator.Evaluate | Type 4 PDF PostScript 計算機能を評価する |
ExternalFontCache.Instance | 外部フォントキャッシュへのシングルトンアクセス |
ExternalFontCache.GetDefaultFontsFolders | デフォルトの外部フォント検索フォルダーを返します |
ExternalFontCache.SetFontsFolders | 外部フォント検索フォルダーを追加または置き換えます |
GraphicsAbsorber.Visit | ページからベクターグラフィック要素を抽出します |
GraphicsAbsorber.Elements | 抽出された GraphicElement/SubPath アイテムのコレクション |
SubPath.Rectangle | 抽出されたサブパスのページ空間における境界矩形 |
PhysicalTextSegment.MeasureSegment | 物理テキストセグメントの文字範囲を測定する |
PhysicalTextSegment.TextState | 物理テキストセグメントの解決済み書式状態 |
ContentsAppender.AppendToBegin | ページのコンテンツストリームの先頭に付加するオペレータをバッファリングする |
ContentsAppender.AppendToEnd | ページのコンテンツストリームに追加するためにオペレーターをバッファリングする |
ContentsAppender.UpdateData | バッファリングされたオペレーターをコンテンツストリームにコミットする |
OptimizedMemoryStream | 2GB MemoryStream の制限を超える拡張可能なインメモリストリーム |
BuildVersionInfo.Product | 実行中のライブラリの製品名 |
BuildVersionInfo.AssemblyVersion | 実行中のライブラリのアセンブリ バージョン |
BuildVersionInfo.FileVersion | 実行中のライブラリのファイル バージョン |