修复重复图片bug

This commit is contained in:
csh 2024-10-25 15:45:15 +08:00
parent 9db7890278
commit 4de1484ec3
1 changed files with 136 additions and 30 deletions

View File

@ -25,10 +25,11 @@ private
function GetUtf8CharLength(byte: string): integer; function GetUtf8CharLength(byte: string): integer;
function SplitTextToTextRange(text: string; rpr: RPrUnitDecorator; link: string); function SplitTextToTextRange(text: string; rpr: RPrUnitDecorator; link: string);
function RToTextRange(r: R; link: string); function RToTextRange(r: R; link: string);
function RToDrawingRange(r: R); function RDrawing(r: R);
function RAlternateContentToRange(r: R); function RAlternateContent(r: R);
function RFootnoteReference(r: R); function RFootnoteReference(r: R);
function RObject(r: R); function RObject(r: R);
function RFldChar(r: R; stack: Stack);
function SetLinesAlignment(); function SetLinesAlignment();
function ResetCoordinates(); function ResetCoordinates();
function NewLineRange(): TSPdfLineRange; function NewLineRange(): TSPdfLineRange;
@ -52,6 +53,58 @@ private
table_style_type_: string; table_style_type_: string;
end; 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); function TSPdfParagraphRange.Create(docx_to_pdf: TSDocxToPdf; pg: TSPage; components: TSDocxComponentsWare; paragraph: P);
begin begin
docx_to_pdf_ := docx_to_pdf; docx_to_pdf_ := docx_to_pdf;
@ -87,6 +140,7 @@ begin
bookmark_id := ''; bookmark_id := '';
bookmark_name := ''; bookmark_name := '';
bookmark_flag := false; bookmark_flag := false;
fld_stack := new Stack();
for _,element in elements do for _,element in elements do
begin begin
if element.LocalName = "r" then if element.LocalName = "r" then
@ -94,37 +148,26 @@ begin
empty_flag := false; empty_flag := false;
if ifnil(element.XmlChildRPr) then element.XmlChildRPr := new RPr(); if ifnil(element.XmlChildRPr) then element.XmlChildRPr := new RPr();
{self.}SetRPr(element.RPr, ppr_unit_decorator_); {self.}SetRPr(element.RPr, ppr_unit_decorator_);
if element.FldChar.FldCharType = "begin" then 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; 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 end
else if fld and numpages then
begin if element.Br.Type = "page" then
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
// {self.}EndY := {self.}LowerBound; // {self.}EndY := {self.}LowerBound;
{self.}CheckAndAddPage({self.}LowerBound, 1); {self.}CheckAndAddPage({self.}LowerBound, 1);
else if ifObj(element.Drawing.XmlNode) then {self.}RToDrawingRange(element); else if ifObj(element.Drawing) then {self.}RDrawing(element);
else if ifObj(element.AlternateContent.XmlNode) then {self.}RAlternateContentToRange(element); else if ifObj(element.AlternateContent) then {self.}RAlternateContent(element);
else if ifObj(element.FootnoteReference.XmlNode) then {self.}RFootnoteReference(element); else if ifObj(element.FootnoteReference) then {self.}RFootnoteReference(element);
else if ifObj(element.Object) then {self.}RObject(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 end
else if element.LocalName = "fldSimple" then else if element.LocalName = "fldSimple" then
begin begin
@ -133,7 +176,6 @@ begin
rpr := new RPrUnitDecorator(element.Rs(0).RPr); rpr := new RPrUnitDecorator(element.Rs(0).RPr);
numpages_index := length(range_array_); numpages_index := length(range_array_);
placeholder_array_ := array(numpages_index, rpr); placeholder_array_ := array(numpages_index, rpr);
numpages := false;
end end
end end
else if element.LocalName = "hyperlink" then else if element.LocalName = "hyperlink" then
@ -454,7 +496,7 @@ begin
end end
end; end;
function TSPdfParagraphRange.RToDrawingRange(r: R); function TSPdfParagraphRange.RDrawing(r: R);
begin begin
if ifObj(r.Drawing._Inline.XmlNode) then if ifObj(r.Drawing._Inline.XmlNode) then
begin begin
@ -497,7 +539,7 @@ begin
end end
end; end;
function TSPdfParagraphRange.RAlternateContentToRange(r: R); function TSPdfParagraphRange.RAlternateContent(r: R);
begin begin
anchor := r.AlternateContent.Choice.Drawing.Anchor; anchor := r.AlternateContent.Choice.Drawing.Anchor;
wsp := anchor.Graphic.GraphicData.Wsp; wsp := anchor.Graphic.GraphicData.Wsp;
@ -562,6 +604,70 @@ begin
range_array_[length(range_array_)] := image_range; range_array_[length(range_array_)] := image_range;
end; 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; function TSPdfParagraphRange.GetXYCordinates(): array of real;
begin begin
xml_file := docx_to_pdf_.GetCurrentXmlFile(); xml_file := docx_to_pdf_.GetCurrentXmlFile();