TPdfFontDataResolver = function(const FontName: WideString;
out FontData: TBytes): Boolean of object;
EPdfHarfBuzzError = class(Exception);
TPdfHarfBuzzTextShaper = class(TPdfTextShaper)
constructor Create(const Resolver: TPdfFontDataResolver);
destructor Destroy; override;
function Shape(const Text, FontName: WideString; FontSize: Single;
const Options: TPdfTextShapingOptions;
out Shaped: TPdfShapedText): Boolean; override;
end;
function HarfBuzzAvailable: Boolean;
function HarfBuzzVersionString: string;
FPdfTextShapingHb は、usp10.dll を持たないターゲットのための、FPdfTextShaping の Uniscribe バックエンドと対になる存在です。インターフェイスは Free Pascal の下でのみコンパイルされます。Delphi は Windows をターゲットとし、そこでは Uniscribe バックエンドが適用されるためです
2 つのバックエンドは仕事の分担が異なります。Uniscribe は 1 パスで item 化、シェーピング、配置、並べ替えを行います。一方 HarfBuzz は、方向とスクリプトが既知の単一の run をシェーピングします。このユニットが残りを供給します。FPdfBidi が埋め込みレベルを解決し、各文字の Unicode スクリプトがテキストを run に分割し、run は UAX #9 の規則 L2 が与える表視順序で配置されます。common、inherited、未知のスクリプトの文字は、今いる run を続行します。数字や空白が単語を分割することはありません
libharfbuzz は DynLibs を通じて実行時にバインドされるため、ビルド依存ではなく、存在しないことは致命的ではなく報告されます。HarfBuzzAvailable はライブラリが見つかり必要なエントリポイントが解決されたかを報告し、HarfBuzzVersionString は読み込まれたライブラリのバージョンを返します
このシェイパーはフォントを検索しません。Uniscribe は GDI デバイスコンテキストからフォントのバイナリを読みますが、これは移植可能な相当物がありません。そのためホストは、フォント名を TrueType または OpenType のバイト列にマップする TPdfFontDataResolver を Create に渡します。これにより、フォントの列挙、つまり fontconfig や CoreText、あるいはアプリケーション自身のフォントフォルダは、その方針を決めるべきでないユニットの外に保たれます
| 関数 | 説明 |
|---|---|
HarfBuzzAvailable | libharfbuzz が見つかり必要なエントリポイントが解決されていれば True です。最初の呼び出しがバインドを行います |
HarfBuzzVersionString | 読み込まれたライブラリのバージョンを "major.minor.micro" の形で返します。ライブラリが利用できない場合は空文字列です |
| 型 | 説明 |
|---|---|
TPdfFontDataResolver | FontName を FontData のフォントファイルバイト列にマップするメソッド参照です。False を返すと、Windows で読めない GDI フォントに対するのと同じやり方でシェイパーは要求を失敗させます |
EPdfHarfBuzzError | リゾルバが設定されていない、libharfbuzz が利用できない、または HarfBuzz の blob、face、font、buffer が作成できない場合に発生する例外です |
TPdfHarfBuzzTextShaper | HarfBuzz を利用する TPdfTextShaper 実装です。Create、Destroy、Shape を持ちます |
| メンバー | 説明 |
|---|---|
Create(Resolver) | シェイパーを作成し、フォントの検索ごとに使う TPdfFontDataResolver を保存します |
Destroy | キャッシュされた HarfBuzz の face と blob を解放し、続いて継承したデストラクタを実行します |
Shape(Text, FontName, FontSize, Options, Shaped) | 埋め込みレベルを解決し、レベルとスクリプトでテキストを分割し、各 run を HarfBuzz でシェーピングし、表視順序の run を Shaped に返します。テキストが glyph を生成しない場合は False です |
HarfBuzzAvailable の最初の呼び出しは、Windows では libharfbuzz-0.dll と harfbuzz.dll、macOS では libharfbuzz.0.dylib と libharfbuzz.dylib、その他では libharfbuzz.so.0 と libharfbuzz.so を探しますShape は、空のテキスト、空のフォント名、正でないフォントサイズ、不正な Options の上限、MaxCharacters を超えるテキスト、MaxGlyphs を超える glyph、リゾルバが供給できなかったフォントデータに対して EPdfTextShapingError を発生させますShape は、TPdfFontDataResolver が設定されていない、libharfbuzz が利用できない、または HarfBuzz オブジェクトが作成できない場合に EPdfHarfBuzzError を発生させますOptions.MaxRuns で上限が付けられ、Options.Direction は ptdLeftToRight と ptdRightToLeft を固定の段落方向にマップし、それ以外は自動で解決しますShaped.FontData はリゾルバが返したバイト列を保持します。TPdf.AddShapedText が CID フォントを構築するのに必要なものです