350 lines
12 KiB
Plaintext
350 lines
12 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; trp: TSTrProperty);
|
||
function Calc();
|
||
function Do();override;
|
||
function SetTSPage(page: TSPage);
|
||
function GetLastPage();
|
||
function AlignHeight(height: real);
|
||
function SetVAlign();
|
||
function IsReComputeByCantSplit(): boolean;
|
||
function IfRemoveEmptyRectangle(): boolean;
|
||
function SetTop();
|
||
|
||
property Tc read tc_;
|
||
|
||
private
|
||
function GetCellPrType(): string;
|
||
function SetBorderRange(range: TSPdfBordersRange);
|
||
|
||
public
|
||
RemoveFlag: boolean;
|
||
Row: integer;
|
||
Col: integer;
|
||
VMerge: integer;
|
||
[weakref]TSTrPr: TSTrProperty;
|
||
|
||
private
|
||
[weakref]parent_: TSPdfTableRange;
|
||
[weakref]docx_to_pdf_: TSDocxToPdf;
|
||
[weakref]last_page_: TSPage;
|
||
[weakref]docx_components_ware_: TSDocxComponentsWare;
|
||
[weakref]tc_: Tc;
|
||
[weakref]tbl_pr_: TblPr;
|
||
tc_pr_unit_decorator_: TcPrUnitDecorator;
|
||
region_array_: array of Region; // 单元格可能跨页,所以可能存在多个
|
||
top_: boolean;
|
||
end;
|
||
|
||
type Region = class
|
||
function Create();
|
||
begin
|
||
BordersRange := new TSPdfBordersRange();
|
||
RangeArr := array();
|
||
end
|
||
|
||
BordersRange: TSPdfBordersRange;
|
||
RangeArr: array of TSPdfBasicRange;
|
||
end;
|
||
|
||
function TSPdfCellRange.Create(table_range: TSPdfTableRange; docx_to_pdf: TSDocxToPdf; pg: TSPage; components: TSDocxComponentsWare; tc: Tc; tbl_pr: TblPr; trp: TSTrProperty);
|
||
begin
|
||
parent_ := table_range;
|
||
docx_to_pdf_ := docx_to_pdf;
|
||
last_page_ := pg;
|
||
docx_components_ware_ := components;
|
||
tc_ := tc;
|
||
tbl_pr_ := tbl_pr;
|
||
region_array_ := array();
|
||
top_ := false;
|
||
tc_pr_unit_decorator_ := new TcPrUnitDecorator(tc_.TcPr);
|
||
{self.}TSTrPr := trp;
|
||
{self.}Tc := tc;
|
||
{self.}VMerge := 1;
|
||
{self.}TSPage := last_page_;
|
||
end;
|
||
|
||
function TSPdfCellRange.Calc();
|
||
begin
|
||
region_array_ := array();
|
||
region := new Region();
|
||
region.BordersRange.EndX := {self.}StartX;
|
||
region.BordersRange.EndY := {self.}StartY;
|
||
region.BordersRange.Width := {self.}Width;
|
||
region.BordersRange.FixedHeight := {self.}FixedHeight;
|
||
region.BordersRange.TSPage := last_page_;
|
||
region.BordersRange.TcPr := tc_pr_unit_decorator_;
|
||
{self.}SetBorderRange(region.BordersRange);
|
||
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_, last_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_, last_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;
|
||
last_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
|
||
last_page_ := docx_to_pdf_.GetNextPage(last_page_);
|
||
if ifnil(last_page_) then last_page_ := docx_to_pdf_.AddTSPage();
|
||
point := docx_to_pdf_.GetCurrentTextPoint();
|
||
{self.}StartY := point.Y;
|
||
{self.}Calc();
|
||
end
|
||
if {self.}TSTrPr.TrPr.TrHeight.HRule <> "exact" and {self.}DynamicHeight > {self.}FixedHeight then
|
||
begin
|
||
region.BordersRange.FixedHeight := {self.}DynamicHeight;
|
||
{self.}FixedHeight := {self.}DynamicHeight;
|
||
end
|
||
if not {self.}Tc.TcPr.VMerge and {self.}DynamicHeight > {self.}TSTrPr.Height then
|
||
{self.}TSTrPr.Height := {self.}DynamicHeight;
|
||
end;
|
||
|
||
function TSPdfCellRange.Do();override;
|
||
begin
|
||
for _,region in region_array_ do
|
||
begin
|
||
if _ = 0 and {self.}RemoveFlag then continue;
|
||
// println("Row = {}, Col = {}", {self.}Row, {self.}Col);
|
||
region.BordersRange.Do();
|
||
for _,range in region.RangeArr do
|
||
range.Do();
|
||
end
|
||
end;
|
||
|
||
function TSPdfCellRange.SetTSPage(page: TSPage);
|
||
begin
|
||
last_page_ := page;
|
||
{self.}TSPage := page;
|
||
end;
|
||
|
||
function TSPdfCellRange.AlignHeight(height: real);
|
||
begin
|
||
region := region_array_[0];
|
||
y_lowerbound := {self.}StartY - {self.}LowerBound;
|
||
surplus := height - y_lowerbound;
|
||
if surplus < 1e-6 then
|
||
begin
|
||
region.BordersRange.DynamicHeight := height;
|
||
{self.}SetBorderRange(region.BordersRange);
|
||
{self.}EndY := {self.}StartY - region.BordersRange.DynamicHeight;
|
||
return;
|
||
end
|
||
region.BordersRange.DynamicHeight := y_lowerbound;
|
||
arr := region.RangeArr;
|
||
region.RangeArr := array();
|
||
hash := array(region.BordersRange.TSPage.Index: region);
|
||
last_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
|
||
last_page_ := docx_to_pdf_.GetNextPage(last_page_);
|
||
region := new Region();
|
||
region.BordersRange.EndX := {self.}StartX;
|
||
region.BordersRange.EndY := y;
|
||
region.BordersRange.Width := {self.}Width;
|
||
region.BordersRange.DynamicHeight := span;
|
||
region.BordersRange.TSPage := last_page_;
|
||
region.BordersRange.TcPr := tc_pr_unit_decorator_;
|
||
region.BordersRange.Top := true;
|
||
region.BordersRange.Bottom := true;
|
||
{self.}SetBorderRange(region.BordersRange);
|
||
region_array_[length(region_array_)] := region;
|
||
surplus -= span;
|
||
hash[region.BordersRange.TSPage.Index] := region;
|
||
end
|
||
if surplus > 1e-6 then
|
||
begin
|
||
last_page_ := docx_to_pdf_.GetNextPage(last_page_);
|
||
region := new Region();
|
||
region.BordersRange.EndX := {self.}StartX;
|
||
region.BordersRange.EndY := y;
|
||
region.BordersRange.Width := {self.}Width;
|
||
region.BordersRange.DynamicHeight := surplus;
|
||
region.BordersRange.TSPage := last_page_;
|
||
region.BordersRange.TcPr := tc_pr_unit_decorator_;
|
||
region.BordersRange.Top := true;
|
||
{self.}SetBorderRange(region.BordersRange);
|
||
region_array_[length(region_array_)] := region;
|
||
hash[region.BordersRange.TSPage.Index] := region;
|
||
{self.}EndY := region.BordersRange.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 last_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.BordersRange.EndY - region.BordersRange.DynamicHeight) - tbl_pr_.TblCellMar.Bottom.W;
|
||
case val of
|
||
"center":
|
||
begin
|
||
offset /= 2;
|
||
for _,range in arr do
|
||
range.AdjustRangeOffset(region.BordersRange.TSPage, nil, -offset);
|
||
end
|
||
end;
|
||
end;
|
||
|
||
function TSPdfCellRange.IsReComputeByCantSplit(): boolean;
|
||
begin
|
||
if {self.}Tc.TcPr.VMerge then return false;
|
||
return {self.}TSTrPr.TrPr.CantSplit and last_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;
|
||
|
||
function TSPdfCellRange.SetBorderRange(range: TSPdfBordersRange);
|
||
begin
|
||
if top_ then range.Top := true;
|
||
if ifObj(tbl_pr_.TblBorders) then
|
||
begin
|
||
if {self.}Row = 0 then
|
||
begin
|
||
if tbl_pr_.TblBorders.Top then
|
||
begin
|
||
tc_pr_unit_decorator_.TcBorders.Top.Copy(tbl_pr_.TblBorders.Top);
|
||
range.Top := true;
|
||
end
|
||
if tbl_pr_.TblBorders.InsideH and {self.}VMerge <> parent_.Rows()-1 then
|
||
begin
|
||
tc_pr_unit_decorator_.TcBorders.Bottom.Copy(tbl_pr_.TblBorders.InsideH);
|
||
range.Bottom := true;
|
||
end
|
||
if tbl_pr_.TblBorders.InsideV and {self.}Col <> parent_.Cols()-1 then
|
||
begin
|
||
tc_pr_unit_decorator_.TcBorders.Right.Copy(tbl_pr_.TblBorders.InsideV);
|
||
range.Right := true;
|
||
end
|
||
if tbl_pr_.TblBorders.Bottom and {self.}VMerge = parent_.Rows()-1 then
|
||
begin
|
||
tc_pr_unit_decorator_.TcBorders.Bottom.Copy(tbl_pr_.TblBorders.Bottom);
|
||
range.Bottom := true;
|
||
end
|
||
end
|
||
else if {self.}Row = parent_.Rows()-1 then
|
||
begin
|
||
if tbl_pr_.TblBorders.Bottom then
|
||
begin
|
||
tc_pr_unit_decorator_.TcBorders.Bottom.Copy(tbl_pr_.TblBorders.Bottom);
|
||
range.Bottom := true;
|
||
end
|
||
if tbl_pr_.TblBorders.InsideV and {self.}Col <> parent_.Cols()-1 then
|
||
begin
|
||
tc_pr_unit_decorator_.TcBorders.Right.Copy(tbl_pr_.TblBorders.InsideV);
|
||
range.Right := true;
|
||
end
|
||
end
|
||
else begin
|
||
if tbl_pr_.TblBorders.Bottom and {self.}VMerge = parent_.Rows()-1 then
|
||
begin
|
||
tc_pr_unit_decorator_.TcBorders.Bottom.Copy(tbl_pr_.TblBorders.Bottom);
|
||
range.Bottom := true;
|
||
end
|
||
if tbl_pr_.TblBorders.InsideH and {self.}VMerge <> parent_.Rows()-1 then
|
||
begin
|
||
tc_pr_unit_decorator_.TcBorders.Bottom.Copy(tbl_pr_.TblBorders.InsideH);
|
||
range.Bottom := true;
|
||
end
|
||
if tbl_pr_.TblBorders.InsideV and {self.}Col <> parent_.Cols()-1 then
|
||
begin
|
||
tc_pr_unit_decorator_.TcBorders.Right.Copy(tbl_pr_.TblBorders.InsideV);
|
||
range.Right := true;
|
||
end
|
||
end
|
||
|
||
if {self.}Col = 0 then
|
||
begin
|
||
if tbl_pr_.TblBorders.Left then
|
||
begin
|
||
tc_pr_unit_decorator_.TcBorders.Left.Copy(tbl_pr_.TblBorders.Left);
|
||
range.Left := true;
|
||
end
|
||
end
|
||
if {self.}Col = parent_.Cols()-1 then
|
||
begin
|
||
if tbl_pr_.TblBorders.Right then
|
||
begin
|
||
tc_pr_unit_decorator_.TcBorders.Right.Copy(tbl_pr_.TblBorders.Right);
|
||
range.Right := true;
|
||
end
|
||
end
|
||
end
|
||
else begin
|
||
range.Left := {self.}Col = 0;
|
||
range.Top := {self.}Row = 0;
|
||
range.Right := true;
|
||
range.Bottom := true;
|
||
end
|
||
end;
|
||
|
||
function TSPdfCellRange.SetTop();
|
||
begin
|
||
top_ := true;
|
||
end;
|