249 lines
7.9 KiB
Plaintext
249 lines
7.9 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;
|
||
function IfRemoveEmptyRectangle(): boolean;
|
||
|
||
private
|
||
function GetCellPrType(): string;
|
||
|
||
public
|
||
VMerge;
|
||
RemoveFlag;
|
||
Row;
|
||
Col;
|
||
|
||
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.SetTblStyleIdAndType(tbl_pr_.TblStyle.Val, {self.}GetCellPrType());
|
||
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 - tbl_pr_.TblCellMar.Bottom.W;
|
||
{self.}DynamicHeight += tbl_pr_.TblCellMar.Top.W + tbl_pr_.TblCellMar.Bottom.W;
|
||
if {self.}EndY < {self.}LowerBound and not range.Empty() then
|
||
begin
|
||
page_ := docx_to_pdf_.GetNextPage(page_);
|
||
if ifnil(page_) then page_ := docx_to_pdf_.AddTSPage();
|
||
point := docx_to_pdf_.GetCurrentTextPoint();
|
||
{self.}StartY := point.Y;
|
||
{self.}Calc();
|
||
end
|
||
end;
|
||
|
||
function TSPdfCellRange.Do();override;
|
||
begin
|
||
for _,region in region_array_ do
|
||
begin
|
||
if _ = 0 and {self.}RemoveFlag 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;
|
||
|
||
function TSPdfCellRange.IfRemoveEmptyRectangle(): boolean;
|
||
begin
|
||
if length(region_array_) < 2 then return false;
|
||
return length(region_array_[0].RangeArr) ? false : true;
|
||
end;
|
||
|
||
function TSPdfCellRange.GetCellPrType(): string;
|
||
begin
|
||
if {self.}Row = 0 then return "firstRow";
|
||
else if ({self.}Row + 1) % 2 = 0 then return "band1Horz";
|
||
else return "band2Horz";
|
||
end;
|