Technical Article

Tvorba přístupných prohlížečů PDF s převodem textu na řeč v Delphi

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.