Technical Article

Saavutettavien PDF-katseluohjelmien rakentaminen tekstistä puheeksi -ominaisuudella Delphissä

Saavutettavuus ei ole enää valinnainen ominaisuus nykyaikaisessa ohjelmistokehityksessä. Säännösten, kuten ADA (Americans with Disabilities Act) ja EU:n saavutettavuusdirektiivin, mukaan asiakirjoja käsittelevien ohjelmistojen on tarjottava avustavia tekniikoita. PDF-katseluohjelmille tämä tarkoittaa vankan tekstistä puheeksi -ominaisuuden (Text-to-Speech, TTS) ja näytönlukijaintegraation toteuttamista.

Tässä artikkelissa tarkastelemme, kuinka semanttisia tekstivirtoja puretaan PDF-tiedostosta käyttämällä PDFiumia Delphissä, ja kuinka tämä teksti syötetään Windows Speech API:lle (SAPI) täysin saavutettavan PDF-katseluohjelman rakentamiseksi.

PDF-tekstin purkamisen haaste

PDF on pohjimmiltaan piirto-ohjeiden kangas. Se ei luonnostaan tiedä, mikä "kappale" tai "sarake" on; se vain sijoittaa glyyfejä tiettyihin X/Y-koordinaatteihin. Asiakirjan lukemiseksi ääneen loogisessa järjestyksessä jäsentimesi on rakennettava lukujärjestys uudelleen.

PDFium käsittelee tämän FPDFText_*-API-perheen kautta, joka analysoi glyyfien spatiaalisia suhteita tuottaakseen johdonmukaisia tekstivirtoja.

Vaihe 1: Tekstin purkaminen PDFiumilla

Ennen kuin voimme puhua tekstin, meidän on purettava se. Seuraava Delphi-koodi näyttää, kuinka tekstisivu alustetaan ja sen sisältö puretaan vakiomerkkijonoksi.

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;

Vaihe 2: Windows Speech API:n (SAPI) integrointi

Kun meillä on semanttinen teksti, voimme välittää sen Windows Speech API:lle. SAPI tarjoaa SpVoice COM-rajapinnan, joka mahdollistaa asynkronisen puhesynteesin, äänen valinnan ja puhenopeuden hallinnan.

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;

Vaihe 3: Puheen ja korostuksen synkronointi

Todella saavutettava katseluohjelma ei lue tekstiä sokeasti; se korostaa sanat näytöllä sitä mukaa, kun niitä puhutaan. SAPI tarjoaa tapahtumia (yhteyspisteiden kautta), jotka laukeavat, kun sanaraja saavutetaan.

Yhdistämällä SAPI:n sanarajatapahtuman palauttaman merkki-indeksin takaisin PDFiumin merkki-indeksiin käyttämällä FPDFText_GetCharBox()-funktiota, voit noutaa parhaillaan puhuttavan sanan rajoituslaatikon ja piirtää korostuksen katseluohjelmasi kankaalle.

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;

Osallistavan sovelluksen rakentaminen

Yhdistämällä PDFiumin spatiaalisen tekstin purkamisen SAPI:n puhemoottoriin, Delphi-kehittäjät voivat luoda tehokkaita työkaluja näkövammaisille käyttäjille tai niille, jotka suosivat auditiivista oppimista. Näiden ominaisuuksien asianmukainen toteuttaminen varmistaa, että sovelluksesi noudattaa tiukkoja yritys- ja viranomaissaavutettavuusstandardeja.

Huomautus: PDFium Component VCL -komponentti tukee täysin integroitua tekstin purkamista ja koordinaattien kartoitusta.