TPDFlibDynamicComponentSession

פריסת עמוד, עימוד, טיפוסי נתונים

תיאור

מרכיבה רכיב בעל מצב עמוד יעד אחד בכל פעם, מבלי לבנות מראש תוכן עבור עמודים מאוחרים יותר כל ניסיון רץ על עותק בתוך Form XObject מבודד ומאשר את העותק רק לאחר שהתוכן המאומת הוצב בהצלחה הצבה מורחבת יכולה לדחות גלישה, לחתוך תוכן בגודלו הטבעי או להקטין אותו באופן פרופורציונלי תוך יישורו בתוך משבצת יעד מדיניות העימוד יכולה לאפשר פיצול רגיל, לדחות את המקטע החלקי הראשון אל אזור טרי או לדרוש שהרכיב כולו יישאר גלוי לפני אישור דבר אילוצי מרחב זרימה יכולים לדחות אזור קצר לפני הפעלת הרכיב או לשמור גובה מספיק אחרי המקטע הסופי שלו עבור רכיב עוקב תוצאה שנדחתה, קריאת ציור שנכשלה או חריגה של callback מסירה את העמוד הזמני, משחזרת את העמוד שהקורא בחר ומשאירה את תוכן היעד ואת מצב הרכיב הנוכחי ללא שינוי מופע ה-

TPDFlib המחובר נותר בבעלות הקורא וחייב להתקיים מעבר להפעלה

הצהרה

const
  PDF_DYNAMIC_COMPONENT_ERROR = 0;
  PDF_DYNAMIC_COMPONENT_MORE = 1;
  PDF_DYNAMIC_COMPONENT_COMPLETE = 2;
  PDF_DYNAMIC_COMPONENT_RETRY = 3;

type
  TPDFlibDynamicPageContext = record
    LibraryInstance: TPDFlib;
    PageNumber: Integer;
    CompositionIndex: Integer;
    DestinationLeft: Double;
    DestinationTop: Double;
    AvailableWidth: Double;
    AvailableHeight: Double;
  end;

  TPDFlibDynamicPageResult = record
    HasContent: Boolean;
    HasMoreContent: Boolean;
    UsedWidth: Double;
    UsedHeight: Double;
  end;

  TPDFlibDynamicOverflowPolicy = (dopReject, dopClip, dopScaleDown);
  TPDFlibDynamicHorizontalAlignment = (dhaLeft, dhaCenter, dhaRight);
  TPDFlibDynamicVerticalAlignment = (dvaTop, dvaCenter, dvaBottom);
  TPDFlibDynamicPaginationPolicy = (dppAllowSplit, dppKeepTogether,
    dppRequireComplete);
  TPDFlibDynamicRetryReason = (drrNone, drrKeepTogether,
    drrRequireComplete, drrMinimumSlotHeight, drrMinimumFollowingHeight);

  TPDFlibDynamicLayoutOptions = record
    ContentWidth: Double;
    ContentHeight: Double;
    OverflowPolicy: TPDFlibDynamicOverflowPolicy;
    HorizontalAlignment: TPDFlibDynamicHorizontalAlignment;
    VerticalAlignment: TPDFlibDynamicVerticalAlignment;
    PaginationPolicy: TPDFlibDynamicPaginationPolicy;
    MinimumSlotHeight: Double;
    MinimumFollowingHeight: Double;
  end;

  TPDFlibDynamicPlacementTransform = record
    M11, M12, M21, M22, MDX, MDY: Double;
  end;

  TPDFlibDynamicPagePlacement = record
    PageNumber: Integer;
    CompositionIndex: Integer;
    Left: Double;
    Top: Double;
    Width: Double;
    Height: Double;
    HasContent: Boolean;
    HasMoreContent: Boolean;
    SourceWidth: Double;
    SourceHeight: Double;
    SlotLeft: Double;
    SlotTop: Double;
    SlotWidth: Double;
    SlotHeight: Double;
    Transform: TPDFlibDynamicPlacementTransform;
    WasClipped: Boolean;
    WasScaled: Boolean;
  end;

  TPDFlibDynamicComponent = class
  public
    function CloneComponent: TPDFlibDynamicComponent; virtual; abstract;
    function Compose(const Context: TPDFlibDynamicPageContext;
      out ComposeResult: TPDFlibDynamicPageResult): Integer; virtual; abstract;
  end;

  TPDFlibDynamicComponentSession = class
  private
    FLibrary: TPDFlib;
    FCompositionCount: Integer;
    FCompleted: Boolean;
    FKeepTogetherRetryPending: Boolean;
    FLastRetryReason: TPDFlibDynamicRetryReason;
    FLastRequiredSlotHeight: Double;
  public
    constructor Create(ALibrary: TPDFlib;
      AComponent: TPDFlibDynamicComponent);
    function AttachComponent(AComponent: TPDFlibDynamicComponent): Integer;
    function Reset: Integer;
    function CloneCurrentComponent: TPDFlibDynamicComponent;
    class function CreateLayoutOptions(ContentWidth, ContentHeight: Double;
      OverflowPolicy: TPDFlibDynamicOverflowPolicy = dopReject;
      HorizontalAlignment: TPDFlibDynamicHorizontalAlignment = dhaLeft;
      VerticalAlignment: TPDFlibDynamicVerticalAlignment = dvaTop;
      PaginationPolicy: TPDFlibDynamicPaginationPolicy = dppAllowSplit;
      MinimumSlotHeight: Double = 0;
      MinimumFollowingHeight: Double = 0):
      TPDFlibDynamicLayoutOptions; static;
    function ComposeNext(Page: Integer; Left, Top, Width, Height: Double;
      out Placement: TPDFlibDynamicPagePlacement): Integer;
    function ComposeNextLayout(Page: Integer; SlotLeft, SlotTop, SlotWidth,
      SlotHeight: Double; const Options: TPDFlibDynamicLayoutOptions;
      out Placement: TPDFlibDynamicPagePlacement): Integer;
    property LibraryInstance: TPDFlib read FLibrary;
    property CompositionCount: Integer read FCompositionCount;
    property Completed: Boolean read FCompleted;
    property KeepTogetherRetryPending: Boolean
      read FKeepTogetherRetryPending;
    property LastRetryReason: TPDFlibDynamicRetryReason read FLastRetryReason;
    property LastRequiredSlotHeight: Double read FLastRequiredSlotHeight;
  end;

