היפר-קישורים ב-PDF הם הערות URI: מלבן המכסה אזור מסוים בעמוד שבעת לחיצה עליו, אומר לצופה לפתוח כתובת URL. ההערה והטקסט שמתחתיה הם אובייקטים בלתי תלויים לחלוטין. ה-PrintHyperlink של HotPDF מאגד את שניהם לקריאה אחת, תוך ציור הטקסט וחישוב מלבן ההערה ממדדי הטקסט שעובד. נוחות זו מסתירה פרט ששווה להבין לפני שאתה כותב קוד ייצור
כיצד PrintHyperlink עובד
PrintHyperlink יושב על THPDFPage ולוקח ארבעה ארגומנטים: קואורדינטות X ו-Y (בנקודות, מקור שמאלי תחתון, Y עולה כלפי מעלה), מחרוזת התווית לציור ויעד ה-URL. פנימית הוא קורא ל-TextOut בצבע ההיפר-קישור הנוכחי, ואז מיד מחשב את מלבן ההערה מ-TextWidth ו-TextHeight במדדי הגופן הנוכחיים. המשמעות היא שיש להגדיר את הגופן והגודל לפני הקריאה, ואסור להם להשתנות בין ציור התווית להצבת ההערה, מכיוון ששניהם נפתרים באותה קריאה
צבע ברירת המחדל הוא clBlue. ה-SetRGBHyperlinkColor משנה אותו עבור קריאות עוקבות בלבד; הוא אינו מעדכן רטרואקטיבית הערות שכבר נכתבו. אם אתה זקוק לצבעים שונים עבור קבוצות קישורים שונות באותו עמוד, קרא ל-SetRGBHyperlinkColor לפני כל קבוצה ואפס אותו לאחר מכן
להלן מסמך מינימלי שכותב שלושה קישורים עם שני צבעים שונים:
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;
מלכודת הקואורדינטות
HotPDF משתמש במקור שמאלי תחתון עם Y שגדל כלפי מעלה, בנקודות (1/72 אינץ'). עמוד A4 הוא 595 x 842 נקודות; עמוד US Letter הוא 612 x 792 נקודות. Y=750 יושב קרוב לראש עמוד A4, ו-Y=50 יהיה קרוב לשוליים התחתונים. כל מי שמגיע מגרפיקת מסך או מ-HTML מניח את ההיפך וממקם את שורת הקישור הראשונה הישר מחוץ לאזור הגלוי
מלבן ההערה ש-PrintHyperlink מחשב משתמש באותה מערכת קואורדינטות. אם בשלב מאוחר יותר תסובב את העמוד, תשנה את קנה המידה שלו, או תשנה את גודל העמוד מבלי לחשב מחדש את ערכי ה-X/Y שלך, הטקסט הגלוי והמלבן הלחיץ יתרחקו זה מזה. הקישור "עובד" במובן שלחיצה איפשהו ליד הטקסט מפעילה את ה-URL, אך האזור החם כבר אינו תואם למה שהקורא רואה. בדוק על גודל העמוד ורמת הזום האמיתיים שאתה שולח, לא רק על מכונת הפיתוח ב-100%
מקרה אחד שבו הסחיפה מובטחת: אם אתה קורא ל-PrintHyperlink עם קואורדינטות המתאימות לעמוד A4 ואז עובר לעמוד מותאם אישית בפורמט צר מבלי להתאים את ערכי ה-X/Y, ההערה יכולה להסתיים מחוץ לעמוד לחלוטין. אובייקט ההערה עדיין נכתב לתוך ה-PDF; רוב הצופים חותכים אותו בשקט, כך שהקישור פשוט נעלם ללא כל שגיאה
טקסט התווית מול יעד ה-URL
הארגומנטים של Text ו-Link הם בלתי תלויים. אתה יכול לצייר "Download invoice PDF" בעוד שהיעד הוא URL מסוג HTTPS מוסמך במלואו עם פרמטרי שאילתה. הפרדה זו היא מכוונת; התווית הגלויה צריכה להיות קריאה לאדם וה-URL יכול להיות ארוך או מיוצר דינמית
מה שיוצר בעיות הוא כאשר התווית היא ה-URL הגולמי עצמו, במיוחד אם הוא ארוך. אם ה-URL עוטף ויזואלית על פני שתי שורות אך מלבן ההערה חושב עבור מחרוזת של שורה אחת, רק השורה הראשונה תהיה לחיצה. PrintHyperlink אינו מטפל בזרימה מרובת שורות; שמור על תווית קצרה מספיק כדי להתאים לשורה אחת בגודל הגופן ורוחב העמוד הנוכחיים, או השתמש בתווית תיאורית קצרה עם ה-URL המלא כיעד
עבור מסמכים שיישמרו בארכיון או יופצו ללא חיבור אינטרנט פעיל, שקול גם האם ה-URL עצמו צריך להופיע בצורה מודפסת איפשהו בגוף המסמך, ולא רק כמטא-נתונים של הערה. קורא שמדפיס את ה-PDF על נייר אינו מקבל דבר מהערת URI
דוגמה מלאה להפקת מסמך
התבנית שלהלן מציגה תרחיש מציאותי יותר: יצירת דוח קצר עם קטע כותרת עליונה, טקסט גוף, ושורת קישורים בתחתית, הכל מקוד במקום מטופס עם שדות 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;
שים לב שנקראת פונקציית SetFont לפני כל קבוצה של קריאות טקסט. הגופן אינו נשמר לרוחב AddPage, ואם תשכח להגדיר אותו לפני PrintHyperlink בעמוד חדש, מלבן ההערה יחושב כנגד המדדים שיהיו מדדי ברירת המחדל של העמוד, אשר עשויים להיות שונים ממה שציפית
היכן הטיפול בהערות משתנה בין צופים (viewers)
הערות URI ב-PDF מוגדרות בתקן ISO 32000-1 סעיף 12.6.4.7, וכל צופה שעומד בתקן אמור לפעול לפיהן. בפועל, מספר התנהגויות נבדלות בין צופים. Adobe Acrobat מציג הנחיית אבטחה בלחיצה ראשונה עבור כתובות URL שאינן ברשימת הדומיינים המהימנים; דפדפנים וצופים קלי משקל רבים אינם עושים זאת. כמה צופי PDF ארגוניים בסביבות נעולות משביתים הערות URI לחלוטין על פי מדיניות, כך שלחיצה לא עושה דבר, ללא שגיאה גלויה. אפליקציות PDF לנייד משתנות בשאלה האם הן פותחות קישורים בתוך תצוגת האינטרנט של האפליקציה או מעבירות לדפדפן המערכת
אף אחד מאלה אינם באגים שניתן לתקן מצד היצירה; אלו החלטות מדיניות של הצופה. מה שאתה יכול לעשות הוא לכתוב תוויות קישור שהופכות את ה-URL לגלוי גם בגוף המסמך, כך שקורא בסביבה מוגבלת עדיין יוכל להעתיק את הכתובת ידנית. ההערה היא הנוחות; הטקסט הוא הגיבוי
פרט נוסף ששווה לדעת: הערות URI ב-PDF אינן נושאות קו תחתון ויזואלי כברירת מחדל. הקו התחתון שאתה רואה ברוב הצופים מצויר על ידי הצופה עצמו בהתבסס על סוג ההערה, ולא על ידי גליף בזרם התוכן. אם אתה זקוק לקו תחתון פיזי ששורד הדפסה למעבד (renderer) לא אינטראקטיבי או להמרה של PDF לתמונה, צייר אותו במפורש עם LineTo ו-Stroke בהיסט ה-Y המתאים מתחת לקו הבסיס של הטקסט. זוהי פעולת ציור נפרדת, לא משהו ש-PrintHyperlink מטפל בו עבורך
ממשק ה-API של ההיפר-קישורים המוצג כאן הוא חלק מרכיב ה-HotPDF עבור Delphi ו-C++Builder