PdfConverter/range/Advanced/TSPdfCellRange.tsf

149 lines
5.1 KiB
Plaintext

type TSPdfCellRange = class(TSPdfBasicRange)
public
function Create(docx_to_pdf: TSDocxToPdf; pg: TSPage; components: TSDocxComponentsWare; sect_ware: TSSectWare; tc: Tc; tbl_pr: TblPr);
function Calc();
function AlignHeight(height: real; surplus: real);
function GetLastPage();
function Do();override;
private
[weakref]docx_to_pdf_: TSDocxToPdf;
[weakref]page_: TSPage;
[weakref]docx_components_ware_: TSDocxComponentsWare;
[weakref]sect_ware_: TSSectWare;
[weakref]tc_: Tc;
[weakref]tbl_pr_: TblPr;
region_array_: array of Region; // 单元格可能跨页,所以可能存在多个
end;
type Region = class
function Create();
begin
RectangleRange := new TSPdfRectangleRange();
RangeArr := array();
end
RectangleRange: TSPdfRectangleRange;
RangeArr: array of TSPdfAbstractRange;
end;
function TSPdfCellRange.Create(docx_to_pdf: TSDocxToPdf; pg: TSPage; components: TSDocxComponentsWare; sect_ware: TSSectWare; tc: Tc; tbl_pr: TblPr);
begin
docx_to_pdf_ := docx_to_pdf;
page_ := pg;
docx_components_ware_ := components;
sect_ware_ := sect_ware;
tc_ := tc;
tbl_pr_ := tbl_pr;
region_array_ := array();
{self.}TSPage := page_;
end;
function TSPdfCellRange.Calc();
begin
region := new Region();
region.RectangleRange.EndX := {self.}StartX;
region.RectangleRange.EndY := {self.}StartY;
region.RectangleRange.Width := {self.}Width;
region.RectangleRange.FixedHeight := {self.}FixedHeight;
region.RectangleRange.TSPage := page_;
region_array_[length(region_array_)] := region;
{self.}EndX := {self.}StartX;
{self.}EndY := {self.}StartY;
cell_x := {self.}EndX + tbl_pr_.TblCellMar.Left.W;
cell_y := {self.}EndY - tbl_pr_.TblCellMar.Top.W;
cell_w := {self.}Width - tbl_pr_.TblCellMar.Right.W - tbl_pr_.TblCellMar.Left.W;
cell_h := {self.}FixedHeight;
elements := tc_.Elements();
for _,element in elements do
begin
range := nil;
if element.LocalName = "p" then
begin
range := new TSPdfParagraphRange(docx_to_pdf_, page_, docx_components_ware_, sect_ware_, element);
range.SetExtraStyleId(tbl_pr_.TblStyle.Val);
end
else if element.LocalName = "tbl" then
begin
range := new TSPdfTableRange(docx_to_pdf_, page_, docx_components_ware_, sect_ware_, element);
end
if ifObj(range) then
begin
range.StartX := cell_x;
range.StartY := cell_y;
range.Width := cell_w;
range.FixedHeight := cell_h;
range.Calc();
region.RangeArr[length(region.RangeArr)] := range;
{self.}DynamicHeight += range.DynamicHeight;
cell_y -= range.DynamicHeight;
end
end
{self.}EndY := cell_y;
{self.}DynamicHeight += tbl_pr_.TblCellMar.Top.W + tbl_pr_.TblCellMar.Bottom.W;
end;
function TSPdfCellRange.Do();override;
begin
for _,region in region_array_ do
begin
region.RectangleRange.Do();
for _,range in region.RangeArr do
range.Do();
end
end;
function TSPdfCellRange.AlignHeight(height: real; surplus: real);
begin
region := region_array_[0];
if surplus < 1e-6 then
begin
region.RectangleRange.DynamicHeight := height;
if region.RectangleRange.FixedHeight then region.RectangleRange.DynamicHeight := region.RectangleRange.FixedHeight;
{self.}EndY := {self.}StartY - region.RectangleRange.DynamicHeight;
return;
end
region.RectangleRange.DynamicHeight := {self.}StartY - sect_ware_.SectPr.PgMar.Bottom;
arr := region.RangeArr;
region.RangeArr := array();
span := sect_ware_.SectPr.PgSz.H - sect_ware_.SectPr.PgMar.Top - sect_ware_.SectPr.PgMar.Bottom;
hash := array(region.RectangleRange.TSPage.Index: region);
while surplus > span do
begin
page_ := docx_to_pdf_.GetNextPage(page_);
region := new Region();
region.RectangleRange.EndX := {self.}StartX;
region.RectangleRange.EndY := {self.}StartY;
region.RectangleRange.Width := {self.}Width;
region.RectangleRange.DynamicHeight := span;
region.RectangleRange.TSPage := page_;
region_array_[length(region_array_)] := region;
surplus -= span;
hash[region.RectangleRange.TSPage.Index] := region;
end
if surplus > 1e-6 then
begin
page_ := docx_to_pdf_.GetNextPage(page_);
region := new Region();
region.RectangleRange.EndX := {self.}StartX;
region.RectangleRange.EndY := sect_ware_.SectPr.PgSz.H - sect_ware_.SectPr.PgMar.Top;
region.RectangleRange.Width := {self.}Width;
region.RectangleRange.DynamicHeight := surplus;
region.RectangleRange.TSPage := page_;
region_array_[length(region_array_)] := region;
hash[region.RectangleRange.TSPage.Index] := region;
{self.}EndY := region.RectangleRange.EndY - surplus;
end
for _,range in arr do
begin
region := hash[range.TSPage.Index];
region.RangeArr[length(region.RangeArr)] := range;
end
end;
function TSPdfCellRange.GetLastPage();
begin
return page_;
end;