PdfConverter/range/Advanced/TSPdfCellRange.tsf

171 lines
5.8 KiB
Plaintext

type TSPdfCellRange = class(TSPdfBasicRange)
public
function Create(docx_to_pdf: TSDocxToPdf; pg: TSPage; components: TSDocxComponentsWare; tc: Tc; tbl_pr: TblPr);
function Calc();
function AlignHeight(height: real; surplus: real);
function GetLastPage();
function Do();override;
function SetVMergeEdge(range: TSPdfCellRange);
function GetRegionArr(): array of Region;
public
VMerge;
private
[weakref]docx_to_pdf_: TSDocxToPdf;
[weakref]page_: TSPage;
[weakref]docx_components_ware_: TSDocxComponentsWare;
[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; tc: Tc; tbl_pr: TblPr);
begin
docx_to_pdf_ := docx_to_pdf;
page_ := pg;
docx_components_ware_ := components;
tc_ := tc;
tbl_pr_ := tbl_pr;
region_array_ := array();
{self.}TSPage := page_;
{self.}VMerge := tc_.TcPr.XmlChildVMerge.Val ? tc_.TcPr.XmlChildVMerge.Val : tc_.TcPr.VMerge;
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.RectangleRange.TcPr := tc_.TcPr;
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_, 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_, element);
end
if ifObj(range) then
begin
range.StartX := cell_x;
range.StartY := cell_y;
range.Width := cell_w;
range.FixedHeight := cell_h;
range.LowerBound := {self.}LowerBound;
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 - {self.}LowerBound;
arr := region.RangeArr;
region.RangeArr := array();
sect_ware := docx_to_pdf_.GetCurrentSectWare();
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.RectangleRange.TcPr := tc_.TcPr;
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.RectangleRange.TcPr := tc_.TcPr;
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;
function TSPdfCellRange.GetRegionArr(): array of Region;
begin
return region_array_;
end;
function TSPdfCellRange.SetVMergeEdge(range: TSPdfCellRange);
begin
rect := region_array_[length(region_array_)-1].RectangleRange;
range_rect := range.GetRegionArr();
range_rect := range_rect[0].RectangleRange;
rect.DynamicHeight += range_rect.DynamicHeight;
end;