PDF אינו פורמט מסמך באותו אופן כמו Word או RTF. פורמטים אלה שומרים רצף של תוכן שמרונדר (renderer) מפרש ברגע התצוגה, כך שהפלט תלוי בגופנים ובמנוע הפריסה שבמקרה נוכחים. PDF שומר את התוצאה של תהליך זה: הוראות רינדור מדויקות, תוכניות גופנים, זרמי תמונות דחוסים, וגרף אובייקטים שקושר אותם יחד לתיאור עצמאי של כל עמוד. הקובץ נושא מספיק מידע כדי לשחזר כל עמוד באופן זהה על כל מרונדר תואם, וזוהי גם מטרת העיצוב העיקרית שלו וגם המקור לרוב המורכבות שאתה נתקל בה כשאתה מנסה לייצר, לנתח, או לשנות אחד באופן תכנותי
מודל האובייקטים
כל PDF הוא אוסף של אובייקטים ממוספרים. אובייקט יכול להיות בוליאני, שלם, מספר ממשי, שם, מחרוזת, מערך, מילון, זרם או null. כמעט כל דבר מעניין הוא מילון, שהוא אוסף של זוגות מפתח-ערך שבהם המפתחות הם שמות והערכים הם כל סוג אובייקט אחר, כולל הפניות לאובייקטים אחרים לפי מספר וספירת דור. זרם (stream) הוא מילון שאחריו מגיע רצף בתים, לרוב דחוס
מילון הקטלוג הוא השורש. הוא מצביע לעץ העמודים, המארגן את מילוני העמודים במבנה עץ מאוזן במקום ברשימה שטוחה, כך שניווט לעמוד 5,000 במסמך של 10,000 עמודים אינו דורש חצייה של כל מתאר-עמוד קודם. כל מילון עמוד מפנה לזרמי התוכן שלו (רצף אחד או יותר של אופרטורים לתיאור-עמוד), למילון המשאבים שלו (אשר בתורו מפנה למתארי גופנים, מרחבי צבע ו-XObjects של תמונות), ולתיבת המדיה שלו (מרחב הקואורדינטות שבו העמוד חי). מקור הקואורדינטות נמצא בפינה השמאלית-תחתונה, עם Y חיובי כלפי מעלה, ביחידות של 1/72 אינץ'
בסוף הקובץ יושבת טבלת ההצלבה (cross-reference table), הממפה כל מספר אובייקט להיסט הבתים שלו בקובץ. זה מה שמאפשר גישה אקראית: קורא קורא תחילה את טבלת ההצלבה, ואז מדלג ישירות לכל האובייקטים שהוא צריך. PDF 1.5 הציג זרמי הצלבה, הדוחסים את הטבלה לאובייקט זרם ואורזים אובייקטים קשורים לתוך זרמי אובייקטים, מה שמפחית את גודל הקובץ במידה ניכרת עבור מסמכים עם הרבה אובייקטים קטנים
זרמי תוכן ומודל הגרפיקה
התוכן החזותי של עמוד חי בזרם תוכן אחד או יותר. כל זרם הוא רצף של אופרטורי PDF שביניהם משובצים האופרנדים שלהם. אופרטור הטקסט BT מתחיל אובייקט טקסט, Tf בוחר גופן וגודל ממילון המשאבים, Td ממקם את סמן הטקסט, Tj או TJ מצייר מחרוזת, ו-ET סוגר את אובייקט הטקסט. גרפיקה וקטורית עוקבת אחר דפוס דומה: m קובע נקודת התחלה של נתיב, l מוסיף מקטע קו, c מוסיף עקומת בזייה, ו-f או S ממלא או משרטט את הנתיב
המצב הגרפי שולט בכל מה שקורה בין האופרטורים: מטריצת טרנספורמציה נוכחית, עובי קו, מרחב צבע, צבע מילוי, צבע מסגרת ונתיב החיתוך (clipping path). אופרטורים כמו q ו-Q דוחפים ומושכים (push and pop) את המצב הגרפי למחסנית, וכך PDF מיישם טרנספורמציות קואורדינטות מקומיות ודריסות מצב זמניות מבלי להשפיע על ההקשר שסביבן. Form XObjects מכלילים זאת: זרם תוכן עצמאי עם מילון משאבים משלו שניתן לצייר על עמוד במיקומים ובקנה מידה שרירותיים עם אופרטור Do בודד
הטמעת גופנים וחילוץ טקסט
PDF יכול להתייחס לגופנים בשם ולהסתמך על הקורא שיחליף משהו, אך בפועל כל מסמך שאתה מתכוון לשתף חייב להטמיע את נתוני הגופן. גופן מסוג Type 1 או TrueType/OpenType המוטמע ב-PDF נושא מילון מתאר גופן המצביע לזרם קובץ גופן. עבור גופני TrueType, הזרם הזה מכיל את תוכנית הגופן הבינארית; עבור Type 1, אלו נתוני PFB. יצירת תת-קבוצה (Subsetting), שזה מה שכל מחולל PDF רציני עושה, מסירה גליפים שאינם מוזכרים במסמך, ושומרת על גדלי קבצים הניתנים לניהול גם עבור גופני Unicode גדולים
חילוץ טקסט הוא המקום שבו הטמעת גופנים חוזרת לנשוך. הייצוג החזותי של תו נקבע על ידי גליף בתוכנית הגופן המוטמעת. ערך ה-Unicode של תו זה נקבע על ידי זרם ToUnicode CMap המחובר למילון הגופנים. כאשר ה-ToUnicode CMap חסר או שגוי, קורא PDF יכול לרנדר טקסט בצורה קריאה אך אינו יכול לחלץ אותו כ-Unicode בעל משמעות, וזו הסיבה שהעתק-הדבק מכמה קובצי PDF מייצר זבל. PDF מתויג (Tagged PDF, לפי ISO 32000 §14.8) מוסיף שכבה שנייה: עץ מבנה לוגי הממפה תוכן עמוד לתפקידים סמנטיים במסמך כמו פסקאות, כותרות ותאי טבלה. קוראי מסך ומנועי הזרמה-מחדש (reflow) משתמשים בעץ המבנה במקום בסדר זרם התוכן הגולמי, מה שמסביר מדוע PDF המעוצב היטב מבחינה חזותית יכול עדיין להיות בלתי נגיש אם התיוג חסר או שגוי
עדכונים מצטברים וחתימות דיגיטליות
כאשר אתה שומר שינויים ב-PDF קיים מבלי לשכתב אותו מאפס, האובייקטים החדשים מצורפים לאחר גוף הקובץ המקורי יחד עם קטע הצלבה חדש ומילון trailer חדש. ה-trailer המעודכן מצביע לנתוני ההצלבה החדשים, ואובייקטים שהוחלפו נשארים בקובץ אך פשוט אינם מוזכרים בשרשרת ההצלבה החדשה. זהו עדכון מצטבר, ויש לו שתי השלכות משמעותיות
ראשית, הקובץ גדל בכל מחזור שמירה. מסמך שנערך ונשמר שוב ושוב צובר שכבות של אובייקטים מיושנים. כלים כמו QPDF יכולים ללינאריז (linearize) או לדחוס-ולשכתב קובץ כדי להשיב מקום זה, אך ברירת המחדל היא צבירה. שנית, חתימות דיגיטליות מסתמכות על עדכונים מצטברים עבור מודל השלמות שלהן. חתימת ISO 32000 מכסה טווח בתים של הקובץ, בדרך כלל הכל פרט למציין המיקום של ערך החתימה עצמו. כל שינויים לאחר-החתימה המופיעים כעדכונים מצטברים נוספים גלויים לקורא מאמת כשינויים שבוצעו לאחר החתימה, וזה בדיוק נתיב הביקורת (audit trail) שאתה רוצה. עם זאת, המשמעות היא גם ששינויים מסוימים, כגון הוספת חתימת אישור או מילוי שדות טופס, מותרים במפורש על ידי התקן מבלי לפסול את החתימה המקורית, ובתנאי שהשינויים תואמים להגדרות ההרשאה של המסמך (ISO 32000-2 §12.7.6). שינוי שחורג מהרשאות אלו מסומן כבלתי מורשה. הבנת ההבחנה הזו נכון חשובה כשאתה מייצר מסמכים שיחתמו עליהם חתימת-קיום (countersigned) בהמשך התהליך
רמות תאימות ומורשת ISO 32000
PDF התחיל כפורמט קנייני של Adobe בשנת 1993, ספג את מודל ההדמיה של PostScript, ולאורך חמש-עשרה גרסאות צבר תכונות: הצפנה ב-1.1, טפסים אינטראקטיביים ב-1.2, חתימות דיגיטליות ומבנה לוגי ב-1.3, שקיפות ב-1.4, זרמי אובייקטים ב-1.5, הצפנת AES ב-1.6. אדובי הגישה את PDF 1.7 ל-ISO ב-2007, והתוצאה הייתה ISO 32000-1:2008. תקן ISO 32000-2:2020 מכסה את PDF 2.0, אשר הידק מספר תחומים שלא הוגדרו מספיק, תיקן את גזירת מפתח ה-AES-256 (גרסה 6 מחליפה את גרסה 5), והוסיף תמיכה מפורשת בקבצים משויכים ומדיה עשירה
תתי-התקנים נגזרים מאותו בסיס. PDF/A (ISO 19005) מוותר על תכונות לטובת יציבות ארכיונית: ללא הצפנה, ללא תלויות תוכן חיצוניות, כל הגופנים מוטמעים, מרחבי צבע בלתי תלויים-במכשיר, מטא-נתוני XMP נדרשים. PDF/A-1 מבוסס על PDF 1.4, PDF/A-2 על PDF 1.7, ו-PDF/A-3 מאפשר קבצים מוטמעים בכל פורמט. PDF/X (ISO 15930) הוא תת-הקבוצה להפקת דפוס: מטרות פלט (output intents), תיבות גלישה וגזירה (bleed and trim boxes), וללא שקיפות ברמות תאימות ישנות יותר. PDF/UA (ISO 14289) מחייב מבנה מתויג, מיפויי Unicode, ומטא-נתוני שפה לנגישות. אלו אינם פורמטים מתחרים; הם סטים של אילוצים נוספים על גבי PDF הליבה, וקובץ יחיד יכול להתאים ליותר מאחד בו-זמנית בתנאי שהאילוצים אינם מתנגשים
עבור כל מי שכותב קוד המייצר או מעבד PDF, נקודת הבסיס המעשית היא ISO 32000-2 תוך שימת לב קפדנית לסעיפים המכסים את מודל ההצלבה (§7.5), המצב הגרפי (§8.4), אופרטורי מצב טקסט (§9.3), מתארי גופנים ו-ToUnicode (§9.6 ו-§9.10), טפסים אינטראקטיביים (§12.7) וחתימות דיגיטליות (§12.8). התקן ארוך, אבל רוב העבודה התכנותית עם PDF נוגעת בנתח צר שלו שוב ושוב. הבנת מודל האובייקטים ומנגנון ההצלבה היא נקודת הכניסה; כל השאר הוא התמחות משם ואילך