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 es el homólogo del backend Uniscribe de FPdfTextShaping, para los destinos que no tienen usp10.dll. La interfaz se compila solo bajo Free Pascal, porque Delphi apunta a Windows, donde aplica el backend Uniscribe
Los dos backends reparten el trabajo de forma distinta. Uniscribe segmenta, da forma, coloca y reordena en una sola pasada, mientras que HarfBuzz da forma a un único tramo cuya dirección y escritura ya se conocen. Esta unidad aporta el resto: FPdfBidi resuelve los niveles de incrustación, la escritura Unicode de cada carácter segmenta el texto en tramos, y los tramos se disponen en el orden visual que da la regla L2 de UAX #9. Los caracteres de escritura Common, Inherited o Unknown continúan el tramo en el que están, de modo que un dígito o un espacio no parte una palabra
libharfbuzz se enlaza en tiempo de ejecución a través de DynLibs, de modo que no es una dependencia de compilación y su ausencia se informa en lugar de ser fatal. HarfBuzzAvailable informa de si la biblioteca se encontró y los puntos de entrada necesarios se resolvieron, y HarfBuzzVersionString devuelve la versión de la biblioteca cargada
El shaper no busca fuentes. Uniscribe lee el binario de la fuente desde un contexto de dispositivo GDI, que no tiene equivalente portable, de modo que el host pasa a Create un TPdfFontDataResolver que asocie un nombre de fuente con los bytes TrueType u OpenType. Así la enumeración de fuentes - fontconfig, CoreText o la carpeta de fuentes propia de la aplicación - queda fuera de una unidad a la que esa política no le corresponde decidir
| Función | Descripción |
|---|---|
HarfBuzzAvailable | True cuando libharfbuzz se encontró y los puntos de entrada necesarios se resolvieron; la primera llamada realiza el enlace |
HarfBuzzVersionString | Versión de la biblioteca cargada como "major.minor.micro", o una cadena vacía cuando la biblioteca no está disponible |
| Tipo | Descripción |
|---|---|
TPdfFontDataResolver | Referencia a método que asocia FontName con los bytes del archivo de fuente en FontData; devolver False hace que el shaper falle la petición igual que una fuente GDI ilegible en Windows |
EPdfHarfBuzzError | Excepción que se lanza cuando no hay ningún resolvedor configurado, cuando libharfbuzz no está disponible o cuando un blob, face, font o buffer de HarfBuzz no puede crearse |
TPdfHarfBuzzTextShaper | Implementación de TPdfTextShaper respaldada por HarfBuzz, con Create, Destroy y Shape |
| Miembro | Descripción |
|---|---|
Create(Resolver) | Crea el shaper y almacena el TPdfFontDataResolver que usará para cada búsqueda de fuente |
Destroy | Libera el face y el blob de HarfBuzz almacenados en caché y después el destructor heredado |
Shape(Text, FontName, FontSize, Options, Shaped) | Resuelve los niveles de incrustación, segmenta el texto por nivel y escritura, da forma a cada tramo a través de HarfBuzz y devuelve los tramos en orden visual en Shaped; False cuando el texto no produce glifos |
HarfBuzzAvailable sondea libharfbuzz-0.dll y harfbuzz.dll en Windows, libharfbuzz.0.dylib y libharfbuzz.dylib en macOS, y libharfbuzz.so.0 y libharfbuzz.so en el restoShape lanza EPdfTextShapingError ante texto vacío, un nombre de fuente vacío, un tamaño de fuente no positivo, límites de Options inválidos, texto por encima de MaxCharacters, glifos por encima de MaxGlyphs o datos de fuente que el resolvedor no pudo suministrarShape lanza EPdfHarfBuzzError cuando no hay ningún TPdfFontDataResolver configurado, cuando libharfbuzz no está disponible o cuando no puede crearse un objeto HarfBuzzOptions.MaxRuns, y Options.Direction asocia ptdLeftToRight y ptdRightToLeft a una dirección de párrafo fija, resolviéndose automáticamente todo lo demásShaped.FontData contiene los bytes que devolvió el resolvedor, que es lo que necesita TPdf.AddShapedText para construir una fuente CID