Доступность больше не является необязательной функцией при разработке современного программного обеспечения. В соответствии с такими нормами, как ADA (Закон о защите прав граждан США с ограниченными возможностями) и Директива ЕС о доступности веб-сайтов, программное обеспечение, работающее с документами, должно предоставлять вспомогательные технологии. Для программ просмотра PDF это означает внедрение надежной интеграции с преобразованием текста в речь (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 VCL.