Pristupačnost više nije izborna značajka u modernom razvoju softvera. Prema propisima kao što su ADA (Zakon o Amerikancima s invaliditetom) i Direktiva EU o pristupačnosti weba, softver koji rukuje dokumentima mora pružati pomoćne tehnologije. Za PDF preglednike, to znači implementaciju robusnog pretvaranja teksta u govor (TTS) i integraciju čitača zaslona.
U ovom ćemo članku pogledati kako izdvojiti semantičke tokove teksta iz PDF-a pomoću PDFiuma u Delphiju, a zatim unijeti taj tekst u Windows Speech API (SAPI) kako bismo izgradili potpuno pristupačan PDF preglednik.
Izazov izdvajanja PDF teksta
PDF je u osnovi platno uputa za slikanje. On inherentno ne zna što je "odlomak" ili "stupac"; on samo postavlja glifove na specifične X/Y koordinate. Da biste naglas čitali dokument u logičnom redoslijedu, vaš parser mora rekonstruirati redoslijed čitanja.
PDFium to rješava putem obitelji API-ja FPDFText_*, koja analizira prostorne odnose glifova kako bi proizvela koherentne tokove teksta.
Korak 1: Izdvajanje teksta pomoću PDFiuma
Prije nego što možemo izgovoriti tekst, moramo ga izdvojiti. Sljedeći Delphi kod demonstrira kako inicijalizirati tekstualnu stranicu i izdvojiti njezin sadržaj u standardni niz.
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;
Korak 2: Integracija Windows Speech API-ja (SAPI)
Nakon što imamo semantički tekst, možemo ga proslijediti Windows Speech API-ju. SAPI pruža COM sučelje SpVoice, koje omogućuje asinkronu sintezu govora, odabir glasa i kontrolu brzine govora.
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;
Korak 3: Sinkronizacija govora s isticanjem
Istinski pristupačan preglednik ne čita tekst samo naslijepo; on ističe riječi na zaslonu dok se izgovaraju. SAPI pruža događaje (putem točaka povezivanja) koji se aktiviraju kada se dosegne granica riječi.
Preslikavanjem indeksa znakova koji vraća SAPI događaj granice riječi natrag na indeks znakova u PDFiumu pomoću FPDFText_GetCharBox(), možete dohvatiti granični pravokutnik trenutno izgovorene riječi i nacrtati preklop za isticanje na platnu vašeg preglednika.
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;
Izgradnja inkluzivne aplikacije
Kombiniranjem PDFiumovog prostornog izdvajanja teksta sa SAPI-jevim govornim motorom, Delphi programeri mogu stvoriti moćne alate za slabovidne korisnike ili one koji preferiraju auditivno učenje. Pravilna implementacija ovih značajki osigurava da vaša aplikacija udovoljava strogim poslovnim i vladinim standardima pristupačnosti.
Napomena: Integrirano izdvajanje teksta i preslikavanje koordinata u potpunosti su podržani u PDFium Component.