Přístupnost (accessibility) již není v moderním vývoji softwaru volitelnou funkcí. Podle předpisů, jako je ADA (Americans with Disabilities Act) a směrnice EU o přístupnosti webových stránek, musí software zpracovávající dokumenty poskytovat asistenční technologie. Pro prohlížeče PDF to znamená implementaci robustního převodu textu na řeč (TTS) a integraci čtečky obrazovky.
V tomto článku se podíváme na to, jak extrahovat sémantické textové streamy z PDF pomocí PDFium v Delphi, a jak pak tento text vložit do Windows Speech API (SAPI) za účelem vytvoření plně přístupného prohlížeče PDF.
Výzva extrakce textu z PDF
Dokument PDF je v zásadě plátno s instrukcemi pro kreslení. Ze své podstaty neví, co je "odstavec" nebo "sloupec"; pouze umisťuje glyfy na specifické souřadnice X/Y. Aby bylo možné číst dokument nahlas v logickém pořadí, musí váš analyzátor rekonstruovat pořadí čtení.
Modul PDFium to řeší prostřednictvím rodiny rozhraní API FPDFText_*, která analyzuje prostorové vztahy glyfů a vytváří souvislé textové streamy.
Krok 1: Extrakce textu pomocí PDFium
Než budeme moci text vyslovit, musíme jej extrahovat. Následující kód v Delphi ukazuje, jak inicializovat textovou stránku a extrahovat její obsah do standardního řetězce.
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;
Krok 2: Integrace Windows Speech API (SAPI)
Jakmile máme sémantický text, můžeme jej předat rozhraní Windows Speech API. SAPI poskytuje rozhraní COM SpVoice, které umožňuje asynchronní syntézu řeči, výběr hlasu a ovládání rychlosti řeči.
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;
Krok 3: Synchronizace řeči se zvýrazněním
Skutečně přístupný prohlížeč nečte text jen naslepo; zvýrazňuje slova na obrazovce tak, jak jsou vyslovována. SAPI poskytuje události (prostřednictvím spojovacích bodů), které se spustí po dosažení hranice slova.
Namapováním indexu znaku vráceného událostí SAPI pro hranici slova zpět na index znaku v modulu PDFium pomocí FPDFText_GetCharBox() můžete získat ohraničující obdélník aktuálně mluveného slova a nakreslit zvýraznění na plátně vašeho prohlížeče.
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;
Tvorba inkluzivní aplikace
Kombinací prostorové extrakce textu PDFium se zvukovým modulem SAPI mohou vývojáři v Delphi vytvářet výkonné nástroje pro zrakově postižené uživatele nebo ty, kteří preferují sluchové učení. Správná implementace těchto funkcí zajistí, že vaše aplikace bude v souladu s přísnými podnikovými a vládními standardy pro přístupnost.
Poznámka: Integrovaná extrakce textu a mapování souřadnic jsou plně podporovány komponentou PDFium Component.