Technical Article

Membangun Penampil PDF Aksesibel dengan Text-to-Speech di Delphi

Aksesibilitas tidak lagi menjadi fitur opsional dalam pengembangan perangkat lunak modern. Di bawah peraturan seperti ADA (Undang-Undang Orang Amerika dengan Disabilitas) dan Petunjuk Aksesibilitas Web Uni Eropa, perangkat lunak yang menangani dokumen harus menyediakan teknologi bantuan. Untuk penampil PDF, ini berarti mengimplementasikan Text-to-Speech (TTS) dan integrasi pembaca layar yang tangguh.

Dalam artikel ini, kita akan melihat cara mengekstrak aliran teks semantik dari PDF menggunakan PDFium di Delphi, lalu memasukkan teks tersebut ke dalam Windows Speech API (SAPI).

Memetakan Elemen PDF ke Unit Baca

Di dalam PDF, tidak ada konsep bawaan tentang "paragraf" atau "kalimat". Teks diposisikan di halaman sebagai serangkaian perintah rendering string individual, sering kali memisahkan karakter ke koordinat tepat untuk kerning.

Modul TextPage dari PDFium menangani beban berat dalam merekombinasi karakter mengambang ini menjadi struktur bahasa yang bermakna. Menggunakan API PDFium, Anda dapat memetakan halaman fisik ke objek halaman teks logis:

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;

Mengekstrak Teks Semantik

Dengan halaman teks dirender, langkah selanjutnya adalah mengekstrak teks dengan cara yang meniru aliran baca alami. PDFium memungkinkan ekstraksi berkelanjutan di seluruh batas halaman semu.

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;

Mengintegrasikan Windows SAPI di Delphi

Dengan teks logis di tangan, menyuarakannya di Delphi adalah proses yang mudah menggunakan antarmuka COM Windows SAPI (Speech API). Anda dapat mengikat teks yang diekstrak PDFium langsung ke suara synthesizer standar.

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;

Sinkronisasi dan Umpan Balik Visual

Penampil PDF aksesibel kelas atas tidak hanya membacakan teks tetapi juga menyorot kata atau kalimat saat sedang diucapkan. SAPI menyediakan kejadian asinkron (OnWord atau OnSentence) yang dapat Anda tangkap. Anda kemudian dapat memetakan batas kata ini kembali ke fungsi pencarian PDFium (FPDFText_FindStart dan FPDFText_GetRect) untuk menggambar kotak sorotan berwarna kuning langsung pada kanvas VCL.

Dengan membangun jalur dari objek teks mentah ke string yang terikat ruang dan ke mesin asinkron, aplikasi Delphi Anda memastikan bahwa pengguna dengan gangguan penglihatan dapat memakai dokumen Anda dengan lancar.

Catatan: Ekstraksi teks aksesibilitas lanjutan dan dukungan perenderan asli tersedia melalui Komponen VCL PDFium Component.