221 lines
7.1 KiB
Plaintext
221 lines
7.1 KiB
Plaintext
type TSPdfCellRange = class(TSPdfBasicRange)
|
||
public
|
||
function Create(table_range: TSPdfTableRange; docx_to_pdf: TSDocxToPdf; pg: TSPage; components: TSDocxComponentsWare; tc: Tc; tbl_pr: TblPr; tr_pr: TrPr);
|
||
function Calc();
|
||
function Do();override;
|
||
function SetTSPage(page: TSPage);
|
||
function GetLastPage();
|
||
function AlignHeight(height: real);
|
||
function IsSamePage(): boolean;
|
||
function FirstValidTSPage(): TSPage;
|
||
function SetVAlign();
|
||
function IsReComputeByCantSplit(): boolean;
|
||
|
||
public
|
||
VMerge;
|
||
|
||
private
|
||
[weakref]parent_: TSPdfTableRange;
|
||
[weakref]docx_to_pdf_: TSDocxToPdf;
|
||
[weakref]page_: TSPage;
|
||
[weakref]docx_components_ware_: TSDocxComponentsWare;
|
||
[weakref]tc_: Tc;
|
||
[weakref]tbl_pr_: TblPr;
|
||
[weakref]tr_pr_: TrPr;
|
||
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(table_range: TSPdfTableRange; docx_to_pdf: TSDocxToPdf; pg: TSPage; components: TSDocxComponentsWare; tc: Tc; tbl_pr: TblPr; tr_pr: TrPr);
|
||
begin
|
||
parent_ := table_range;
|
||
docx_to_pdf_ := docx_to_pdf;
|
||
page_ := pg;
|
||
docx_components_ware_ := components;
|
||
tc_ := tc;
|
||
tbl_pr_ := tbl_pr;
|
||
tr_pr_ := tr_pr;
|
||
region_array_ := array();
|
||
{self.}TSPage := page_;
|
||
{self.}VMerge := 0;
|
||
end;
|
||
|
||
function TSPdfCellRange.Calc();
|
||
begin
|
||
region_array_ := array();
|
||
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;
|
||
{self.}DynamicHeight := 0;
|
||
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);
|
||
continue; // TODO:表中表存在不可靠问题
|
||
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.EndY;
|
||
page_ := range.GetLastPage();
|
||
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
|
||
// if length(region.RangeArr) = 0 then continue;
|
||
region.RectangleRange.Do();
|
||
for _,range in region.RangeArr do
|
||
range.Do();
|
||
end
|
||
end;
|
||
|
||
function TSPdfCellRange.SetTSPage(page: TSPage);
|
||
begin
|
||
page_ := page;
|
||
{self.}TSPage := page;
|
||
end;
|
||
|
||
function TSPdfCellRange.AlignHeight(height: real);
|
||
begin
|
||
if {self.}FixedHeight > height then height := {self.}FixedHeight;
|
||
region := region_array_[0];
|
||
surplus := height - ({self.}StartY - {self.}LowerBound);
|
||
if surplus < 1e-6 then
|
||
begin
|
||
region.RectangleRange.DynamicHeight := height;
|
||
if {self.}FixedHeight then region.RectangleRange.DynamicHeight := {self.}FixedHeight;
|
||
{self.}EndY := {self.}StartY - region.RectangleRange.DynamicHeight;
|
||
return;
|
||
end
|
||
region.RectangleRange.DynamicHeight := {self.}StartY - {self.}LowerBound;
|
||
arr := region.RangeArr;
|
||
region.RangeArr := array();
|
||
hash := array(region.RectangleRange.TSPage.Index: region);
|
||
page_ := {self.}TSPage;
|
||
[x, y] := docx_to_pdf_.CalculateTextCoordinates();
|
||
ftr_point := docx_to_pdf_.GetCurrentFtrPoint();
|
||
span := y - ftr_point.Y;
|
||
while surplus > span do
|
||
begin
|
||
page_ := docx_to_pdf_.GetNextPage(page_);
|
||
region := new Region();
|
||
region.RectangleRange.EndX := {self.}StartX;
|
||
region.RectangleRange.EndY := y;
|
||
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 := y;
|
||
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
|
||
if range is class(TSPdfParagraphRange) then
|
||
begin
|
||
line_arr := range.GetLineRangeArr();
|
||
for _,r in line_arr do
|
||
begin
|
||
region := hash[r.TSPage.Index];
|
||
region.RangeArr[length(region.RangeArr)] := r;
|
||
end
|
||
end
|
||
end
|
||
end;
|
||
|
||
function TSPdfCellRange.GetLastPage();
|
||
begin
|
||
return page_;
|
||
end;
|
||
|
||
function TSPdfCellRange.SetVAlign();
|
||
begin
|
||
val := tc_.TcPr.VAlign.Val;
|
||
region := region_array_[0];
|
||
arr := region.RangeArr;
|
||
if length(arr) = 0 then return;
|
||
last_y := arr[length(arr)-1].EndY;
|
||
offset := last_y - (region.RectangleRange.EndY - region.RectangleRange.DynamicHeight) - tbl_pr_.TblCellMar.Bottom.W;
|
||
case val of
|
||
"center":
|
||
begin
|
||
offset /= 2;
|
||
for _,range in arr do
|
||
range.AdjustRangeOffset(region.RectangleRange.TSPage, nil, -offset);
|
||
end
|
||
end;
|
||
end;
|
||
|
||
function TSPdfCellRange.IsSamePage(): boolean;
|
||
begin
|
||
return page_ = {self.}TSPage;
|
||
end;
|
||
|
||
function TSPdfCellRange.FirstValidTSPage(): TSPage;
|
||
begin
|
||
return region_array_[0].RangeArr[0].TSPage;
|
||
end;
|
||
|
||
function TSPdfCellRange.IsReComputeByCantSplit(): boolean;
|
||
begin
|
||
if {self.}VMerge then return false;
|
||
return tr_pr_.CantSplit and page_ <> {self.}TSPage;
|
||
end;
|