THotPDF.AssignSyntheticCodepointForGID / GetSyntheticCodepointForGID

מקצה נקודות קוד סינתטיות של THotPDF PUA (v2.119.68)

GSUB Engine  Auto Shaping Pipeline  Arabic Shaping

מקצה ושאילת נקודות קוד סינתטיות של Private Use Area (U+E000 - U+F8FF) עבור גליפי תחליף OpenType GSUB שאין להם נקודת קוד יוניקוד טבעית הנגישה דרך ה-cmap של הגופן. סוגר את פער הפליטה ברמת ה-GID בצד היצרן שהושאר על ידי ממשקי ה-API של שאילתות ושיפורי GSUB של v2.119.43-66

תחביר Delphi:

function AssignSyntheticCodepointForGID(GID: Word; out SyntheticCP: Word): Boolean;

function GetSyntheticCodepointForGID(GID: Word): Word;

מדוע ה-API קיים

צינור העיצוב האוטומטי בצד היצרן v2.119.32-67 (ערבית / לטינית / Devanagari) דורש שגליפי תחליף GID המוחזרים על ידי מנוע ה-GSUB יהיו נגישים דרך נקודת קוד יוניקוד - צינור הטקסט הקיים המקודד בהקס פולט נקודות קוד, לא GID, וקורא הקצה פותר את נקודת הקוד בחזרה ל-GID דרך ה-/CIDToGIDMap המוטמע. עבור גליפי תחליף שיש להם נקודת קוד יוניקוד טבעית דרך ה-cmap של הגופן (צורות תצוגה בערבית, ליגטורות לטיניות סטנדרטיות FB00-FB06), הצינור הקיים עובד מצוין

אך תחליפים ספציפיים לגופן הנוחתים על גליפי GID פנימיים של הגופן - רוב צורות צבירי Devanagari, חלופות סגנוניות שמעצב הגופן מספק רק כגליפי GID ממוספרים, רצפי וריאציות אידיאוגרפיות של CJK (IVS), ליגטורות מיוחדות ללא צורת תצוגה מתאימה - אינם בעלי נקודת קוד כלל ב-cmap של הגופן. לפני v2.119.68 גליפי GID אלו לא היו נגישים דרך צינור ההקס בצד היצרן; גרסה v2.119.68 סוגרת פער זה על ידי מתן אפשרות לקוראים להקצות נקודת קוד סינתטית ב-Private Use Area עבור כל GID

סמנטיקה של AssignSyntheticCodepointForGID

מקצה את נקודת הקוד הבאה הפנויה ב-PUA (החל מ-U+E000) עבור ה-GID שסופק ומשקף את ההקצאה לכל מטמון שבו תלויים צינור ההקס הקיים בצד היצרן + שרשרת הפתרון של קורא הקצה:

1. FUnicodeCpToGid[SyntheticCP] := GID - כך שצינור ההקס בצד היצרן פולט את SyntheticCP לתוך אופרטור הצגת הטקסט וקורא הקצה פותר את SyntheticCP בחזרה ל-GID דרך /CIDToGIDMap בזמן הרינדור

2. FAcroFormUnicodeAdvances[SyntheticCP] := em-fraction - כך שמחשב יישור המילים v2.65 מוצא את התקדמות hmtx הנכונה עבור נקודת הקוד הסינתטית כשהיא מופיעה בתוכן שדה טקסט של AcroForm

3. FUnicodeSyntheticCpForGID[GID] := SyntheticCP - טבלת החיפוש ההפוך לכל GID המשמשת את GetSyntheticCodepointForGID כדי להפוך קריאות חוזרות של AssignSyntheticCodepointForGID לאידמפוטנטיות (הקריאה השנייה עם אותו GID מחזירה את ה-SyntheticCP שכבר הוקצה)

מחזיר True בהצלחה כאשר SyntheticCP מוגדר לנקודת הקוד שהוקצתה. מחזיר False (ומשאיר את SyntheticCP ב-0) תחת כל אחד מתנאי הגנה אלו: לא נרשם גופן (RegisterUnicodeTTF מעולם לא נקרא או נקרא עם ארגומנטים ריקים כדי לאפס מצב), GID לא חוקי (אפס או מעבר למספר הגליפים של ה-cmap), טווח ה-PUA הסתיים (כל 6400 החריצים U+E000 - U+F8FF הוקצו), המטמון לא אותחל בכניסה

סמנטיקה של GetSyntheticCodepointForGID

