Dostopnost ni več neobvezna funkcija v sodobnem razvoju programske opreme. Po predpisih, kot sta ADA (Zakon o Američanih invalidih) in Direktiva EU o spletni dostopnosti, mora programska oprema, ki obravnava dokumente, zagotavljati podporne tehnologije. Za pregledovalnike PDF to pomeni implementacijo robustne integracije besedila v govor (Text-to-Speech - TTS) in bralnikov zaslona.
V tem članku si bomo ogledali, kako s pomočjo mehanizma PDFium v Delphiju izluščiti semantične tokove besedila iz PDF dokumenta in nato to besedilo posredovati v Windows Speech API (SAPI) za izdelavo popolnoma dostopnega pregledovalnika PDF.
Izziv pri luščenju besedila iz PDF-jev
PDF je v osnovi platno z navodili za risanje. Sam po sebi ne ve, kaj je "odstavek" ali "stolpec"; le postavlja glife na specifične X/Y koordinate. Če želite prebrati dokument naglas v logičnem vrstnem redu, mora vaš razčlenjevalnik rekonstruirati vrstni red branja.
PDFium to obravnava prek družine API-jev FPDFText_*, ki analizira prostorske odnose glifov in izpiše koherentne tokove besedila.
1. korak: Luščenje besedila s PDFium
Preden lahko izgovorimo besedilo, ga moramo izluščiti. Naslednja Delphi koda prikazuje, kako inicializirati stran z besedilom in izluščiti njeno vsebino v standarden niz (string).
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;
2. korak: Integracija z Windows Speech API (SAPI)
Ko imamo semantično besedilo, ga lahko posredujemo v Windows Speech API. SAPI zagotavlja COM vmesnik SpVoice, ki omogoča asinhrono sintezo govora, izbiro glasu in nadzor hitrosti 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;
3. korak: Sinhronizacija govora z označevanjem besedila
Resnično dostopen pregledovalnik besedila ne prebere zgolj slepo; izgovorjene besede hkrati označi (highlight) na zaslonu. SAPI zagotavlja dogodke (prek priključnih točk - connection points), ki se sprožijo, ko je dosežena meja besede.
S preslikavo indeksa znaka, ki ga vrne dogodek meje besede API-ja SAPI, nazaj v indeks znaka v PDFium z uporabo FPDFText_GetCharBox(), lahko pridobite omejevalni pravokotnik trenutno izgovorjene besede in narišete označevalno prekrivanje (highlight overlay) na platnu (canvas) vašega pregledovalnika.
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;
Izdelava vključujoče aplikacije
Z združevanjem prostorskega luščenja besedila, ki ga ponuja PDFium, in SAPI-jevega mehanizma za govor, lahko razvijalci v Delphiju ustvarijo zmogljiva orodja za slepe in slabovidne uporabnike ali tiste, ki se raje učijo slušno. Pravilna implementacija teh funkcij zagotavlja, da je vaša aplikacija v skladu s strogimi standardi dostopnosti za podjetja in državne ustanove.
Opomba: Integrirano luščenje besedila in preslikavo koordinat v celoti podpira PDFium Component.