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.