שאילתה פונקציונלית טהורה של כל הקצאה קיימת. מחזיר את נקודת הקוד הסינתטית שהוקצתה עבור GID אם AssignSyntheticCodepointForGID(GID, ...) נקרא בעבר; אחרת מחזיר 0 (שאינו נקודת קוד PUA חוקית, ולכן משמש גם כזקיף של 'אין הקצאה'). אינו מקצה. בטוח לקריאה לפני הרצת AssignSyntheticCodepointForGID כלשהי

מחזור חיים של מצב המקצה

FUnicodeSyntheticCpForGID וסמן ה-PUA הבא הפנוי (FUnicodeNextSyntheticCp) מוקצים בעצלתיים בקריאה הראשונה של AssignSyntheticCodepointForGID. הסמן מתחיל ב-0 (לא מאותחל) ומזנק ל-$E000 בהקצאה הראשונה; הקצאות הבאות מזיזות אותו דרך $E001, $E002, ..., $F8FF. שני השדות מאופסים לריק / 0 בכל קריאה של RegisterUnicodeTTF('', nil) יחד עם שאר מצב תת-הקבוצה לכל גופן, כך שקוראים העושים שימוש חוזר במופע THotPDF על פני מספר מסמכים מתחילים כל מסמך עם סמן PUA חדש

זרימת עבודה טיפוסית (צורת צביר Devanagari)

PDF.RegisterUnicodeTTF('NotoDeva', 'NotoSansDevanagari-Regular.ttf');

PDF.ShapingFeatures := [sfIndicShaping];

PDF.SetGSUBScript('deva');

// Get a font-internal cluster GID through the GSUB engine

ClusterGID := PDF.GetSingleSubstituteGlyph(BaseGID, 'nukt');

if ClusterGID <> BaseGID then

begin

// Check if cmap reaches the substitute - usually no for Indic

// clusters, since cluster GIDs are font-internal

// Allocate a synthetic codepoint that the producer-side

// hex pipeline can emit

if PDF.AssignSyntheticCodepointForGID(ClusterGID, SyntheticCP) then

begin

// SyntheticCP is now in the U+E000-F8FF range; emit it

// through UnicodeTextOut just like a normal codepoint

PDF.CurrentPage.UnicodeTextOut(X, Y, 0, UnicodeChar(SyntheticCP));

PDF.MarkUnicodeGlyphUsed(ClusterGID);

end;

end;

דוגמה לאידמפוטנטיות

PDF.AssignSyntheticCodepointForGID(150, CP1); // CP1 = $E000

PDF.AssignSyntheticCodepointForGID(151, CP2); // CP2 = $E001

PDF.AssignSyntheticCodepointForGID(150, CP3); // CP3 = $E000 (idempotent)

CP4 := PDF.GetSyntheticCodepointForGID(150); // CP4 = $E000

CP5 := PDF.GetSyntheticCodepointForGID(999); // CP5 = 0 (no assignment)

התנהגות קורא הקצה

קורא הקצה רואה את נקודת הקוד PUA באופרטור הצגת הטקסט ופותח אותה דרך ה-/CIDToGIDMap המוטמע במסמך ל-GID המטרה, ולאחר מכן מרנדר את ה-GID הזה באמצעות תוכנית הגופן המוטמעת. מנקודת המבט של הקורא אין הבדל בין נקודת קוד יוניקוד "טבעית" שה-cmap מנתב ל-GID לבין נקודת קוד סינתטית PUA ש-/CIDToGIDMap מנתב ל-GID - שתיהן מייצרות את אותו גליף מרונדר

התנהגות העתק/הדבק: נקודות קוד PUA חוזרות כעצמן דרך העתק/הדבק כאשר ה-ToUnicode CMap מצהיר עליהן כמיפויי זהות. קוראים שרוצים שתווי היוניקוד של המקור (ריצת הקלט שייצרה את התחליף) יחזרו במקום זאת, יכולים לרשום מיפוי הפוך עם RegisterToUnicodeReverseMapping או לכתוב מאפייני רצף תוכן מסומן ActualText דרך BeginTaggedContent ולפלוט את נקודות הקוד הסינתטיות בתוך התוכן שבסוגריים. HotPDF משתמש באותו דפוס CID פנימי באופן אוטומטי עבור זרמי מראה של AcroForm המגובים ב-RegisterUnicodeTTF ומכילים תווים של יוניקוד ממשטח משלים

Phase 8 roadmap closure

סגירת מפת הדרכים של שלב 8

ראה גם: