Műszaki cikk

HotPDF Delphi hiperhivatkozások: PrintHyperlink annotációs tippek

A PDF hiperhivatkozások URI annotációk: egy téglalap, amely lefed egy oldalrészt, és amelyre kattintva a nézegető megnyit egy URL-t. Az annotáció és az alatta lévő szöveg teljesen független objektumok. A HotPDF PrintHyperlink-je mindkettőt egyetlen hívásba csomagolja, megrajzolja a szöveget, és a renderelt szöveg metrikáiból kiszámítja az annotáció téglalapját. Ez a kényelem elrejt egy részletet, amelyet érdemes megérteni, mielőtt éles kódot írnál

Hogyan működik a PrintHyperlink

A PrintHyperlink a THPDFPage-en él, és négy argumentumot vesz fel: X és Y koordinátákat (pontokban, bal alsó origó, az Y felfelé növekszik), a megrajzolandó címke karakterláncát és az URL célt. Belsőleg meghívja a TextOut-ot az aktuális hiperhivatkozás színével, majd azonnal kiszámítja az annotáció téglalapját a TextWidth és TextHeight alapján az aktuális betűtípus metrikáival. Ez azt jelenti, hogy a betűtípust és a méretet a hívás előtt be kell állítani, és nem változhatnak a címke megrajzolása és az annotáció elhelyezése között, mivel mindkettő ugyanabban a hívásban oldódik fel

Az alapértelmezett szín a clBlue. A SetRGBHyperlinkColor csak a későbbi hívásokra változtatja meg; nem frissíti visszamenőleg a már megírt annotációkat. Ha különböző színekre van szükséged a különböző hivatkozási csoportokhoz ugyanazon az oldalon, hívd meg a SetRGBHyperlinkColor-t minden csoport előtt, és utána állítsd vissza

Íme egy minimális dokumentum, amely három hivatkozást ír ki két különböző színnel:

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;

A koordináta csapda

A HotPDF bal alsó origót használ, az Y felfelé növekszik pontokban (1/72 hüvelyk). Egy A4-es oldal 595 x 842 pt; egy US Letter oldal 612 x 792 pt. Az Y=750 egy A4-es oldal tetejéhez közel helyezkedik el, az Y=50 pedig az alsó margóhoz lenne közel. Bárki, aki képernyőgrafikából vagy HTML-ből érkezik, ennek az ellenkezőjét feltételezi, és az első hivatkozási sort egyenesen a látható területen kívülre helyezi

Az annotációs téglalap, amelyet a PrintHyperlink kiszámít, ugyanezt a koordinátarendszert használja. Ha később elforgatod az oldalt, átméretezed, vagy módosítod az oldalméretet anélkül, hogy újraszámolnád az X/Y értékeket, a látható szöveg és a kattintható téglalap elsodródik egymástól. A hivatkozás "működik" abban az értelemben, hogy a szöveg közelében valahova kattintva elindul az URL, de a forró zóna már nem egyezik azzal, amit az olvasó lát. Tesztelj a tényleges oldalméreten és az általad szállított nagyítási szinten, ne csak a fejlesztői gépen 100%-on

Egy olyan eset, amikor az elsodródás garantált: ha a PrintHyperlink-et egy A4-es oldalhoz megfelelő koordinátákkal hívod meg, majd átváltasz egy egyéni, keskeny formátumú oldalra anélkül, hogy beállítanád az X/Y értékeket, az annotáció teljesen lekerülhet az oldalról. Az annotációs objektum továbbra is be van írva a PDF-be; a legtöbb nézegető csendben levágja, így a hivatkozás egyszerűen eltűnik mindenféle hiba nélkül

Címkeszöveg kontra URL cél

A Text és a Link argumentumok függetlenek. Rajzolhatsz egy "Számla PDF letöltése" szöveget, miközben a cél egy teljesen minősített HTTPS URL lekérdezési paraméterekkel. Ez a szétválasztás szándékos; a látható címkének ember által olvashatónak kell lennie, az URL pedig lehet hosszú vagy dinamikusan generált

