A acessibilidade já não é uma funcionalidade opcional no desenvolvimento de software moderno. Ao abrigo de regulamentações como a ADA (Lei dos Americanos com Deficiência) e a Diretiva de Acessibilidade Web da UE, o software que lida com documentos deve fornecer tecnologias de apoio. Para visualizadores de PDF, isto significa implementar uma robusta integração de Texto para Voz (Text-to-Speech - TTS) e leitores de ecrã.
Neste artigo, veremos como extrair fluxos de texto semântico de um PDF usando PDFium em Delphi e, em seguida, alimentar esse texto na API de Voz 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 (canvas) de instruções de pintura. Não sabe inerentemente o que é um "parágrafo" ou uma "coluna"; apenas coloca glifos em coordenadas X/Y específicas. Para ler um documento em voz alta numa ordem lógica, o seu analisador deve reconstruir a ordem de leitura.
O PDFium lida com isto através da família de APIs FPDFText_*, que analisa as relações espaciais dos glifos para produzir fluxos de texto coerentes.
Passo 1: Extrair Texto com PDFium
Antes de podermos vocalizar o texto, devemos extraí-lo. O código Delphi seguinte demonstra como inicializar uma página de texto e extrair o seu conteúdo para uma cadeia de caracteres (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;
Passo 2: Integrar a API de Voz do Windows (SAPI)
Assim que tivermos o texto semântico, podemos passá-lo para a API de Voz do Windows. A SAPI fornece a interface COM SpVoice, que permite a síntese de voz assíncrona, seleção de voz e controlo da velocidade da 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;
Passo 3: Sincronizar a Voz com o Realce
Um visualizador verdadeiramente acessível não lê apenas o texto de forma cega; realça as palavras no ecrã à medida que são faladas. A SAPI fornece eventos (através de pontos de ligação) que disparam quando se atinge o limite de uma palavra.
Ao mapear o índice do caráter devolvido pelo evento de limite de palavra da SAPI de volta ao índice do caráter no PDFium utilizando FPDFText_GetCharBox(), pode recuperar o retângulo delimitador (bounding rectangle) da palavra falada atualmente e desenhar uma sobreposição de realce na tela do seu 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;
Construir uma Aplicação Inclusiva
Ao combinar a extração espacial de texto do PDFium com o motor de voz SAPI, os programadores Delphi podem criar ferramentas poderosas para utilizadores com deficiência visual ou aqueles que preferem a aprendizagem auditiva. A implementação adequada destas funcionalidades garante que a sua aplicação cumpre rigorosos padrões de acessibilidade empresariais e governamentais.
Nota: A extração integrada de texto e o mapeamento de coordenadas são totalmente suportados pelo Componente VCL PDFium Component.