Technical Article

Изграждане на достъпни PDF зрители с Text-to-Speech в Delphi

Достъпността вече не е опционална функция в съвременната разработка на софтуер. Съгласно регулации като ADA (Закон за американците с увреждания) и Директивата на ЕС за уеб достъпност, софтуерът, който обработва документи, трябва да предоставя помощни технологии. За програмите за преглед на PDF това означава внедряване на стабилна интеграция на Text-to-Speech (TTS) и екранни четци.

В тази статия ще разгледаме как да извличаме семантични текстови потоци от PDF с помощта на PDFium в Delphi и след това да подаваме този текст към Windows Speech API (SAPI), за да изградим напълно достъпен PDF зрител.

Предизвикателството на извличането на текст от PDF

PDF по същество е платно от инструкции за рисуване. Той по своята същност не знае какво е "параграф" или "колона"; той просто поставя глифове на специфични X/Y координати. За да прочете документ на глас в логичен ред, вашият синтактичен анализатор трябва да реконструира реда за четене.

PDFium се справя с това чрез фамилията API FPDFText_*, която анализира пространствените взаимоотношения на глифовете, за да изведе съгласувани текстови потоци.

Стъпка 1: Извличане на текст с PDFium

Преди да можем да произнесем текста, трябва да го извлечем. Следният код на Delphi демонстрира как да инициализирате текстова страница и да извлечете съдържанието й в стандартен низ.

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: Интегриране на Windows Speech API (SAPI)

След като разполагаме със семантичния текст, можем да го предадем на Windows Speech API. SAPI предоставя COM интерфейса SpVoice, който позволява асинхронен синтез на реч, избор на глас и контрол на скоростта на речта.

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: Синхронизиране на речта с подчертаване

Истински достъпният зрител не просто чете текста сляпо; той подчертава думите на екрана, докато се произнасят. SAPI предоставя събития (чрез точки на свързване), които се задействат при достигане на граница на дума.

Чрез съпоставяне на индекса на знака, върнат от събитието за граница на дума на SAPI, обратно към индекса на знака в PDFium с помощта на FPDFText_GetCharBox(), можете да извлечете ограничаващия правоъгълник на текущо произнасяната дума и да начертаете наслагване на подчертаване върху платното на вашия зрител.

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;

Изграждане на приобщаващо приложение

Комбинирайки пространственото извличане на текст на PDFium с речевата машина на SAPI, разработчиците на Delphi могат да създадат мощни инструменти за потребители със зрителни увреждания или такива, които предпочитат слуховото обучение. Правилното внедряване на тези функции гарантира, че вашето приложение отговаря на строгите корпоративни и правителствени стандарти за достъпност.

Забележка: Интегрираното извличане на текст и съпоставянето на координати се поддържат напълно от PDFium Component.