Prieinamumas nebėra pasirenkama funkcija šiuolaikinėje programinės įrangos kūrimo aplinkoje. Pagal tokius reglamentus kaip ADA (Amerikiečių su negalia aktas) ir ES interneto prieinamumo direktyva, dokumentus apdorojanti programinė įranga privalo teikti pagalbines technologijas. PDF skaityklėms tai reiškia tvirtą teksto skaitymo balsu (TTS) ir ekrano skaitytuvų integraciją.
Šiame straipsnyje apžvelgsime, kaip „Delphi“ programoje išskirti semantinius teksto srautus iš PDF naudojant „PDFium“, o tada perduoti šį tekstą į „Windows Speech API“ (SAPI), siekiant sukurti visiškai prieinamą PDF skaityklę.
PDF teksto išskyrimo iššūkis
PDF iš esmės yra piešimo instrukcijų drobė. Formatas savaime „nežino“, kas yra „pastraipa“ ar „stulpelis“; jis tiesiog perkelia glifus į konkrečias X/Y koordinates. Norint logiška seka skaityti dokumentą garsiai, jūsų analizatorius turi atkurti skaitymo tvarką.
„PDFium“ tai sprendžia naudodamas FPDFText_* API šeimą, kuri analizuoja erdvinius glifų ryšius ir išveda nuoseklius teksto srautus.
1 žingsnis: teksto išskyrimas su „PDFium“
Prieš sakydami tekstą, privalome jį išskirti. Toliau pateiktas „Delphi“ kodas demonstruoja, kaip inicijuoti teksto puslapį ir išskirti jo turinį į standartinę eilutę.
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 žingsnis: „Windows Speech API“ (SAPI) integravimas
Gavę semantinį tekstą, galime jį perduoti į „Windows Speech API“. SAPI suteikia SpVoice COM sąsają, leidžiančią asinchroninę kalbos sintezę, balso pasirinkimą ir kalbėjimo greičio valdymą.
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 žingsnis: kalbos sinchronizavimas su paryškinimu
Tikrai prieinama skaityklė ne tik aklai skaito tekstą; ji taip pat paryškina žodžius ekrane juos tariant. SAPI suteikia įvykius (per ryšio taškus), kurie suveikia pasiekus žodžio ribą.
Susiedami simbolio indeksą, grąžintą iš SAPI žodžio ribos įvykio, su simbolio indeksu „PDFium“ variklyje per FPDFText_GetCharBox(), galite gauti šiuo metu tariamo žodžio ribojantį stačiakampį (angl. bounding rectangle) ir nupiešti paryškinimo perdengimą savo skaityklės drobėje.
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;
Įtraukios programos kūrimas
Derindami „PDFium“ erdvinį teksto išskyrimą su SAPI kalbos varikliu, „Delphi“ kūrėjai gali sukurti galingus įrankius silpnaregiams vartotojams arba tiems, kurie teikia pirmenybę mokymuisi klausantis. Tinkamas šių funkcijų įgyvendinimas užtikrina jūsų programos atitiktį griežtiems įmonių ir vyriausybių prieinamumo standartams.
Pastaba: integruotas teksto išskyrimas ir koordinačių susiejimas yra visiškai palaikomi „PDFium Component VCL“ komponente.