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 همتای پسپایانهٔ Uniscribe در FPdfTextShaping برای هدفهایی است که usp10.dll ندارند. این واحد فقط زیر Free Pascal کامپایل میشود، چون Delphi روی ویندوز هدف میگیرد و همانجاست که پسپایانهٔ Uniscribe اعمال میشود
این دو پسپایانه کار را طور متفاوتی تقسیم میکنند. Uniscribe در یک گذر بخشبندی، شکلدهی، جایگذاری و مرتبسازی میکند، در حالی که HarfBuzz یک ران منفرد را شکل میدهد که جهت و خط آن از پیش معلوم است. باقی کار با این واحد است: FPdfBidi سطوح درونسازی را حل میکند، خط Unicode هر نویسه متن را به رانها تقسیم میکند و رانها به ترتیب بصری چیده میشوند که قاعدهٔ L2 از UAX #9 میسازد. نویسههای با خط Common، Inherited و ناشناخته در ران فعلی خود ادامه مییابند، پس یک رقم یا یک فاصله کلمه را نمیشکند
libharfbuzz از طریق DynLibs در زمان اجرا مقید میشود، پس وابستگیِ بیلد نیست و نبودش گزارش میشود نه آنکه مهلک باشد. HarfBuzzAvailable گزارش میدهد آیا کتابخانه پیدا شده و نقاط ورود لازم تفکیک شدهاند، و HarfBuzzVersionString نسخهٔ کتابخانهٔ بارگذاریشده را برمیگرداند
شکلدهنده خودش دنبال فونت نمیگردد. Uniscribe باینری فونت را از یک GDI device context میخواند که معادل قابلحملی ندارد، پس میزبان یک TPdfFontDataResolver به Create میدهد که نام فونت را به بایتهای TrueType یا OpenType نگاشت میکند. اینطور فهرستکردن فونتها - fontconfig، CoreText یا پوشهٔ فونت خودِ برنامه - بیرون از واحدی میماند که چنین سیاستی اصلاً به آن مربوط نیست
| Function | Description |
|---|---|
HarfBuzzAvailable | True وقتی libharfbuzz پیدا شده و نقاط ورود لازم تفکیک شده باشند؛ نخستین فراخوانی، مقیدسازی را انجام میدهد |
HarfBuzzVersionString | نسخهٔ کتابخانهٔ بارگذاریشده به صورت "major.minor.micro"، یا رشتهٔ خالی وقتی کتابخانه در دسترس نباشد |
| Type | Description |
|---|---|
TPdfFontDataResolver | ارجاع متدی که FontName را به بایتهای فایل فونت در FontData نگاشت میکند؛ برگرداندن False درخواست را شکست میدهد، درست مثل وقتی در ویندوز فونت GDI خواندنی نباشد |
EPdfHarfBuzzError | استثنایی که وقتی هیچ resolverای پیکربندی نشده، وقتی libharfbuzz در دسترس نیست یا وقتی نمیتوان blob، face، فونت یا بافر HarfBuzz را ساخت برپا میشود |
TPdfHarfBuzzTextShaper | پیادهسازی TPdfTextShaper بر پایهٔ HarfBuzz، همراه با Create، Destroy و Shape |
| Member | Description |
|---|---|
Create(Resolver) | شکلدهنده را میسازد و TPdfFontDataResolverای را که برای هر جستوجوی فونت به کار میرود ذخیره میکند |
Destroy | face و blob کششدهٔ HarfBuzz را آزاد میکند و سپس destructor بهارثرسیده اجرا میشود |
Shape(Text, FontName, FontSize, Options, Shaped) | سطوح درونسازی را حل میکند، متن را بر اساس سطح و خط بخشبندی میکند، هر ران را از طریق HarfBuzz شکل میدهد و رانها را به ترتیب بصری در Shaped برمیگرداند؛ False وقتی متن هیچ گلیفی تولید نکند |
HarfBuzzAvailable در ویندوز libharfbuzz-0.dll و harfbuzz.dll را امتحان میکند، در macOS libharfbuzz.0.dylib و libharfbuzz.dylib را و در دیگر سیستمها libharfbuzz.so.0 و libharfbuzz.so راShape برای متن خالی، نام فونت خالی، اندازهٔ فونت نامثبت، کرانهای نامعتبر در Options، متنی بلندتر از MaxCharacters، گلیفهای بیشتر از MaxGlyphs یا دادهٔ فونتی که resolver نتوانسته تأمین کند، EPdfTextShapingError صادر میکندShape وقتی هیچ TPdfFontDataResolverای پیکربندی نشده، وقتی libharfbuzz در دسترس نیست یا وقتی نمیتوان شیء HarfBuzz را ساخت، EPdfHarfBuzzError صادر میکندOptions.MaxRuns سقف میخورد و Options.Direction مقدارهای ptdLeftToRight و ptdRightToLeft را روی یک جهت پاراگراف ثابت مینشاند و هر مقدار دیگری خودکار حل میشودShaped.FontData بایتهای برگرداندهشده از resolver را نگه میدارد؛ همان چیزی که TPdf.AddShapedText برای ساخت یک فونت CID لازم دارد