From 003268fd406782cd4b83ad9ff3259652cdfe9cb6 Mon Sep 17 00:00:00 2001 From: csh Date: Wed, 13 Nov 2024 16:38:43 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E9=87=8D=E6=9E=84=E9=83=A8=E5=88=86?= =?UTF-8?q?=E8=A1=A8=E6=A0=BC=E4=BB=A3=E7=A0=81=202.=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E8=A1=A8=E6=A0=BC=E7=9A=84=E8=BE=B9=E6=A1=86=E6=A0=B7=E5=BC=8F?= =?UTF-8?q?`single`=E5=92=8C`dashed`=203.=20=E9=81=87=E5=88=B0=E4=B8=8D?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E7=9A=84=E9=A1=B9=E7=9B=AE=E7=AC=A6=E5=8F=B7?= =?UTF-8?q?=E9=87=87=E7=94=A8=E6=95=B0=E5=AD=97=E4=BB=A3=E6=9B=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- range/Advanced/TSPdfCellRange.tsf | 232 +++++++++++++++++-------- range/Advanced/TSPdfTableRange.tsf | 252 ++++++++++++++-------------- range/basic/TSPdfBordersRange.tsf | 76 +++++++++ range/basic/TSPdfRectangleRange.tsf | 33 ---- ware/TSNumberingWare.tsf | 2 + 5 files changed, 363 insertions(+), 232 deletions(-) create mode 100644 range/basic/TSPdfBordersRange.tsf delete mode 100644 range/basic/TSPdfRectangleRange.tsf diff --git a/range/Advanced/TSPdfCellRange.tsf b/range/Advanced/TSPdfCellRange.tsf index acd999a..2032d72 100644 --- a/range/Advanced/TSPdfCellRange.tsf +++ b/range/Advanced/TSPdfCellRange.tsf @@ -6,67 +6,75 @@ public function SetTSPage(page: TSPage); function GetLastPage(); function AlignHeight(height: real); - function IsSamePage(): boolean; - function FirstValidTSPage(): TSPage; function SetVAlign(); function IsReComputeByCantSplit(): boolean; function IfRemoveEmptyRectangle(): boolean; + function SetTop(); + + property Tc read tc_; private function GetCellPrType(): string; + function SetBorderRange(range: TSPdfBordersRange); public - VMerge; - RemoveFlag; - Row; - Col; + RemoveFlag: boolean; + Row: integer; + Col: integer; + VMerge: integer; [weakref]TSTrPr: TSTrProperty; private [weakref]parent_: TSPdfTableRange; [weakref]docx_to_pdf_: TSDocxToPdf; - [weakref]page_: TSPage; + [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 - RectangleRange := new TSPdfRectangleRange(); + BordersRange := new TSPdfBordersRange(); RangeArr := array(); end - RectangleRange: TSPdfRectangleRange; - RangeArr: array of TSPdfAbstractRange; + 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; - page_ := pg; + 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.}TSPage := page_; - {self.}VMerge := 0; + {self.}Tc := tc; + {self.}VMerge := 1; + {self.}TSPage := last_page_; 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.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; @@ -82,12 +90,12 @@ begin range := nil; if element.LocalName = "p" then begin - range := new TSPdfParagraphRange(docx_to_pdf_, page_, docx_components_ware_, element); + 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_, page_, docx_components_ware_, element); + range := new TSPdfTableRange(docx_to_pdf_, last_page_, docx_components_ware_, element); continue; // TODO:表中表存在不可靠问题 end if ifObj(range) then @@ -101,25 +109,26 @@ begin region.RangeArr[length(region.RangeArr)] := range; {self.}DynamicHeight += range.DynamicHeight; cell_y := range.EndY; - page_ := range.GetLastPage(); + 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 - page_ := docx_to_pdf_.GetNextPage(page_); - if ifnil(page_) then page_ := docx_to_pdf_.AddTSPage(); + 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 not {self.}VMerge and {self.}TSTrPr.TrPr.TrHeight.HRule <> "exact" and {self.}DynamicHeight > {self.}FixedHeight then + if {self.}TSTrPr.TrPr.TrHeight.HRule <> "exact" and {self.}DynamicHeight > {self.}FixedHeight then begin - region.RectangleRange.FixedHeight := {self.}DynamicHeight; + region.BordersRange.FixedHeight := {self.}DynamicHeight; {self.}FixedHeight := {self.}DynamicHeight; end - if not {self.}VMerge and {self.}DynamicHeight > {self.}TSTrPr.Height then + if not {self.}Tc.TcPr.VMerge and {self.}DynamicHeight > {self.}TSTrPr.Height then {self.}TSTrPr.Height := {self.}DynamicHeight; end; @@ -128,7 +137,8 @@ begin for _,region in region_array_ do begin if _ = 0 and {self.}RemoveFlag then continue; - region.RectangleRange.Do(); + // println("Row = {}, Col = {}", {self.}Row, {self.}Col); + region.BordersRange.Do(); for _,range in region.RangeArr do range.Do(); end @@ -136,57 +146,62 @@ end; function TSPdfCellRange.SetTSPage(page: TSPage); begin - page_ := page; + last_page_ := page; {self.}TSPage := page; end; function TSPdfCellRange.AlignHeight(height: real); begin - if {self.}TSTrPr.Height > height then height := {self.}TSTrPr.Height; region := region_array_[0]; - surplus := height - ({self.}StartY - {self.}LowerBound); + y_lowerbound := {self.}StartY - {self.}LowerBound; + surplus := height - y_lowerbound; if surplus < 1e-6 then begin - region.RectangleRange.DynamicHeight := height; - if {self.}TSTrPr.Height then region.RectangleRange.DynamicHeight := {self.}TSTrPr.Height; - {self.}EndY := {self.}StartY - region.RectangleRange.DynamicHeight; + region.BordersRange.DynamicHeight := height; + {self.}SetBorderRange(region.BordersRange); + {self.}EndY := {self.}StartY - region.BordersRange.DynamicHeight; return; end - region.RectangleRange.DynamicHeight := {self.}StartY - {self.}LowerBound; + region.BordersRange.DynamicHeight := y_lowerbound; arr := region.RangeArr; region.RangeArr := array(); - hash := array(region.RectangleRange.TSPage.Index: region); - page_ := {self.}TSPage; + 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 - page_ := docx_to_pdf_.GetNextPage(page_); + last_page_ := docx_to_pdf_.GetNextPage(last_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.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.RectangleRange.TSPage.Index] := region; + hash[region.BordersRange.TSPage.Index] := region; end if surplus > 1e-6 then begin - page_ := docx_to_pdf_.GetNextPage(page_); + last_page_ := docx_to_pdf_.GetNextPage(last_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.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.RectangleRange.TSPage.Index] := region; - {self.}EndY := region.RectangleRange.EndY - surplus; + hash[region.BordersRange.TSPage.Index] := region; + {self.}EndY := region.BordersRange.EndY - surplus; end for _,range in arr do begin @@ -204,7 +219,7 @@ end; function TSPdfCellRange.GetLastPage(); begin - return page_; + return last_page_; end; function TSPdfCellRange.SetVAlign(); @@ -214,31 +229,21 @@ begin 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; + 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.RectangleRange.TSPage, nil, -offset); + range.AdjustRangeOffset(region.BordersRange.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 {self.}TSTrPr.TrPr.CantSplit and page_ <> {self.}TSPage; + if {self.}Tc.TcPr.VMerge then return false; + return {self.}TSTrPr.TrPr.CantSplit and last_page_ <> {self.}TSPage; end; function TSPdfCellRange.IfRemoveEmptyRectangle(): boolean; @@ -253,3 +258,92 @@ begin 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; diff --git a/range/Advanced/TSPdfTableRange.tsf b/range/Advanced/TSPdfTableRange.tsf index a9e6149..481a843 100644 --- a/range/Advanced/TSPdfTableRange.tsf +++ b/range/Advanced/TSPdfTableRange.tsf @@ -3,47 +3,51 @@ public function Create(docx_to_pdf: TSDocxToPdf; pg: TSPage; components: Components; table: Tbl); function Do();override; function Calc(); - function FirstValidTSPage(): TSPage; - function IsSamePage(): boolean; function GetLastPage(): TSPage; + function Rows(): integer; + function Cols(): integer; private function GetCellMatrix(grid_cols: array of GridColUnitDecorator); function CreateTableMatrix(grid_cols: array of GridColUnitDecorator; trs: array of Tr); function ComputeMatrixCells(); - function ResetCoordinates(tbl_pr: TblPr; grid_cols: array of GridCol); - function SetTblPr(tbl_pr: TblPr); + function ResetCoordinates(tbl_pr: TblPrUnitDecorator; grid_cols: array of GridCol); + function SetTblTblPr(var table: Tbl); function SetTblPrByStyleId(var tbl_pr: TblPr; style_id: string); - function SetTrPr(var tr_pr: TrPr); + function SetTrTrPr(var tr_pr: TrPr); function SetTrPrByStyleId(var tr_pr: TrPr; style_id: string); - function SetTcPr(var tc_pr: TcPr); + function SetTcTcPr(var tc: Tc); function SetTcPrByStyleId(var tc_pr: TcPr; style_id: string); - function SetTblStylePr(var tc_pr: TcPr; type: string); + function OverrideTcPrByTblStylePrType(var tc_pr: TcPr; type: string); private [weakref]docx_to_pdf_: TSDocxToPdf; + [weakref]last_page_: TSPage; [weakref]docx_components_ware_: Components; [weakref]table_: Tbl; - [weakref]page_: TSPage; tbl_pr_unit_decorator_: TblPrUnitDecorator; - cell_range_array_: tableArray; - tr_array_: array of TSTrProperty; + ts_trpr_array_: array of TSTrProperty; + cell_range_matrix_: array of TSPdfCellRange; + rows_: integer; + cols_: integer; end; function TSPdfTableRange.Create(docx_to_pdf: TSDocxToPdf; pg: PdfPage; components: Components; table: Tbl); begin docx_to_pdf_ := docx_to_pdf; - page_ := pg; + last_page_ := pg; docx_components_ware_ := Components; table_ := table; - cell_range_array_ := array(); - tr_array_ := array(); - {self.}TSPage := page_; + ts_trpr_array_ := array(); + cell_range_matrix_ := array(); + rows_ := 0; + cols_ := 0; + {self.}TSPage := last_page_; end; function TSPdfTableRange.Calc(); begin - {self.}SetTblPr(table_.TblPr); + {self.}SetTblTblPr(table_); tbl_pr_unit_decorator_ := new TblPrUnitDecorator(table_.TblPr); grid_cols := table_.TblGrid.GridCols(); for i:=0 to length(grid_cols)-1 do @@ -57,13 +61,14 @@ end; function TSPdfTableRange.Do();override; begin - for _,row in cell_range_array_ do + for _,row in cell_range_matrix_ do begin flag := nil; for __,range in row do begin if ifnil(flag) and ifObj(range) then flag := range.IfRemoveEmptyRectangle(); - if not ifObj(range) or flag <> range.IfRemoveEmptyRectangle() then + if ifnil(range) then continue; + if flag <> range.IfRemoveEmptyRectangle() then begin flag := false; break; @@ -83,6 +88,9 @@ end; function TSPdfTableRange.GetCellMatrix(grid_cols: array of GridColUnitDecorator); begin trs := table_.Trs(); + rows_ := length(trs); + cols_ := length(grid_cols); + cell_range_matrix_ := nils(rows_, cols_); // 先构建一个矩阵 {self.}CreateTableMatrix(grid_cols, trs); // 遍历矩阵后进行计算合并 @@ -91,159 +99,150 @@ end; function TSPdfTableRange.CreateTableMatrix(grid_cols: array of GridColUnitDecorator; trs: array of Tr); begin - vmerge_arr := array(); for i,tr in trs do begin - {self.}SetTrPr(tr.TrPr); + {self.}SetTrTrPr(tr); tr_pr := new TrPrUnitDecorator(tr.TrPr); - tc_h := tr_pr.TrHeight.Val; tc_x := {self.}EndX; tcs := tr.Tcs(); - pos := 0; trp := new TSTrProperty(); trp.TrPr := tr_pr; - tr_array_[i] := trp; + ts_trpr_array_[i] := trp; + pos := 0; for j,tc in tcs do begin - {self.}SetTcPr(tc.TcPr); - if i = 0 then {self.}SetTblStylePr(tc.TcPr, "firstRow"); - else if (i + 1) % 2 = 0 then {self.}SetTblStylePr(tc.TcPr, "band1Horz"); - else {self.}SetTblStylePr(tc.TcPr, "band2Horz"); - vmerge := tc.TcPr.XmlChildVMerge.Val ? tc.TcPr.XmlChildVMerge.Val : tc.TcPr.VMerge; - if vmerge = "restart" then + {self.}SetTcTcPr(tc); + if i = 0 then {self.}OverrideTcPrByTblStylePrType(tc.TcPr, "firstRow"); + else if i = length(trs)-1 then {self.}OverrideTcPrByTblStylePrType(tc.TcPr, "lastRow") + else if (i + 1) % 2 = 0 then {self.}OverrideTcPrByTblStylePrType(tc.TcPr, "band1Horz"); + else {self.}OverrideTcPrByTblStylePrType(tc.TcPr, "band2Horz"); + + grid_span := new GridSpanUnitDecorator(tc.TcPr.GridSpan); + if tc.TcPr.VMerge and tc.TcPr.VMerge <> "restart" then begin - if ifarray(vmerge_arr[pos]) then cell_range_array_[vmerge_arr[pos][0]][pos].VMerge := vmerge_arr[pos][1]; - vmerge_arr[pos] := array(i, 0); - end - else if vmerge then - begin - vmerge_arr[pos][1]++; - cell_range_array_[i][pos] := 0; - tc_x += grid_cols[pos].W; - grid_span := new GridSpanUnitDecorator(tc.TcPr.GridSpan); - pos++; + tc_x += grid_cols[pos++].W; for k:=grid_span.Val-1 downto 1 do tc_x += grid_cols[pos++].W; continue; end - else if ifarray(vmerge_arr[pos]) then - begin - cell_range_array_[vmerge_arr[pos][0]][pos].VMerge := vmerge_arr[pos][1]; - vmerge_arr[pos] := nil; - end - cell_range := new TSPdfCellRange(self, docx_to_pdf_, page_, docx_components_ware_, tc, tbl_pr_unit_decorator_, trp); + cell_range := new TSPdfCellRange(self, docx_to_pdf_, last_page_, docx_components_ware_, tc, tbl_pr_unit_decorator_, trp); cell_range.StartX := tc_x; cell_range.Width := grid_cols[pos].W; cell_range.LowerBound := {self.}LowerBound; - cell_range.FixedHeight := tc_h; + cell_range.FixedHeight := tr_pr.TrHeight.Val; cell_range.Row := i; - cell_range.Col := j; - cell_range_array_[i][pos] := cell_range; - grid_span := new GridSpanUnitDecorator(tc.TcPr.GridSpan); + cell_range.Col := pos; + cell_range_matrix_[i][pos] := cell_range; pos++; for k:=grid_span.Val-1 downto 1 do cell_range.Width += grid_cols[pos++].W; tc_x += cell_range.Width; end end - for pos,arr in vmerge_arr do - if ifarray(arr) then - cell_range_array_[arr[0]][pos].VMerge := arr[1]; - // for i,arr in cell_range_array_ do - // begin - // println("i = {}, tr = {}", i, tr_array_[i]); - // println("i = {}, len = {}, arr = {}", i, length(arr), arr); - // end + // for i,arr in cell_range_matrix_ do + // println("i = {}, arr = {}", i, arr); + // println("\n"); return; end; function TSPdfTableRange.ComputeMatrixCells(); begin i := 0; - vmerge_arr := array(); - row_height := array(); - while i < length(cell_range_array_) do + merge_arr := array(); + vmerge_height := array(); + while i < rows_ do begin + j := 0; tc_y := {self.}EndY; - max_height := 0; recompute_flag := false; - vmerge_flag_arr := array(); - for j,range in cell_range_array_[i] do + while j < cols_ do begin - if range = 0 then + range := cell_range_matrix_[i][j]; + if ifnil(range) then begin - vmerge_arr[j][1]--; - if vmerge_arr[j][1] = 0 then vmerge_flag_arr[length(vmerge_flag_arr)] := j; + j++; continue; end range.StartY := tc_y; - range.SetTSPage(page_); + range.SetTSPage(last_page_); range.Calc(); if range.IsReComputeByCantSplit() then begin // 调整上一行的下边界 - arr := cell_range_array_[i - 1]; - if ifarray then + arr := cell_range_matrix_[i-1]; + for _,r in arr do begin - for k,range in arr do + if ifnil(r) then begin - if range = 0 then + pos := i-2; + while pos > 0 do begin - pos := i - 2; - while pos > 0 do - begin - r := cell_range_array_[pos][k]; - if r = 0 then continue; - r.LowerBound := tc_y; - break; - end - end - else begin - range.LowerBound := tc_y; + rr := cell_range_matrix_[pos][_]; + pos--; + if ifnil(rr) then continue; + rr.LowerBound := tc_y; + break; end end + if not ifnil(r) then r.LowerBound := tc_y; end - page_ := docx_to_pdf_.GetNextPage(page_); + last_page_ := docx_to_pdf_.GetNextPage(last_page_); [x, y] := docx_to_pdf_.CalculateTextCoordinates(); {self.}EndY := y; + j := 0; recompute_flag := true; + arr := cell_range_matrix_[i]; + for _,r in arr do + if not ifnil(r) then r.SetTop(); break; end - if range.VMerge then vmerge_arr[j] := array(i, range.VMerge); - if not range.VMerge and range.DynamicHeight > max_height then max_height := range.DynamicHeight; + if range.Tc.TcPr.VMerge then + begin + b_merge_index := i; + e_merge_index := i + 1; + while ifnil(cell_range_matrix_[e_merge_index+1][j]) and e_merge_index < rows_-1 do + e_merge_index++; + merge_arr[e_merge_index][j] := b_merge_index; + range.VMerge := e_merge_index; + if ifnil(vmerge_height[e_merge_index]) or range.DynamicHeight > vmerge_height[e_merge_index] then + vmerge_height[e_merge_index] := range.DynamicHeight; + end + j++; end if recompute_flag then continue; - row_height[i] := max_height; - for _,col_index in vmerge_flag_arr do + i_height := 0; + for k,v in merge_arr[i] do begin - total_height := max_height; - row_index := vmerge_arr[col_index][0]; - r := cell_range_array_[row_index][col_index]; - // 统计总高度 - while row_index <= i-1 do - total_height += row_height[row_index++]; - r_height := total_height; - if r.DynamicHeight > r_height then r_height := r.DynamicHeight; - r.AlignHeight(r_height); + i_height := ts_trpr_array_[i].Height; + r := cell_range_matrix_[v][k]; + total_height := 0; + for index:=v to i-1 do + total_height += ts_trpr_array_[index].Height; + h := vmerge_height[i]; + if h > total_height + i_height then + i_height := h - total_height; + else + h := total_height + i_height; + r.AlignHeight(h); r.SetVAlign(); - max_height := r_height - total_height + max_height; end - for j,range in cell_range_array_[i] do + if i_height then ts_trpr_array_[i].Height := i_height; + for _,range in cell_range_matrix_[i] do begin - if not ifObj(range) or range.VMerge then continue; - range.AlignHeight(max_height); + if not ifObj(range) or range.Tc.TcPr.VMerge then continue; + range.AlignHeight(ts_trpr_array_[i].Height); range.SetVAlign(); {self.}EndY := range.EndY; - page_ := range.GetLastPage(); + last_page_ := range.GetLastPage(); end i++; end end; -function TSPdfTableRange.SetTblStylePr(var tc_pr: TcPr; type: string); +function TSPdfTableRange.OverrideTcPrByTblStylePrType(var tc_pr: TcPr; type: string); begin - {self.}SetTcPr(tc_pr); + // tc_pr应该是经过外层copy的 tbl_style_pr := docx_components_ware_.GetTblStylePrByType(tbl_pr_unit_decorator_.TblStyle.Val, type); if tbl_style_pr then tc_pr.Copy(tbl_style_pr.TcPr); end; @@ -268,12 +267,12 @@ begin {self.}Width := total_width; end; -function TSPdfTableRange.SetTblPr(var tbl_pr: TblPr); +function TSPdfTableRange.SetTblTblPr(var tbl: Tbl); begin new_tbl_pr := new TblPr(); - {self.}SetTblPrByStyleId(new_tbl_pr, tbl_pr.TblStyle.Val); - new_tbl_pr.Copy(tbl_pr); - tbl_pr.Copy(new_tbl_pr); + {self.}SetTblPrByStyleId(new_tbl_pr, tbl.TblPr.TblStyle.Val); + new_tbl_pr.Copy(tbl.TblPr); + tbl.TblPr.Copy(new_tbl_pr); end; function TSPdfTableRange.SetTblPrByStyleId(var tbl_pr: TblPr; style_id: string); @@ -288,15 +287,12 @@ begin end end; -function TSPdfTableRange.SetTrPr(var tr_pr: TrPr); +function TSPdfTableRange.SetTrTrPr(var tr: Tr); begin new_tr_pr := new TrPr(); {self.}SetTrPrByStyleId(new_tr_pr, tbl_pr_unit_decorator_.TblStyle.Val); - if ifObj(tr_pr) then - begin - new_tr_pr.Copy(tr_pr); - tr_pr.Copy(new_tr_pr); - end + new_tr_pr.Copy(tr.TrPr); + tr.TrPr.Copy(new_tr_pr); end; function TSPdfTableRange.SetTrPrByStyleId(var tr_pr: TrPr; style_id: string); @@ -311,15 +307,12 @@ begin end end; -function TSPdfTableRange.SetTcPr(var tc_pr: TcPr); +function TSPdfTableRange.SetTcTcPr(var tc: Tc); begin new_tc_pr := new TcPr(); {self.}SetTcPrByStyleId(new_tc_pr, tbl_pr_unit_decorator_.TblStyle.Val); - if ifObj(tc_pr) then - begin - new_tc_pr.Copy(tc_pr); - tc_pr.Copy(new_tc_pr); - end + new_tc_pr.Copy(tc.TcPr); + tc.TcPr.Copy(new_tc_pr); end; function TSPdfTableRange.SetTcPrByStyleId(var tc_pr: TcPr; style_id: string); @@ -334,18 +327,17 @@ begin end end; -function TSPdfTableRange.FirstValidTSPage(): TSPage; -begin - range := cell_range_array_[0][0]; - return ifObj(range) ? range.TSPage : page_; -end; - -function TSPdfTableRange.IsSamePage(): boolean; -begin - return page_ = {self.}TSPage; -end; - function TSPdfTableRange.GetLastPage(): TSPage; begin - return page_; + return last_page_; +end; + +function TSPdfTableRange.Rows(): integer; +begin + return rows_; +end; + +function TSPdfTableRange.Cols(): integer; +begin + return cols_; end; diff --git a/range/basic/TSPdfBordersRange.tsf b/range/basic/TSPdfBordersRange.tsf new file mode 100644 index 0000000..b6ab5a7 --- /dev/null +++ b/range/basic/TSPdfBordersRange.tsf @@ -0,0 +1,76 @@ +type TSPdfBordersRange = class(TSPdfBasicRange) +uses TSColorToolKit; +public + function Create(); + function Do();override; +public + TcPr: TcPr; + Left: boolean; + Top: boolean; + Right: boolean; + Bottom: boolean; + +private + function SetDash(val: string); + function DrawLine(border: Border; x1: real; y1: real; x2: real; y2: real); +end; + +function TSPdfBordersRange.Create(); +begin + class(TSPdfBasicRange).Create(); + {self.}TcPr := nil; + {self.}Left := false; + {self.}Top := false; + {self.}Right := false; + {self.}Bottom := false; +end; + +function TSPdfBordersRange.Do();override; +begin + // println("Left = {}, Top = {}, Right = {}, Bottom = {}, Tl2Br = {}, Tr2Bl = {}", Left, Top, Right, Bottom, Tl2Br, Tr2Bl); + if {self.}TcPr.Shd.Fill then + begin + [r, g, b] := array(0, 0, 0); + if {self.}TcPr.Shd.Fill <> "auto" then [r, g, b] := TSColorToolKit.HexToRGB({self.}TcPr.Shd.Fill); + {self.}TSPage.PdfPage.SetRGBFill(r/255, g/255, b/255); + {self.}TSPage.PdfPage.Rectangle({self.}EndX, {self.}EndY - {self.}DynamicHeight, {self.}Width, {self.}DynamicHeight); + {self.}TSPage.PdfPage.Fill(); + {self.}TSPage.PdfPage.SetRGBFill(0, 0, 0); + {self.}Left := true; + end + borders := {self.}TcPr.TcBorders; + if {self.}Left then + {self.}DrawLine(borders.Left, {self.}EndX, {self.}EndY, {self.}EndX, {self.}EndY - {self.}DynamicHeight); + if {self.}Top then + {self.}DrawLine(borders.Top, {self.}EndX, {self.}EndY, {self.}EndX + {self.}Width, {self.}EndY); + if {self.}Right then + {self.}DrawLine(borders.Right, {self.}EndX + {self.}Width, {self.}EndY, {self.}EndX + {self.}Width, {self.}EndY - {self.}DynamicHeight); + if {self.}Bottom then + {self.}DrawLine(borders.Bottom, {self.}EndX, {self.}EndY - {Self.}DynamicHeight, {self.}EndX + {self.}Width, {self.}EndY - {self.}DynamicHeight); + if borders.Tl2Br then + {self.}DrawLine(borders.Tl2Br, {self.}EndX, {self.}Y, {self.}EndX + {self.}Width, {self.}EndY - {self.}DynamicHeight); + if borders.Tr2Bl then + {self.}DrawLine(borders.Tr2Bl, {self.}EndX + {self.}Width, {self.}Y, {self.}EndX, {self.}EndY - {self.}DynamicHeight); +end; + +function TSPdfBordersRange.SetDash(val: string); +begin + if val = "single" or ifnil(val) then + {self.}TSPage.PdfPage.SetDash(array(), 0, 0); + if val = "dashed" then + {self.}TSPage.PdfPage.SetDash(array(1), 1, 0); +end; + +function TSPdfBordersRange.DrawLine(border: Border; x1: real; y1: real; x2: real; y2: real); +begin + [r, g, b] := array(0, 0, 0); + line_width := border.Sz ?: 0.5; + {self.}SetDash(border.Val); + if border.Color and border.Color <> "auto" then [r, g, b] := TSColorToolKit.HexToRGB(border.Color); + {self.}TSPage.PdfPage.SetRGBStroke(r, g, b); + {self.}TSPage.PdfPage.SetLineWidth(line_width); + {self.}TSPage.PdfPage.MoveTo(x1, y1); + {self.}TSPage.PdfPage.LineTo(x2, y2); + {self.}TSPage.PdfPage.Stroke(); + {self.}TSPage.PdfPage.SetRGBStroke(0, 0, 0); +end; diff --git a/range/basic/TSPdfRectangleRange.tsf b/range/basic/TSPdfRectangleRange.tsf deleted file mode 100644 index 736405a..0000000 --- a/range/basic/TSPdfRectangleRange.tsf +++ /dev/null @@ -1,33 +0,0 @@ -type TSPdfRectangleRange = class(TSPdfBasicRange) -uses TSColorToolKit; -public - function Create(); - function Do();override; -public - TcPr: TcPr; -end; - -function TSPdfRectangleRange.Create(); -begin - class(TSPdfBasicRange).Create(); -end; - -function TSPdfRectangleRange.Do();override; -begin - // {self.}Page.SetRGBStroke(1.0, 0.0, 0.0); - // println("page = {}, endx = {}, endy = {}, DynamicHeight = {}, Width = {}", {self.}Page, {self.}EndX, {self.}EndY, {self.}DynamicHeight, {self.}Width); - if {self.}TcPr.Shd.Fill then - begin - [r, g, b] := array(0, 0, 0); - if {self.}TcPr.Shd.Fill <> "auto" then [r, g, b] := TSColorToolKit.HexToRGB({self.}TcPr.Shd.Fill); - {self.}TSPage.PdfPage.SetRGBFill(r/255, g/255, b/255); - {self.}TSPage.PdfPage.Rectangle({self.}EndX, {self.}EndY - {self.}DynamicHeight, {self.}Width, {self.}DynamicHeight); - {self.}TSPage.PdfPage.Fill(); - {self.}TSPage.PdfPage.SetRGBFill(0, 0, 0); - end - {self.}TSPage.PdfPage.SetGrayStroke(0.5); - {self.}TSPage.PdfPage.SetLineWidth(0.25); - {self.}TSPage.PdfPage.Rectangle({self.}EndX, {self.}EndY - {self.}DynamicHeight, {self.}Width, {self.}DynamicHeight); - {self.}TSPage.PdfPage.Stroke(); - {self.}TSPage.PdfPage.SetGrayStroke(0); -end; diff --git a/ware/TSNumberingWare.tsf b/ware/TSNumberingWare.tsf index 77d7910..c6864a7 100644 --- a/ware/TSNumberingWare.tsf +++ b/ware/TSNumberingWare.tsf @@ -65,6 +65,8 @@ begin return format("%d", num); else if num_fmt = "chineseCountingThousand" then return {self.}ChineseCountingThousand(num); + else + return format("%d", num); end; function TSNumberingWare.ChineseCountingThousand(n: integer): string;