From 5121a94b158bdc88947d504e970573cc500fa87a Mon Sep 17 00:00:00 2001 From: csh Date: Wed, 7 May 2025 14:16:17 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=AC=E5=BC=8F=E5=9F=BA=E5=87=86=E8=B0=83?= =?UTF-8?q?=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/DTPAdvancedRanges.tsf | 107 +- internal/DTPAdvancedRanges_bk.tsf | 2411 ----------------------------- 2 files changed, 68 insertions(+), 2450 deletions(-) delete mode 100644 internal/DTPAdvancedRanges_bk.tsf diff --git a/internal/DTPAdvancedRanges.tsf b/internal/DTPAdvancedRanges.tsf index 55ef0c9..2a5584b 100644 --- a/internal/DTPAdvancedRanges.tsf +++ b/internal/DTPAdvancedRanges.tsf @@ -135,6 +135,7 @@ private function FldSimple(fld_simple: fldSimple); function Hyperlink(hyperlink: Hyperlink); function OMathPara(o_math_para: OMathPara); + function OMath(o_math: OMath); private [weakref]docx_to_pdf_: TSDocxToPdf; @@ -236,7 +237,7 @@ public function AdjustOffset(x: real; y: real);override; public - BaseY: real; // 基准Y值 + BaseHeight: real; // 基准高度 private [weakref]docx_to_pdf_: TSDocxToPdf; @@ -254,8 +255,9 @@ public function SetMathSize(); public - BaseY: real; // 基准Y值 + BaseHeight: real; // 基准高度 BaseSz: real; // 基准字体大小 + SingleLine: boolean; // 是否单行公式 private [weakref]docx_to_pdf_: TSDocxToPdf; @@ -272,7 +274,7 @@ public function AdjustOffset(x: real; y: real);overload; public - BaseY: real; // 基准Y值 + BaseHeight: real; // 基准高度 BaseSz: real; // 基准字体大小 private @@ -290,7 +292,7 @@ public function AdjustOffset(x: real; y: real);overload; public - BaseY: real; // 基准Y值 + BaseHeight: real; // 基准高度 BaseSz: real; // 基准字体大小 private @@ -308,7 +310,7 @@ public function AdjustOffset(x: real; y: real);overload; public - BaseY: real; // 基准Y值 + BaseHeight: real; // 基准高度 BaseSz: real; // 基准字体大小 private @@ -326,7 +328,7 @@ public function AdjustOffset(x: real; y: real);overload; public - BaseY: real; // 基准Y值 + BaseHeight: real; // 基准高度 BaseSz: real; // 基准字体大小 private @@ -344,7 +346,7 @@ public function AdjustOffset(x: real; y: real);overload; public - BaseY: real; // 基准Y值 + BaseHeight: real; // 基准高度 BaseSz: real; // 基准字体大小 private @@ -362,7 +364,7 @@ public function AdjustOffset(x: real; y: real);overload; public - BaseY: real; // 基准Y值 + BaseHeight: real; // 基准高度 BaseSz: real; // 基准字体大小 private @@ -380,7 +382,7 @@ public function AdjustOffset(x: real; y: real);overload; public - BaseY: real; // 基准Y值 + BaseHeight: real; // 基准高度 BaseSz: real; // 基准字体大小 private @@ -398,7 +400,7 @@ public function AdjustOffset(x: real; y: real);overload; public - BaseY: real; // 基准Y值 + BaseHeight: real; // 基准高度 BaseSz: real; // 基准字体大小 private @@ -634,7 +636,7 @@ begin y_offset := {self.}StartY - offset; for _,range in range_array_ do begin - if range is class(OMathParaRange) then // 公式不是y值,需要处理公式 + if range is class(OMathRange) then // 公式不是y值,需要处理公式 range.Offset(x, y, page); // range.Offset(0, 841.9, page); else @@ -803,10 +805,7 @@ begin else if element.LocalName = "oMath" then begin // 公式嵌入段落 - o_math_para := new OMathPara(); - o_math_para.XmlChildOMath := element; - // o_math_para.OMath.Copy(element); - {self.}OMathPara(o_math_para); + {self.}OMath(element); end end {self.}RangesToLines(); @@ -1078,10 +1077,23 @@ end; function PRange.OMathPara(o_math_para: OMathPara); begin - math_range := new OMathParaRange(docx_to_pdf_, o_math_para); - math_range.Width := {self.}Width; + math_para_range := new OMathParaRange(docx_to_pdf_, o_math_para); + math_para_range.Width := 0; + math_para_range.Parent := self; + math_para_range.Calc(); + body_range_array_[length(body_range_array_)] := math_para_range; +end; + +function PRange.OMath(o_math: OMath); +begin + math_range := new OMathRange(docx_to_pdf_, o_math); + math_range.Width := 0; math_range.Parent := self; + math_range.XOffset := 0; + math_range.YOffset := 0; + math_range.SetMathSize(); math_range.Calc(); + math_range.AdjustOffset(0, -math_range.DynamicHeight); body_range_array_[length(body_range_array_)] := math_range; end; @@ -1209,7 +1221,8 @@ begin if range is class(TextRange) and range.RPr.Sz.Val > pline_range.TextMaxSize then pline_range.TextMaxSize := range.RPr.Sz.Val; if range.DynamicHeight > pline_range.DynamicHeight then pline_range.DynamicHeight := range.DynamicHeight; - range.XOffset := pline_range.XOffset; + range.AdjustOffset(pline_range.XOffset, 0); + // range.XOffset := pline_range.XOffset; range.Parent := pline_range; pline_range.AddRange(range); pline_range.XOffset += range.Width; @@ -2285,6 +2298,7 @@ begin o_math_range_.Parent := self; o_math_range_.XOffset := 0; o_math_range_.YOffset := 0; + o_math_range_.SingleLine := true; o_math_range_.SetMathSize(); o_math_range_.Calc(); o_math_range_.AdjustOffset(0, -o_math_range_.DynamicHeight); @@ -2295,7 +2309,7 @@ end; function OMathParaRange.AdjustOffset(x: real; y: real);override; begin class(BasicRange).AdjustOffset(x, y); - o_math_para_.AdjustOffset(x, y); + o_math_range_.AdjustOffset(x, y); end; function OMathRange.Create(docx_to_pdf: TSDocxToPdf; element: OpenXmlElement); @@ -2303,8 +2317,9 @@ begin class(AdvancedRange).Create(); docx_to_pdf_ := docx_to_pdf; element_ := element; - {self.}BaseY := 0; + {self.}BaseHeight := 0; {self.}BaseSz := 0; + {self.}SingleLine := false; end; function OMathRange.Do();override; @@ -2333,6 +2348,7 @@ begin x := {self.}XOffset; y := {self.}YOffset; elements := element_.Elements(); + up_h := 0; for _,element in elements do begin range := nil; @@ -2344,7 +2360,7 @@ begin else if element.LocalName = "f" then begin range := new OMathFRange(docx_to_pdf_, element); - range.BaseSz := {self.}BaseSz; + range.BaseSz := {self.}SingleLine ? {self.}BaseSz : 0.7 * {self.}BaseSz; end else if element.LocalName = "rad" then begin @@ -2389,15 +2405,18 @@ begin x += range.Width; // 下一个元素偏移位置 {self.}Width += range.Width; - if {self.}DynamicHeight < range.DynamicHeight then - {self.}DynamicHeight := range.DynamicHeight; + if range.BaseHeight > {self.}BaseHeight then + {self.}BaseHeight := range.BaseHeight; + if range.DynamicHeight - range.BaseHeight > up_h then + up_h := range.DynamicHeight - range.BaseHeight; + // if range.DynamicHeight > {self.}DynamicHeight then + // {self.}DynamicHeight := range.DynamicHeight; + range_array_[length(range_array_)] := range; end + {self.}DynamicHeight := {self.}BaseHeight + up_h; for _,range in range_array_ do - begin - h := ({self.}DynamicHeight - range.DynamicHeight) / 2; - range.AdjustOffset(0, h); - end + range.AdjustOffset(0, {self.}BaseHeight - range.BaseHeight); end; function OMathRange.SetMathSize(); @@ -2445,8 +2464,7 @@ end; function OMathFRange.Calc();override; begin - bar_margin := {self.}BaseSz * 0.1; - x := {self.}XOffset + bar_margin; + x := {self.}XOffset; y := {self.}YOffset; // 分子分母单独计算高度,最后再合并 @@ -2464,7 +2482,7 @@ begin num_range.YOffset := y; num_range.Calc(); // 需要得到高宽 - max_len := max(den_range.Width, num_range.Width) + 2*bar_margin; + max_len := max(den_range.Width, num_range.Width); xo := (max_len - num_range.Width) / 2; num_range.AdjustOffset(xo, den_range.DynamicHeight + 0.3 * {self.}BaseSz); @@ -2479,9 +2497,12 @@ begin line_range.LineWidth := 0.04 * {self.}BaseSz; {self.}DynamicHeight := num_range.DynamicHeight + den_range.DynamicHeight + 0.3 * {self.}BaseSz; - {self.}Width := line_range.Width + bar_margin; + {self.}Width := line_range.Width; range_array_ union= array(den_range, num_range, line_range); + + // 分式的基准在line处 + {self.}BaseHeight := den_range.DynamicHeight; end; function OMathFRange.AdjustOffset(x: real; y: real);override; @@ -2613,6 +2634,7 @@ begin range_array_[length(range_array_)] := text_range; {self.}Width += text_range.Width; end + {self.}BaseHeight := {self.}BaseSz / 4; end; function OMathNaryRange.Create(docx_to_pdf: TSDocxToPdf; nary: Nary); @@ -2670,13 +2692,13 @@ begin symbol_range.DynamicHeight := size; sub_range := new OMathRange(docx_to_pdf_, nary_.Sub); - sub_range.BaseSz := {self.}BaseSz * 0.5; + sub_range.BaseSz := {self.}BaseSz / 2; sub_range.XOffset := x; sub_range.YOffset := y; sub_range.Calc(); sup_range := new OMathRange(docx_to_pdf_, nary_.Sup); - sup_range.BaseSz := {self.}BaseSz * 0.5; + sup_range.BaseSz := {self.}BaseSz / 2; sup_range.XOffset := x; sup_range.YOffset := y; sup_range.Calc(); // 需要得到高宽 @@ -2709,6 +2731,7 @@ begin {self.}Width += e_range.Width; {self.}DynamicHeight := max({self.}DynamicHeight, e_range.DynamicHeight); + {self.}BaseHeight := symbol_range.DynamicHeight / 4 + sub_range.DynamicHeight; end; function OMathRadRange.Create(docx_to_pdf: TSDocxToPdf; rad: Rad); @@ -2740,11 +2763,11 @@ end; function OMathRadRange.Calc();override; begin - x := {self.}XOffset + 0.2*{self.}BaseSz; + x := {self.}XOffset; y := {self.}YOffset; deg_range := new OMathRange(docx_to_pdf_, rad_.Deg); - deg_range.BaseSz := {self.}BaseSz * 0.5; + deg_range.BaseSz := {self.}BaseSz / 2; deg_range.XOffset := x; deg_range.YOffset := y; deg_range.Calc(); @@ -2771,7 +2794,7 @@ begin symbol_range.RPr.Sz.Val := size; symbol_range.DynamicHeight := size; - deg_range.AdjustOffset(0, -e_range.DynamicHeight * 0.5); + deg_range.AdjustOffset(0, -e_range.DynamicHeight / 2); symbol_range.AdjustOffset(deg_range.Width, 0); e_range.AdjustOffset(size*0.3 + deg_range.Width, 0); @@ -2785,6 +2808,8 @@ begin {self.}Width := deg_range.Width + symbol_range.Width + e_range.Width + 0.3*size; {self.}DynamicHeight := symbol_range.DynamicHeight; + + {self.}BaseHeight := symbol_range.DynamicHeight / 2; end; function OMathSSupRange.Create(docx_to_pdf: TSDocxToPdf; s_sup: SSup); @@ -2816,7 +2841,7 @@ end; function OMathSSupRange.Calc();override; begin - x := {self.}XOffset + 0.2*{self.}BaseSz; + x := {self.}XOffset; y := {self.}YOffset; e_range := new OMathRange(docx_to_pdf_, s_sup_.E); @@ -2830,13 +2855,14 @@ begin sup_range.XOffset := x; sup_range.YOffset := y; sup_range.Calc(); - sup_range.AdjustOffset(e_range.Width, e_range.DynamicHeight * 0.5); + sup_range.AdjustOffset(e_range.Width, e_range.DynamicHeight / 2); range_array_ union= array(e_range, sup_range); {self.}Width := e_range.Width + sup_range.Width; - h := sup_range.DynamicHeight + e_range.DynamicHeight * 0.5; + h := sup_range.DynamicHeight + e_range.DynamicHeight / 2; {self.}DynamicHeight := max(h, e_range.DynamicHeight); + {self.}BaseHeight := e_range.BaseHeight; end; function OMathSSubRange.Create(docx_to_pdf: TSDocxToPdf; s_sub: SSub); @@ -2889,6 +2915,7 @@ begin {self.}Width += e_range.Width + sub_range.Width; h := e_range.DynamicHeight + sub_range.DynamicHeight - {self.}BaseSz * 0.4; {self.}DynamicHeight := max(h, e_range.DynamicHeight); + {self.}BaseHeight := e_range.BaseHeight; end; function OMathDRange.Create(docx_to_pdf: TSDocxToPdf; d: D); @@ -2966,6 +2993,7 @@ begin range_array_ union= array(beg_range, e_range, end_range); {self.}Width := beg_range.Width + e_range.Width + end_range.Width; {self.}DynamicHeight := max_h; + {self.}BaseHeight := {self.}DynamicHeight / 2; end; function OMathFuncRange.Create(docx_to_pdf: TSDocxToPdf; func: Func); @@ -3021,6 +3049,7 @@ begin {self.}Width += f_name_range.Width + e_range.Width; {self.}DynamicHeight := max(f_name_range.DynamicHeight, e_range.DynamicHeight); + {self.}BaseHeight := f_name_range.BaseHeight; end; end. diff --git a/internal/DTPAdvancedRanges_bk.tsf b/internal/DTPAdvancedRanges_bk.tsf deleted file mode 100644 index 961b489..0000000 --- a/internal/DTPAdvancedRanges_bk.tsf +++ /dev/null @@ -1,2411 +0,0 @@ -unit DTPAdvancedRanges; -interface -uses DTPPrimitiveRanges, DTPUtils, DTPModules, SharedML, DocxML, DrawingMLUnitDecorator, DocxMLUnitDecorator; - -type RangeCollection = class(BasicRange) -public - function Create(); - function Do();override; - function Add(range: BasicRange); - -private - range_array_: array of BasicRange; -end; - -type ParagraphLineRange = class(BasicRange) -public - function Create(pg: Page); - function Do();override; - function AddRange(range: BasicRange); - function SetAllRangeProp(pg: Page; sx: real; sy: real; ex: real; ey: real; w: real; fh: real; dh: real); - function Align(jc: string); - function AdjustRangeOffset(pg: Page; x_offset: real; y_offset: real); - function AlignRightBound(right_bound: real); - function Offset(x_offset: real; y_offset; real); - -private - range_array_: array of BasicRange; -end; - -type ParagraphRange = class(BasicRange) -public - function Create(docx_to_pdf: TSDocxToPdf; pg: Page; components: DocxComponentsModule; paragraph: P); - function Calc(); - function Do();override; - function SetTblStyleIdAndType(style_id: string; type: string); - function SetNumPages(num: integer); - function RangesToLines(); - function GetLastPage(): Page; - function AdjustRangeOffset(pg: Page; x_offset: real; y_offset: real); - function GetParagraphLineRangeArr(): array of ParagraphLineRange; - function Empty(): boolean; - function Offset(x: real; y: real); - -private - function SetPPPr(var p: P); - function SetPPrByStyleId(var ppr: PPr; style_id: string); - function SetRRPr(var r: R; ppr_unit_decorator: PPrUnitDecorator); - function SetRPrByStyleId(var rpr: RPr; style_id: string); - function SetRPrByTblStyleId(var rpr: RPr; style_id: string); - function SetLvlText(); - function GetImageFileType(data: binary): string; - function GetImageData(id: string): PdfImage; - function GetParagraphLineSpace(size: real; line: integer; line_rule: string): real; - function BasicRangesToParagraphLineRange(): tableArray; - function UpdateTextRangeWidth(); - function CheckAndAddPage(y: real; offset: real): boolean; - function SplitTextToTextRange(range_arr: array of BasicRange; text: string; rpr: RPrUnitDecorator; link: string); - function RAlternateContent(r: R); - function RDrawing(r: R); - function RFldChar(r: R; stack: Stack); - function RFootnoteReference(r: R); - function RFootnoteRef(r: R); - function RObject(r: R); - function RT(r: R; link: string); - function FldSimple(fld_simple: FldSimple); - function Hyperlink(hyperlink: Hyperlink); - - function SetLinesAlignment(); - function ResetCoordinates(); - function NewParagraphLineRange(): ParagraphLineRange; - function BookMarkLinkToc(); - function HyperlinkToToc(); - function HyperlinkToTextRange(hyperlink: Hyperlink; ppr: PPrUnitDecorator); - function GetXYCordinates(): array of real; - function AlignRightBound(); - function Init(); - function OMathPara(element: OMathPara); - -private - [weakref]docx_to_pdf_: TSDocxToPdf; - [weakref]docx_components_module_: DocxComponentsModule; - [weakref]paragraph_: P; - [weakref]page_: Page; - body_range_array_: array of BasicRange; // 正文的range - bullet_range_array_: array of BasicRange; // 项目符号的range - line_range_array_: array of ParagraphLineRange; - - hyperlink_array_: tableArray; - bookmark_array_: tableArray; - ppr_unit_decorator_: PPrUnitDecorator; - placeholder_array_: tableArray; - table_style_id_: string; - table_style_type_: string; - empty_: boolean; - right_bound_: real; - footnote_reference_hash_: hash; -end; - -type TableRange = class(BasicRange) -public - function Create(docx_to_pdf: TSDocxToPdf; pg: Page; components: DocxComponentsModule; table: Tbl); - function Do();override; - function Calc(); - function GetLastPage(): Page; - function Rows(): integer; - function Cols(): integer; - function RowLowerBound(row: integer): real; - -private - function CreateTableMatrix(grid_cols: array of GridColUnitDecorator; trs: array of Tr); - function ComputeMatrixCells(); - 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 SetTrTrPr(var tr_pr: TrPr); - function SetTrPrByStyleId(var tr_pr: TrPr; style_id: string); - function SetTcTcPr(var tc: Tc); - function SetTcPrByStyleId(var tc_pr: TcPr; style_id: string); - function OverrideTcPrByTblStylePrType(var tc_pr: TcPr; type: string); - -private - [weakref]docx_to_pdf_: TSDocxToPdf; - [weakref]last_page_: Page; - [weakref]docx_components_module_: DocxComponentsModule; - [weakref]table_: Tbl; - tbl_pr_unit_decorator_: TblPrUnitDecorator; - ts_trpr_array_: array of TSTrProperty; - cell_range_matrix_: array of CellRange; - row_lower_bound_: hash; - rows_: integer; - cols_: integer; -end; - -type CellRange = class(BasicRange) -public - function Create(docx_to_pdf: TSDocxToPdf; pg: Page; components: DocxComponentsModule; tc: Tc; tbl_pr: TblPr; trp: TSTrProperty); - function Calc(); - function Do();override; - function SetPage(pg: Page); - function GetLastPage(); - function AlignHeight(height: real; lb: real); - function SetVAlign(); - function IsReComputeByCantSplit(): boolean; - function IfRemoveEmptyRectangle(): boolean; - function SetTop(); - - property Tc read tc_; - -private - function GetCellPrType(): string; - function SetBorderRange(range: BordersRange); - -public - RemoveFlag: boolean; - Row: integer; - Col: integer; - VMerge: integer; - [weakref]TSTrPr: TSTrProperty; - -private - [weakref]docx_to_pdf_: TSDocxToPdf; - [weakref]last_page_: Page; - [weakref]docx_components_module_: DocxComponentsModule; - [weakref]tc_: Tc; - [weakref]tbl_pr_: TblPr; - tc_pr_unit_decorator_: TcPrUnitDecorator; - region_array_: array of Region; // 单元格可能跨页,所以可能存在多个 - top_: boolean; -end; - -type ColumnRange = class(BasicRange) -public - function Create(docx_to_pdf: TSDocxToPdf; pg: Page; components: DocxComponentsModule); - function AddElement(ele: Element); - function Elements(): array of Element; - function GetLastPage(): Page; - function Do();override; - -private - [weakref]docx_to_pdf_: TSDocxToPdf; - [weakref]docx_components_module_: DocxComponentsModule; - [weakref]page_: Page; - elements_: array of Elements; - paragraph_: P; - last_y_: real; -end; - -type MathRange = class(BasicRange) -public - function Create(docx_to_pdf: TSDocxToPdf; pg: Page; o_math_para: OMathPara); - function Calc(); - function Do();override; - -private - [weakref]docx_to_pdf_: TSDocxToPdf; - [weakref]o_math_para_: OMathPara; - sub_math_range_: SubMathRange; -end; - -type SubMathRange = class(BasicRange) -public - function Create(docx_to_pdf: TSDocxToPdf; pg: Page; element: OpenXmlElement; sz: real); - function Do();override; - function Calc(); - -private - function MathR(r: R; sz: real; x: real; y: real): RangeCollection; - function MathF(f: F; sz: real; x: real; y: real): RangeCollection; - function MathRad(rad: Rad; sz: real; x: real; y: real): RangeCollection; - function MathNary(nary: Nary; sz: real; x: real; y: real): RangeCollection; - function MathSSup(s_sup: SSup; sz: real; x: real; y: real): RangeCollection; - -private - [weakref]docx_to_pdf_: TSDocxToPdf; - [weakref]ts_page_: Page; - [weakref]openxml_element_: OpenXmlElement; - range_collection_: RangeCollection; - sz_: real; -end; - -implementation - -function MathRange.Create(docx_to_pdf: TSDocxToPdf; pg: Page; o_math_para: OMathPara); -begin - class(BasicRange).Create(); - docx_to_pdf_ := docx_to_pdf; - o_math_para_ := o_math_para; - sub_math_range_ := nil; - {self.}Page := pg; -end; - -function MathRange.Calc(); -begin - sub_math_range_ := new SubMathRange(docx_to_pdf_, {self.}Page, o_math_para_.OMath, 11); - sub_math_range_.StartX := {self.}StartX; - sub_math_range_.StartY := {self.}StartY; - sub_math_range_.EndX := {self.}EndX; - sub_math_range_.EndY := {self.}EndY; - sub_math_range_.DynamicHeight := 100; - sub_math_range_.Calc(); - - {self.}EndX := sub_math_range_.EndX; - {self.}EndY := sub_math_range_.EndY; - {self.}Width := sub_math_range_.Width; - {self.}DynamicHeight := sub_math_range_.DynamicHeight; -end; - -function MathRange.Do();override; -begin - sub_math_range_.Do(); -end; - -function SubMathRange.Create(docx_to_pdf: TSDocxToPdf; pg: Page; element: OpenXmlElement; sz: real); -begin - class(BasicRange).Create(); - docx_to_pdf_ := docx_to_pdf; - ts_page_ := pg; - openxml_element_ := element; - {self.}Page := pg; - range_collection_ := new RangeCollection(); - sz_ := sz; -end; - -function SubMathRange.Do();override; -begin - range_collection_.Do(); -end; - -function SubMathRange.Calc(); -begin - elements := openxml_element_.Elements(); - min_y := {self.}StartY; - max_y := {self.}StartY; - {self.}EndX := {self.}StartX; - {self.}EndY := {self.}StartY; - for _,element in elements do - begin - range := nil; - if element.LocalName = "r" then - range := {self.}MathR(element, sz_, {self.}EndX, {self.}EndY); - else if element.LocalName = "f" then - range := {self.}MathF(element, sz_, {self.}EndX, {self.}EndY); - else if element.LocalName = "rad" then - range := {self.}MathRad(element, sz_, {self.}EndX, {self.}EndY); - else if element.LocalName = "nary" then - range := {self.}MathNary(element, sz_, {self.}EndX, {self.}EndY); - else if element.LocalName = "sSup" then - range := {self.}MathSSup(element, sz_, {self.}EndX, {self.}EndY); - - if not ifObj(range) then - begin - echo forma("Not support <%s>\n", element.ElementName); - continue; - end - if min_y > range.EndY then min_y := range.EndY; - if max_y < range.EndY + range.DynamicHeight then max_y := range.EndY + range.DynamicHeight; - - {self.}EndX := range.EndX; - {self.}EndY := range.EndY; - {self.}Width += range.Width; - range_collection_.Add(range); - end - range_collection_.DynamicHeight := max_y - min_y; - {self.}DynamicHeight := range_collection_.DynamicHeight; -end; - -function SubMathRange.MathSSup(s_sup: SSup; sz: real; x: real; y: real): RangeCollection; -begin - prange := new RangeCollection(); - prange.StartX := x; - prange.StartY := y; - prange.EndX := x; - prange.EndY := y; - - e_range := new SubMathRange(docx_to_pdf_, {self.}Page, s_sup.E, sz); - e_range.StartX := x; - e_range.StartY := y; - e_range.Calc(); - - sup_range := new SubMathRange(docx_to_pdf_, {self.}Page, s_sup.Sup, sz * 0.4); - sup_range.StartX := x + e_range.Width; - sup_range.StartY := y + sz * 0.57; - sup_range.Calc(); - - prange.Add(e_range); - prange.Add(sup_range); - prange.EndX := maxValue(array(e_range.EndX, sup_range.EndX)); - prange.EndY := e_range.EndY; - prange.Width := prange.EndX - prange.StartX; - prange.DynamicHeight := e_range.DynamicHeight + sup_range.DynamicHeight * 0.5; - - return prange; -end; - -function SubMathRange.MathR(r: R; sz: real; x: real; y: real): RangeCollection; -begin - // println("x = {}, y = {}", x, y); - prange := new RangeCollection(); - prange.StartX := x; - prange.StartY := y; - prange.EndX := x; - prange.EndY := y; - text := r.T.Text(); - pos := 1; - // println("text = {}", text); - while pos <= length(text) do - begin - num := Utf8CharLengthFromByte(text[pos]); - a_word := text[pos : pos+num-1]; - if num = 1 or DTPUtils.IsChineseChar(a_word) or DTPUtils.IsChinesePunctuation(a_word) then - begin - word := utf8ToAnsi(a_word); - font_obj := docx_to_pdf_.Font.GetCNSFont("SimSun", false, true); - end - else begin - word := class(SymbolMapper).SymbolChr(a_word); - if ifnil(word) then - begin - echo format("error symbol {{%s}}", a_word); - word := chr(0x20); - end - font_obj := docx_to_pdf_.Font.GetSymbolFont(); - end - rpr := new RPr(); - rpr.Sz.Val := sz; - ts_page_.PdfPage.SetFontAndSize(font_obj, rpr.Sz.Val); - word_width := ts_page_.PdfPage.TextWidth(word); - text_range := new TextRange(); - text_range.RPr := rpr; - text_range.Text := word; - text_range.Font := font_obj; - text_range.StartX := prange.EndX; - text_range.StartY := prange.EndY; - text_range.Page := {self.}Page; - text_range.EndX := text_range.StartX; - text_range.EndY := text_range.StartY; - text_range.Width := word_width; - pos += num; - prange.Add(text_range); - prange.EndX += text_range.Width; - prange.Width += text_range.Width; - end - prange.DynamicHeight := sz; - return prange; -end; - -function SubMathRange.MathF(f: F; sz: real; x: real; y: real); -begin - prange := new ParagraphLineRange(); - prange.StartX := x; - prange.StartY := y; - prange.EndX := x; - prange.EndY := y; - - den_range := new SubMathRange(docx_to_pdf_, {self.}Page, f.Den, sz); - den_range.StartX := x; - den_range.StartY := y; - den_range.Calc(); - - num_range := new SubMathRange(docx_to_pdf_, {self.}Page, f.Num, sz); - num_range.StartX := x; - num_range.StartY := y + 1.418 * sz; - num_range.Calc(); - - max_len := max(den_range.Width, num_range.Width); - bar := max_len / 0.9; - line_range := new LineRange(); - line_range.StartX := x - (bar - max_len) / 2; - line_range.StartY := y + 0.928 * sz; - line_range.EndX := line_range.StartX; - line_range.EndY := line_range.StartY; - line_range.Width := bar; - line_range.Page := {self.}Page; - line_range.LineWidth := 0.04 * sz; - - prange.EndX := maxValue(array(den_range.EndX, num_range.EndX, line_range.EndX)); - prange.AddRange(den_range); - prange.AddRange(num_range); - prange.AddRange(line_range); - - return prange; - - // TODO: delete - // pg := {self.}Page.PdfPage; - // pg.SetFontAndSize(font, sz); - // len1 := pg.TextWidth(range1.Text); - // len2 := pg.TextWidth(range2.Text); - // max_len := len1 > len2 ? len1 : len2; - // bar := max_len / 0.9; - // pg.SetLineWidth(0.05*sz); - // pg.SetRGBStroke(0, 0, 0); - // x := {self.}StartX - (bar - max_len) / 2; - // y := {self.}StartY + 0.928 * sz; - // pg.MoveTo(x, y); - // pg.LineTo(x + bar, y); - // pg.Stroke(); - - // elements := f.Den.Elements(); - // {self.}TraverseElement(elements); - // elements := f.Num.Elements(); - // {self.}TraverseElement(elements); - - // for _,element in elements do - // begin - // if - // range1 := new TextRange(); - // range1.Text := "a"; - // range1.EndX := {self.}StartX; - // range1.EndY := {self.}StartY; - // rpr := new RPr(); - // rpr.Sz.Val := sz; - // range1.RPr := rpr; - // range1.Page := {self.}Page; - // range1.Font := font; - // range1.Do(); - // end - // for _,element in elements do - // begin - // range2 := new TextRange(); - // range2.Text := "b"; - // range2.EndX := {self.}StartX; - // range2.EndY := {self.}StartY + 1.418*sz; - // rpr := new RPr(); - // rpr.Sz.Val := sz; - // range2.RPr := rpr; - // range2.Page := {self.}Page; - // range2.Font := font; - // range2.Do(); - // // if element.LocalName = "r" then - // // begin - // // range1 := new TextRange(); - // // range1.Text := element.T.Text(); - // // end - // end -end; - -function SubMathRange.MathRad(rad: Rad; sz: real; x: real; y: real): ParagraphLineRange; -begin - prange := new ParagraphLineRange(); - prange.StartX := x; - prange.StartY := y; - prange.EndX := x; - prange.EndY := y; - - symbol := chr(0xD6); - symbol_font := docx_to_pdf_.Font.GetSymbolFont(); - pg := {self.}Page.PdfPage; - pg.SetFontAndSize(symbol_font, sz); - symbol_range := new TextRange(); - symbol_range.Text := symbol; - symbol_range.EndX := x; - symbol_range.EndY := y; - symbol_range.Font := symbol_font; - symbol_range.Width := pg.TextWidth(symbol); - symbol_range.RPr := new RPr(); - symbol_range.RPr.Sz.Val := sz; - symbol_range.Page := {self.}Page; - - deg_range := new SubMathRange(docx_to_pdf_, {self.}Page, rad.Deg, sz * 0.5); - deg_range.StartX := x; - deg_range.StartY := y + sz * 0.57; - deg_range.Calc(); - - e_range := new SubMathRange(docx_to_pdf_, {self.}Page, rad.E, sz); - e_range.StartX := x + symbol_range.Width; - e_range.StartY := y; - e_range.Calc(); - - line_range := new LineRange(); - line_range.StartX := x + symbol_range.Width * 0.9; - line_range.StartY := y + sz * 0.9; - line_range.EndX := line_range.StartX; - line_range.EndY := line_range.StartY; - line_range.Width := e_range.Width + symbol_range.Width / 3; - line_range.Page := {self.}Page; - line_range.LineWidth := 0.04 * sz; - - prange.EndX := maxValue(array(symbol_range.EndX, e_range.EndX, deg_range.EndX, line_range.EndX)); - prange.AddRange(symbol_range); - prange.AddRange(deg_range); - prange.AddRange(e_range); - prange.AddRange(line_range); - - return prange; - - // TODO: delete - // range := new TextRange(); - // range.Text := chr_hash_['α']; - // range.EndX := {self.}StartX; - // range.EndY := {self.}StartY + sz * 0.57; - // range.Font := symbol_font; - // range.RPr := new RPr(); - // range.RPr.Sz.Val := sz / 2; - // range.Page := {self.}Page; - // range.Do(); - - // range := new TextRange(); - // range.Text := "abcd"; - // range.EndX := {self.}StartX + symbol_w; - // range.EndY := {self.}StartY; - // range.Font := font; - // range.RPr := new RPr(); - // range.RPr.Sz.Val := sz; - // range.Page := {self.}Page; - // range.Do(); - - // pg.SetFontAndSize(font, sz); - // pg.SetLineWidth(0.04*sz); - // pg.SetRGBStroke(0, 0, 0); - // x := {self.}StartX + symbol_w * 0.9; - // y := {self.}StartY + sz * 0.9; - // pg.MoveTo(x, y); - // pg.LineTo(x + pg.TextWidth(range.Text)+symbol_w/3, y); - // pg.Stroke(); - -end; - -function SubMathRange.MathNary(nary: Nary; sz: real; x: real; y: real): ParagraphLineRange; -begin - prange := new ParagraphLineRange(); - prange.StartX := x; - prange.StartY := y; - prange.EndX := x; - prange.EndY := y; - - val := nary.NaryPr.Chr.Val ?: "Į"; - symbol := class(SymbolMapper).SymbolChr(val); - if ifnil(symbol) then raise format("error = %s", val); - symbol_font := docx_to_pdf_.Font.GetSymbolFont(); - pg := {self.}Page.PdfPage; - pg.SetFontAndSize(symbol_font, sz * 1.5); - symbol_range := new TextRange(); - symbol_range.Text := symbol; - symbol_range.EndX := x; - symbol_range.EndY := y; - symbol_range.Font := symbol_font; - symbol_range.RPr := new DocxML.RPr(); - symbol_range.RPr.Sz.Val := 1.5 * sz; - symbol_range.Page := {self.}Page; - symbol_range.Width := pg.TextWidth(symbol); - - if nary.NaryPr.LimLoc.Val = "subSup" then - begin - sup_start_x := x + symbol_range.Width * 1.2; - sup_start_y := y + sz * 1.5 * 0.73; - sub_start_x := x + symbol_range.Width * 0.7; - sub_start_y := y - sz * 1.5 * 0.2; - end - // else if nary.Nary.LimLoc.Val = "undOvr" then - else begin // undOvr - sup_start_x := x + symbol_range.Width * 0.5; - sup_start_y := y + sz * 1.5 * 0.8; - sub_start_x := x; - sub_start_y := y - sz * 1.5 * 0.5; - end - - sup_range := new SubMathRange(docx_to_pdf_, {self.}Page, nary.Sup, sz * 0.7); - sup_range.StartX := sup_start_x; - sup_range.StartY := sup_start_y; - sup_range.Calc(); - - sub_range := new SubMathRange(docx_to_pdf_, {self.}Page, nary.Sub, sz * 0.7); - sub_range.StartX := sub_start_x; - sub_range.StartY := sub_start_y; - sub_range.Calc(); - - if nary.NaryPr.LimLoc.Val = "subSup" then - begin - e_start_x := x + symbol_range.Width * 0.5 + max(sup_range.Width, sub_range.Width); - e_start_y := y + sz * 0.3; - end - else begin - e_start_x := x + symbol_range.Width; - e_start_y := y + sz * 0.3; - end - - e_range := new SubMathRange(docx_to_pdf_, {self.}Page, nary.E, sz); - e_range.StartX := e_start_x; - e_range.StartY := e_start_y; - e_range.Calc(); - - prange.EndX := maxValue(array(symbol_range.EndX, sup_range.EndX, sub_range.EndX, e_range.EndX)); - prange.AddRange(symbol_range); - prange.AddRange(sup_range); - prange.AddRange(sub_range); - prange.AddRange(e_range); - - return prange; - // TODO: delete - // val := nary.NaryPr.Chr.Val; - // symbol := class(SymbolMapper).SymbolChr(nary.NaryPr.Chr.Val); - // sz := 11; - // symbol_font := docx_to_pdf_.PdfFile().GetFont("Symbol", ""); - // symbol_range := new TextRange(); - // symbol_range.Text := symbol; - // symbol_range.EndX := {self.}StartX; - // symbol_range.EndY := {self.}StartY; - // symbol_range.Font := symbol_font; - // symbol_range.RPr := new RPr(); - // symbol_range.RPr.Sz.Val := 1.5 * sz; - // symbol_range.Page := {self.}Page; - // symbol_range.Do(); - - // pg := {self.}Page.PdfPage; - // pg.SetFontAndSize(symbol_font, sz * 1.5); - // symbol_w := pg.TextWidth(symbol); - // font := docx_to_pdf_.PdfFile().GetFont("SimSun,Italic", "GBK-EUC-H"); - - // range := new TextRange(); - // range.Text := chr_hash_["∞"]; - // range.EndX := {self.}StartX + symbol_w / 5; - // range.EndY := {self.}StartY + sz * 0.8 * 1.5; - // range.Font := symbol_font; - // range.RPr := new RPr(); - // range.RPr.Sz.Val := sz * 0.7; - // range.Page := {self.}Page; - // range.Do(); - - // range := new TextRange(); - // range.Text := "n=1"; - // pg.SetFontAndSize(font, sz*0.7); - // tw := pg.TextWidth(range.Text); - // range.EndX := {self.}StartX + (symbol_w - tw)/2; - // range.EndY := {self.}StartY - sz * 0.5 * 1.5; - // range.Font := font; - // range.RPr := new RPr(); - // range.RPr.Sz.Val := sz * 0.7; - // range.Page := {self.}Page; - // range.Do(); - - // range := new TextRange(); - // range.Text := chr_hash_["f"]; - // pg.SetFontAndSize(font, sz); - // tw := pg.TextWidth(range.Text); - // range.EndX := {self.}StartX + symbol_w; - // range.EndY := {self.}StartY + sz * 0.3; - // range.Font := symbol_font; - // range.RPr := new RPr(); - // range.RPr.Sz.Val := sz; - // range.Page := {self.}Page; - // range.Do(); - -end; - -// ColumnRange -function ColumnRange.Create(docx_to_pdf: TSDocxToPdf; pg: Page; components: DocxComponentsModule); -begin - docx_to_pdf_ := docx_to_pdf; - page_ := pg; - docx_components_module_ := components; - elements_ := array(); - last_y_ := 0; -end; - -function ColumnRange.AddElement(ele: Element); -begin - elements_[length(elements_)] := ele; -end; - -function ColumnRange.Elements(): array of Element; -begin - return elements_; -end; - -function ColumnRange.Do();override; -begin - x := {self.}StartX; - y := {self.}StartY; - for _,element in elements_ do - begin - range := nil; - if element.LocalName = "p" then - range := new ParagraphRange(docx_to_pdf_, page_, docx_components_module_, element); - else if element.LocalName = "tbl" then - range := new TableRange(docx_to_pdf_, page_, docx_components_module_, element); - if ifnil(range) then continue; - range.StartX := x; - range.StartY := y; - range.Width := {self.}Width; - range.LowerBound := {self.}LowerBound; - range.Calc(); - range.Do(); - y := range.EndY; - page_ := range.GetLastPage(); - end - {self.}EndY := y; -end; - -function ColumnRange.GetLastPage(): Page; -begin - return page_; -end; - -// TableRange -function TableRange.Create(docx_to_pdf: TSDocxToPdf; pg: Page; components: Components; table: Tbl); -begin - docx_to_pdf_ := docx_to_pdf; - last_page_ := pg; - docx_components_module_ := Components; - table_ := table; - ts_trpr_array_ := array(); - cell_range_matrix_ := array(); - row_lower_bound_ := array(); - rows_ := 0; - cols_ := 0; - {self.}Page := last_page_; -end; - -function TableRange.Calc(); -begin - {self.}SetTblTblPr(table_); - tbl_pr_unit_decorator_ := new TblPrUnitDecorator(table_.TblPr); - tbl_grid_unit_decorator := new TblGridUnitDecorator(table_.TblGrid); - grid_cols := tbl_grid_unit_decorator.GridCols(); - {self.}ResetCoordinates(tbl_pr_unit_decorator_, grid_cols); - {self.}EndX := {self.}StartX; - {self.}EndY := {self.}StartY; - // 如果是根据内容自适应,应该计算并调整grid_cols的值 - trs := table_.Trs(); - rows_ := length(trs); - cols_ := length(grid_cols); - cell_range_matrix_ := nils(rows_, cols_); - // 先构建一个矩阵 - {self.}CreateTableMatrix(grid_cols, trs); - // 遍历矩阵后进行计算合并 - {self.}ComputeMatrixCells(); -end; - -function TableRange.Do();override; -begin - 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) then continue; - if flag <> range.IfRemoveEmptyRectangle() then - begin - flag := false; - break; - end - end - for __,range in row do - begin - if ifObj(range) then - begin - range.RemoveFlag := flag; - range.Do(); - end - end - end -end; - -function TableRange.CreateTableMatrix(grid_cols: array of GridColUnitDecorator; trs: array of Tr); -begin - for i,tr in trs do - begin - {self.}SetTrTrPr(tr); - tr_pr := new TrPrUnitDecorator(tr.TrPr); - tc_x := {self.}EndX; - tcs := tr.Tcs(); - trp := new DTPUtils.TrProperty(); - trp.TrPr := tr_pr; - ts_trpr_array_[i] := trp; - pos := 0; - for j,tc in tcs do - begin - {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 - tc_x += grid_cols[pos++].W; - for k:=grid_span.Val-1 downto 1 do - begin - cell_range_matrix_[i][pos] := 0; - tc_x += grid_cols[pos++].W; - end - continue; - end - cell_range := new CellRange(docx_to_pdf_, last_page_, docx_components_module_, 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 := tr_pr.TrHeight.Val; - cell_range.Parent := self; - cell_range.Row := i; - cell_range.Col := pos; - cell_range_matrix_[i][pos] := cell_range; - pos++; - // 水平合并的单元格,占位需要和垂直的区分 - for k:=grid_span.Val-1 downto 1 do - begin - cell_range_matrix_[i][pos] := 0; - cell_range.Width += grid_cols[pos++].W; - end - tc_x += cell_range.Width; - end - end - - // for i,arr in cell_range_matrix_ do - // println("i = {}, arr = {}", i, arr); - // println("\n"); - return; -end; - -function TableRange.ComputeMatrixCells(); -begin - i := 0; - merge_arr := array(); - vmerge_height := array(); - while i < rows_ do - begin - j := 0; - tc_y := {self.}EndY; - recompute_flag := false; - while j < cols_ do - begin - range := cell_range_matrix_[i][j]; - if not ifObj(range) then - begin - j++; - continue; - end - range.StartY := tc_y; - range.SetPage(last_page_); - range.Calc(); - if range.IsReComputeByCantSplit() then - begin - // 调整上一行的下边界 - arr := cell_range_matrix_[i-1]; - for _,r in arr do - begin - if ifnil(r) then - begin - pos := i-2; - while pos > 0 do - begin - 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 - last_page_ := docx_to_pdf_.PageManager[last_page_.Index + 1]; - [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.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; - i_height := 0; - for k,v in merge_arr[i] do - begin - 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, row_lower_bound_[i-1]); - r.SetVAlign(); - end - 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.Tc.TcPr.VMerge then continue; - range.AlignHeight(ts_trpr_array_[i].Height, row_lower_bound_[i]); - range.SetVAlign(); - {self.}EndY := range.EndY; - last_page_ := range.GetLastPage(); - row_lower_bound_[i] := range.LowerBound; - end - i++; - end -end; - -function TableRange.RowLowerBound(row: integer): real; -begin - return row_lower_bound_[row]; -end; - -function TableRange.OverrideTcPrByTblStylePrType(var tc_pr: TcPr; type: string); -begin - // tc_pr应该是经过外层copy的 - tbl_style_pr := docx_components_module_.GetTblStylePrByType(tbl_pr_unit_decorator_.TblStyle.Val, type); - if tbl_style_pr then tc_pr.Copy(tbl_style_pr.TcPr); -end; - -function TableRange.ResetCoordinates(tbl_pr: TblPr; grid_cols: array of GridCol); -begin - total_width := 0; - for _,grid_col in grid_cols do - total_width += grid_col.W; - diff := total_width - {self.}Width; - case tbl_pr.Jc.Val of - "center": - begin - offset := diff/2; - {self.}StartX -= offset; - end - "right": - begin - {self.}StartX -= diff; - end - end; - {self.}Width := total_width; -end; - -function TableRange.SetTblTblPr(var tbl: Tbl); -begin - new_tbl_pr := new TblPr(); - {self.}SetTblPrByStyleId(new_tbl_pr, tbl.TblPr.TblStyle.Val); - new_tbl_pr.Copy(tbl.TblPr); - tbl.TblPr.Copy(new_tbl_pr); -end; - -function TableRange.SetTblPrByStyleId(var tbl_pr: TblPr; style_id: string); -begin - styles := docx_components_module_.GetStylesAdapter(); - style := styles.GetStyleByStyleId(style_id); - if ifObj(style) then - begin - based_on := style.BasedOn.Val; - {self.}SetTblPrByStyleId(tbl_pr, based_on); - tbl_pr.Copy(style.TblPr); - end -end; - -function TableRange.SetTrTrPr(var tr: Tr); -begin - new_tr_pr := new TrPr(); - {self.}SetTrPrByStyleId(new_tr_pr, tbl_pr_unit_decorator_.TblStyle.Val); - new_tr_pr.Copy(tr.TrPr); - tr.TrPr.Copy(new_tr_pr); -end; - -function TableRange.SetTrPrByStyleId(var tr_pr: TrPr; style_id: string); -begin - styles := docx_components_module_.GetStylesAdapter(); - style := styles.GetStyleByStyleId(style_id); - if ifObj(style) then - begin - based_on := style.BasedOn.Val; - {self.}SetTrPrByStyleId(tr_pr, based_on); - tr_pr.Copy(style.TrPr); - end -end; - -function TableRange.SetTcTcPr(var tc: Tc); -begin - new_tc_pr := new TcPr(); - {self.}SetTcPrByStyleId(new_tc_pr, tbl_pr_unit_decorator_.TblStyle.Val); - new_tc_pr.Copy(tc.TcPr); - tc.TcPr.Copy(new_tc_pr); -end; - -function TableRange.SetTcPrByStyleId(var tc_pr: TcPr; style_id: string); -begin - styles := docx_components_module_.GetStylesAdapter(); - style := styles.GetStyleByStyleId(style_id); - if ifObj(style) then - begin - based_on := style.BasedOn.Val; - {self.}SetTcPrByStyleId(tc_pr, based_on); - tc_pr.Copy(style.TcPr); - end -end; - -function TableRange.GetLastPage(): Page; -begin - return last_page_; -end; - -function TableRange.Rows(): integer; -begin - return rows_; -end; - -function TableRange.Cols(): integer; -begin - return cols_; -end; - -// CellRange -function CellRange.Create(docx_to_pdf: TSDocxToPdf; pg: Page; components: DocxComponentsModule; tc: Tc; tbl_pr: TblPr; trp: TSTrProperty); -begin - docx_to_pdf_ := docx_to_pdf; - last_page_ := pg; - docx_components_module_ := 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.}Page := last_page_; -end; - -function CellRange.Calc(); -begin - region_array_ := array(); - region := new DTPUtils.Region(); - region.BordersRange.EndX := {self.}StartX; - region.BordersRange.EndY := {self.}StartY; - region.BordersRange.Width := {self.}Width; - region.BordersRange.FixedHeight := {self.}FixedHeight; - region.BordersRange.Page := 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 ParagraphRange(docx_to_pdf_, last_page_, docx_components_module_, element); - range.SetTblStyleIdAndType(tbl_pr_.TblStyle.Val, {self.}GetCellPrType()); - end - else if element.LocalName = "tbl" then - begin - range := new TableRange(docx_to_pdf_, last_page_, docx_components_module_, 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.Parent := self; - 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_.PageManager[last_page_.Index + 1]; - if ifnil(last_page_) then last_page_ := docx_to_pdf_.AddPage(); - {self.}StartY := last_page_.TextPoint.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 CellRange.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 CellRange.SetPage(pg: Page); -begin - last_page_ := pg; - {self.}Page := pg; -end; - -function CellRange.AlignHeight(height: real; lb: 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; - {self.}LowerBound := {self.}StartY - height; - return; - end - // if lb then y_lowerbound := {self.}StartY - lb; - region.BordersRange.DynamicHeight := y_lowerbound; - arr := region.RangeArr; - region.RangeArr := array(); - hash := array(region.BordersRange.Page.Index: region); - last_page_ := {self.}Page; - [x, y] := last_page_.OriginalTextCoordinates(); - span := y - last_page_.FtrPoint.Y; - while surplus > span do - begin - last_page_ := docx_to_pdf_.PageManager[last_page_.Index + 1]; - region := new DTPUtils.Region(); - region.BordersRange.EndX := {self.}StartX; - region.BordersRange.EndY := y; - region.BordersRange.Width := {self.}Width; - region.BordersRange.DynamicHeight := span; - region.BordersRange.Page := 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.Page.Index] := region; - end - if surplus > 1e-6 then - begin - last_page_ := docx_to_pdf_.PageManager[last_page_.Index + 1]; - region := new DTPUtils.Region(); - region.BordersRange.EndX := {self.}StartX; - region.BordersRange.EndY := y; - region.BordersRange.Width := {self.}Width; - region.BordersRange.DynamicHeight := surplus; - region.BordersRange.Page := 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.Page.Index] := region; - {self.}EndY := region.BordersRange.EndY - surplus; - end - for _,range in arr do - begin - if range is class(ParagraphRange) then - begin - line_arr := range.GetParagraphLineRangeArr(); - for _,r in line_arr do - begin - region := hash[r.Page.Index]; - region.RangeArr[length(region.RangeArr)] := r; - end - end - end -end; - -function CellRange.GetLastPage(); -begin - return last_page_; -end; - -function CellRange.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.Page, nil, -offset); - end - end; -end; - -function CellRange.IsReComputeByCantSplit(): boolean; -begin - if {self.}Tc.TcPr.VMerge then return false; - return {self.}TSTrPr.TrPr.CantSplit and last_page_ <> {self.}Page; -end; - -function CellRange.IfRemoveEmptyRectangle(): boolean; -begin - if length(region_array_) < 2 then return false; - return length(region_array_[0].RangeArr) ? false : true; -end; - -function CellRange.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 CellRange.SetBorderRange(range: BordersRange); -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 - if not tc_pr_unit_decorator_.TcBorders.Top then - tc_pr_unit_decorator_.TcBorders.Top.Copy(tbl_pr_.TblBorders.Top); - range.Top := true; - end - if tbl_pr_.TblBorders.InsideH and {self.}VMerge <> {self.}Parent.Rows()-1 then - begin - if not tc_pr_unit_decorator_.TcBorders.Bottom then - tc_pr_unit_decorator_.TcBorders.Bottom.Copy(tbl_pr_.TblBorders.InsideH); - range.Bottom := true; - end - if tbl_pr_.TblBorders.InsideV and {self.}Col <> {self.}Parent.Cols()-1 then - begin - if not tc_pr_unit_decorator_.TcBorders.Right then - tc_pr_unit_decorator_.TcBorders.Right.Copy(tbl_pr_.TblBorders.InsideV); - range.Right := true; - end - if tbl_pr_.TblBorders.Bottom and {self.}VMerge = {self.}Parent.Rows()-1 then - begin - if not tc_pr_unit_decorator_.TcBorders.Bottom then - tc_pr_unit_decorator_.TcBorders.Bottom.Copy(tbl_pr_.TblBorders.Bottom); - range.Bottom := true; - end - end - else if {self.}Row = {self.}Parent.Rows()-1 then - begin - if tbl_pr_.TblBorders.Bottom then - begin - if not tc_pr_unit_decorator_.TcBorders.Bottom then - tc_pr_unit_decorator_.TcBorders.Bottom.Copy(tbl_pr_.TblBorders.Bottom); - range.Bottom := true; - end - if tbl_pr_.TblBorders.InsideV and {self.}Col <> {self.}Parent.Cols()-1 then - begin - if not tc_pr_unit_decorator_.TcBorders.Right then - 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 = {self.}Parent.Rows()-1 then - begin - if not tc_pr_unit_decorator_.TcBorders.Bottom then - tc_pr_unit_decorator_.TcBorders.Bottom.Copy(tbl_pr_.TblBorders.Bottom); - range.Bottom := true; - end - if tbl_pr_.TblBorders.InsideH and {self.}VMerge <> {self.}Parent.Rows()-1 then - begin - if not tc_pr_unit_decorator_.TcBorders.Bottom then - tc_pr_unit_decorator_.TcBorders.Bottom.Copy(tbl_pr_.TblBorders.InsideH); - range.Bottom := true; - end - if tbl_pr_.TblBorders.InsideV and {self.}Col <> {self.}Parent.Cols()-1 then - begin - if not tc_pr_unit_decorator_.TcBorders.Right then - 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 - if not tc_pr_unit_decorator_.TcBorders.Left then - tc_pr_unit_decorator_.TcBorders.Left.Copy(tbl_pr_.TblBorders.Left); - range.Left := true; - end - end - if {self.}Col = {self.}Parent.Cols()-1 then - begin - if tbl_pr_.TblBorders.Right then - begin - if not tc_pr_unit_decorator_.TcBorders.Right then - 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 CellRange.SetTop(); -begin - top_ := true; -end; - -// RangeCollection; -function RangeCollection.Create(); -begin - class(BasicRange).Create(); - range_array_ := array(); -end; - -function RangeCollection.Do();override; -begin - for _,range in range_array_ do - range.Do(); -end; - -function RangeCollection.Add(range: BasicRange); -begin - range_array_[length(range_array_)] := range; -end; - -// ParagraphLineRange -function ParagraphLineRange.Create(pg: Page); -begin - class(BasicRange).Create(); - {self.}Page := pg; - range_array_ := array(); -end; - -function ParagraphLineRange.AddRange(range: BasicRange); -begin - range_array_[length(range_array_)] := range; -end; - -function ParagraphLineRange.Do();override; -begin - for _,range in range_array_ do - range.Do(); -end; - -function ParagraphLineRange.SetAllRangeProp(pg: Page; sx: real; sy: real; ex: real; ey: real; w: real; fh: real; dh: real); -begin - for _,range in range_array_ do - begin - if not ifnil(pg) then range.Page := pg; - if not ifnil(sx) then range.StartX := sx; - if not ifnil(sy) then range.StartY := sy; - if not ifnil(ex) then range.EndX := ex; - if not ifnil(ey) then range.EndY := ey; - if not ifnil(w) then range.Width := w; - if not ifnil(fh) then range.FixedHeight := fh; - if not ifnil(dh) then range.DynamicHeight := dh; - end -end; - -function ParagraphLineRange.Align(jc: string); -begin - offset := 0; - first := range_array_[0]; - last := range_array_[length(range_array_)-1]; - case jc of - "center": - offset := ({self.}Width + StartX - last.EndX - last.Width) / 2; - "right": - offset := {self.}Width - last.EndX + first.EndX - last.Width; - end; - if offset <= 0 then return; - for _,range in range_array_ do - range.EndX += offset; -end; - -function ParagraphLineRange.AdjustRangeOffset(pg: Page; x_offset: real; y_offset: real); -begin - if pg <> {self.}Page then return; - for _,range in range_array_ do - begin - if not ifnil(x_offset) then range.EndX += x_offset; - if not ifnil(y_offset) then range.EndY += y_offset; - end; -end; - -function ParagraphLineRange.AlignRightBound(right_bound: real); -begin - last := range_array_[length(range_array_)-1]; - diff := right_bound - (last.EndX + last.Width); - if diff > 1e-6 then - begin - avg := diff / (length(range_array_) - 1); - for i:=1 to length(range_array_)-1 do - range_array_[i].EndX += avg * i; - end -end; - -function ParagraphLineRange.Offset(x_offset: real; y_offset; real); -begin - for _,range in range_array_ do - begin - range.EndX += x_offset; - range.EndY -= y_offset; - end -end; - - -// ParagraphRange -function ParagraphRange.Create(docx_to_pdf: TSDocxToPdf; pg: Page; components: DocxComponentsModule; paragraph: P); -begin - docx_to_pdf_ := docx_to_pdf; - page_ := pg; - docx_components_module_ := components; - paragraph_ := paragraph; - table_style_id_ := ""; - table_style_type_ := ""; - body_range_array_ := array(); - bullet_range_array_ := array(); - line_range_array_ := array(); - hyperlink_array_ := array(); - bookmark_array_ := array(); - empty_ := false; - {self.}Page := page_; - footnote_reference_hash_ := array(); -end; - -function ParagraphRange.Init(); -begin - body_range_array_ := array(); - right_bound_ := {self.}StartX + {self.}Width; - {self.}ResetCoordinates(); - {self.}EndX := {self.}StartX; - {self.}EndY := {self.}StartY; - {self.}CheckAndAddPage({self.}EndY, ppr_unit_decorator_.Spacing.Before); - {self.}EndY -= ppr_unit_decorator_.Spacing.Before; - {self.}DynamicHeight += ppr_unit_decorator_.Spacing.Before; - - // TODO:项目符号应该单独写入 - {self.}SetLvlText(); -end; - -function ParagraphRange.Calc(): tableArray; -begin - // ppr.rpr是无效的,应该以ppr.pStyle为准 - {self.}SetPPPr(paragraph_); - ppr_unit_decorator_ := new DocxMLUnitDecorator.PPrUnitDecorator(paragraph_.PPr); - {self.}Init(); - if not ppr_unit_decorator_.RPr.Sz.Val then ppr_unit_decorator_.RPr.Sz.Val := docx_to_pdf_.Font.GetDefaultSz(); - if paragraph_.PPr.PageBreakBefore then - {self.}CheckAndAddPage({self.}LowerBound, 1); - - elements := paragraph_.Elements(); - empty_flag := true; - bookmark_id := ''; - bookmark_name := ''; - bookmark_flag := false; - fld_stack := new DTPUtils.Stack(); - for _,element in elements do - begin - // println("LocalName = {}", element.LocalName); - if element.LocalName = "r" then - begin - empty_flag := false; - {self.}SetRRPr(element, ppr_unit_decorator_); - - if element.FldChar.FldCharType = "begin" then - begin - fld_struct := new DTPUtils.FldStruct(); - fld_stack.Push(fld_struct); - end - if not fld_stack.Empty() then - begin - {self.}RFldChar(element, fld_stack); - continue; - end - - if element.Br.Type = "page" then - {self.}EndY := {self.}LowerBound; - else if element.Drawing then {self.}RDrawing(element); - else if element.AlternateContent then {self.}RAlternateContent(element); - else if element.FootnoteReference then {self.}RFootnoteReference(element); - else if element.Object then {self.}RObject(element); - else if element.FootnoteRef then {self.}RFootnoteRef(element); - else if element.Anchor then {self.}Hyperlink(element); // - else if element.T then {self.}RT(element, bookmark_name); - end - else if element.LocalName = "fldSimple" then - begin - {self.}FldSimple(element); - end - else if element.LocalName = "hyperlink" then - begin - empty_flag := false; - {self.}Hyperlink(element); - end - else if element.LocalName = "bookmarkStart" then - begin - bookmark_id := element.Id; - bookmark_name := element.Name; - bookmark_array_[bookmark_name] := array(); - end - else if element.LocalName = "bookmarkEnd" then - begin - bookmark_id := ''; - bookmark_name := ''; - end - else if element.LocalName = "oMathPara" then - begin - {self.}OMathPara(element); - end - else if element.LocalName = "oMath" then - begin - o_math_para := new OMathPara(); - o_math_para.XmlChildOMath := element; - // o_math_para.OMath.Copy(element); - {self.}OMathPara(o_math_para); - end - end - if empty_flag then - begin - line_space := {self.}GetParagraphLineSpace(ppr_unit_decorator_.RPr.Sz.Val, ppr_unit_decorator_.Spacing.Line, ppr_unit_decorator_.Spacing.LineRule); - {self.}DynamicHeight += line_space; - {self.}EndY -= {self.}DynamicHeight; - empty_ := true; - end - if placeholder_array_ then return false; - {self.}RangesToLines(); - if hyperlink_array_ then {self.}HyperlinkToToc(); - if bookmark_array_ then {self.}BookMarkLinkToc(); - return true; -end; - -function ParagraphRange.SetNumPages(num: integer); -begin - text := tostring(num); - last_index := length(body_range_array_); - {self.}SplitTextToTextRange(body_range_array_, text, placeholder_array_[1], link); - arr := array(); - len := length(body_range_array_); - for i:=last_index to len-1 do - arr[length(arr)] := body_range_array_[i]; - diff := len - last_index; - for i:=len-1 downto placeholder_array_[0] do - body_range_array_[i] := body_range_array_[i-diff]; - k := 0; - for i:=placeholder_array_[0] to placeholder_array_[0]+diff-1 do - body_range_array_[i] := arr[k++]; -end; - -function ParagraphRange.BookMarkLinkToc(); -begin - for name,arr in bookmark_array_ do - if arr[0] then docx_to_pdf_.Toc.LinkToToc(name, arr[0].Page, arr[0].EndX, arr[0].EndY + arr[0].RPr.Sz.Val); -end; - -function ParagraphRange.HyperlinkToToc(); -begin - ppr := ppr_unit_decorator_; - max_size := 0; - for anchor,arr in hyperlink_array_ do // 整理hyperlink发送到docx_to_pdf_ - begin - pg := arr[0].Page; - left := {self.}StartX; - right := {self.}StartX + {self.}Width; - top := {self.}StartY; - bottom := {self.}StartY; - x := arr[0].EndX; - y := arr[0].EndY; - if top - {self.}GetParagraphLineSpace(arr[0].RPr.Sz.Val, ppr.Spacing.Line, ppr.Spacing.LineRule) then - begin - top := pg.TextPoint.Y; - bottom := top; - end - for _,range in arr do - begin - if x + range.Width - {self.}StartX > {self.}Width + 1e-6 then // 换行 - begin - line_space := {self.}GetParagraphLineSpace(max_size, ppr.Spacing.Line, ppr.Spacing.LineRule); - bottom -= line_space; - max_size := 0; - if range.Page <> pg then - begin - rect := array(left, bottom, right, top); - toc := new DTPModules.Toc(ppr, rect, pg, x, y); - docx_to_pdf_.Toc.AddToc(anchor, toc); - pg := range.Page; - bottom := {self.}StartY; - end - end - if range.RPr.Sz.Val > max_size then max_size := range.RPr.Sz.Val; - x := range.EndX + range.Width; - y := range.EndY; - end - font_name := ppr.RPr.RFonts.EastAsia ? ppr.RPr.RFonts.EastAsia : ppr.RPr.RFonts.Ascii; - font_obj := docx_to_pdf_.Font.GetCNSFont(font_name, ppr.RPr.B, ppr.RPr.I); - line_space := {self.}GetParagraphLineSpace(max_size, ppr.Spacing.Line, ppr.Spacing.LineRule); - pg.PdfPage.SetFontAndSize(font_obj, max_size); - bottom -= line_space; - num_width := pg.PdfPage.TextWidth("." + tostring(pg.Number)); - if x + num_width - {self.}StartX > {self.}Width + 1e-6 then // 换行 - begin - offset := (line_space - max_size) / 2 + max_size - max_size / 5; - diff := {self.}EndY - {self.}LowerBound; - if {self.}CheckAndAddPage({self.}EndY, line_space) then - begin - {self.}DynamicHeight += diff; - pg := page_; - rect := array(left, bottom, right, top); - toc := new TSToc(ppr, rect, pg, x, y); - docx_to_pdf_.Toc.AddToc(anchor, toc); - bottom := {self.}StartY; - end - else begin - bottom -= line_space; - x := {self.}StartX; - y := {self.}EndY - offset; - {self.}EndY -= line_space; - {self.}DynamicHeight += line_space; - end - end - rect := array(left, bottom, right, top); - toc := new DTPModules.Toc(ppr, rect, pg, x, y, font_obj); - docx_to_pdf_.Toc.AddToc(anchor, toc); - end -end; - -function ParagraphRange.FldSimple(fld_simple: FldSimple); -begin - if fld_simple.Instr then - begin - fields := str2array(fld_simple.Instr, " "); - fld_struct := new DTPUtils.FldStruct2(); - for _,field in fields do - begin - fld := trim(field); - if fld = "NUMPAGES" then - fld_struct.Type.NumPages := true; - else if fld = "Arabic" then - fld_struct.Arabic := true; - else if fld = "MERGEFORMAT" then - fld_struct.MergeFormat := true; - end - end - r := fld_simple.Rs(0); - {self.}SetRRPr(r, ppr_unit_decorator_); - rpr := new RPrUnitDecorator(r.RPr); - if fld_struct.Type.NumPages then - begin - if fld_struct.Arabic then - begin - placeholder_array_ := array(length(body_range_array_), rpr); - end - end -end; - -function ParagraphRange.Hyperlink(hyperlink: Hyperlink); -begin - i := length(body_range_array_); - rs := hyperlink.Rs(); - separate := false; - stack := new DTPUtils.Stack(); - for _,r in rs do - begin - if r.FldChar.FldCharType = "begin" then - begin - fld_struct := new FldStruct2(); - stack.Push(fld_struct); - end - // if r.InstrText.Text - else if r.FldChar.FldCharType = "end" then - begin - stack.Pop(); - end - else if r.FldChar.FldCharType = "separate" then - begin - separate := true; - end - else if separate then - begin - docx_to_pdf_.Toc.AddDocxPage(hyperlink.Anchor, r); - end - else if stack.Empty() then - begin - {self.}SetRRPr(r, ppr_unit_decorator_); - r.RPr.Color.Val := nil; - {self.}RT(r, hyperlink.Anchor); - end - end - arr := array(); - while i < length(body_range_array_) do - begin - arr[length(arr)] := body_range_array_[i]; - i++; - end - hyperlink_array_[hyperlink.Anchor] := arr; -end; - -function ParagraphRange.Do();override; -begin - for _,line_range in line_range_array_ do - line_range.Do(); -end; - -function ParagraphRange.SetTblStyleIdAndType(style_id: string; type: string); -begin - table_style_id_ := style_id; - table_style_type_ := type; -end; - -function ParagraphRange.NewParagraphLineRange(): ParagraphLineRange; -begin - line_range := new ParagraphLineRange(page_); - line_range.StartX := {self.}StartX; - line_range.StartY := {self.}EndY; - line_range.Width := {self.}Width; - return line_range; -end; - -function ParagraphRange.UpdateTextRangeWidth(); -begin - head_range := body_range_array_[0]; - i := 1; - while i < length(body_range_array_) do - begin - tail_range := body_range_array_[i]; - if not tail_range is class(TextRange) then - begin - head_range := body_range_array_[i+1]; - i += 2; - continue; - end - if not last_range is class(TextRange) then - begin - head_range := tail_range; - i++; - continue; - end - if head_range then - begin - if head_range.Type in array(1, 2) and tail_range.Type = 3 then - head_range.Width += head_range.Width / 2; - else if head_range.Type = 3 and tail_range.Type in array(1, 2) then - head_range.Width += tail_range.Width / 2; - end - head_range := tail_range; - i++; - end -end; - -function ParagraphRange.RangesToLines();overload; -begin - {self.}UpdateTextRangeWidth(); - {self.}BasicRangesToParagraphLineRange(); - {self.}DynamicHeight += ppr_unit_decorator_.Spacing.After; - {self.}EndY -= ppr_unit_decorator_.Spacing.After; - if not {self.}Empty() and ppr_unit_decorator_.PBdr.Bottom.Val = "single" then - begin - sect_pr := page_.SectPr; - page_.PdfPage.SetLineWidth(0.05); - page_.PdfPage.SetGrayStroke(0.25); - page_.PdfPage.MoveTo(sect_pr.PgMar.Left, {self.}EndY); - page_.PdfPage.LineTo(sect_pr.PgSz.W - sect_pr.PgMar.Right, {self.}EndY); - page_.PdfPage.Stroke(); - end -end; - -function ParagraphRange.BasicRangesToParagraphLineRange(); -begin - ppr := ppr_unit_decorator_; - line_range := {self.}NewParagraphLineRange(); - i := 0; - max_size := 0; - max_y := 0; - while i <= length(body_range_array_)-1 do - begin - range := body_range_array_[i]; - if i = 0 then {self.}EndX += ppr.Ind.FirstLine; - if range is class(TextRange) and range.RPr.Sz.Val > max_size then - max_size := range.RPr.Sz.Val; - if range.DynamicHeight > max_y then max_y := range.DynamicHeight; - line_space := {self.}GetParagraphLineSpace(max_size, ppr.Spacing.Line, ppr.Spacing.LineRule); - diff := {self.}EndY - {self.}LowerBound; - if {self.}CheckAndAddPage({self.}EndY, max(line_space, range.DynamicHeight)) then - {self.}DynamicHeight += diff; - if_newline := {self.}EndX + range.Width - {self.}StartX > {self.}Width + 1e-6; - if i = 0 then if_newline := 0; - if if_newline and (range is class(TextRange)) and (AnsiToUtf8(range.Text) in array(";", ":", "。", "“", "”", "!", "?", ",")) then - if_newline := 0; - if if_newline and range.Width < {self.}Width then - begin - offset := line_space > max_y ? (line_space - max_size) / 2 + max_size - max_size / 5 : max_y; - max_value := max(line_space, max_y); - line_range.Page := page_; - line_range.EndY := {self.}EndY - max_value; - line_range.DynamicHeight := max_value; - line_range.SetAllRangeProp(pg: page_, ey: {self.}EndY - offset); - line_range_array_[length(line_range_array_)] := line_range; - - line_range := {self.}NewParagraphLineRange(); - max_size := 0; - max_y := 0; - {self.}DynamicHeight += max_value; - {self.}EndY -= max_value; - {self.}EndX := {self.}StartX; - // w:hanging - if range is class(TextRange) then - sz := range.RPr.SzCs.Val ? range.RPr.SzCs.Val : range.RPr.Sz.Val ? range.RPr.Sz.Val : docx_to_pdf_.Font.GetDefaultSz(); - else - sz := docx_to_pdf_.Font.GetDefaultSz(); - {self.}EndX -= ppr.Ind.HangingChars ? ppr.Ind.HangingChars * sz : ppr.Ind.Hanging; - continue; - end - range.EndX := {self.}EndX - range.StartX; - {self.}EndX += range.Width; - line_range.AddRange(range); - i++; - if i = length(body_range_array_) then - begin - offset := line_space > max_y ? (line_space - max_size) / 2 + max_size - max_size / 5 : max_y; - max_value := max(line_space, max_y); - line_range.Page := page_; - line_range.EndY := {self.}EndY - max_value; - line_range.DynamicHeight := max_value; - line_range.SetAllRangeProp(pg: page_, ey: {self.}EndY - offset); - line_range_array_[length(line_range_array_)] := line_range; - {self.}DynamicHeight += max_value; - {self.}EndY -= max_value; - end - end - {self.}SetLinesAlignment(); - if not {self.}Parent is class(CellRange) then - {self.}AlignRightBound(); -end; - -function ParagraphRange.SetLinesAlignment(); -begin - for _,line_range in line_range_array_ do - line_range.Align(ppr_unit_decorator_.Jc.Val); -end; - -function ParagraphRange.AlignRightBound(); -begin - len := length(line_range_array_); - if len = 1 then return; - for i:=0 to len-2 do - line_range_array_[i].AlignRightBound(right_bound_); -end; - -function ParagraphRange.CheckAndAddPage(y: real; offset: real): boolean; -begin - if y - offset < {self.}LowerBound then - begin - page_ := docx_to_pdf_.PageManager[page_.Index + 1]; - if ifnil(page_) then page_ := docx_to_pdf_.AddPage(); - {self.}EndY := page_.TextPoint.Y; - return true; - end - return false; -end; - -function ParagraphRange.RT(r: R; link: string); -begin - rpr := new RPrUnitDecorator(r.RPr); - text := r.T.Text; - if ifString(text) then {self.}SplitTextToTextRange(body_range_array_, text, rpr, link); -end; - -function ParagraphRange.SplitTextToTextRange(range_arr: array of BasicRange; text: string; rpr: RPrUnitDecorator; link: string); -begin - pos := 1; - if not rpr.Sz.Val then rpr.Sz.Val := rpr.SzCs.Val ? rpr.SzCs.Val : docx_to_pdf_.Font.GetDefaultSz(); - while pos <= length(text) do - begin - text_range := new TextRange(); - num := DTPUtils.Utf8CharLengthFromByte(text[pos]); - a_word := text[pos : pos+num-1]; - if num = 1 then - begin - char := ord(a_word); - if char >= 0x30 and char <= 0x39 then - text_range.Type := 1; - else if char >= 0x41 and char <= 0x5A then - text_range.Type := 2; - else if char >= 0x61 and char <= 0x7A then - text_range.Type := 2; - word := a_word; - font_name := rpr.RFonts.EastAsia ? rpr.RFonts.EastAsia : rpr.RFonts.Ascii; - font_obj := docx_to_pdf_.Font.GetCNSFont(font_name, rpr.B, rpr.I); - end - else if DTPUtils.IsChineseChar(a_word) then - begin - text_range.Type := 3; - word := utf8ToAnsi(a_word); - font_name := rpr.RFonts.EastAsia ? rpr.RFonts.EastAsia : rpr.RFonts.Ascii; - font_obj := docx_to_pdf_.Font.GetCNSFont(font_name, rpr.B, rpr.I); - end - else if DTPUtils.IsChinesePunctuation(a_word) then - begin - text_range.Type := 4; - word := utf8ToAnsi(a_word); - font_name := rpr.RFonts.EastAsia ? rpr.RFonts.EastAsia : rpr.RFonts.Ascii; - font_obj := docx_to_pdf_.Font.GetCNSFont(font_name, rpr.B, rpr.I); - end - else begin - word := utf8ToAnsi(a_word); - if word = "?" then - begin - word := class(SymbolMapper).ZapfDingbatsChr(a_word); - if ifnil(word) then word := "u"; - font_obj := docx_to_pdf_.Font.GetZapfDingbatsFont(); - end - else begin - font_name := rpr.RFonts.EastAsia ? rpr.RFonts.EastAsia : rpr.RFonts.Ascii; - font_obj := docx_to_pdf_.Font.GetCNSFont(font_name, rpr.B, rpr.I); - end - end - page_.PdfPage.SetFontAndSize(font_obj, rpr.Sz.Val); - word_width := page_.PdfPage.TextWidth(word); - text_range.RPr := rpr; - text_range.Text := word; - text_range.Font := font_obj; - text_range.Width := word_width; - pos += num; - range_arr[length(range_arr)] := text_range; - if ifarray(bookmark_array_[link]) then bookmark_array_[link] union= array(text_range); - end -end; - -function ParagraphRange.RDrawing(r: R); -begin - if r.Drawing._Inline then - begin - id := r.Drawing._Inline.Graphic.GraphicData.Pic.BlipFill.Blip.Embed; - [image_type, image] := {self.}GetImageData(id); - if not image then return; - xfrm := new XfrmUnitDecorator(r.Drawing._Inline.Graphic.GraphicData.Pic.SpPr.Xfrm); - image_range := new ImageRange(); - image_range.Image := image; - image_range.Type := image_type; - image_range.StartX := 0; - image_range.StartY := 0; - image_range.Width := xfrm.Ext.CX; - image_range.DynamicHeight := xfrm.Ext.CY; - body_range_array_[length(body_range_array_)] := image_range; - end - else if r.Drawing.Anchor then - begin - anchor := r.Drawing.Anchor; - id := anchor.Graphic.GraphicData.Pic.BlipFill.Blip.Embed; - [image_type, image] := {self.}GetImageData(id); - if not image then return; - [x, y] := {self.}GetXYCordinates(); - xfrm := new XfrmUnitDecorator(anchor.Graphic.GraphicData.Pic.SpPr.Xfrm); - position_h := new PositionHUnitDecorator(anchor.PositionH); - position_v := new PositionVUnitDecorator(anchor.PositionV); - if position_h.RelativeFrom = "paragraph" then - x := {self.}StartY; - if position_v.RelativeFrom = "paragraph" then - y := {self.}StartY; - image_range := new ImageRange(); - image_range.Image := image; - image_range.Type := image_type; - image_range.EndX := x + position_h.PosOffset.Text; - image_range.EndY := y - position_v.PosOffset.Text - xfrm.Ext.CY; - image_range.Width := xfrm.Ext.CX; - image_range.DynamicHeight := xfrm.Ext.CY; - image_range.Page := page_; - image_range.Do(); - end -end; - -function ParagraphRange.RAlternateContent(r: R); -begin - anchor := r.AlternateContent.Choice.Drawing.Anchor; - wsp := anchor.Graphic.GraphicData.Wsp; - [x, y] := {self.}GetXYCordinates(); - xfrm := new XfrmUnitDecorator(wsp.SpPr.Xfrm); - position_h := new PositionHUnitDecorator(anchor.PositionH); - position_v := new PositionVUnitDecorator(anchor.PositionV); - if position_h.RelativeFrom = "paragraph" then - x := {self.}StartY; - if position_v.RelativeFrom = "paragraph" then - y := {self.}StartY; - x += position_h.PosOffset.Text; - y -= position_v.PosOffset.Text; - w := xfrm.Ext.CX; - body_pr := new BodyPrUnitDecorator(wsp.BodyPr); - x += body_pr.LIns; - w -= (body_pr.LIns + body_pr.RIns); - ps := wsp.Txbx.TxbxContent.Ps(); - for _,p in ps do - begin - range := new ParagraphRange(docx_to_pdf_, page_, docx_components_module_, p); - range.StartX := x; - range.StartY := y; - range.Width := w; - range.Calc(); - range.Do(); - y := range.EndY; - end -end; - -function ParagraphRange.RFootnoteReference(r: R); -begin - return; - id := R.FootnoteReference.Id; - footnotes_adapter := docx_components_module_.GetFootnotesAdapter(); - footnote := footnotes_adapter.GetFootnoteById(id); - sect_pr := page_.SectPr; - w := sect_pr.SectPr.PgSz.W - sect_pr.SectPr.PgMar.Right - sect_pr.SectPr.PgMar.Left; - lb := 0; - x := sect_pr.SectPr.PgMar.Left; - y := sect_pr.SectPr.PgSz.H; - - arr := array(); - elements := footnote.Elements(); - for _,element in elements do - begin - if element.LocalName = "p" then - begin - range := new ParagraphRange(docx_to_pdf_, page_, docx_components_module_, element); - range.StartX := x; - range.StartY := y; - range.Width := w; - range.LowerBound := 0; - range.Calc(); - arr[length(arr)] := arr; - end - end - rpr := new RPrUnitDecorator(r.RPr); - note := docx_to_pdf_.Note; - text := docx_to_pdf_.GetCurrentNoteModule().GetIndex(); - i := length(body_range_array_); - if ifString(text) then {self.}SplitTextToTextRange(body_range_array_, text, rpr, nil); - footnote_reference_hash_[body_range_array_[i]] := arr; - - // range := new ParagraphRange(self, page_, docx_components_module_, ); -end; - -function ParagraphRange.RFootnoteRef(r: R); -begin - return; - note_module := docx_to_pdf_.GetCurrentNoteModule(); - rpr := new RPrUnitDecorator(r.RPr); - text := note_module.GetFootnoteOrderNumber(); - if ifString(text) then {self.}SplitTextToTextRange(body_range_array_, text, rpr, nil); -end; - -function ParagraphRange.RObject(r: R); -begin - id := r.Object.Shape.Imagedata.Id; - [image_type, image] := {self.}GetImageData(id); - if not image then return; - style := r.Object.Shape.Style; - style_arr := str2array(style, ";"); - for _,str in style_arr do - begin - if startsStr("width:", str) then w := strtofloat(str[7:length(str)-2]); - else if startsStr("height:", str) then h := strtofloat(str[8:length(str)-2]); - end - image_range := new ImageRange(); - image_range.Image := image; - image_range.Type := image_type; - image_range.StartX := 0; - image_range.StartY := 0; - image_range.Width := w; - image_range.DynamicHeight := h; - body_range_array_[length(body_range_array_)] := image_range; -end; - -function ParagraphRange.RFldChar(r: R; stack: Stack); -begin - fld_struct := stack.Pop(); - - if r.FldChar.FldCharType = "begin" then - fld_struct.EndFld := false; - else if r.FldChar.FldCharType = "end" then - fld_struct.EndFld := true; - else if r.FldChar.FldCharType = "separate" then - fld_struct.Separate := true; - - instr_text := ifString(r.InstrText.Text) ? trim(r.InstrText.Text) : ""; - if instr_text <> "" then - begin - if instr_text = "QUOTE" then - fld_struct.Quote := true; - else if instr_text = "\\* MERGEFORMAT" then - fld_struct.MergeFormat := true; - else if instr_text = "PAGE \\* Arabic \\* MERGEFORMAT" or instr_text = "PAGE \\* MERGEFORMAT" then - fld_struct.PageArabicMergeFormat := true; - else if instr_text = "NUMPAGES" then - fld_struct.NumPages := true; - else if instr_text = "\\* Arabic \\* MERGEFORMAT" then - fld_struct.ArabicMergeFormat := true; - else if instr_text = "NUMPAGES \\* Arabic \\* MERGEFORMAT" then - fld_struct.NumPages := fld_struct.ArabicMergeFormat := true; - end - if fld_struct.Quote then - begin - if not fld_struct.EndFld and not fld_struct.Separate then - begin - stack.Push(fld_struct); - return; - end - end - else if fld_struct.PageArabicMergeFormat then - begin - if fld_struct.Separate then - begin - r.T.Text := tostring(page_.Number); - {self.}RT(r, nil); - fld_struct.PageArabicMergeFormat := false; - end - end - else if fld_struct.ArabicMergeFormat then - begin - if fld_struct.Separate then - begin - rpr := new RPrUnitDecorator(r.RPr); - numpages_index := length(body_range_array_); - placeholder_array_ := array(numpages_index, rpr); - fld_struct.NumPages := false; - end - end - if not fld_struct.EndFld then - begin - stack.Push(fld_struct); - end - if ifObj(r.Drawing) then {self.}RDrawing(r); - else if ifObj(r.AlternateContent) then {self.}RAlternateContent(r); - else if ifObj(r.FootnoteReference) then {self.}RFootnoteReference(r); - else if ifObj(r.Object) then {self.}RObject(r); -end; - -function ParagraphRange.GetXYCordinates(): array of real; -begin - xml_file := docx_to_pdf_.GetCurrentXmlFile(); - if xml_file = "document.xml" then - begin - [x, y] := page_.OriginalTextPoint(); - end - else begin - x := page_.SectPr.PgMar.Left; - if ansiContainsStr(xml_file, "footer") then - y := page_.SectPr.PgMar.Bottom; - else if ansiContainsStr(xml_file, "header") then - y := page_.SectPr.PgSz.H - page_.SectPr.PgMar.Header; - end - return array(x, y); -end; - -function ParagraphRange.GetImageData(id: string): PdfImage; -begin - xml_file := docx_to_pdf_.GetCurrentXmlFile(); - if xml_file = "document.xml" then - rels_adapter := docx_components_module_.GetDocumentRelsAdapter(); - else if ansiContainsStr(xml_file, "footer") then - rels_adapter := docx_components_module_.GetFtrRelsAdapter(xml_file); - else if ansiContainsStr(xml_file, "header") then - rels_adapter := docx_components_module_.GetHdrRelsAdapter(xml_file); - rel := rels_adapter.GetRelationshipById(id); - image_path := "word/" + rel.Target; - image := docx_components_module_.Zip().Get(image_path); - data := image.Data(); - image_path := docx_to_pdf_.GetCachePath(image_path); - writeFile(rwBinary(), "", image_path, 0, length(data), data); - image := nil; - image_type := GetImageFileType(data); - case image_type of - "png": - image := docx_to_pdf_.PdfFile().LoadPngImageFromFile("", image_path); - "jpg": - image := docx_to_pdf_.PdfFile().LoadJpegImageFromFile("", image_path); - "emf": - image := docx_to_pdf_.PdfFile().LoadEmfImageFromFile("", image_path); - "wmf": - image := docx_to_pdf_.PdfFile().LoadWmfImageFromFile("", image_path); - end; - fileDelete("", image_path); - return array(image_type, image); -end; - -function ParagraphRange.GetImageFileType(data: binary): string; -begin - stream := new TMemoryStream(); - size := length(data); - stream.Write(data[0:size-1], size); - def := array( - ('name': 'png', 'position': 0, 'value': array(0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A)), - ('name': 'jpg', 'position': 0, 'value': array(0xFF, 0xD8)), - ('name': 'emf', 'position': 40, 'value': array(0x20, 0x45, 0x4d, 0x46)), - ('name': 'wmf', 'position': 0, 'value': array(0xd7, 0xcd, 0xc6, 0x9a)), - ); - for i:=0 to length(def)-1 do - begin - value := def[i]['value']; - stream.Seek(def[i]['position']); - for j:=0 to length(value)-1 do - begin - r := 0; - stream.Read(r, 1); - if r <> value[j] then break; - if j = length(value)-1 then return def[i]['name']; - end - end - return ''; -end; - -function ParagraphRange.GetParagraphLineSpace(size: real; line: integer; line_rule: string): real; -begin - if not line then line := 240; - if line_rule = "exact" or line_rule = "atLeast" then - begin - lines := line / 240; - return size + lines; - end - else begin - lines := roundto(line / 240, -1); - multi := ceil(size / page_.BaseSize); - if (not ifnil(ppr_unit_decorator_.SnapToGrid) and not ppr_unit_decorator_.SnapToGrid) or - ((ifnil(ppr_unit_decorator_.SnapToGrid) or ppr_unit_decorator_.SnapToGrid) and lines > multi) then - multi *= lines; - return page_.SectPr.DocGrid.LinePitch * multi; - end -end; - -function ParagraphRange.SetPPPr(var p: P); -begin - new_ppr := new PPr(); - styles := docx_components_module_.GetStyles(); - new_ppr.Copy(styles.DocDefaults.PPrDefault.PPr); - new_ppr.RPr.Copy(styles.DocDefaults.RPrDefault.RPr); - {self.}SetPPrByStyleId(new_ppr, table_style_id_); - {self.}SetPPrByStyleId(new_ppr, p.PPr.PStyle.Val); - new_ppr.Copy(p.PPr); - p.PPr.Copy(new_ppr); -end; - -function ParagraphRange.SetPPrByStyleId(var ppr: PPr; style_id: string); -begin - styles := docx_components_module_.GetStylesAdapter(); - style := styles.GetStyleByStyleId(style_id); - if ifObj(style) then - begin - based_on := style.BasedOn.Val; - {self.}SetPPrByStyleId(ppr, based_on); - ppr.Copy(style.PPr); - ppr.RPr.Copy(style.RPr); - end -end; - -function ParagraphRange.SetRRPr(var r: R; ppr_unit_decorator: PPrUnitDecorator); -begin - new_rpr := new RPr(); - styles := docx_components_module_.GetStyles(); - new_rpr.Copy(styles.DocDefaults.RPrDefault.RPr); - {self.}SetRPrByTblStyleId(new_rpr, table_style_id_); - {self.}SetRPrByStyleId(new_rpr, ppr_unit_decorator.PStyle.Val); - {self.}SetRPrByStyleId(new_rpr, r.RPr.RStyle.Val); - new_rpr.Copy(r.RPr); - r.RPr.Copy(new_rpr); -end; - -function ParagraphRange.SetRPrByTblStyleId(var rpr: RPr; style_id: string); -begin - styles := docx_components_module_.GetStylesAdapter(); - style := styles.GetStyleByStyleId(style_id); - if ifObj(style) then - begin - based_on := style.BasedOn.Val; - {self.}SetRPrByTblStyleId(rpr, based_on); - rpr.Copy(style.RPr); - end - if table_style_type_ then - begin - tbl_style_pr := docx_components_module_.GetTblStylePrByType(table_style_id_, table_style_type_); - if tbl_style_pr then rpr.Copy(tbl_style_pr.RPr); - end -end; - -function ParagraphRange.SetRPrByStyleId(var rpr: RPr; style_id: string); -begin - styles := docx_components_module_.GetStylesAdapter(); - style := styles.GetStyleByStyleId(style_id); - if ifObj(style) then - begin - based_on := style.BasedOn.Val; - {self.}SetRPrByStyleId(rpr, based_on); - rpr.Copy(style.RPr); - end -end; - -function ParagraphRange.SetLvlText(); -begin - numbering_module := docx_components_module_.GetNumberingModule(); - if not ifObj(numbering_module) then return; - [lvl_text, lvl] := numbering_module.GetNumberLvl(paragraph_.PPr); - if lvl_text = "" and ifnil(lvl) then return; - {self.}SetRRPr(lvl, ppr_unit_decorator_); - rpr := new RPrUnitDecorator(lvl.RPr); - // {self.}SplitTextToTextRange(bullet_range_array_, lvl_text, rpr); - {self.}SplitTextToTextRange(body_range_array_, lvl_text, rpr); -end; - -function ParagraphRange.ResetCoordinates(); -begin - // 根据段落的间距确定新的坐标 - ppr := ppr_unit_decorator_; - sz := ppr.RPr.SzCs.Val ? ppr.RPr.SzCs.Val : ppr.RPr.Sz.Val ? ppr.RPr.Sz.Val : docx_to_pdf_.Font.GetDefaultSz(); - {self.}StartX += ppr.Ind.LeftChars ? ppr.Ind.LeftChars * sz : ppr.Ind.Left; - {self.}Width -= ppr.Ind.LeftChars ? ppr.Ind.LeftChars * sz : ppr.Ind.Left; - {self.}Width -= ppr.Ind.RightChars ? ppr.Ind.RightChars * sz : ppr.Ind.Right; -end; - -function ParagraphRange.GetLastPage(): Page; -begin - return page_; -end; - -function ParagraphRange.AdjustRangeOffset(pg: Page; x_offset: real; y_offset: real); -begin - for _,line_range in line_range_array_ do - line_range.AdjustRangeOffset(pg, x_offset, y_offset); -end; - -function ParagraphRange.GetParagraphLineRangeArr(): array of ParagraphLineRange; -begin - return line_range_array_; -end; - -function ParagraphRange.Empty(): boolean; -begin - return empty_; -end; - -function ParagraphRange.Offset(x: real; y: real); -begin - for _,line_range in line_range_array_ do - line_range.Offset(x, y); -end; - -function ParagraphRange.OMathPara(element: OMathPara); -begin - math_range := new MathRange(docx_to_pdf_, page_, element); - math_range.StartX := {self.}StartX; - math_range.StartY := {self.}StartY - 15.6; - math_range.Calc(); - // math_range.Do(); - body_range_array_[length(body_range_array_)] := math_range; -end; - -end.