PdfConverter/range/Advanced/TSPdfCellRange.tsf

148 lines
4.8 KiB
Plaintext

type TSPdfCellRange = class(TSPdfBasicRange)
public
function Create(docx_to_pdf: TSDocxToPdf; pg: PdfPage; components: Components; sect_ware: TSSectWare; tc: Tc; tbl_pr: TblPr);
function Calc();
function AlignHeight(surplus: real);
function GetLastPage();
function Do();override;
private
docx_to_pdf_: TSDocxToPdf;
page_: PdfPage;
docx_components_: Components;
sect_ware_: TSSectWare;
tc_: Tc;
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: PdfPage; components: Components; sect_ware: TSSectWare; tc: Tc; tbl_pr: TblPr);
begin
docx_to_pdf_ := docx_to_pdf;
page_ := pg;
docx_components_ := components;
sect_ware_ := sect_ware;
tc_ := tc;
tbl_pr_ := tbl_pr;
region_array_ := array();
self.Page := 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.Page := 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_, 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_, 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(surplus: real);
begin
region := region_array_[0];
if surplus < 1e-6 then
begin
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.Page: 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.Page := page_;
region_array_[length(region_array_)] := region;
surplus -= span;
hash[region.RectangleRange.Page] := 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.Page := page_;
region_array_[length(region_array_)] := region;
hash[region.RectangleRange.Page] := region;
self.EndY := region.RectangleRange.EndY - surplus;
end
for _,range in arr do
begin
region := hash[range.Page];
region.RangeArr[length(region.RangeArr)] := range;
end
end;
function TSPdfCellRange.GetLastPage();
begin
return page_;
end;