Tehnični članak

Hiperpovezave HotPDF Delphi: Namigi za anotacijo PrintHyperlink

Hiperpovezave v PDF-jih so anotacije URI: pravokotnik, ki pokriva določeno površino strani in ko ga kliknete, pregledovalniku naroči, naj odpre URL. Anotacija in besedilo pod njo sta popolnoma neodvisna objekta. HotPDF-ov PrintHyperlink združi oba v en klic, ki nariše besedilo in izračuna pravokotnik anotacije iz dimenzij izrisanega besedila. Ta prikladnost skriva podrobnost, ki jo je vredno razumeti, preden napišete produkcijsko kodo

Kako deluje PrintHyperlink

PrintHyperlink živi na THPDFPage in sprejme štiri argumente: koordinati X in Y (v točkah, izhodišče spodaj levo, Y narašča navzgor), niz oznake za prikaz in ciljni URL. Interno pokliče TextOut v trenutni barvi hiperpovezave, nato pa takoj izračuna pravokotnik anotacije iz vrednosti TextWidth in TextHeight pri trenutnih metrikah pisave. To pomeni, da morata biti pisava in velikost nastavljeni pred klicem in se ne smeta spremeniti med risanjem oznake in postavljanjem anotacije, ker se oba razrešita v istem klicu

Privzeta barva je clBlue. SetRGBHyperlinkColor jo spremeni le za naslednje klice; anotacij, ki so že zapisane, retroaktivno ne posodablja. Če na isti strani potrebujete različne barve za različne skupine povezav, pokličite SetRGBHyperlinkColor pred vsako skupino in jo po njej ponastavite

Tukaj je minimalni dokument, ki zapiše tri povezave v dveh različnih barvah:

procedure CreateLinkedReport(const FileName: string);
var
  Pdf: THotPDF;
begin
  Pdf := THotPDF.Create(nil);
  try
    Pdf.FileName := FileName;
    Pdf.BeginDoc;

    Pdf.CurrentPage.SetFont('Arial', [], 11);

    // Default blue for informational links
    Pdf.CurrentPage.TextOut(50, 750, 0, 'Reference links:');
    Pdf.CurrentPage.PrintHyperlink(50, 720, 'Product page', 'https://www.loslab.com/en-us/pdf-library/delphi-pdf-component.html');
    Pdf.CurrentPage.PrintHyperlink(50, 695, 'Online manual', 'https://www.loslab.com/en-us/pdf-library/delphi-pdf-component.html');

    // Red for the action link
    Pdf.CurrentPage.SetRGBHyperlinkColor(clRed);
    Pdf.CurrentPage.PrintHyperlink(50, 660, 'Purchase license', 'https://www.loslab.com/en-us/buy-hotpdf-fastspring.html');
    Pdf.CurrentPage.SetRGBHyperlinkColor(clBlue);  // restore default

    Pdf.EndDoc;
  finally
    Pdf.Free;
  end;
end;

Past koordinatnega sistema

HotPDF uporablja izhodišče spodaj levo, pri čemer Y narašča navzgor, v točkah (1/72 palca). Stran formata A4 meri 595 x 842 točk, stran US Letter pa 612 x 792 točk. Y=750 je blizu vrha strani A4, Y=50 pa bi bil blizu spodnjega roba. Vsakdo, ki prihaja iz sveta zaslonske grafike ali HTML-ja, predpostavlja ravno nasprotno in postavi prvo vrstico s povezavo naravnost zunaj vidnega območja

Pravokotnik anotacije, ki ga izračuna PrintHyperlink, uporablja enak koordinatni sistem. Če stran pozneje zavrtite, jo spremenite v merilu ali spremenite njeno velikost brez ponovnega izračuna vrednosti X in Y, se vidno besedilo in klikabilni pravokotnik razmakneta. Povezava "deluje" v smislu, da klik nekje blizu besedila sproži URL, vendar vroča cona ne ustreza več temu, kar bralec vidi. Testirajte na dejanski velikosti strani in stopnji povečave, ki jo dobavite, in ne samo na razvojnem računalniku pri 100-odstotni povečavi

En primer, kjer je razmik zagotovljen: če pokličete PrintHyperlink s koordinatami, primernimi za stran A4, nato pa preklopite na stransko obliko po meri brez prilagoditve vrednosti X in Y, se anotacija lahko znajde popolnoma zunaj strani. Objekt anotacije je še vedno zapisan v PDF; večina pregledovalnikov ga tiho odreže, zato povezava preprosto izgine brez kakršne koli napake

Besedilo oznake v primerjavi s ciljnim URL-jem

Argumenta Text in Link sta neodvisna. Prikazano besedilo je lahko "Prenesi račun v PDF", medtem ko je cilj povsem označen HTTPS URL s parametri poizvedbe. Ta ločitev je namerna; vidna oznaka naj bo berljiva za človeka, URL pa je lahko dolg ali dinamično ustvarjen