חוזה הרכיב

שיטות

Createמחבר ספרייה בבעלות הקורא ומשכפל את הרכיב שסופק לתמונות מצב ראשוניות ונוכחיות בלתי תלויות
AttachComponentמחליף באופן אטומי את שתי תמונות המצב בעותקים של רכיב בבעלות הקורא ומנקה את מצב ההשלמה
Resetמשחזר עותק נוכחי חדש מתמונת המצב הראשונית ומאפס את מניין ההרכבות שהצליחו
CloneCurrentComponentמחזיר עותק בבעלות הקורא לבחינת מצב הרכיב הנוכחי שאושר
CreateLayoutOptionsבונה הגדרות מוקלדות של בד טבעי, גלישה, יישור, עימוד ומרחב זרימה עבור הצבה מורחבת
ComposeNextמרכיב משבצת עמוד אחת, מאמת ומציב את ה-Form XObject שלה, משחרר את מזהה הלכידה ומאשר את מצב העבודה
ComposeNextLayoutמרכיב על בד התוכן הטבעי המוגדר, מחיל מדיניות גלישה ויישור ומחזיר נתוני מקור, משבצת והתמרה סופית

גלישה והצבה

dopRejectדוחה תוכן רחב או גבוה מהמשבצת מבלי לשנות תוכן יעד או מצב רכיב שאושר
dopClipשומר על קנה מידה 1 ומצליב את נתיב החיתוך של העמוד עם משבצת היעד לפני הפעלת ה-Form XObject
dopScaleDownמשתמש ביחס הרוחב או הגובה הקטן יותר רק לפי הצורך ולעולם אינו מגדיל תוכן

היישור נפתר מהמלבן בשימוש המותמר, כך שתוכן ממורכז או חתוך-סופי בוחר את החלק הגלוי המתאים

Transform[M11 M12 M21 M22 MDX MDY]

SlotLeft מדווח על מטריצת הפריסה הלוגית SlotTop מקואורדינטות מקומיות של הרכיב אל קואורדינטות המסמך הסופיות מלמעלה למטה SlotWidth, SlotHeight,

מדיניות עימוד

