L'accessibilità non è più una funzionalità opzionale nello sviluppo di software moderno. In base a normative come l'ADA (Americans with Disabilities Act) e la Direttiva UE sull'Accessibilità del Web, i software che gestiscono documenti devono fornire tecnologie assistive. Per i visualizzatori PDF, questo significa implementare una robusta sintesi vocale (Text-to-Speech, TTS) e l'integrazione degli screen reader.
In questo articolo, vedremo come estrarre flussi di testo semantico da un PDF utilizzando PDFium in Delphi, per poi passare tale testo all'API vocale di Windows (SAPI) per creare un visualizzatore PDF completamente accessibile.
La Sfida dell'Estrazione del Testo dai PDF
Un PDF è fondamentalmente un canvas di istruzioni di disegno. Non sa intrinsecamente cosa sia un "paragrafo" o una "colonna"; si limita a posizionare i glifi a specifiche coordinate X/Y. Per leggere un documento ad alta voce in un ordine logico, il parser deve ricostruire l'ordine di lettura.
PDFium gestisce questo tramite la famiglia di API FPDFText_*, che analizza le relazioni spaziali dei glifi per produrre flussi di testo coerenti.
Passaggio 1: Estrazione del Testo con PDFium
Prima di poter pronunciare il testo, dobbiamo estrarlo. Il seguente codice Delphi dimostra come inizializzare una pagina di testo ed estrarne i contenuti in una stringa standard.
uses
System.SysUtils, pdfium_lib;
function ExtractPageText(Doc: FPDF_DOCUMENT; PageIndex: Integer): string;
var
Page: FPDF_PAGE;
TextPage: FPDF_TEXTPAGE;
CharCount: Integer;
Buffer: array of WideChar;
begin
Result := '';
Page := FPDF_LoadPage(Doc, PageIndex);
if Page = nil then Exit;
try
// Initialize the text extraction engine for this page
TextPage := FPDFText_LoadPage(Page);
if TextPage <> nil then
begin
try
CharCount := FPDFText_CountChars(TextPage);
if CharCount > 0 then
begin
SetLength(Buffer, CharCount + 1);
// Extract the text into the wide string buffer
FPDFText_GetText(TextPage, 0, CharCount, @Buffer[0]);
Result := WideCharToString(@Buffer[0]);
end;
finally
FPDFText_ClosePage(TextPage);
end;
end;
finally
FPDF_ClosePage(Page);
end;
end;
Passaggio 2: Integrazione dell'API Vocale di Windows (SAPI)
Una volta ottenuto il testo semantico, possiamo passarlo all'API Vocale di Windows. SAPI fornisce l'interfaccia COM SpVoice, che consente la sintesi vocale asincrona, la selezione della voce e il controllo della velocità del parlato.
uses
System.Win.ComObj, Winapi.ActiveX;
const
SVSFlagsAsync = 1;
procedure SpeakText(const TextToSpeak: string);
var
SpVoice: OLEVariant;
begin
CoInitialize(nil);
try
SpVoice := CreateOleObject('SAPI.SpVoice');
// Speak asynchronously so the UI does not freeze
SpVoice.Speak(TextToSpeak, SVSFlagsAsync);
finally
CoUninitialize;
end;
end;
Passaggio 3: Sincronizzare la Voce con l'Evidenziazione
Un visualizzatore veramente accessibile non si limita a leggere il testo in modo cieco; evidenzia le parole sullo schermo man mano che vengono pronunciate. SAPI fornisce eventi (tramite connection point) che si attivano quando si raggiunge il limite di una parola.
Mappando l'indice del carattere restituito dall'evento SAPI al corrispondente indice del carattere in PDFium usando FPDFText_GetCharBox(), è possibile recuperare il rettangolo di delimitazione della parola attualmente pronunciata e disegnare un'evidenziazione sul canvas del visualizzatore.
procedure HighlightWord(TextPage: FPDF_TEXTPAGE; CharIndex: Integer; CharCount: Integer);
var
i: Integer;
L, T, R, B: Double;
begin
// Iterate through the characters of the spoken word
for i := CharIndex to CharIndex + CharCount - 1 do
begin
// Get the physical bounding box on the PDF page
FPDFText_GetCharBox(TextPage, i, @L, @R, @B, @T);
// Transform PDF coordinates to screen coordinates and draw highlighting rect...
end;
end;
Creare un'Applicazione Inclusiva
Combinando l'estrazione spaziale del testo di PDFium con il motore di sintesi vocale di SAPI, gli sviluppatori Delphi possono creare strumenti potenti per utenti non vedenti o ipovedenti, o per coloro che preferiscono l'apprendimento uditivo. L'implementazione corretta di queste funzionalità garantisce che l'applicazione sia conforme ai rigorosi standard di accessibilità governativi e aziendali.
Nota: l'estrazione del testo e la mappatura delle coordinate sono pienamente supportate dal Componente VCL PDFium Component.