Težave nastanejo, ko je oznaka sam URL, zlasti dolg. Če se URL vizualno prelomi čez dve vrstici, a je pravokotnik anotacije bil izračunan za enonitkični niz, je klikabilna samo prva vrstica. PrintHyperlink ne obravnava večvrstičnega toka; oznako ohranite dovolj kratko, da se ujema v eno vrstico pri trenutni velikosti pisave in širini strani, ali pa uporabite kratko opisno oznako s polnim URL-jem kot ciljem

Za dokumente, ki bodo arhivirani ali razposlani brez aktivne internetne povezave, razmislite tudi o tem, ali naj se sam URL pojavi v natisnjeni obliki nekje v telesu dokumenta, ne samo kot metapodatki anotacije. Bralec, ki tiska PDF na papir, od anotacije URI ne dobi ničesar

Primer generiranja celotnega dokumenta

Vzorec spodaj prikazuje bolj realistični scenarij: generiranje kratkega poročila z glavo, besedilom telesa in vrstico z linki v nogi, vse iz kode in ne iz obrazca s polji TEdit:

procedure GenerateProductSheet(
  const FileName, ProductName, ProductURL, SupportURL: string);
var
  Pdf: THotPDF;
begin
  Pdf := THotPDF.Create(nil);
  try
    Pdf.FileName := FileName;
    Pdf.Compression := cmFlateDecode;
    Pdf.BeginDoc;

    // Header
    Pdf.CurrentPage.SetFont('Arial', [fsBold], 16);
    Pdf.CurrentPage.TextOut(50, 750, 0, WideString(ProductName));

    // Body paragraph placeholder
    Pdf.CurrentPage.SetFont('Arial', [], 11);
    Pdf.CurrentPage.TextOut(50, 710, 0, 'See the links below for full documentation.');

    // Footer links
    Pdf.CurrentPage.SetFont('Arial', [], 10);
    Pdf.CurrentPage.TextOut(50, 80, 0, 'Links:');
    Pdf.CurrentPage.PrintHyperlink(50, 60, 'Product page', ProductURL);
    Pdf.CurrentPage.PrintHyperlink(200, 60, 'Support', SupportURL);

    Pdf.EndDoc;
  finally
    Pdf.Free;
  end;
end;

Upoštevajte, da je SetFont klican pred vsako skupino klicev za besedilo. Pisava ne ostane v veljavi po klicu AddPage, in če jo pozabite nastaviti pred PrintHyperlink na novi strani, bo pravokotnik anotacije izračunan glede na privzete metrike strani, ki se morda razlikujejo od pričakovanih

Kje se obravnava anotacij razlikuje med pregledovalniki

Anotacije URI v PDF-ju so opredeljene v ISO 32000-1 §12.6.4.7, in vsak skladen pregledovalnik bi jih moral upoštevati. V praksi pa se nekatera vedenja razlikujejo glede na pregledovalnik. Adobe Acrobat ob prvem kliku prikaže varnostno opozorilo za URL-je, ki niso na seznamu zaupanja vrednih domen; mnogi brskalniki in lažji pregledovalniki tega ne počnejo. Nekateri poslovni pregledovalniki PDF v zaklepnjenih okoljih onemogočijo anotacije URI povsem po pravilniku, zato klik ne naredi ničesar brez vidne napake. Mobilne aplikacije za PDF se razlikujejo v tem, ali odprejo povezave v pogledu spletnega brskalnika znotraj aplikacije ali jih predajo sistemskemu brskalniku

Nobene od teh težav ne morete odpraviti na strani generiranja; gre za odločitve o pravilnikih pregledovalnika. Kar lahko storite, je pisati oznake povezav, ki naredijo URL viden tudi v telesu dokumenta, tako da ga bralec v omejenem okolju še vedno lahko ročno skopira. Anotacija je pripomoček; besedilo je nadomestna rešitev

Ena podrobnost, ki jo je vredno poznati: anotacije URI v PDF-ju privzeto ne nosijo nobenega vizualnega podčrtaja. Podčrtaj, ki ga vidite v večini pregledovalnikov, nariše pregledovalnik sam glede na vrsto anotacije in ne glif v toku vsebine. Če potrebujete fizični podčrtaj, ki preživi tiskanje v neinteraktivni renderer ali pretvorbo PDF v sliko, ga izrišite izrecno z LineTo in Stroke pri ustreznem odmiku Y pod izhodiščno črto besedila. To je ločena risarska operacija in ni nekaj, kar PrintHyperlink naredi namesto vas

Vmesnik API za hiperpovezave, prikazan tukaj, je del komponente HotPDF Component za Delphi in C++Builder