dppAllowSplitמשמר את התנהגות ברירת המחדל ומאשר כל מקטע תקף שה-callback שלו מדווח על תוכן נוסף
dppKeepTogetherמחזיר PDF_DYNAMIC_COMPONENT_RETRY עבור הניסיון הראשון החלקי או שאינו גלוי, ואז מתיר פיצול או את החלופה הנבחרת לחיתוך בניסיון התקף הבא עבור אותו מקטע שלא אושר
dppRequireCompleteמחזיר PDF_DYNAMIC_COMPONENT_RETRY עד שה-callback מדווח שלא נותר תוכן והמלבן בשימוש המלא נכנס למשבצת או נשאר גלוי באמצעות הקטנה פרופורציונלית

Placement

KeepTogetherRetryPending ריקה Reset מזהה את מצב החלופה החד-פעמי ומתנקה לאחר אישור מוצלח, AttachComponent או

אילוצי מרחב הזרימה

MinimumSlotHeightמחזיר PDF_DYNAMIC_COMPONENT_RETRY לפני שכפול או הפעלת הרכיב כאשר משבצת היעד קצרה מהגובה המוגדר
MinimumFollowingHeightחל רק על מקטע תוכן סופי ודורש שגובהו הנפתר בתוספת הגובה השמור לעוקבים ייכנס למשבצת

ניסיון חוזר של גובה עוקב משליך את הניסיון המבודד תוך שמירה על מקטעים שאושרו קודם לכן, ומאפשר לכותרת, לתווית או לפתיח קצר לנוע עם האזור השמיש הראשון של הרכיב הבא

LastRetryReason מבחין בין ניסיונות חוזרים של רכיב שלם, השלמה מחמירה, משבצת מזערית ומרחב עוקב, בעוד LastRequiredSlotHeight מדווח על הגובה הנדרש הידוע עבור אילוצי מרחב זרימה בדיקת המשבצת המזערית רצה לפני שכפול הרכיב ולכידת ה-Form, כך שאזורים קצרים הנדחים שוב ושוב אינם גוררים עלות callback של רכיב או עמוד זמני

ערכים מוחזרים

PDF_DYNAMIC_COMPONENT_ERRORהבקשה, ה-callback של הרכיב, הגיאומטריה של התוצאה או הצבת ה-Form נכשלו ולא נשמר שום מצב
PDF_DYNAMIC_COMPONENT_MOREהתוכן אושר והרכיב ביקש משבצת עמוד נוספת
PDF_DYNAMIC_COMPONENT_COMPLETEהרכיב השלים, או שההפעלה כבר הושלמה ולא בוצע callback
PDF_DYNAMIC_COMPONENT_RETRYמדיניות העימוד או מרחב הזרימה הנבחרת דחתה את ההצבה מבלי לאשר תוכן או מצב

דוגמה

type
  TNumberedPagesComponent = class(TPDFlibDynamicComponent)
  private
    FNextPage: Integer;
    FPageCount: Integer;
  public
    constructor Create(ANextPage, APageCount: Integer);
    function CloneComponent: TPDFlibDynamicComponent; override;
    function Compose(const Context: TPDFlibDynamicPageContext;
      out ComposeResult: TPDFlibDynamicPageResult): Integer; override;
  end;

constructor TNumberedPagesComponent.Create(ANextPage, APageCount: Integer);
begin
  inherited Create;
  FNextPage := ANextPage;
  FPageCount := APageCount;
end;

function TNumberedPagesComponent.CloneComponent: TPDFlibDynamicComponent;
begin
  Result := TNumberedPagesComponent.Create(FNextPage, FPageCount);
end;

function TNumberedPagesComponent.Compose(
  const Context: TPDFlibDynamicPageContext;
  out ComposeResult: TPDFlibDynamicPageResult): Integer;
begin
  Context.LibraryInstance.DrawText(0, 0, IntToStr(FNextPage));
  Inc(FNextPage);
  ComposeResult.HasContent := True;
  ComposeResult.HasMoreContent := FNextPage <= FPageCount;
  ComposeResult.UsedWidth := Context.AvailableWidth;
  ComposeResult.UsedHeight := 24;
  Result := 1;
end;

Template := TNumberedPagesComponent.Create(1, 10);
try
  Session := TPDFlibDynamicComponentSession.Create(PDF, Template);
  try
    repeat
      Status := Session.ComposeNext(PageNumber, 36, 36, 540, 720,
        Placement);
      if Status = PDF_DYNAMIC_COMPONENT_MORE then
        PageNumber := PDF.NewPage;
    until Status <> PDF_DYNAMIC_COMPONENT_MORE;
  finally
    Session.Free;
  end;
finally
  Template.Free;
end;

ראה גם

BeginFormXObject, ReleaseCapturedPage, ApplyRepeatedPageFragment