TPDFlibDynamicComponentSession

เลย์เอาต์หน้า, การแบ่งหน้า, ชนิดข้อมูล

คำอธิบาย

จัดองค์ประกอบคอมโพเนนต์ที่มีสถานะทีละหน้าปลายทาง โดยไม่สร้างเนื้อหาของหน้าถัด ๆ ไปล่วงหน้า ความพยายามแต่ละครั้งทำงานบนโคลนภายใน Form XObject แบบแยกส่วน และยืนยันโคลนก็ต่อเมื่อเนื้อหาที่ผ่านการตรวจถูกวางสำเร็จ การวางแบบขยายสามารถปฏิเสธการล้น, ตัดเนื้อหาขนาดธรรมชาติ หรือย่อลงตามสัดส่วน ขณะจัดแนวไว้ในช่องปลายทาง นโยบายการจัดหน้าสามารถอนุญาตให้แบ่งตามปกติ, เลื่อนชิ้นส่วนบางส่วนแรกไปยังภูมิภาคใหม่ หรือบังคับให้คอมโพเนนต์ทั้งหมดต้องมองเห็นได้ก่อนยืนยันอะไร ข้อจำกัดพื้นที่ขั้นตอนสามารถปฏิเสธภูมิภาคสั้นก่อนเรียกคอมโพเนนต์ หรือสงวนความสูงพอหลังชิ้นส่วนสุดท้ายของมัน ไว้ให้คอมโพเนนต์ถัดไป ผลลัพธ์ที่ถูกปฏิเสธ, การเรียกวาดที่ล้มเหลว หรือข้อยกเว้นจากคอลแบ็ก จะลบหน้าชั่วคราว, คืนหน้าที่ผู้เรียกเลือกไว้ และทิ้งเนื้อหาปลายทางและสถานะคอมโพเนนต์ปัจจุบันไว้เหมือนเดิม อินสแตนซ์

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คงพฤติกรรมเริ่มต้นไว้ และยืนยันชิ้นส่วนที่ถูกต้องใด ๆ ที่คอลแบ็กรายงานว่ายังมีเนื้อหาต่อ
dppKeepTogetherคืน PDF_DYNAMIC_COMPONENT_RETRY สำหรับความพยายามบางส่วนหรือไม่มองเห็นครั้งแรก แล้วจึงอนุญาตให้แบ่งหรือใช้ทางเลือกตัดตามที่เลือก ในความพยายามที่ถูกต้องถัดไปของชิ้นส่วนเดิมที่ยังไม่ยืนยัน
dppRequireCompleteคืน PDF_DYNAMIC_COMPONENT_RETRY จนกว่าคอลแบ็กรายงานว่าไม่เหลือเนื้อหา และสี่เหลี่ยมที่ใช้ทั้งหมดพอดีช่องหรือยังมองเห็นได้ครบผ่านการย่อตามสัดส่วน

Placement

KeepTogetherRetryPending ที่ว่างเปล่า Reset ระบุสถานะทางเลือกสำรองแบบใช้ครั้งเดียว และถูกล้างหลังการยืนยันสำเร็จ, AttachComponent หรือ

ข้อจำกัดของพื้นที่ไหล

MinimumSlotHeightคืน PDF_DYNAMIC_COMPONENT_RETRY ก่อนโคลนหรือเรียกคอมโพเนนต์ เมื่อช่องปลายทางสั้นกว่าความสูงที่ตั้งค่าไว้
MinimumFollowingHeightมีผลเฉพาะชิ้นส่วนเนื้อหาสุดท้าย และกำหนดให้ความสูงที่แก้ไขแล้วของมันบวกความสูงที่สงวนไว้สำหรับส่วนถัดไป ต้องพอดีช่อง

การลองซ้ำแบบความสูงถัดไปจะทิ้งการทดลองแบบแยกส่วน ขณะคงชิ้นส่วนที่ยืนยันไว้ก่อนหน้า หัวข้อ ป้ายกำกับ หรือคำนำสั้นจึงย้ายไปพร้อมภูมิภาคใช้งานแรกของคอมโพเนนต์ถัดไปได้

LastRetryReason แยกแยะการลองซ้ำแบบทั้งคอมโพเนนต์, แบบบังคับสมบูรณ์, แบบช่องขั้นต่ำ และแบบพื้นที่ถัดไป ส่วน LastRequiredSlotHeight รายงานความสูงที่ต้องการซึ่งรู้แล้ว สำหรับข้อจำกัดพื้นที่ขั้นตอน การตรวจช่องขั้นต่ำทำงานก่อนการโคลนคอมโพเนนต์และการจับฟอร์ม ภูมิภาคสั้นที่ถูกปฏิเสธซ้ำ ๆ จึงไม่เกิดค่าใช้จ่ายคอลแบ็กคอมโพเนนต์หรือหน้าชั่วคราว

ค่าที่ส่งกลับ

PDF_DYNAMIC_COMPONENT_ERRORคำขอ, คอลแบ็กคอมโพเนนต์, เรขาคณิตผลลัพธ์ หรือการวางฟอร์มล้มเหลว และไม่มีสถานะใดถูกยืนยัน
PDF_DYNAMIC_COMPONENT_MOREเนื้อหาถูกยืนยันแล้ว และคอมโพเนนต์ร้องขอช่องหน้าอีกช่อง
PDF_DYNAMIC_COMPONENT_COMPLETEคอมโพเนนต์เสร็จสมบูรณ์ หรือเซสชันสมบูรณ์อยู่แล้วและไม่มีการเรียกคอลแบ็ก
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