PDF hipersaitai (angl. hyperlinks) yra URI anotacijos: tai puslapio sritį dengiantis stačiakampis, kurį spustelėjus peržiūros programa atidaro URL adresą. Anotacija ir po ja esantis tekstas yra visiškai nepriklausomi objektai. HotPDF funkcija PrintHyperlink apjungia abu veiksmus į vieną iškvietimą: ji nupiešia tekstą ir apskaičiuoja anotacijos stačiakampį pagal atvaizduoto teksto matmenis. Už šio patogumo slepiasi detalė, kurią naudinga suprasti prieš rašant kodą gamybinei aplinkai
Jei tekstą nupiešėte patys, AddURILink leidžia virš jo uždėti spustelėjamą sritį, o AddGoToLink tvarko vidinę navigaciją dokumente. Šie metodai papildo PrintHyperlink, kai nuoroda turi apimti ne tik etiketę
Kaip veikia PrintHyperlink
Metodas PrintHyperlink yra klasėje THPDFPage ir priima keturis argumentus: X ir Y koordinates (taškais, pradinė koordinatė apačioje kairėje, Y didėja į viršų), piešiamą etiketės eilutę ir tikslo URL adresą. Vidinėje logikoje jis iškviečia TextOut su nustatyta hipersaito spalva, o po to iškart apskaičiuoja anotacijos stačiakampį pagal TextWidth ir TextHeight reikšmes, atsižvelgdamas į dabartinio šrifto matmenis. Tai reiškia, kad šriftas ir jo dydis turi būti nustatyti prieš iškvietimą ir negali keistis tarp etiketės piešimo ir anotacijos patalpinimo, nes abu veiksmai atliekami tame pačiame iškvietime
Numatytoji spalva yra clBlue. SetRGBHyperlinkColor pakeičia ją tik būsimiems iškvietimams; ji neatnaujina jau įrašytų anotacijų spalvos atbuline data. Jei tame pačiame puslapyje skirtingoms saitų grupėms reikia skirtingų spalvų, iškvieskite SetRGBHyperlinkColor prieš kiekvieną grupę, o po to nustatykite spalvą iš naujo
Štai minimalus dokumento pavyzdys, kuriame įrašomi trys hipersaitai su dviem skirtingomis spalvomis:
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;
Koordinačių spąstai
HotPDF naudoja koordinačių sistemą su pradžios tašku apačioje kairėje, kur Y reikšmė didėja į viršų, matuojant taškais (1/72 colio). A4 puslapis yra 595 x 842 taškų dydžio; JAV Letter puslapis – 612 x 792 taškų. Y=750 reikšmė yra netoli A4 puslapio viršaus, o Y=50 būtų arti apatinės maržos. Kiekvienas, atėjęs iš ekrano grafikos ar HTML programavimo, daro priešingą prielaidą ir pirmąją saito eilutę nupiešia visiškai už matomos srities ribų
Anotacijos stačiakampis, kurį apskaičiuoja PrintHyperlink, naudoja tą pačią koordinačių sistemą. Jei vėliau pasuksite puslapį, pakeisite jo mastelį ar puslapio dydį neperskaičiavę X/Y reikšmių, matomas tekstas ir spustelėjamas stačiakampis išsiskirs. Saitas teoriškai veiks ta prasme, kad spustelėjus kur nors netoli teksto bus atidarytas URL, tačiau spustelėjimo sritis nebeatitiks to, ką mato skaitytojas. Atlikite testavimą su realiu puslapio dydžiu ir masteliu, o ne tik kūrimo mašinoje su 100% masteliu
Vienas iš atvejų, kai nesutapimas yra garantuotas: jei iškvieskite PrintHyperlink su A4 puslapiui tinkamomis koordinatėmis, o po to pereisite prie pasirinktinio siauro formato puslapio nepritaikę X/Y reikšmių, anotacija gali atsidurti visiškai už puslapio ribų. Anotacijos objektas vis tiek bus įrašytas į PDF failą; dauguma peržiūros programų jį tiesiog nukirps, todėl saitas tiesiog išnyks be jokio klaidos pranešimo
Etiketės tekstas prieš URL adresą
Argumentai Text ir Link yra nepriklausomi. Galite nupiešti etiketę „Atsisiųsti sąskaitą faktūrą PDF“, o tikslo adresas gali būti pilnas HTTPS URL su užklausos parametrais. Šis atskyrimas yra apgalvotas; matoma etiketė turi būti suprantama žmogui, o pats URL gali būti ilgas arba sugeneruotas dinamiškai
Problemos kyla kai pati etiketė yra neapdorotas URL adresas, ypač ilgas. Jei URL vizualiai persikelia į dvi eilutes, tačiau anotacijos stačiakampis buvo apskaičiuotas vienai eilutei, spustelėti bus galima tik pirmąją eilutę. PrintHyperlink neapdoroja kelių eilučių teksto; laikykite etiketę pakankamai trumpą, kad ji tilptų vienoje eilutėje su dabartiniu šrifto dydžiu ir puslapio pločiu, arba naudokite trumpą aprašomąją etiketę su pilnu URL adresu kaip tikslu
Dokumentuose, kurie bus archyvuojami arba platinami be aktyvaus interneto ryšio, taip pat apsvarstykite, ar pats URL adresas neturėtų būti atspausdintas kur nors dokumento tekste, o ne tik kaip anotacijos metaduomenys. Skaitytojas, atspausdinęs PDF failą ant popieriaus, iš URI anotacijos negaus jokios naudos
Kaip apeiti kelių eilučių apribojimą
PrintHyperlink apskaičiuoja vieną anotacijos stačiakampį, todėl kelių eilučių etiketės negalima patikimai naudoti kaip vienos nuorodos. Kiekvieną eilutę pieškite atskirai ir sukurkite atskirą anotaciją arba naudokite didesnę bendrą sritį, jei priimtina, kad spustelėjama būtų visa grupė
Spustelėjamos sritys virš savarankiškai nupiešto turinio su AddURILink
AddURILink tinka, kai nuorodos tekstą, piktogramą ar spalvotą foną jau nupiešėte kitais metodais. Perduokite tikslo URL ir tikslų stačiakampį puslapio koordinatėmis, kad anotacija sutaptų su matomu turiniu
Vidinė navigacija su AddGoToLink
AddGoToLink nukreipia į kitą to paties dokumento puslapį ir nekuria išorinės URI nuorodos. Tai patogus būdas kurti turinį, kryžmines nuorodas ar ankstesnio ir kito puslapio valdiklius, kai paskirties puslapis žinomas generavimo metu
Abiem metodams koordinates reikia skaičiuoti taip pat kaip ir piešiamam elementui: PDF pradžios taškas yra apačioje kairėje, o vertikali kryptis kyla į viršų. Jei puslapis pasuktas arba mastelis keičiamas, anotacijos stačiakampį transformuokite kartu su turiniu
Kelių eilučių tekstui kiekvienos eilutės plotį apskaičiuokite pagal tuo metu aktyvų šriftą, kad nuorodos sritis nesibaigtų per anksti
URI anotacija netikrina, ar URL yra pasiekiamas, todėl generavimo metu verta validuoti schemą ir tinkamai koduoti tikslo eilutę
Vidinė nuoroda nepriklauso nuo išorinio tinklo ryšio ir ypač tinka turiniui, priedams bei grįžimui į ilgų ataskaitų pradžią
Nuorodos stačiakampis turi būti tame pačiame koordinačių paviršiuje kaip ir puslapio turinys. Maišant ekrano ir PDF koordinates spustelėjama sritis pasislinks
Jei anotacija dedama virš vaizdo, jos ribas nustatykite pagal faktinį vaizdo dydį, įskaitant mastelį ir apkarpymą
Skirtingų spalvų grupėms nustatykite spalvą prieš kiekvieną grupę, nes vėlesnis nustatymas nekeičia jau įrašytų anotacijų
Peržiūros programos gali skirtingai rodyti anotacijos paryškinimą, tačiau paskirties veiksmą gauna iš PDF anotacijos žodyno
Generuojant dokumentą verta turėti pagalbinę funkciją, kuri vienu metu nupiešia etiketę, apskaičiuoja stačiakampį ir įrašo veiksmą
Prieš išleidimą patikrinkite nuorodas darbalaukio ir naršyklės peržiūros programose, nes jų paryškinimo stilius gali skirtis
Kiekvieną laužytos eilutės taikinį laikykite atskiru elementu, kad eilučių sritys nepersidengtų ir būtų lengvai testuojamos
Pilnas dokumento generavimo pavyzdys
Žemiau pateiktas pavyzdys rodo realesnį scenarijų: trumpos ataskaitos su antraštės skiltimi, pagrindiniu tekstu ir hipersaitų eilute puslapio apačioje generavimas tiesiogiai iš kodo, nenaudojant formos su TEdit laukeliais:
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;
Atkreipkite dėmesį, kad SetFont iškviečiamas prieš kiekvieną teksto iškvietimų grupę. Šriftas neišlieka sukūrus naują puslapį per AddPage, ir jei pamiršite jį nustatyti prieš PrintHyperlink naujame puslapyje, anotacijos stačiakampis bude apskaičiuojamas pagal numatytuosius puslapio šrifto matmenis, kurie gali skirtis nuo jūsų planuotų
Anotacijų apdorojimo skirtumai skirtingose peržiūros programose
PDF URI anotacijos yra apibrėžtos ISO 32000-1 §12.6.4.7 standarte ir kiekviena jį atitinkanti peržiūros programa turėtų jų laikytis. Praktikoje kai kurios elgsenos skiriasi priklausomai nuo programos. „Adobe Acrobat“ parodo saugumo įspėjimą pirmą kartą spustelėjus URL adresus, kurie nėra įtraukti į patikimų domenų sąrašą; daugelis naršyklių ir lengvų peržiūros programų to nedaro. Kai kurios įmonių PDF peržiūros programos apribotose aplinkose dėl saugumo politikos visiškai išjungia URI anotacijas, zodžiu, spustelėjimas nieko nedaro ir nerodo jokios klaidos. Mobiliosios PDF programos taip pat skiriasi tuo, ar atidaro nuorodas pačioje programoje, ar perduoda jas sisteminei naršyklei
Nei vieno iš šių atvejų nėra klaida, kurią galėtumėte ištaisyti generavimo pusėje; tai yra peržiūros programų politikos sprendimai. Ką galite padaryti, tai sukurti nuorodų etiketes taip, kad pats URL būtų matomas ir dokumento tekste – taip skaitytojas apribotoje aplinkoje vis tiek galės nukopijuoti adresą rankiniu būdu. Anotacija yra patogumas, o tekstas – atsarginis variantas
Dar viena detalė, kurią verta žinoti: PDF URI anotacijos pagal numatytuosius nustatymus neturi jokio vizualinio pabraukimo. Pabraukimas, kurį matote daugelyje peržiūros programų, yra nupiešiamas pačios peržiūros programos pagal anotacijos tipą, o ne pačiame turinio sraute. Jei jums reikia fizinio pabraukimo, kuris išliktų spausdinant neinteraktyviu atvaizdavimo įrengniu arba konvertuojant PDF į vaizdą, nupieškite jį patys naudodami LineTo ir Stroke su atitinkamu Y poslinkiu žemiau teksto bazinės linijos. Tai yra atskira braižymo operacija, kurios PrintHyperlink neatlieka už jus
Čia parodytas hipersaitų API yra HotPDF komponento dalis, skirta „Delphi“ ir „C++Builder“