Odkazy v PDF sú anotáciami typu URI: obdĺžnik pokrývajúci určitú plochu stránky, ktorý po kliknutí inštruuje prehliadač, aby otvoril danú adresu URL. Anotácia a text pod ňou sú úplne nezávislé objekty. Metóda PrintHyperlink v komponente HotPDF spája obe tieto činnosti do jediného volania – vykreslí text a automaticky vypočíta obdĺžnik anotácie na základe rozmerov vykresleného textu. Táto praktická funkcia však skrýva detaily, ktoré je dôležité pochopiť pred písaním produkčného kódu
Ako funguje PrintHyperlink
Metóda PrintHyperlink je súčasťou triedy THPDFPage a prijíma štyri argumenty: súradnice X a Y (v bodoch, s počiatkom vľavo dole a osou Y rastúcou nahor), zobrazovaný text (label) a cieľovú adresu URL. Interne volá metódu TextOut s aktuálne nastavenou farbou odkazu a okamžite vypočíta obdĺžnik anotácie pomocou funkcií TextWidth a TextHeight pre aktuálne nastavenie písma. To znamená, že font a jeho veľkosť musíte nastaviť pred volaním metódy a nesmiete ich meniť medzi vykreslením textu a umiestnením anotácie, keďže obe akcie sa vykonávajú v rámci jedného volania
Predvolenou farbou je clBlue. Volanie SetRGBHyperlinkColor zmení farbu iba pre nasledujúce volania. Neupravuje spätne anotácie, ktoré už boli zapísané. Ak na jednej stránke potrebujete rôzne farby pre odlišné skupiny odkazov, zavolajte SetRGBHyperlinkColor pred každou skupinou a po jej vykreslení farbu vráťte na pôvodnú hodnotu
Tu je ukážka minimálneho dokumentu, ktorý vytvára tri odkazy s dvoma rôznymi farbami:
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;
Pasca so súradnicami
HotPDF používa počiatok v ľavom dolnom rohu, pričom súradnica Y rastie smerom nahor a udáva sa v bodoch (1/72 palca). Stránka formátu A4 má rozmery 595 x 842 bodov, formát US Letter má 612 x 792 bodov. Hodnota Y=750 sa nachádza blízko horného okraja stránky A4, zatiaľ čo Y=50 je blízko dolného okraja. Každý, kto prichádza zo sveta počítačovej grafiky alebo HTML, predpokladá opak a umiestni prvý riadok s odkazom úplne mimo viditeľnú oblasť
Obdĺžnik anotácie, ktorý metóda PrintHyperlink vypočítava, využíva rovnaký súradnicový systém. Ak neskôr stránku otočíte, zmeníte jej mierku alebo veľkosť bez prepočítania hodnôt X/Y, viditeľný text a klikateľná oblasť sa posunú. Odkaz bude síce technicky „fungovať“ (kliknutie niekde v blízkosti textu otvorí adresu URL), no aktívna zóna už nebude zodpovedať tomu, čo vidí čitateľ. Odkazy preto testujte pri skutočnej veľkosti stránky a priblížení, ktoré plánujete distribuovať, a nie iba na vývojárskom počítači pri 100 % zobrazení
Jeden z prípadov, kedy k posunu určite dôjde: ak zavoláte PrintHyperlink so súradnicami určenými pre stránku formátu A4 a potom prepnete na vlastný úzky formát stránky bez úpravy hodnôt X/Y. Anotácia môže skončiť úplne mimo stránky. Objekt anotácie sa síce do PDF zapíše, ale väčšina prehliadačov ho potichu osekne, takže odkaz bez akéhokoľvek varovania proste zmizne
Zobrazovaný text vs. cieľová URL
Argumenty Text a Link sú nezávislé. Môžete vykresliť text „Stiahnuť faktúru v PDF“, zatiaľ čo cieľom bude kompletná HTTPS adresa s parametrami dotazu. Toto oddelenie je zámerné – viditeľný text by mal byť ľahko čitateľný pre človeka, kým adresa URL môže byť dlhá alebo generovaná dynamicky
Obmedzenie viacriadkového textu
Problémy vznikajú, ak je ako zobrazovaný text použitá priamo samotná surová adresa URL, najmä ak je dlhá. Ak sa URL vizuálne rozdelí do dvoch riadkov, ale obdĺžnik anotácie bol vypočítaný pre jednoriadkový text, klikateľný bude iba prvý riadok. Metóda PrintHyperlink nepodporuje viacriadkový zalomený text. Udržujte preto popis dostatočne krátky, aby sa zmestil na jeden riadok pri aktuálnej veľkosti písma a šírke stránky, prípadne použite krátky popisný názov a celú adresu URL nastavte ako cieľ
Pri dokumentoch určených na archiváciu alebo distribúciu bez aktívneho internetového pripojenia zvážte, či by sa samotná URL nemala zobraziť aj v tlačenej podobe niekde v tele dokumentu, nie iba ako metadáta anotácie. Čitateľovi, ktorý si vytlačí PDF na papier, je totiž samotná anotácia URI k ničomu
Kompletný príklad generovania dokumentu
Nižšie uvedená šablóna ukazuje reálnejší scenár – vygenerovanie krátkej správy s hlavičkou, hlavným textom a pätou s odkazmi, všetko čisto pomocou kódu, nie z formulára s poliami typu 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;
Všimnite si, že metóda SetFont sa volá pred každou skupinou textových volaní. Nastavenie písma sa neprenáša na novú stránku po volaní AddPage. Ak ho zabudnete nastaviť pred PrintHyperlink na novej stránke, obdĺžnik anotácie sa vypočíta podľa predvolených rozmerov písma stránky, čo môže viesť k nečakaným výsledkom
Rozdiely v spracovaní anotácií v prehliadačoch
URI anotácie v PDF sú definované v norme ISO 32000-1 §12.6.4.7 a každý kompatibilný prehliadač by sa nimi mal riadiť. V praxi sa však niektoré funkcie v závislosti od prehliadača líšia. Adobe Acrobat zobrazí pri prvom kliknutí bezpečnostné upozornenie, ak adresa nepatrí medzi dôveryhodné domény; mnohé webové prehliadače a jednoduché čítačky to nerobia. Niektoré firemné prehliadače PDF v zabezpečených prostrediach môžu URI anotácie úplne zakázať pomocou zásad skupiny (policy), takže kliknutie nevyvolá žiadnu akciu ani chybu. Mobilné aplikácie pre PDF sa tiež líšia v tom, či odkazy otvárajú vo vlastnom integrovanom prehliadači alebo ich odovzdávajú systémovému webovému prehliadaču
Žiadna z týchto vlastností nie je chybou, ktorú by ste mohli vyriešiť na strane generovania dokumentu – ide o rozhodnutia na úrovni nastavení prehliadačov. Čo však môžete urobiť, je písať popisy odkazov tak, aby bola adresa URL viditeľná priamo v tele dokumentu. Čitateľ v obmedzenom prostredí si tak bude môcť adresu skopírovať ručne. Anotácia predstavuje uľahčenie prístupu, zatiaľ čo samotný text slúži ako záložné riešenie
Ešte jeden detail, ktorý je dobré vedieť: URI anotácie v PDF predvolene neobsahujú žiadne vizuálne podčiarknutie. Podčiarknutie, ktoré vidíte vo väčšine prehliadačov, vykresľuje samotný prehliadač na základe typu anotácie, nie pomocou znaku v prúde obsahu (content stream). Ak potrebujete pevné podčiarknutie, ktoré zostane viditeľné aj po vytlačení na papier alebo po konverzii PDF na obrázok, nakreslite ho ručne pomocou metód LineTo a Stroke s vhodným posunom Y pod líniou textu. Ide o samostatnú kresliacu operáciu, ktorú za vás PrintHyperlink nevyrieši
Tu predstavené API pre prácu s odkazmi je súčasťou komponentu HotPDF Component pre Delphi a C++Builder