From 4de1484ec3337d4d69f898fe8a393362f4ccd354 Mon Sep 17 00:00:00 2001 From: csh Date: Fri, 25 Oct 2024 15:45:15 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=87=8D=E5=A4=8D=E5=9B=BE?= =?UTF-8?q?=E7=89=87bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- range/Advanced/TSPdfParagraphRange.tsf | 166 ++++++++++++++++++++----- 1 file changed, 136 insertions(+), 30 deletions(-) diff --git a/range/Advanced/TSPdfParagraphRange.tsf b/range/Advanced/TSPdfParagraphRange.tsf index 9824ac1..7c9866d 100644 --- a/range/Advanced/TSPdfParagraphRange.tsf +++ b/range/Advanced/TSPdfParagraphRange.tsf @@ -25,10 +25,11 @@ private function GetUtf8CharLength(byte: string): integer; function SplitTextToTextRange(text: string; rpr: RPrUnitDecorator; link: string); function RToTextRange(r: R; link: string); - function RToDrawingRange(r: R); - function RAlternateContentToRange(r: R); + function RDrawing(r: R); + function RAlternateContent(r: R); function RFootnoteReference(r: R); function RObject(r: R); + function RFldChar(r: R; stack: Stack); function SetLinesAlignment(); function ResetCoordinates(); function NewLineRange(): TSPdfLineRange; @@ -52,6 +53,58 @@ private table_style_type_: string; end; +type FldStruct = class +public + function create(); + begin + FldLock := false; + MergeFormat := false; + Quote := false; + Separate := false; + PageArabicMergeFormat := false; + NumPages := false; + ArabicMergeFormat := false; + EndFld := false; + end; +public + FldLock: boolean; + MergeFormat: boolean; + Quote: boolean; + Separate: boolean; + PageArabicMergeFormat: boolean; + NumPages: boolean; + ArabicMergeFormat: boolean; + EndFld: boolean; +end; + +type Stack = class +public + function create(); + begin + arr_ := array(); + index_ := 0; + end; + function Pop(); + begin + if index_ = 0 then return nil; + index_--; + ret := arr_[index_]; + arr_[index_] := nil; + return ret; + end; + function Push(element: any); + begin + arr_[index_++] := element; + end; + function Empty(): boolean; + begin + return index_ = 0; + end; +private + arr_: tableArray; + index_: integer; +end; + function TSPdfParagraphRange.Create(docx_to_pdf: TSDocxToPdf; pg: TSPage; components: TSDocxComponentsWare; paragraph: P); begin docx_to_pdf_ := docx_to_pdf; @@ -87,6 +140,7 @@ begin bookmark_id := ''; bookmark_name := ''; bookmark_flag := false; + fld_stack := new Stack(); for _,element in elements do begin if element.LocalName = "r" then @@ -94,37 +148,26 @@ begin empty_flag := false; if ifnil(element.XmlChildRPr) then element.XmlChildRPr := new RPr(); {self.}SetRPr(element.RPr, ppr_unit_decorator_); + if element.FldChar.FldCharType = "begin" then + begin + fld_struct := new FldStruct(); + fld_stack.Push(fld_struct); + end + if not fld_stack.Empty() then + begin + {self.}RFldChar(element, fld_stack); continue; - else if element.FldChar.FldCharType = "separate" then - fld := true; - else if element.FldChar.FldCharType = "end" then - fld := false; - else if ifString(element.InstrText.Text) and trim(element.InstrText.Text) = "PAGE \\* Arabic \\* MERGEFORMAT" then - page_number := true; - else if ifString(element.InstrText.Text) and trim(element.InstrText.Text) = "NUMPAGES" then - numpages := true; - else if fld and page_number then - begin - element.T.Text := tostring(page_.Number); - {self.}RToTextRange(element, nil); - page_number := false; end - else if fld and numpages then - begin - rpr := new RPrUnitDecorator(element.RPr); - numpages_index := length(range_array_); - placeholder_array_ := array(numpages_index, rpr); - numpages := false; - end - else if element.Br.Type = "page" then + + if element.Br.Type = "page" then // {self.}EndY := {self.}LowerBound; {self.}CheckAndAddPage({self.}LowerBound, 1); - else if ifObj(element.Drawing.XmlNode) then {self.}RToDrawingRange(element); - else if ifObj(element.AlternateContent.XmlNode) then {self.}RAlternateContentToRange(element); - else if ifObj(element.FootnoteReference.XmlNode) then {self.}RFootnoteReference(element); + else if ifObj(element.Drawing) then {self.}RDrawing(element); + else if ifObj(element.AlternateContent) then {self.}RAlternateContent(element); + else if ifObj(element.FootnoteReference) then {self.}RFootnoteReference(element); else if ifObj(element.Object) then {self.}RObject(element); - else if not fld then {self.}RToTextRange(element, bookmark_name); + else {self.}RToTextRange(element, bookmark_name); end else if element.LocalName = "fldSimple" then begin @@ -133,7 +176,6 @@ begin rpr := new RPrUnitDecorator(element.Rs(0).RPr); numpages_index := length(range_array_); placeholder_array_ := array(numpages_index, rpr); - numpages := false; end end else if element.LocalName = "hyperlink" then @@ -454,7 +496,7 @@ begin end end; -function TSPdfParagraphRange.RToDrawingRange(r: R); +function TSPdfParagraphRange.RDrawing(r: R); begin if ifObj(r.Drawing._Inline.XmlNode) then begin @@ -497,7 +539,7 @@ begin end end; -function TSPdfParagraphRange.RAlternateContentToRange(r: R); +function TSPdfParagraphRange.RAlternateContent(r: R); begin anchor := r.AlternateContent.Choice.Drawing.Anchor; wsp := anchor.Graphic.GraphicData.Wsp; @@ -562,6 +604,70 @@ begin range_array_[length(range_array_)] := image_range; end; +function TSPdfParagraphRange.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; + if r.FldChar.FldLock then + fld_struct.FldLock := 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" 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; + 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.}RToTextRange(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(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 TSPdfParagraphRange.GetXYCordinates(): array of real; begin xml_file := docx_to_pdf_.GetCurrentXmlFile();