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 нацелен на Windows, где действует бэкенд Uniscribe
Два бэкенда делят работу по-разному. Uniscribe разбивает на элементы, шейпит, размещает и переупорядочивает за один проход, а HarfBuzz шейпит отдельный run, у которого направление и письменность уже известны. Остальное обеспечивает этот модуль: FPdfBidi вычисляет уровни вложенности, письменность Unicode каждого символа разбивает текст на runs, а runs раскладываются в визуальном порядке, который даёт правило L2 из UAX #9. Символы с письменностью common, inherited и unknown продолжают тот run, в котором находятся, поэтому цифра или пробел не разрывает слово
libharfbuzz привязывается во время выполнения через DynLibs, поэтому это не зависимость сборки, а её отсутствие сообщается, а не становится фатальным. HarfBuzzAvailable сообщает, найдена ли библиотека и разрешены ли требуемые точки входа, а HarfBuzzVersionString возвращает версию загруженной библиотеки
Шейпер не ищет шрифты. Uniscribe читает бинарные данные шрифта из контекста устройства GDI, переносимого аналога у которого нет, поэтому хост передаёт в Create TPdfFontDataResolver, отображающий имя шрифта в байты TrueType или OpenType. Так перечисление шрифтов — fontconfig, CoreText или собственная папка шрифтов приложения — остаётся за пределами модуля, которому не положено решать такую политику
| Function | Description |
|---|---|
HarfBuzzAvailable | True, когда libharfbuzz найдена и требуемые точки входа разрешены; первый вызов выполняет привязку |
HarfBuzzVersionString | Версия загруженной библиотеки в виде "major.minor.micro" либо пустая строка, если библиотека недоступна |
| Type | Description |
|---|---|
TPdfFontDataResolver | Ссылка на метод, отображающая FontName в байты файла шрифта в FontData; возврат False заставляет шейпер отклонить запрос так же, как на Windows поступает нечитаемый шрифт GDI |
EPdfHarfBuzzError | Исключение, возникающее, когда распознаватель не настроен, libharfbuzz недоступна или не удаётся создать blob, face, шрифт или буфер HarfBuzz |
TPdfHarfBuzzTextShaper | Реализация TPdfTextShaper на базе HarfBuzz, с Create, Destroy и Shape |
| Member | Description |
|---|---|
Create(Resolver) | Создаёт шейпер и сохраняет TPdfFontDataResolver, который будет использоваться при каждом поиске шрифта |
Destroy | Освобождает кешированные face и blob HarfBuzz, затем унаследованный деструктор |
Shape(Text, FontName, FontSize, Options, Shaped) | Вычисляет уровни вложенности, разбивает текст по уровню и письменности, шейпит каждый run через HarfBuzz и возвращает runs в визуальном порядке в Shaped; False, когда текст не даёт глифов |
HarfBuzzAvailable пробует libharfbuzz-0.dll и harfbuzz.dll на Windows, libharfbuzz.0.dylib и libharfbuzz.dylib на macOS, а также libharfbuzz.so.0 и libharfbuzz.so в остальных системахShape возбуждает EPdfTextShapingError при пустом тексте, пустом имени шрифта, неположительном размере шрифта, недопустимых пределах Options, тексте свыше MaxCharacters, глифах свыше MaxGlyphs или данных шрифта, которые распознаватель не смог предоставитьShape возбуждает EPdfHarfBuzzError, когда TPdfFontDataResolver не настроен, libharfbuzz недоступна или объект HarfBuzz не создаётсяOptions.MaxRuns, а Options.Direction отображает ptdLeftToRight и ptdRightToLeft на фиксированное направление абзаца, всё остальное вычисляется автоматическиShaped.FontData содержит байты, возвращённые распознавателем, — именно они нужны TPdf.AddShapedText для построения CID-шрифта