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 este contrapiesa backend-ului Uniscribe din FPdfTextShaping, pentru ținte care nu au usp10.dll. Interfața este compilată doar sub Free Pascal, pentru că Delphi vizează Windows, unde se aplică backend-ul Uniscribe
Cele două backend-uri își împart lucrul diferit. Uniscribe împarte în itemi, modelează, poziționează și reordonează într-o singură trecere, în timp ce HarfBuzz modelează un singur run a cărui direcție și script sunt deja cunoscute. Această unitate furnizează restul: FPdfBidi rezolvă nivelurile de embedding, scriptul Unicode al fiecărui caracter segmentează textul în runs, iar runs-urile sunt așezate în ordinea vizuală pe care o dă regula L2 din UAX #9. Caracterele cu script Common, Inherited și necunoscut continuă run-ul în care se află, astfel încât o cifră sau un spațiu nu taie un cuvânt
libharfbuzz este legat la rulare prin DynLibs, deci nu este o dependență de build, iar absența sa este raportată, nu fatală. HarfBuzzAvailable raportează dacă biblioteca a fost găsită și punctele de intrare necesare au fost rezolvate, iar HarfBuzzVersionString returnează versiunea bibliotecii încărcate
Shaper-ul nu caută fonturi. Uniscribe citește binarul fontului dintr-un context de dispozitiv GDI, ceea ce nu are un echivalent portabil, așa că aplicația gazdă transmite lui Create un TPdfFontDataResolver care asociază un nume de font cu octeții TrueType sau OpenType. Astfel, enumerarea fonturilor - fontconfig, CoreText sau propriul dosar de fonturi al aplicației - rămâne în afara unei unități care nu are nicio treabă cu acea politică
| Function | Description |
|---|---|
HarfBuzzAvailable | True când libharfbuzz a fost găsit și punctele de intrare necesare rezolvate; primul apel execută legarea |
HarfBuzzVersionString | Versiunea bibliotecii încărcate ca "major.minor.micro", sau un șir vid când biblioteca nu este disponibilă |
| Type | Description |
|---|---|
TPdfFontDataResolver | Referință de metodă care asociază FontName cu octeții fișierului de font din FontData; returnarea False face ca shaper-ul să eșueze cererea la fel cum o face un font GDI ilizibil pe Windows |
EPdfHarfBuzzError | Excepție ridicată când niciun rezolvator nu este configurat, când libharfbuzz nu este disponibil sau când un blob, o față, un font sau un buffer HarfBuzz nu poate fi creat |
TPdfHarfBuzzTextShaper | Implementare TPdfTextShaper bazată pe HarfBuzz, cu Create, Destroy și Shape |
| Member | Description |
|---|---|
Create(Resolver) | Creează shaper-ul și reține TPdfFontDataResolver pe care îl va folosi la fiecare căutare de font |
Destroy | Eliberează fața HarfBuzz și blob-ul din cache, apoi destructorul moștenit |
Shape(Text, FontName, FontSize, Options, Shaped) | Rezolvă nivelurile de embedding, segmentează textul după nivel și script, modelează fiecare run prin HarfBuzz și returnează runs-urile în ordine vizuală în Shaped; False când textul nu produce glife |
HarfBuzzAvailable sondează libharfbuzz-0.dll și harfbuzz.dll pe Windows, libharfbuzz.0.dylib și libharfbuzz.dylib pe macOS, respectiv libharfbuzz.so.0 și libharfbuzz.so în restShape ridică EPdfTextShapingError pentru text vid, nume de font vid, dimensiune de font nepozitivă, limite Options invalide, text peste MaxCharacters, glife peste MaxGlyphs sau date de font pe care rezolvatorul nu le-a putut furnizaShape ridică EPdfHarfBuzzError când niciun TPdfFontDataResolver nu este configurat, când libharfbuzz nu este disponibil sau când un obiect HarfBuzz nu poate fi creatOptions.MaxRuns, iar Options.Direction aplică ptdLeftToRight și ptdRightToLeft pe o direcție fixă de paragraf, orice altceva fiind rezolvat automatShaped.FontData reține octeții returnați de rezolvator, exact ceea ce are nevoie TPdf.AddShapedText pentru a construi un font CID