현대 소프트웨어 개발에서 접근성은 더 이상 선택 기능이 아닙니다. 미국 장애인법(ADA) 및 EU 웹 접근성 지침과 같은 규정에 따라 문서를 처리하는 소프트웨어는 보조 기술을 제공해야 합니다. PDF 뷰어의 경우 이는 강력한 TTS(Text-to-Speech) 및 화면 판독기 통합을 구현하는 것을 의미합니다.
이 기사에서는 Delphi의 PDFium을 사용하여 PDF에서 시맨틱 텍스트 스트림을 추출한 다음, 해당 텍스트를 Windows Speech API(SAPI)에 공급하여 완벽하게 접근 가능한 PDF 뷰어를 구축하는 방법을 살펴봅니다.
PDF 텍스트 추출의 어려움
PDF는 기본적으로 페인팅 지침의 캔버스입니다. 본질적으로 "단락"이나 "열"이 무엇인지 알지 못하며 특정 X/Y 좌표에 글리프(glyph)를 배치할 뿐입니다. 문서를 논리적 순서로 소리 내어 읽으려면 파서가 읽기 순서를 재구성해야 합니다.
PDFium은 FPDFText_* API 제품군을 통해 이 문제를 처리하며, 글리프의 공간적 관계를 분석하여 일관된 텍스트 스트림을 출력합니다.
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는 비동기식 음성 합성, 음성 선택 및 음성 속도 제어를 허용하는 SpVoice COM 인터페이스를 제공합니다.
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 단어 경계 이벤트에서 반환된 문자 인덱스를 FPDFText_GetCharBox()를 사용하여 PDFium의 문자 인덱스에 매핑하면 현재 말하고 있는 단어의 경계 사각형을 검색하여 뷰어 캔버스에 강조 표시 오버레이를 그릴 수 있습니다.
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;
포괄적인 애플리케이션 구축
Delphi 개발자는 PDFium의 공간적 텍스트 추출 기능과 SAPI의 음성 엔진을 결합하여 시각 장애가 있는 사용자나 청각적 학습을 선호하는 사용자를 위한 강력한 도구를 만들 수 있습니다. 이러한 기능을 올바르게 구현하면 애플리케이션이 엄격한 기업 및 정부 접근성 표준을 준수하게 됩니다.
참고: 통합 텍스트 추출 및 좌표 매핑은 PDFium Component에서 완벽하게 지원됩니다.