Khả năng truy cập không còn là một tính năng tùy chọn trong phát triển phần mềm hiện đại. Theo các quy định như ADA (Đạo luật Người khuyết tật Hoa Kỳ) và Chỉ thị về Khả năng truy cập Web của EU, phần mềm xử lý tài liệu phải cung cấp các công nghệ hỗ trợ. Đối với trình xem PDF, điều này có nghĩa là triển khai sự tích hợp mạnh mẽ với công cụ Chuyển văn bản thành giọng nói (Text-to-Speech - TTS) và trình đọc màn hình.
Trong bài viết này, chúng ta sẽ xem xét cách trích xuất các luồng văn bản ngữ nghĩa từ tệp PDF bằng PDFium trong Delphi, sau đó đưa văn bản đó vào Windows Speech API (SAPI) để xây dựng một trình xem PDF hoàn toàn có thể truy cập được.
Thách thức của việc trích xuất văn bản PDF
Về cơ bản, một tệp PDF là một khung vẽ (canvas) của các lệnh đồ họa. Bản thân nó không biết "đoạn văn" hoặc "cột" là gì; nó chỉ đơn thuần đặt các ký tự (glyphs) tại các tọa độ X/Y cụ thể. Để đọc to một tài liệu theo một thứ tự hợp lý, trình phân tích cú pháp của bạn phải xây dựng lại thứ tự đọc.
PDFium xử lý điều này thông qua họ API FPDFText_*, phân tích các mối quan hệ không gian của các ký tự để xuất ra các luồng văn bản mạch lạc.
Bước 1: Trích xuất văn bản với PDFium
Trước khi chúng ta có thể nói văn bản, chúng ta phải trích xuất nó. Mã Delphi sau đây thể hiện cách khởi tạo một trang văn bản và trích xuất nội dung của nó vào một chuỗi chuẩn.
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;
Bước 2: Tích hợp Windows Speech API (SAPI)
Khi chúng ta có văn bản ngữ nghĩa, chúng ta có thể chuyển nó đến Windows Speech API. SAPI cung cấp giao diện COM SpVoice, cho phép tổng hợp giọng nói không đồng bộ, chọn giọng nói và kiểm soát tốc độ nói.
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;
Bước 3: Đồng bộ hóa giọng nói với tính năng làm nổi bật (Highlighting)
Một trình xem thực sự có thể truy cập không chỉ đọc văn bản một cách mù quáng; nó làm nổi bật các từ trên màn hình khi chúng được nói. SAPI cung cấp các sự kiện (thông qua các điểm kết nối) sẽ kích hoạt khi đạt đến ranh giới từ.
Bằng cách ánh xạ chỉ số ký tự được trả về bởi sự kiện ranh giới từ của SAPI trở lại chỉ số ký tự trong PDFium bằng cách sử dụng FPDFText_GetCharBox(), bạn có thể lấy hình chữ nhật bao quanh (bounding rectangle) của từ đang được nói và vẽ một lớp phủ làm nổi bật trên khung xem (viewer canvas) của mình.
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;
Xây dựng một ứng dụng hòa nhập
Bằng cách kết hợp việc trích xuất văn bản không gian của PDFium với công cụ giọng nói của SAPI, các nhà phát triển Delphi có thể tạo ra các công cụ mạnh mẽ cho người dùng khiếm thị hoặc những người thích học qua thính giác. Việc triển khai đúng đắn các tính năng này đảm bảo ứng dụng của bạn tuân thủ các tiêu chuẩn về khả năng truy cập nghiêm ngặt của doanh nghiệp và chính phủ.
Lưu ý: Khả năng trích xuất văn bản và ánh xạ tọa độ tích hợp được hỗ trợ đầy đủ bởi PDFium Component.