Ami problémákat okoz, az az, amikor a címke maga a nyers URL, különösen, ha az hosszú. Ha az URL vizuálisan két sorba törik át, de az annotációs téglalapot egysoros karakterláncra számították ki, csak az első sor lesz kattintható. A PrintHyperlink nem kezeli a többsoros folyamot; tartsd a címkét elég rövidnek ahhoz, hogy az aktuális betűméretnél és oldalszélességnél elférjen egy sorban, vagy használj egy rövid leíró címkét a teljes URL-lel mint céllal

Azoknál a dokumentumoknál, amelyeket archiválnak vagy aktív internetkapcsolat nélkül terjesztenek, azt is fontold meg, hogy maga az URL nyomtatott formában jelenjen-e meg valahol a dokumentum törzsében, ne csak annotációs metaadatként. A PDF-et papírra nyomtató olvasó semmit sem kap egy URI annotációból

Egy teljes dokumentumgenerálási példa

Az alábbi minta egy reálisabb forgatókönyvet mutat: egy rövid jelentés generálása fejléccel, törzsszöveggel és egy láblécsorral, amely hivatkozásokat tartalmaz, mindezt kódból, nem pedig TEdit mezőkkel ellátott űrlapból:

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;

Vedd figyelembe, hogy a SetFont minden szöveghívási csoport előtt meghívásra kerül. A betűtípus nem marad meg az AddPage-en keresztül, és ha elfelejted beállítani a PrintHyperlink előtt egy új oldalon, az annotáció téglalapja az oldal alapértelmezett metrikái alapján lesz kiszámítva, ami eltérhet attól, amit elvársz

Ahol az annotációkezelés eltér a nézegetők között

A PDF URI annotációkat az ISO 32000-1 §12.6.4.7 definiálja, és minden megfelelő nézegetőnek követnie kellene őket. A gyakorlatban néhány viselkedés eltér a nézegetők között. Az Adobe Acrobat biztonsági figyelmeztetést jelenít meg az első kattintáskor azoknál az URL-eknél, amelyek nincsenek a megbízható tartományok listáján; sok böngésző és könnyűsúlyú olvasó nem. Egyes vállalati PDF nézegetők a zárolt környezetekben irányelvek alapján teljesen letiltják az URI annotációkat, így a kattintás semmit sem tesz, látható hiba nélkül. A mobil PDF alkalmazások eltérnek abban, hogy a hivatkozásokat az alkalmazás webes nézetében nyitják-e meg, vagy átadják a rendszerböngészőnek

Ezek egyike sem olyan hiba, amelyet a generálási oldalról kijavíthatsz; ezek a nézegetők irányelvi döntései. Amit tehetsz, hogy olyan hivatkozási címkéket írsz, amelyek az URL-t láthatóvá teszik a dokumentum törzsében is, így a korlátozott környezetben lévő olvasó manuálisan továbbra is átmásolhatja a címet. Az annotáció a kényelem; a szöveg a tartalék

Még egy további részlet, amit érdemes tudni: a PDF URI annotációk alapértelmezés szerint nem hordoznak semmilyen vizuális aláhúzást. Az aláhúzást, amelyet a legtöbb nézegetőben látsz, maga a nézegető rajzolja meg az annotáció típusa alapján, nem pedig egy glifa a tartalomfolyamban. Ha olyan fizikai aláhúzásra van szükséged, amely túléli a nyomtatást egy nem interaktív renderelőre vagy a PDF-ből képpé konvertálást, rajzold meg kifejezetten a LineTo és Stroke használatával a megfelelő Y eltolásnál a szöveg alapvonala alatt. Ez egy különálló rajzolási művelet, nem pedig olyan dolog, amit a PrintHyperlink elintéz helyetted

Az itt bemutatott hiperhivatkozás API a Delphihez és C++Builderhez készült HotPDF komponens része

A frissített útmutató lefedi a PrintHyperlink koordináta-csapdáját, a címkeszöveg és URL szétválasztását, az AddURILink és AddGoToLink használatát, valamint a nézegetők eltérő annotációkezelését