From 600ce2e358046e0bc4ef53c2bddd8973625acee8 Mon Sep 17 00:00:00 2001 From: csh Date: Tue, 22 Apr 2025 17:48:52 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E6=AD=A5refactor=20xml=E5=85=AC?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TSDocxToPdf.tsf | 3 +- internal/DTPAdvancedRanges.tsf | 970 ++++++++++++++++++++++++++------ internal/DTPModules.tsf | 6 +- internal/DTPPrimitiveRanges.tsf | 35 +- internal/DTPUtils.tsf | 4 + 5 files changed, 843 insertions(+), 175 deletions(-) diff --git a/TSDocxToPdf.tsf b/TSDocxToPdf.tsf index 7b7fe39..210773e 100644 --- a/TSDocxToPdf.tsf +++ b/TSDocxToPdf.tsf @@ -278,7 +278,8 @@ begin ftr_range.Parent := self; ftr_range.LowerBound := 0; flag := ftr_range.Calc(); - y_offset := current_page_.SectPr.PgSz.H - ftr_range.DynamicHeight - current_page_.SectPr.PgMar.Footer; + // y_offset := current_page_.SectPr.PgSz.H - ftr_range.DynamicHeight - current_page_.SectPr.PgMar.Footer; + y_offset := current_page_.SectPr.PgMar.Footer + ftr_range.DynamicHeight; ftr_range.Offset(current_page_.SectPr.PgMar.Left, y_offset, current_page_); if flag then ftr_range.Do(); diff --git a/internal/DTPAdvancedRanges.tsf b/internal/DTPAdvancedRanges.tsf index f4843b8..55ef0c9 100644 --- a/internal/DTPAdvancedRanges.tsf +++ b/internal/DTPAdvancedRanges.tsf @@ -38,7 +38,7 @@ public function Create(docx_to_pdf: TSDocxToPdf; hdr: Hdr); function Do();override; function Calc(): boolean;override; - function Offset(x: real; y: real; page: Page);virtual; + function Offset(x: real; y: real; page: Page);override; function ProcessRealtimeArray(); private @@ -55,7 +55,7 @@ public function Create(docx_to_pdf: TSDocxToPdf; ftr: Ftr); function Do();override; function Calc(): boolean;override; - function Offset(x: real; y: real; page: Page);virtual; + function Offset(x: real; y: real; page: Page);override; function ProcessRealtimeArray(); private @@ -131,6 +131,7 @@ private function RDrawing(r: R); function RFldChar(r: R; stack: Stack); function RAlternateContent(r: R); + function RObject(r: R); function FldSimple(fld_simple: fldSimple); function Hyperlink(hyperlink: Hyperlink); function OMathPara(o_math_para: OMathPara); @@ -230,8 +231,12 @@ type OMathParaRange = class(AdvancedRange) public function Create(docx_to_pdf: TSDocxToPdf; o_math_para: OMathPara); function Do();override; - function Run(); - function Calc(); + function Calc();override; + function Offset(x: real; y: real; page: Page);override; + function AdjustOffset(x: real; y: real);override; + +public + BaseY: real; // 基准Y值 private [weakref]docx_to_pdf_: TSDocxToPdf; @@ -243,19 +248,18 @@ type OMathRange = class(AdvancedRange) public function Create(docx_to_pdf: TSDocxToPdf; element: OpenXmlElement); function Do();override; - function Run(); - function Calc(); + function Calc();override; + function Offset(x: real; y: real; page: Page);override; + function AdjustOffset(x: real; y: real);override; function SetMathSize(); - property Sz read sz_ write sz_; - -private - function MR(r: R; x: real; y: real); +public + BaseY: real; // 基准Y值 + BaseSz: real; // 基准字体大小 private [weakref]docx_to_pdf_: TSDocxToPdf; element_: OMath; - sz_: real; range_array_: array of BasicRange; end; @@ -263,32 +267,144 @@ type OMathRRange = class(AdvancedRange) public function Create(docx_to_pdf: TSDocxToPdf; r: R); function Do();override; - function Run(); - function Calc(); + function Calc();override; + function Offset(x: real; y: real; page: Page);override; + function AdjustOffset(x: real; y: real);overload; - property Sz read sz_ write sz_; +public + BaseY: real; // 基准Y值 + BaseSz: real; // 基准字体大小 private [weakref]docx_to_pdf_: TSDocxToPdf; r_: R; range_array_: array of BasicRange; - sz_: real; end; type OMathFRange = class(AdvancedRange) public function Create(docx_to_pdf: TSDocxToPdf; f: F); function Do();override; - function Calc(); - function Run(); + function Calc();override; + function Offset(x: real; y: real; page: Page);override; + function AdjustOffset(x: real; y: real);overload; - property Sz read sz_ write sz_; +public + BaseY: real; // 基准Y值 + BaseSz: real; // 基准字体大小 private [weakref]docx_to_pdf_: TSDocxToPdf; f_: F; range_array_: array of BasicRange; - sz_: real; +end; + +type OMathNaryRange = class(AdvancedRange) +public + function Create(docx_to_pdf: TSDocxToPdf; nary: Nary); + function Do();override; + function Calc();override; + function Offset(x: real; y: real; page: Page);override; + function AdjustOffset(x: real; y: real);overload; + +public + BaseY: real; // 基准Y值 + BaseSz: real; // 基准字体大小 + +private + [weakref]docx_to_pdf_: TSDocxToPdf; + nary_: Nary; + range_array_: array of BasicRange; +end; + +type OMathRadRange = class(AdvancedRange) +public + function Create(docx_to_pdf: TSDocxToPdf; rad: Rad); + function Do();override; + function Calc();override; + function Offset(x: real; y: real; page: Page);override; + function AdjustOffset(x: real; y: real);overload; + +public + BaseY: real; // 基准Y值 + BaseSz: real; // 基准字体大小 + +private + [weakref]docx_to_pdf_: TSDocxToPdf; + rad_: rad; + range_array_: array of BasicRange; +end; + +type OMathSSupRange = class(AdvancedRange) +public + function Create(docx_to_pdf: TSDocxToPdf; s_sup: SSup); + function Do();override; + function Calc();override; + function Offset(x: real; y: real; page: Page);override; + function AdjustOffset(x: real; y: real);overload; + +public + BaseY: real; // 基准Y值 + BaseSz: real; // 基准字体大小 + +private + [weakref]docx_to_pdf_: TSDocxToPdf; + s_sup_: SSup; + range_array_: array of BasicRange; +end; + +type OMathSSubRange = class(AdvancedRange) +public + function Create(docx_to_pdf: TSDocxToPdf; s_sub: SSub); + function Do();override; + function Calc();override; + function Offset(x: real; y: real; page: Page);override; + function AdjustOffset(x: real; y: real);overload; + +public + BaseY: real; // 基准Y值 + BaseSz: real; // 基准字体大小 + +private + [weakref]docx_to_pdf_: TSDocxToPdf; + s_sub_: SSub; + range_array_: array of BasicRange; +end; + +type OMathDRange = class(AdvancedRange) +public + function Create(docx_to_pdf: TSDocxToPdf; d: D); + function Do();override; + function Calc();override; + function Offset(x: real; y: real; page: Page);override; + function AdjustOffset(x: real; y: real);overload; + +public + BaseY: real; // 基准Y值 + BaseSz: real; // 基准字体大小 + +private + [weakref]docx_to_pdf_: TSDocxToPdf; + d_: D; + range_array_: array of BasicRange; +end; + +type OMathFuncRange = class(AdvancedRange) +public + function Create(docx_to_pdf: TSDocxToPdf; func: Func); + function Do();override; + function Calc();override; + function Offset(x: real; y: real; page: Page);override; + function AdjustOffset(x: real; y: real);overload; + +public + BaseY: real; // 基准Y值 + BaseSz: real; // 基准字体大小 + +private + [weakref]docx_to_pdf_: TSDocxToPdf; + func_: Func; + range_array_: array of BasicRange; end; implementation @@ -303,6 +419,16 @@ begin range_array_ := array(); end; +function AdvancedRange.Offset(x: real; y: real; page: Page); +begin + {self.}StartX := {self.}XOffset + x; + {self.}StartY := {self.}YOffset + y; + {self.}StartPage := page; + {self.}EndX := {self.}StartX; + {self.}EndY := {self.}StartY; + {self.}EndPage := {self.}StartPage; +end; + function TocRange.Create(); begin class(AdvancedRange).Create(); @@ -380,12 +506,7 @@ end; function HdrRange.Offset(x: real; y: real; page: Page);virtual; begin - {self.}StartX := x + XOffset; - {self.}StartY := y + YOffset; - {self.}StartPage := page; - {self.}EndX := {self.}StartX; - {self.}EndY := {self.}StartY; - {self.}EndPage := {self.}StartPage; + class(AdvancedRange).Offset(x, y, page); for _,range in range_array_ do begin range.LowerBound := {self.}LowerBound; @@ -446,13 +567,7 @@ end; function FtrRange.Offset(x: real; y: real; page: Page);virtual; begin - sy := page.SectPr.PgMar.Footer + {self.}DynamicHeight; - {self.}StartX := x + XOffset; - {self.}StartY := sy + YOffset; - {self.}StartPage := page; - {self.}EndX := {self.}StartX; - {self.}EndY := {self.}StartY; - {self.}EndPage := {self.}StartPage; + class(AdvancedRange).Offset(x, y, page); for _,range in range_array_ do begin range.LowerBound := {self.}LowerBound; @@ -515,10 +630,16 @@ begin {self.}EndX := x + {self.}XOffset; {self.}EndY := y - {self.}DynamicHeight; // 没用上YOffset {self.}EndPage := page; - y_offset := {self.}LineSpace >= {self.}DynamicHeight ? ({self.}LineSpace - {self.}TextMaxSize) / 2 + {self.}TextMaxSize - {self.}TextMaxSize / 5 : {self.}DynamicHeight; - y := {self.}StartY - y_offset; + offset := {self.}LineSpace >= {self.}DynamicHeight ? ({self.}LineSpace - {self.}TextMaxSize) / 2 + {self.}TextMaxSize - {self.}TextMaxSize / 5 : {self.}DynamicHeight; + y_offset := {self.}StartY - offset; for _,range in range_array_ do - range.Offset(x, y, page); // 公式不是y值,需要处理公式 + begin + if range is class(OMathParaRange) then // 公式不是y值,需要处理公式 + range.Offset(x, y, page); + // range.Offset(0, 841.9, page); + else + range.Offset(x, y_offset, page); + end end; function PLineRange.CanFitInLine(range: BasicRange): boolean; @@ -528,6 +649,7 @@ begin if range is class(TextRange) and range.Type = 4 and not ({self.}Parent.Parent is class(TcRange)) then return false; // 中文标点不换行 + if range is class(OMathParaRange) then return false; // 公式不换行 return true; end; @@ -662,6 +784,8 @@ begin 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.Anchor then {self.}Hyperlink(element); end else if element.LocalName = "fldSimple" then begin @@ -673,10 +797,12 @@ begin 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); @@ -692,12 +818,7 @@ end; function PRange.Offset(x: real; y: real; page: Page);override; begin // println("PRange::x = {}, y = {}, page = {}", x, y, page); - {self.}StartX := x + {self.}XOffset; - {self.}StartY := y + {self.}YOffset; // 段落的YOffset实际为0 - {self.}StartPage := page; - {self.}EndX := {self.}StartX; - {self.}EndY := {self.}StartY; - {self.}EndPage := {self.}StartPage; + class(AdvancedRange).Offset(x, y, page); right_bound_ := {self.}StartX + {self.}Width; // 检查是否需要实时计算页码 @@ -729,7 +850,7 @@ begin rpr := new RPrUnitDecorator(r.RPr); if not rpr.Sz.Val then rpr.Sz.Val := rpr.SzCs.Val ? rpr.SzCs.Val : docx_to_pdf_.Font.GetDefaultSz(); font_name := rpr.RFonts.Ascii ?: rpr.RFonts.EastAsia; - font_obj := docx_to_pdf_.Font.GetCNSFont(font_name, rpr.B, rpr.I); + font_obj := docx_to_pdf_.Font.GetCNSFont(font_name, rpr.B.IsApplied, rpr.I.IsApplied); text := new TextRange(); text.RPr := rpr; text.Font := font_obj; @@ -752,15 +873,39 @@ begin [image_type, image] := {self.}GetImageData(id); if not image then return; xfrm := new XfrmUnitDecorator(r.Drawing._Inline.Graphic.GraphicData.Pic.SpPr.Xfrm); + rpr := new RPrUnitDecorator(r.RPr); image_range := new ImageRange(); image_range.Image := image; image_range.Type := image_type; image_range.Width := xfrm.Ext.CX; image_range.DynamicHeight := xfrm.Ext.CY; + image_range.RPr := rpr; body_range_array_[length(body_range_array_)] := image_range; end end; +function PRange.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 + rpr := new RPrUnitDecorator(r.RPr); + image_range := new ImageRange(); + image_range.Image := image; + image_range.Type := image_type; + image_range.Width := w; + image_range.DynamicHeight := h; + image_range.RPr := rpr; + body_range_array_[length(body_range_array_)] := image_range; +end; + function PRange.RFldChar(r: R; stack: Stack); begin fld_struct := stack.Pop(); @@ -801,7 +946,7 @@ begin rpr := new RPrUnitDecorator(r.RPr); if not rpr.Sz.Val then rpr.Sz.Val := rpr.SzCs.Val ? rpr.SzCs.Val : docx_to_pdf_.Font.GetDefaultSz(); font_name := rpr.RFonts.EastAsia ? rpr.RFonts.EastAsia : rpr.RFonts.Ascii; - font_obj := docx_to_pdf_.Font.GetCNSFont(font_name, rpr.B, rpr.I); + font_obj := docx_to_pdf_.Font.GetCNSFont(font_name, rpr.B.IsApplied, rpr.I.IsApplied); text := new TextRange(); text.RPr := rpr; // text.Type := 1; @@ -816,7 +961,7 @@ begin rpr := new RPrUnitDecorator(r.RPr); if not rpr.Sz.Val then rpr.Sz.Val := rpr.SzCs.Val ? rpr.SzCs.Val : docx_to_pdf_.Font.GetDefaultSz(); font_name := rpr.RFonts.EastAsia ? rpr.RFonts.EastAsia : rpr.RFonts.Ascii; - font_obj := docx_to_pdf_.Font.GetCNSFont(font_name, rpr.B, rpr.I); + font_obj := docx_to_pdf_.Font.GetCNSFont(font_name, rpr.B.IsApplied, rpr.I.IsApplied); text := new TextRange(); text.RPr := rpr; // text.Type := 1; @@ -826,10 +971,13 @@ begin realtime_numpages_array_[length(realtime_numpages_array_)] := text; body_range_array_[length(body_range_array_)] := text; end + else if fld_struct.Type.Quote then + begin + if r.Drawing then {self.}RDrawing(r); + end fld_struct.Status := 2; end if fld_struct.Status <> 2 then stack.Push(fld_struct); - end; function PRange.RAlternateContent(r: R); @@ -864,7 +1012,7 @@ begin rpr := new RPrUnitDecorator(r.RPr); if not rpr.Sz.Val then rpr.Sz.Val := rpr.SzCs.Val ? rpr.SzCs.Val : docx_to_pdf_.Font.GetDefaultSz(); font_name := rpr.RFonts.EastAsia ? rpr.RFonts.EastAsia : rpr.RFonts.Ascii; - font_obj := docx_to_pdf_.Font.GetCNSFont(font_name, rpr.B, rpr.I); + font_obj := docx_to_pdf_.Font.GetCNSFont(font_name, rpr.B.IsApplied, rpr.I.IsApplied); text := new TextRange(); text.RPr := rpr; // text.Type := 1; @@ -904,7 +1052,7 @@ begin rpr := new RPrUnitDecorator(r.RPr); if not rpr.Sz.Val then rpr.Sz.Val := rpr.SzCs.Val ? rpr.SzCs.Val : docx_to_pdf_.Font.GetDefaultSz(); font_name := rpr.RFonts.EastAsia ? rpr.RFonts.EastAsia : rpr.RFonts.Ascii; - font_obj := docx_to_pdf_.Font.GetCNSFont(font_name, rpr.B, rpr.I); + font_obj := docx_to_pdf_.Font.GetCNSFont(font_name, rpr.B.IsApplied, rpr.I.IsApplied); text := new TextRange(); text.RPr := rpr; text.Font := font_obj; @@ -1102,10 +1250,16 @@ end; function PRange.UpdateTextRangeWidth(); begin if length(realtime_page_array_) > 0 or length(realtime_numpages_array_) > 0 then return; - head_range := body_range_array_[0]; - i := 1; - while i < length(body_range_array_) do + i := 0; + head_range := nil; + tail_range := nil; + while i < length(body_range_array_)-1 do begin + if not (head_range is class(TextRange)) then + begin + i++; + head_range := body_range_array_[i]; + end tail_range := body_range_array_[i]; if not (tail_range is class(TextRange)) then begin @@ -1312,23 +1466,23 @@ begin text_range.Type := 5; word := a_word; font_name := rpr.RFonts.EastAsia ?: rpr.RFonts.Ascii; - font_obj := docx_to_pdf_.Font.GetCNSFont(font_name, rpr.B, rpr.I); + font_obj := docx_to_pdf_.Font.GetCNSFont(font_name, rpr.B.IsApplied, rpr.I.IsApplied); // font_name := rpr.RFonts.Ascii ?: rpr.RFonts.EastAsia; - // font_obj := docx_to_pdf_.Font.GetAsciiFont(font_name, rpr.B, rpr.I); + // font_obj := docx_to_pdf_.Font.GetAsciiFont(font_name, rpr.B.IsApplied, rpr.I.IsApplied); end else if DTPUtils.IsChineseChar(a_word) then begin text_range.Type := 3; word := utf8ToAnsi(a_word); font_name := rpr.RFonts.EastAsia ?: rpr.RFonts.Ascii; - font_obj := docx_to_pdf_.Font.GetCNSFont(font_name, rpr.B, rpr.I); + font_obj := docx_to_pdf_.Font.GetCNSFont(font_name, rpr.B.IsApplied, rpr.I.IsApplied); end else if DTPUtils.IsChinesePunctuation(a_word) then begin text_range.Type := 4; word := utf8ToAnsi(a_word); font_name := rpr.RFonts.EastAsia ?: rpr.RFonts.Ascii; - font_obj := docx_to_pdf_.Font.GetCNSFont(font_name, rpr.B, rpr.I); + font_obj := docx_to_pdf_.Font.GetCNSFont(font_name, rpr.B.IsApplied, rpr.I.IsApplied); end else begin word := utf8ToAnsi(a_word); @@ -1340,7 +1494,7 @@ begin end else begin font_name := rpr.RFonts.EastAsia ?: rpr.RFonts.Ascii; - font_obj := docx_to_pdf_.Font.GetCNSFont(font_name, rpr.B, rpr.I); + font_obj := docx_to_pdf_.Font.GetCNSFont(font_name, rpr.B.IsApplied, rpr.I.IsApplied); end end first_page := docx_to_pdf_.PageManager[0]; @@ -1581,7 +1735,7 @@ begin {self.}DynamicHeight += {self.}Parent.TblPr.TblCellMar.Bottom.W + {self.}Parent.TblPr.TblCellMar.Top.W; // 同步行高 - if not tc_.TcPr.VMerge and {self.}DynamicHeight > trp_.Height then + if not tc_.TcPr.VMerge.IsApplied and {self.}DynamicHeight > trp_.Height then trp_.Height := {self.}DynamicHeight; return true; end; @@ -1589,12 +1743,7 @@ end; function TcRange.Offset(x: real; y: real; page: Page);override; begin // println("TcRange::x = {}, y = {}, page = {}", x, y, page); - {self.}StartX := x + {self.}XOffset; - {self.}StartY := y + {self.}YOffset; - {self.}StartPage := page; - {self.}EndX := {self.}StartX; - {self.}EndY := {self.}StartY; - {self.}EndPage := {self.}StartPage; + class(AdvancedRange).Offset(x, y, page); content_next_page_ := false; cell_x := {self.}EndX + {self.}Parent.TblPr.TblCellMar.Left.W; @@ -1824,12 +1973,12 @@ begin end end else begin - range.Left := {self.}Col = 0; - range.Top := {self.}Row = 0; - range.Right := true; - range.Bottom := true; + range.Left := false; + range.Top := false; + range.Right := false; + range.Bottom := false; end - if top_ then range.Top := true; + if top_ and ifObj(tbl_pr.TblBorders) then range.Top := true; end; function TcRange.GetTblStyleId(): string; @@ -1900,7 +2049,7 @@ begin else {self.}OverrideTcPrByTblStylePrType(tc.TcPr, "band2Horz"); grid_span := new GridSpanUnitDecorator(tc.TcPr.GridSpan); - if tc.TcPr.VMerge and tc.TcPr.VMerge <> "restart" then + if tc.TcPr.VMerge.IsApplied and tc.TcPr.VMerge.Val <> "restart" then begin tc_x += grid_cols[pos++].W; for k:=grid_span.Val-1 downto 1 do @@ -1979,7 +2128,7 @@ begin {self.}EndY := y; break; end - if range.Tc.TcPr.VMerge then + if range.Tc.TcPr.VMerge.IsApplied then begin b_merge_index := i; e_merge_index := i + 1; @@ -2013,7 +2162,7 @@ begin if i_height then tr_pr_array_[i].Height := i_height; for _,range in tc_range_matrix_[i] do begin - if not ifObj(range) or range.Tc.TcPr.VMerge then continue; + if not ifObj(range) or range.Tc.TcPr.VMerge.IsApplied then continue; range.AlignHeight(tr_pr_array_[i].Height); range.SetVAlign(); {self.}EndY := range.EndY; @@ -2123,26 +2272,30 @@ begin o_math_range_.Do(); end; -function OMathParaRange.Run();override; +function OMathParaRange.Offset(x: real; y: real; page: Page);override; begin - o_math_range_.StartX := {self.}StartX; - o_math_range_.StartY := {self.}StartY; - o_math_range_.EndX := {self.}StartX; - o_math_range_.EndY := {self.}StartY; - o_math_range_.StartPage := {self.}StartPage; - o_math_range_.EndPage := {self.}StartPage; - o_math_range_.Run(); + class(AdvancedRange).Offset(x, y, page); + o_math_range_.Offset({self.}EndX, {self.}EndY, {self.}EndPage); end; -function OMathParaRange.Calc(); +function OMathParaRange.Calc();override; begin o_math_range_ := new OMathRange(docx_to_pdf_, o_math_para_.OMath); o_math_range_.Width := {self.}Width; o_math_range_.Parent := self; - o_math_range_.StartX := 0; - o_math_range_.StartY := 0; + o_math_range_.XOffset := 0; + o_math_range_.YOffset := 0; o_math_range_.SetMathSize(); o_math_range_.Calc(); + o_math_range_.AdjustOffset(0, -o_math_range_.DynamicHeight); + {self.}Width := o_math_range_.Width; + {self.}DynamicHeight := o_math_range_.DynamicHeight; +end; + +function OMathParaRange.AdjustOffset(x: real; y: real);override; +begin + class(BasicRange).AdjustOffset(x, y); + o_math_para_.AdjustOffset(x, y); end; function OMathRange.Create(docx_to_pdf: TSDocxToPdf; element: OpenXmlElement); @@ -2150,7 +2303,8 @@ begin class(AdvancedRange).Create(); docx_to_pdf_ := docx_to_pdf; element_ := element; - sz_ := 0; + {self.}BaseY := 0; + {self.}BaseSz := 0; end; function OMathRange.Do();override; @@ -2159,41 +2313,69 @@ begin range.Do(); end; -function OMathRange.Run();override; +function OMathRange.Offset(x: real; y: real; page: Page);override; begin - {self.}EndX := {self.}StartX; - {self.}EndY := {self.}StartY; - {self.}EndPage := {self.}StartPage; + class(AdvancedRange).Offset(x, y, page); for _,range in range_array_ do - begin - range.StartX := {self.}StartX; - range.StartY := {self.}StartY; - range.StartPage := {self.}StartPage; - range.Run(); - end + range.Offset(x, y, page); end; -function OMathRange.Calc(); +function OMathRange.AdjustOffset(x: real; y: real);overload; +begin + class(BasicRange).AdjustOffset(x, y); + for _,range in range_array_ do + range.AdjustOffset(x, y); +end; + +function OMathRange.Calc();override; begin range_array_ := array(); - {self.}EndX := {self.}StartX; - {self.}EndY := {self.}StartY; - min_y := {self.}StartY; - max_y := {self.}StartY; + x := {self.}XOffset; + y := {self.}YOffset; elements := element_.Elements(); for _,element in elements do begin range := nil; if element.LocalName = "r" then + begin range := new OMathRRange(docx_to_pdf_, element); + range.BaseSz := {self.}BaseSz; + end else if element.LocalName = "f" then + begin range := new OMathFRange(docx_to_pdf_, element); - // else if element.LocalName = "rad" then - // range := new OMathRadRange(docx_to_pdf_, element); - // else if element.LocalName = "nary" then - // range := new OMathNaryRange(docx_to_pdf_, element); - // else if element.LocalName = "sSup" then - // range := new OMathSSupRange(docx_to_pdf_, element); + range.BaseSz := {self.}BaseSz; + end + else if element.LocalName = "rad" then + begin + range := new OMathRadRange(docx_to_pdf_, element); + range.BaseSz := {self.}BaseSz; + end + else if element.LocalName = "nary" then + begin + range := new OMathNaryRange(docx_to_pdf_, element); + range.BaseSz := {self.}BaseSz; + end + else if element.LocalName = "sSup" then + begin + range := new OMathSSupRange(docx_to_pdf_, element); + range.BaseSz := {self.}BaseSz; + end + else if element.LocalName = "sSub" then + begin + range := new OMathSSubRange(docx_to_pdf_, element); + range.BaseSz := {self.}BaseSz; + end + else if element.LocalName = "d" then + begin + range := new OMathDRange(docx_to_pdf_, element); + range.BaseSz := {self.}BaseSz; + end + else if element.LocalName = "func" then + begin + range := new OMathFuncRange(docx_to_pdf_, element); + range.BaseSz := {self.}BaseSz; + end if not ifObj(range) then begin @@ -2201,19 +2383,21 @@ begin continue; end range.Parent := self; - range.StartX := {self.}EndX; - range.StartY := {self.}EndY; - range.Sz := sz_; + range.XOffset := x; + range.YOffset := y; range.Calc(); + x += range.Width; // 下一个元素偏移位置 + {self.}Width += range.Width; - 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; + if {self.}DynamicHeight < range.DynamicHeight then + {self.}DynamicHeight := range.DynamicHeight; range_array_[length(range_array_)] := range; end - {self.}DynamicHeight := max_y - min_y; + for _,range in range_array_ do + begin + h := ({self.}DynamicHeight - range.DynamicHeight) / 2; + range.AdjustOffset(0, h); + end end; function OMathRange.SetMathSize(); @@ -2222,20 +2406,20 @@ begin element := elements[0]; rpr := nil; if element.LocalName = "r" then - rpr := element.RPr; + rpr := element.RPr("w"); else if element.LocalName = "f" then - rpr := element.FPr.CtrlPr.RPr; + rpr := element.FPr.CtrlPr.RPr("w"); else if element.LocalName = "nary" then - rpr := element.NaryPr.CtrlPr.RPr; + rpr := element.NaryPr.CtrlPr.RPr("w"); else if element.LocalName = "rad" then - rpr := element.RadPr.CtrlPr.RPr; + rpr := element.RadPr.CtrlPr.RPr("w"); else if element.LocalName = "sSup" then - rpr := element.SSupPr.CtrlPr.RPr; + rpr := element.SSupPr.CtrlPr.RPr("w"); styles := docx_to_pdf_.DocxComponents.GetStyles(); - default_rpr := styles.DocDefaults.RPrDefault.RPr(); + default_rpr := styles.DocDefaults.RPrDefault.RPr; if rpr then default_rpr.Copy(rpr); - sz_ := strtofloat(default_rpr.Sz.Val); + {self.}BaseSz := strtofloat(default_rpr.Sz.Val) / 2; end; function OMathFRange.Create(docx_to_pdf: TSDocxToPdf; f: F); @@ -2252,51 +2436,59 @@ begin range.Do(); end; -function OMathFRange.Run(); +function OMathFRange.Offset(x: real; y: real; page: Page);override; begin - {self.}EndX := {self.}StartX; - {self.}EndY := {self.}StartY; - {self.}EndPage := {self.}StartPage; + class(AdvancedRange).Offset(x, y, page); for _,range in range_array_ do - begin - range.StartX := {self.}StartX; - range.StartY := {self.}StartY; - range.StartPage := {self.}StartPage; - range.Run(); - end + range.Offset(x, y, page); end; -function OMathFRange.Calc(); +function OMathFRange.Calc();override; begin - {self.}EndX := {self.}StartX; - {self.}EndY := {self.}StartY; + bar_margin := {self.}BaseSz * 0.1; + x := {self.}XOffset + bar_margin; + y := {self.}YOffset; + + // 分子分母单独计算高度,最后再合并 + // 分母 + den_range := new OMathRange(docx_to_pdf_, f_.Den); + den_range.BaseSz := {self.}BaseSz; + den_range.XOffset := x; + den_range.YOffset := y; + den_range.Calc(); // 需要得到高宽 // 分子 num_range := new OMathRange(docx_to_pdf_, f_.Num); - num_range.Sz := sz_; - num_range.StartX := {self.}EndX; - num_range.StartY := {self.}EndY; + num_range.BaseSz := {self.}BaseSz; + num_range.XOffset := x; + num_range.YOffset := y; num_range.Calc(); // 需要得到高宽 - // 分母 - den_range := new OMathRange(docx_to_pdf_, f_.Den); - den_range.Sz := sz_; - den_range.StartX := {self.}EndX; - den_range.StartY := num_range.EndY - 0.418 * sz; - den_range.Calc(); // 需要得到高宽 + max_len := max(den_range.Width, num_range.Width) + 2*bar_margin; - max_len := max(den_range.Width, num_range.Width); - bar := max_len / 0.9; + xo := (max_len - num_range.Width) / 2; + num_range.AdjustOffset(xo, den_range.DynamicHeight + 0.3 * {self.}BaseSz); + xo := (max_len - den_range.Width) / 2; + den_Range.AdjustOffset(xo, 0); + + // 线 line_range := new LineRange(); - line_range.StartX := {self.}EndX - (bar - max_len) / 2; - line_range.StartY := + 0.928 * sz; - line_range.EndX := line_range.StartX; - line_range.EndY := line_range.StartY; - line_range.Width := bar; - line_range.LineWidth := 0.04 * sz; + line_range.XOffset := {self.}XOffset; + line_range.YOffset := y + den_range.DynamicHeight; + line_range.Width := max_len; + line_range.LineWidth := 0.04 * {self.}BaseSz; - range_array_ union= array(den_range, num_range); - // range_array_ union= array(den_range, num_range, line_range); + {self.}DynamicHeight := num_range.DynamicHeight + den_range.DynamicHeight + 0.3 * {self.}BaseSz; + {self.}Width := line_range.Width + bar_margin; + + range_array_ union= array(den_range, num_range, line_range); +end; + +function OMathFRange.AdjustOffset(x: real; y: real);override; +begin + class(BasicRange).AdjustOffset(x, y); + for _,range in range_array_ do + range.AdjustOffset(x, y); end; function OMathRRange.Create(docx_to_pdf: TSDocxToPdf; r: R); @@ -2313,27 +2505,56 @@ begin range.Do(); end; -function OMathRRange.Run(); +function OMathRRange.Offset(x: real; y: real; page: Page); begin - {self.}EndX := {self.}StartX; - {self.}EndPage := {self.}StartPage; - {self.}DynamicHeight := sz_; - {self.}EndY := {self.}StartY - sz_; + class(AdvancedRange).Offset(x, y, page); + {self.}DynamicHeight := {self.}BaseSz; for _,range in range_array_ do - begin - range.EndX += {self.}StartX; - range.EndY := range.StartY + {self.}EndY - sz_; - range.EndPage := {self.}EndPage; - end; + range.Offset(x, y, page); + {self.}EndY := {self.}StartY - {self.}DynamicHeight; +end; + +function OMathRRange.AdjustOffset(x: real; y: real);override; +begin + class(BasicRange).AdjustOffset(x, y); + for _,range in range_array_ do + range.AdjustOffset(x, y); end; function OMathRRange.Calc(); begin + {self.}DynamicHeight := {self.}BaseSz; if not r_.T then return; - x := {self.}StartX; - y := {self.}StartY; + x := {self.}XOffset; + y := {self.}YOffset; text := r_.T.Text; pos := 1; + case r_.RPr.Sty.Val of + "p": + begin + b := false; + i := false; + end + "b": + begin + b := true; + i := false; + end + "i": + begin + b := false; + i := true; + end + "bi": + begin + b := true; + i := true; + end + else begin + b := false; + i := true; + end + end; while pos <= length(text) do begin text_range := new TextRange(); @@ -2351,19 +2572,19 @@ begin else if char = 0x44 or char = 0x46 then text_range.Type := 5; word := a_word; - font_obj := docx_to_pdf_.Font.GetCNSFont("SimSun", false, true); + font_obj := docx_to_pdf_.Font.GetCNSFont("Times-Roman", b, i); end else if DTPUtils.IsChineseChar(a_word) then begin text_range.Type := 3; word := utf8ToAnsi(a_word); - font_obj := docx_to_pdf_.Font.GetCNSFont("SimSun", false, true); + font_obj := docx_to_pdf_.Font.GetCNSFont("SimSun", b, i); end else if DTPUtils.IsChinesePunctuation(a_word) then begin text_range.Type := 4; word := utf8ToAnsi(a_word); - font_obj := docx_to_pdf_.Font.GetCNSFont("SimSun", false, true); + font_obj := docx_to_pdf_.Font.GetCNSFont("SimSun", b, i); end else begin word := class(SymbolMapper).SymbolChr(a_word); @@ -2375,22 +2596,431 @@ begin font_obj := docx_to_pdf_.Font.GetSymbolFont(); end rpr := new RPr(); - rpr.Sz.Val := sz_; + rpr.Sz.Val := {self.}BaseSz; first_page := docx_to_pdf_.PageManager[0]; pdf_page := first_page.PdfPage; - pdf_page.SetFontAndSize(font_obj, sz); + pdf_page.SetFontAndSize(font_obj, {self.}BaseSz); text_range.RPr := rpr; text_range.Text := word; text_range.Font := font_obj; text_range.Width := pdf_page.TextWidth(word); text_range.Parent := self; text_range.DynamicHeight := rpr.Sz.Val; - text_range.EndX := x; - text_range.EndY := y; + text_range.XOffset := x; + text_range.YOffset := y; x += text_range.Width; pos += num; range_array_[length(range_array_)] := text_range; + {self.}Width += text_range.Width; end end; +function OMathNaryRange.Create(docx_to_pdf: TSDocxToPdf; nary: Nary); +begin + class(AdvancedRange).Create(); + docx_to_pdf_ := docx_to_pdf; + nary_ := nary; + range_array_ := array(); +end; + +function OMathNaryRange.Do();override; +begin + for _,range in range_array_ do + range.Do(); +end; + +function OMathNaryRange.Offset(x: real; y: real; page: Page);override; +begin + class(AdvancedRange).Offset(x, y, page); + for _,range in range_array_ do + range.Offset(x, y, page); +end; + +function OMathNaryRange.AdjustOffset(x: real; y: real);overload; +begin + for _,range in range_array_ do + range.AdjustOffset(x, y); +end; + +function OMathNaryRange.Calc();override; +begin + x := {self.}XOffset; + y := {self.}YOffset; + + val := nary_.NaryPr.Chr.Val ?: "Į"; + symbol := class(SymbolMapper).SymbolChr(val); + if ifnil(symbol) then + begin + echo format("error = %s", val); + return; + end + symbol_font := docx_to_pdf_.Font.GetSymbolFont(); + first_page := docx_to_pdf_.PageManager[0]; + pdf_page := first_page.PdfPage; + size := {self.}BaseSz; + pdf_page.SetFontAndSize(symbol_font, size); + symbol_range := new TextRange(); + symbol_range.Text := symbol; + symbol_range.XOffset := x; + symbol_range.YOffset := y; + symbol_range.Width := pdf_page.TextWidth(symbol); + symbol_range.Font := symbol_font; + symbol_range.RPr := new DocxML.RPr(); + symbol_range.RPr.Sz.Val := size; + symbol_range.DynamicHeight := size; + + sub_range := new OMathRange(docx_to_pdf_, nary_.Sub); + sub_range.BaseSz := {self.}BaseSz * 0.5; + 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.XOffset := x; + sup_range.YOffset := y; + sup_range.Calc(); // 需要得到高宽 + + if nary_.NaryPr.LimLoc.Val = "subSup" then + begin + max_width := max(sub_range.Width, sup_range.Width) + symbol_range.Width; + sub_range.AdjustOffset(symbol_range.Width, -sub_range.DynamicHeight/2); + sup_range.AdjustOffset(symbol_range.Width, symbol_range.DynamicHeight - sup_range.DynamicHeight/2); + {self.}Width := max_width; + {self.}DynamicHeight := symbol_range.DynamicHeight + sub_range.DynamicHeight/2 + sup_range.DynamicHeight + {self.}BaseSz * 0.1; + end + // else if nary_.Nary.LimLoc.Val = "undOvr" then + else begin // undOvr + max_width := maxValue(array(sub_range.Width, sup_range.Width, symbol_range.Width)); + sub_range.AdjustOffset((max_width - sub_range.Width)/2, 0); + symbol_range.AdjustOffset((max_width - symbol_range.Width)/2, sub_range.DynamicHeight); + sup_range.AdjustOffset((max_width - sup_range.Width)/2, symbol_range.DynamicHeight + sub_range.DynamicHeight); + {self.}Width := max_width; + {self.}DynamicHeight := sup_range.DynamicHeight + symbol_range.DynamicHeight + sub_range.DynamicHeight; + end + + e_range := new OMathRange(docx_to_pdf_, nary_.E); + e_range.BaseSz := {self.}BaseSz; + e_range.XOffset := x + max_width; + e_range.YOffset := y + sub_range.DynamicHeight; + e_range.Calc(); + + range_array_ union= array(symbol_range, sub_range, sup_range, e_range); + + {self.}Width += e_range.Width; + {self.}DynamicHeight := max({self.}DynamicHeight, e_range.DynamicHeight); +end; + +function OMathRadRange.Create(docx_to_pdf: TSDocxToPdf; rad: Rad); +begin + class(AdvancedRange).Create(); + docx_to_pdf_ := docx_to_pdf; + rad_ := rad; + range_array_ := array(); +end; + +function OMathRadRange.Do();override; +begin + for _,range in range_array_ do + range.Do(); +end; + +function OMathRadRange.Offset(x: real; y: real; page: Page);override; +begin + class(AdvancedRange).Offset(x, y, page); + for _,range in range_array_ do + range.Offset(x, y, page); +end; + +function OMathRadRange.AdjustOffset(x: real; y: real);overload; +begin + for _,range in range_array_ do + range.AdjustOffset(x, y); +end; + +function OMathRadRange.Calc();override; +begin + x := {self.}XOffset + 0.2*{self.}BaseSz; + y := {self.}YOffset; + + deg_range := new OMathRange(docx_to_pdf_, rad_.Deg); + deg_range.BaseSz := {self.}BaseSz * 0.5; + deg_range.XOffset := x; + deg_range.YOffset := y; + deg_range.Calc(); + + e_range := new OMathRange(docx_to_pdf_, rad_.E); + e_range.BaseSz := {self.}BaseSz; + e_range.XOffset := x; + e_range.YOffset := y; + e_range.Calc(); // 需要得到高宽 + + symbol := chr(0xD6); + symbol_font := docx_to_pdf_.Font.GetSymbolFont(); + first_page := docx_to_pdf_.PageManager[0]; + pdf_page := first_page.PdfPage; + size := e_range.DynamicHeight; + pdf_page.SetFontAndSize(symbol_font, size); + symbol_range := new TextRange(); + symbol_range.Text := symbol; + symbol_range.XOffset := x; + symbol_range.YOffset := y; + symbol_range.Width := pdf_page.TextWidth(symbol); + symbol_range.Font := symbol_font; + symbol_range.RPr := new DocxML.RPr(); + symbol_range.RPr.Sz.Val := size; + symbol_range.DynamicHeight := size; + + deg_range.AdjustOffset(0, -e_range.DynamicHeight * 0.5); + symbol_range.AdjustOffset(deg_range.Width, 0); + e_range.AdjustOffset(size*0.3 + deg_range.Width, 0); + + line_range := new LineRange(); + line_range.XOffset := symbol_range.XOffset + symbol_range.Width * 0.9; + line_range.YOffset := symbol_range.DynamicHeight * 0.9; + line_range.Width := e_range.Width; + line_range.LineWidth := 0.04 * size; + + range_array_ union= array(symbol_range, deg_range, e_range, line_range); + + {self.}Width := deg_range.Width + symbol_range.Width + e_range.Width + 0.3*size; + {self.}DynamicHeight := symbol_range.DynamicHeight; +end; + +function OMathSSupRange.Create(docx_to_pdf: TSDocxToPdf; s_sup: SSup); +begin + class(AdvancedRange).Create(); + docx_to_pdf_ := docx_to_pdf; + s_sup_ := s_sup; + range_array_ := array(); +end; + +function OMathSSupRange.Do();override; +begin + for _,range in range_array_ do + range.Do(); +end; + +function OMathSSupRange.Offset(x: real; y: real; page: Page);override; +begin + class(AdvancedRange).Offset(x, y, page); + for _,range in range_array_ do + range.Offset(x, y, page); +end; + +function OMathSSupRange.AdjustOffset(x: real; y: real);overload; +begin + for _,range in range_array_ do + range.AdjustOffset(x, y); +end; + +function OMathSSupRange.Calc();override; +begin + x := {self.}XOffset + 0.2*{self.}BaseSz; + y := {self.}YOffset; + + e_range := new OMathRange(docx_to_pdf_, s_sup_.E); + e_range.BaseSz := {self.}BaseSz; + e_range.XOffset := x; + e_range.YOffset := y; + e_range.Calc(); // 需要得到高宽 + + sup_range := new OMathRange(docx_to_pdf_, s_sup_.Sup); + sup_range.BaseSz := {self.}BaseSz * 0.4; + sup_range.XOffset := x; + sup_range.YOffset := y; + sup_range.Calc(); + sup_range.AdjustOffset(e_range.Width, e_range.DynamicHeight * 0.5); + + 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; + {self.}DynamicHeight := max(h, e_range.DynamicHeight); +end; + +function OMathSSubRange.Create(docx_to_pdf: TSDocxToPdf; s_sub: SSub); +begin + class(AdvancedRange).Create(); + docx_to_pdf_ := docx_to_pdf; + s_sub_ := s_sub; + range_array_ := array(); +end; + +function OMathSSubRange.Do();override; +begin + for _,range in range_array_ do + range.Do(); +end; + +function OMathSSubRange.Offset(x: real; y: real; page: Page);override; +begin + class(AdvancedRange).Offset(x, y, page); + for _,range in range_array_ do + range.Offset(x, y, page); +end; + +function OMathSSubRange.AdjustOffset(x: real; y: real);overload; +begin + for _,range in range_array_ do + range.AdjustOffset(x, y); +end; + +function OMathSSubRange.Calc();override; +begin + x := {self.}XOffset; + y := {self.}YOffset; + + e_range := new OMathRange(docx_to_pdf_, s_sub_.E); + e_range.BaseSz := {self.}BaseSz; + e_range.XOffset := x; + e_range.YOffset := y; + e_range.Calc(); // 需要得到高宽 + + sub_range := new OMathRange(docx_to_pdf_, s_sub_.Sub); + sub_range.BaseSz := {self.}BaseSz * 0.4; + sub_range.XOffset := x; + sub_range.YOffset := y; + sub_range.Calc(); + sub_range.AdjustOffset(e_range.Width, -(sub_range.DynamicHeight - {self.}BaseSz * 0.4)); + + range_array_ union= array(e_range, sub_range); + + {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); +end; + +function OMathDRange.Create(docx_to_pdf: TSDocxToPdf; d: D); +begin + class(AdvancedRange).Create(); + docx_to_pdf_ := docx_to_pdf; + d_ := d; + range_array_ := array(); +end; + +function OMathDRange.Do();override; +begin + for _,range in range_array_ do + range.Do(); +end; + +function OMathDRange.Offset(x: real; y: real; page: Page);override; +begin + class(AdvancedRange).Offset(x, y, page); + for _,range in range_array_ do + range.Offset(x, y, page); +end; + +function OMathDRange.AdjustOffset(x: real; y: real);overload; +begin + for _,range in range_array_ do + range.AdjustOffset(x, y); +end; + +function OMathDRange.Calc();override; +begin + x := {self.}XOffset; + y := {self.}YOffset; + + e_range := new OMathRange(docx_to_pdf_, d_.E); + e_range.BaseSz := {self.}BaseSz; + e_range.XOffset := x; + e_range.YOffset := y; + e_range.Calc(); + + beg_chr := class(SymbolMapper).SymbolChr(d_.DPr.BegChr.Val) ?: chr(0x28); // ( + end_chr := class(SymbolMapper).SymbolChr(d_.DPr.EndChr.Val) ?: chr(0x29); // ) + + max_h := e_range.DynamicHeight; + font_obj := docx_to_pdf_.Font.GetSymbolFont(); + first_page := docx_to_pdf_.PageManager[0]; + pdf_page := first_page.PdfPage; + pdf_page.SetFontAndSize(font_obj, max_h); + + beg_range := new TextRange(); + beg_range.Text := beg_chr; + beg_range.RPr := new RPr(); + beg_range.RPr.Sz.Val := max_h; + beg_range.Font := font_obj; + beg_range.Width := pdf_page.TextWidth(beg_chr); + beg_range.Parent := self; + beg_range.DynamicHeight := max_h; + beg_range.XOffset := x; + beg_range.YOffset := y; + + end_range := new TextRange(); + end_range.Text := end_chr; + end_range.RPr := new RPr(); + end_range.RPr.Sz.Val := max_h; + end_range.Font := font_obj; + end_range.Width := pdf_page.TextWidth(end_chr); + end_range.Parent := self; + end_range.DynamicHeight := max_h; + end_range.XOffset := x; + end_range.YOffset := y; + + e_range.AdjustOffset(beg_range.Width, 0); + end_range.AdjustOffset(e_range.Width + beg_range.Width, 0); + + 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; +end; + +function OMathFuncRange.Create(docx_to_pdf: TSDocxToPdf; func: Func); +begin + class(AdvancedRange).Create(); + docx_to_pdf_ := docx_to_pdf; + func_ := func; + range_array_ := array(); +end; + +function OMathFuncRange.Do();override; +begin + for _,range in range_array_ do + range.Do(); +end; + +function OMathFuncRange.Offset(x: real; y: real; page: Page);override; +begin + class(AdvancedRange).Offset(x, y, page); + for _,range in range_array_ do + range.Offset(x, y, page); +end; + +function OMathFuncRange.AdjustOffset(x: real; y: real);overload; +begin + for _,range in range_array_ do + range.AdjustOffset(x, y); +end; + +function OMathFuncRange.Calc();override; +begin + x := {self.}XOffset; + y := {self.}YOffset; + + f_name_range := new OMathRange(docx_to_pdf_, func_.FName); + f_name_range.BaseSz := {self.}BaseSz; + f_name_range.XOffset := x; + f_name_range.YOffset := y; + f_name_range.Calc(); // 需要得到高宽 + + e_range := new OMathRange(docx_to_pdf_, func_.E); + e_range.BaseSz := {self.}BaseSz; + e_range.XOffset := x; + e_range.YOffset := y; + e_range.Calc(); + + max_h := max(f_name_range.DynamicHeight, e_range.DynamicHeight); + + e_range.AdjustOffset(f_name_range.Width, (max_h - e_range.DynamicHeight) / 2); + f_name_range.AdjustOffset(0, (max_h - f_name_range.DynamicHeight) / 2); + + range_array_ union= array(f_name_range, e_range); + + {self.}Width += f_name_range.Width + e_range.Width; + {self.}DynamicHeight := max(f_name_range.DynamicHeight, e_range.DynamicHeight); +end; + end. diff --git a/internal/DTPModules.tsf b/internal/DTPModules.tsf index f5b888a..5e6708b 100644 --- a/internal/DTPModules.tsf +++ b/internal/DTPModules.tsf @@ -608,7 +608,9 @@ begin i := 0; while true do begin - y := {self.}TextPoint.Y - i * {self.}SectPr.DocGrid.LinePitch; + y := {self.}SectPr.PgSz.H - max({self.}SectPr.PgMar.Top, {self.}SectPr.PgMar.Header); + y := min(y, {self.}HdrPoint.Y); + y := y - i * {self.}SectPr.DocGrid.LinePitch; if y <= {self.}SectPr.PgMar.Bottom then break; pdf_page_.SetLineWidth(0.05); pdf_page_.SetGrayStroke(0.75); @@ -627,7 +629,7 @@ begin x4 := x2; y4 := y3; pdf_page_.SetLineWidth(0.05); - pdf_page_.SetGrayStroke(0.5); + pdf_page_.SetGrayStroke(0.70); pdf_page_.MoveTo(x1, y1); pdf_page_.LineTo(x2, y2); pdf_page_.Stroke(); diff --git a/internal/DTPPrimitiveRanges.tsf b/internal/DTPPrimitiveRanges.tsf index a70b5e7..f5ae75c 100644 --- a/internal/DTPPrimitiveRanges.tsf +++ b/internal/DTPPrimitiveRanges.tsf @@ -7,6 +7,7 @@ public function Create(); function Do();virtual; function Offset(x: real; y: real; page: Page);virtual; + function AdjustOffset(x: real; y: real);virtual; public [weakref]Parent: tslobj; @@ -59,6 +60,7 @@ public function Do();override; public + RPr: RPrUnitDecorator; Image: PdfImage; Type: string; end; @@ -98,6 +100,12 @@ begin {self.}EndPage := page; end; +function BasicRange.AdjustOffset(x: real; y: real);virtual; +begin + {self.}XOffset += x; + {self.}YOffset += y; +end; + // ImageRange function ImageRange.Create(); begin @@ -108,6 +116,18 @@ end; function ImageRange.Do();override; begin + if {self.}RPr.Highlight.Val = "yellow" then + begin + {self.}EndPage.PdfPage.SetRGBFill(1, 1, 0); + x := {self.}EndX; + y := {self.}Parent.EndY; + w := {self.}Width; + h := {self.}Parent.DynamicHeight; + {self.}EndPage.PdfPage.Rectangle(x, y, w, h); + {self.}EndPage.PdfPage.Fill(); + {self.}EndPage.PdfPage.SetRGBFill(0, 0, 0); + end + // println("image = {}, type = {}, x = {}, y = {}, w = {}, h = {}", {self.}image, {self.}Type, {self.}endx, {self.}endy, {self.}width, {self.}DynamicHeight); if {self.}Type = "emf" then {self.}EndPage.PdfPage.DrawEmf({self.}Image, {self.}EndX, {self.}EndY, {self.}Width, {self.}DynamicHeight); @@ -140,7 +160,7 @@ function BordersRange.DoFill(); begin borders := {self.}TcPr.TcBorders; // println("TcPr.Shd.Val = {}", TcPr.Shd.Val); - if {self.}TcPr.Shd.Val <> "clear" and {self.}TcPr.Shd.Fill and {self.}TcPr.Shd.Fill <> "auto" then + if {self.}TcPr.Shd.Val = "clear" and {self.}TcPr.Shd.Fill and {self.}TcPr.Shd.Fill <> "auto" then begin [r, g, b] := DTPColorToolKit.HexToRGB({self.}TcPr.Shd.Fill); {self.}EndPage.PdfPage.SetRGBFill(r/255, g/255, b/255); @@ -227,6 +247,17 @@ begin y += sz / 3; sz := sz * 2 / 3; end + if {self.}RPr.Highlight.Val = "yellow" then + begin + {self.}EndPage.PdfPage.SetRGBFill(1, 1, 0); + x := {self.}EndX; + y := {self.}Parent.EndY; + w := {self.}Width; + h := {self.}Parent.DynamicHeight; + {self.}EndPage.PdfPage.Rectangle(x, y, w, h); + {self.}EndPage.PdfPage.Fill(); + {self.}EndPage.PdfPage.SetRGBFill(0, 0, 0); + end {self.}EndPage.PdfPage.SetRGBFill(r / 255, g / 255, b / 255); {self.}EndPage.PdfPage.SetFontAndSize({self.}Font, sz); {self.}EndPage.PdfPage.BeginText(); @@ -254,7 +285,7 @@ end; function LineRange.Do();override; begin - // println("endx = {}, endy = {}, width = {}", EndX, EndY, Width); + // println("endx = {}, endy = {}, width = {}, line_width = {}", EndX, EndY, Width, LineWidth); {self.}EndPage.PdfPage.SetLineWidth({self.}LineWidth); {self.}EndPage.PdfPage.SetRGBStroke(0, 0, 0); {self.}EndPage.PdfPage.MoveTo({self.}EndX, {self.}EndY); diff --git a/internal/DTPUtils.tsf b/internal/DTPUtils.tsf index b902a84..8694298 100644 --- a/internal/DTPUtils.tsf +++ b/internal/DTPUtils.tsf @@ -185,18 +185,22 @@ begin "β": chr(0x62), "ε": chr(0x65), "γ": chr(0x67), + "π": chr(0x70), "θ": chr(0x71), "{": chr(0x7B), "}": chr(0x7D), "∞": chr(0xA5), "f": chr(0xA6), "±": chr(0xB1), + "×": chr(0xB4), "∂": chr(0xB6), "∏": chr(0xD5), "〈": chr(0xE1), "∑": chr(0xE5), + "⌊": chr(0xEB), "〉": chr(0xF1), "Į": chr(0xF2), + "⌋": chr(0xFB), // "": chr(0x), ); end