A acessibilidade não é mais um recurso opcional no desenvolvimento de software moderno. Sob regulamentações como a ADA (Lei dos Americanos com Deficiências) e a Diretiva de Acessibilidade da Web da UE, os softwares que lidam com documentos devem fornecer tecnologias assistivas. Para visualizadores de PDF, isso significa implementar recursos robustos de Text-to-Speech (TTS) e integração de leitores de tela.
Neste artigo, veremos como extrair fluxos de texto semânticos de um PDF usando o PDFium no Delphi e, em seguida, alimentar esse texto na API de Fala do Windows (SAPI) para construir um visualizador de PDF totalmente acessível.
O Desafio da Extração de Texto de PDF
Um PDF é fundamentalmente uma tela de instruções de pintura. Ele não sabe inerentemente o que é um "parágrafo" ou uma "coluna"; ele meramente posiciona glifos em coordenadas X/Y específicas. Para ler um documento em voz alta em uma ordem lógica, seu analisador deve reconstruir a ordem de leitura.
O PDFium lida com isso através da família de APIs FPDFText_*, que analisa as relações espaciais dos glifos para gerar fluxos de texto coerentes.
Etapa 1: Extraindo Texto com o PDFium
Antes de podermos falar o texto, devemos extraí-lo. O código Delphi a seguir demonstra como inicializar uma página de texto e extrair seu conteúdo para uma string padrão.
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;
Etapa 2: Integrando a API de Fala do Windows (SAPI)
Assim que tivermos o texto semântico, podemos passá-lo para a API de Fala do Windows. A SAPI fornece a interface COM SpVoice, que permite síntese de fala assíncrona, seleção de voz e controle da taxa de fala.
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;
Etapa 3: Sincronizando a Fala com o Realce
Um visualizador verdadeiramente acessível não apenas lê o texto cegamente; ele realça as palavras na tela conforme são faladas. A SAPI fornece eventos (por meio de pontos de conexão) que são acionados quando um limite de palavra é alcançado.
Ao mapear o índice de caractere retornado pelo evento de limite de palavra da SAPI de volta para o índice de caractere no PDFium usando FPDFText_GetCharBox(), você pode recuperar o retângulo delimitador da palavra falada no momento e desenhar uma sobreposição de realce na tela do visualizador.
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;
Construindo um Aplicativo Inclusivo
Ao combinar a extração de texto espacial do PDFium com o mecanismo de fala da SAPI, os desenvolvedores do Delphi podem criar ferramentas poderosas para usuários com deficiência visual ou aqueles que preferem o aprendizado auditivo. Implementar adequadamente esses recursos garante que seu aplicativo esteja em conformidade com rigorosos padrões de acessibilidade corporativos e governamentais.
Nota: A extração de texto integrada e o mapeamento de coordenadas são totalmente suportados pelo PDFium Component.