parent
a118ff6c26
commit
9f84a72595
268
TSDocxToPdf.tsf
268
TSDocxToPdf.tsf
|
|
@ -8,10 +8,9 @@ public
|
|||
|
||||
function GetCachePath(image_path: string): string;
|
||||
function GetCurrentXmlFile(): string;
|
||||
function GetCurrentNoteModule(): NoteModule;
|
||||
|
||||
function AddPage(flag: boolean): Page;
|
||||
function ProcessNumpages();
|
||||
function ProcessRealtimeRange();
|
||||
|
||||
// docx页码扩展
|
||||
function UpdateDocxPageNumPages();
|
||||
|
|
@ -19,10 +18,13 @@ public
|
|||
function SaveDocxFile(alias: string; file: string);overload;
|
||||
|
||||
property PdfFile read pdf_;
|
||||
property DocxComponents read docx_components_module_;
|
||||
property Font read font_module_;
|
||||
property PageManager read page_manager_module_;
|
||||
property Toc read toc_module_;
|
||||
property Note read note_module_;
|
||||
property CurrentSect read current_sect_module_;
|
||||
property CurrentPage read current_page_;
|
||||
|
||||
private
|
||||
function InitDocxComponents(alias: string; file: string);
|
||||
|
|
@ -31,16 +33,17 @@ private
|
|||
function InitSectModule();
|
||||
function AllocateElementsToSectModule();
|
||||
function ClassifyCols(var point: Point; cols: Cols);
|
||||
function RangesSpacing(range: BasicRange);
|
||||
|
||||
function SetHdr(type: string);
|
||||
function SetFtr(type: string);
|
||||
function TransformP(paragraph: P; x: real; y: real; w: real; lb: real): ParagraphRange;
|
||||
function TransformTbl(table: Tbl; x: real; y: real; w: real; lb: real): TableRange;
|
||||
function TransformSdt(sdt: Sdt; x: real; y: real; w: real; lb: real): array of ParagraphRange;
|
||||
function TransformP(p: P);
|
||||
function TransformTbl(tbl: Tbl);
|
||||
function TransformSdt(sdt: Sdt);
|
||||
|
||||
private
|
||||
pdf_: PdfFile;
|
||||
docx_components_module_: DocxComponentsModule; // TSDocxComponentsModule
|
||||
docx_components_module_: DocxComponentsModule; // DocxComponentsModule
|
||||
cache_path_: string; // 临时目录,用来存放临时文件
|
||||
font_module_: FontModule; // 字体模块
|
||||
sect_module_array_: array of SectModule; // 页面布局模块数组
|
||||
|
|
@ -53,11 +56,13 @@ private
|
|||
toc_module_: TocModule; // 目录模块
|
||||
note_module_: NoteModule; // 脚注/尾注
|
||||
|
||||
range_page_number_array_: tableArray;
|
||||
|
||||
xml_file_: string;
|
||||
even_and_odd_flag_: boolean;
|
||||
|
||||
realtime_range_array_: array of BasicRange; // 最后才能计算出来的range,比如包含总页码的
|
||||
|
||||
last_range_: BasicRange; // 上一个range
|
||||
|
||||
// 回写docx
|
||||
docx_page_arr_: tableArray;
|
||||
update_docx_pages_: boolean;
|
||||
|
|
@ -77,13 +82,14 @@ begin
|
|||
page_manager_module_ := new DTPModules.PageManagerModule(pdf_);
|
||||
|
||||
toc_module_ := new DTPModules.TocModule();
|
||||
range_page_number_array_ := array();
|
||||
|
||||
xml_file_ := "document.xml";
|
||||
settings := docx_components_module_.Settings;
|
||||
settings.XmlChildEvenAndOddHeaders.Deserialize();
|
||||
even_and_odd_flag_ := settings.EvenAndOddHeaders ? true : false;
|
||||
note_module_ := new ;
|
||||
note_module_ := new DTPModules.NoteModule(self);
|
||||
|
||||
realtime_range_array_ := array();
|
||||
|
||||
// 回写docx
|
||||
docx_page_arr_ := array();
|
||||
|
|
@ -109,7 +115,6 @@ begin
|
|||
current_sect_module_ := sect_module;
|
||||
current_sect_pr_adapter_ := new SectPrAdapter(current_sect_module_.SectPr.GetObject());
|
||||
{self.}AddPage(true);
|
||||
xml_file_ := "document.xml";
|
||||
end
|
||||
|
||||
// 分栏
|
||||
|
|
@ -120,28 +125,18 @@ begin
|
|||
columns := {self.}ClassifyCols(current_page_.TextPoint, cols);
|
||||
end
|
||||
else begin
|
||||
w := current_page_.SectPr.PgSz.W - current_page_.SectPr.PgMar.Right - current_page_.SectPr.PgMar.Left;
|
||||
lb := max(current_page_.SectPr.PgMar.Bottom, current_page_.FtrPoint.Y);
|
||||
for _,element in elements do
|
||||
begin
|
||||
x := current_page_.TextPoint.X;
|
||||
y := current_page_.TextPoint.Y;
|
||||
// if _ = 266 then break;
|
||||
// if _ = 20 then
|
||||
// println("_ = {}, xml_file_ = {}, error = {}", _, xml_file_, pdf_.GetError());
|
||||
range := nil;
|
||||
if element.LocalName = "p" then range := {self.}TransformP(element, x, y, w, lb);
|
||||
else if element.LocalName = "tbl" then range := {self.}TransformTbl(element, x, y, w, lb);
|
||||
else if element.LocalName = "sdt" then {self.}TransformSdt(element, x, y, w, lb);
|
||||
if ifObj(range) then
|
||||
begin
|
||||
current_page_.TextPoint.Y := range.EndY;
|
||||
range.Do();
|
||||
end
|
||||
// if _ = 100 then break;
|
||||
// if _ = 17 then
|
||||
// println("_ = {}, paraid = {}, xml_file_ = {}, error = {}", _, element.ParaId, xml_file_, pdf_.GetError());
|
||||
if element.LocalName = "p" then {self.}TransformP(element);
|
||||
else if element.LocalName = "tbl" then {self.}TransformTbl(element);
|
||||
else if element.LocalName = "sdt" then {self.}TransformSdt(element);
|
||||
end
|
||||
end
|
||||
end
|
||||
{self.}ProcessNumpages();
|
||||
{self.}ProcessRealtimeRange();
|
||||
end;
|
||||
|
||||
function TSDocxToPdf.GetCachePath(image_path: string): string;
|
||||
|
|
@ -197,12 +192,13 @@ begin
|
|||
sect.PgSz.Orient := sect.PgSz.Orient ? "portrait" : "landscape";
|
||||
sect.Type.Val := sect.Type.Val ?: "nextPage";
|
||||
module.SectPr := sect;
|
||||
module.BaseSize := round(sect.DocGrid.LinePitch * 0.75);
|
||||
end
|
||||
for i:=0 to length(elements)-1 do
|
||||
begin
|
||||
element := elements[i];
|
||||
module.AddElement(element);
|
||||
if element.LocalName = "p" and ifObj(element.PPr.SectPr) then
|
||||
if element.LocalName = "p" and element.PPr.SectPr then
|
||||
begin
|
||||
##fp(module, element.PPr.SectPr);
|
||||
sect_module_array_[length(sect_module_array_)] := module;
|
||||
|
|
@ -224,22 +220,8 @@ begin
|
|||
page := page_manager_module_.NewPage();
|
||||
page.SectPr := current_sect_module_.SectPr;
|
||||
page.Number := flag ? ifnil(current_sect_module_.SectPr.PgNumType.Start) ? 1 : current_sect_module_.SectPr.PgNumType.Start : page_manager_module_[page_manager_module_.Count() - 2].Number + 1;
|
||||
page.BaseSize := round(page.SectPr.DocGrid.LinePitch * 0.75);
|
||||
|
||||
// 正文、页眉页脚坐标
|
||||
// 页眉:从上往下,不需要调整
|
||||
page.HdrPoint.X := page.SectPr.PgMar.Left;
|
||||
page.HdrPoint.Y := page.SectPr.PgSz.H - page.SectPr.PgMar.Header;
|
||||
// 页脚:从下往上,需要调整
|
||||
page.FtrPoint.X := page.SectPr.PgMar.Left;
|
||||
page.FtrPoint.Y := page.SectPr.PgSz.H;
|
||||
// 正文:运行完页眉页脚后需要再次计算
|
||||
page.TextPoint.X := page.SectPr.PgMar.Left;
|
||||
page.TextPoint.Y := page.SectPr.PgSz.H - max(page.SectPr.PgMar.Top, page.SectPr.PgMar.Header);
|
||||
|
||||
current_page_ := page;
|
||||
// println("TextPoint.X = {}, TextPoint.Y = {}", current_page_.TextPoint.X, current_page_.TextPoint.Y);
|
||||
// println("len = {}, Number = {}", page_manager_module_.Count(), current_page_.Number);
|
||||
|
||||
// 页眉页脚
|
||||
if current_sect_module_.SectPr.TitlePg and current_page_.Index = 0 then
|
||||
|
|
@ -251,11 +233,17 @@ begin
|
|||
else
|
||||
type_name := "default";
|
||||
|
||||
bk_file := xml_file_;
|
||||
{self.}SetHdr(type_name);
|
||||
{self.}SetFtr(type_name);
|
||||
xml_file_ := bk_file;
|
||||
|
||||
// 设置完页眉页脚计算正文坐标
|
||||
page.TextPoint.X := page.SectPr.PgMar.Left;
|
||||
page.TextPoint.Y := page.SectPr.PgSz.H - max(page.SectPr.PgMar.Top, page.SectPr.PgMar.Header);
|
||||
page.TextPoint.Y := min(page.TextPoint.Y, page.HdrPoint.Y);
|
||||
page.UpperBound := page.TextPoint.Y;
|
||||
page.LowerBound := max(page.SectPr.PgMar.Bottom, page.FtrPoint.Y);
|
||||
|
||||
// println("len = {}, Number = {}", page_manager_module_.Count(), current_page_.Number);
|
||||
// println("W = {}, H = {}", current_page_.SectPr.PgSz.W, current_page_.SectPr.PgSz.H);
|
||||
// println("Top = {}, Bottom = {}", current_page_.SectPr.PgMar.Top, current_page_.SectPr.PgMar.Bottom);
|
||||
// println("Left = {}, Right = {}", current_page_.SectPr.PgMar.Left, current_page_.SectPr.PgMar.Right);
|
||||
|
|
@ -264,121 +252,146 @@ begin
|
|||
// println("HdrPoint.X = {}, HdrPoint.Y = {}", current_page_.HdrPoint.X, current_page_.HdrPoint.Y);
|
||||
// println("FtrPoint.X = {}, FtrPoint.Y = {}", current_page_.FtrPoint.X, current_page_.FtrPoint.Y);
|
||||
|
||||
xml_file_ := "document.xml";
|
||||
return current_page_;
|
||||
end;
|
||||
|
||||
function TSDocxToPdf.SetFtr(type: string);
|
||||
begin
|
||||
// 页脚:从下往上,需要调整
|
||||
current_page_.FtrPoint.X := current_page_.SectPr.PgMar.Left;
|
||||
current_page_.FtrPoint.Y := current_page_.SectPr.PgMar.Footer;
|
||||
|
||||
footer_reference := current_sect_pr_adapter_.GetFooterReferenceByType(type);
|
||||
ftr_range := array();
|
||||
if ifObj(footer_reference) then
|
||||
begin
|
||||
rels_adapter := docx_components_module_.GetDocumentRelsAdapter();
|
||||
rel := rels_adapter.GetRelationshipById(footer_reference.Id);
|
||||
w := current_page_.SectPr.PgSz.W - current_page_.SectPr.PgMar.Right - current_page_.SectPr.PgMar.Left;
|
||||
lb := 0;
|
||||
obj := docx_components_module_.GetFtr(rel.Target);
|
||||
xml_file_ := rel.Target;
|
||||
elements := obj.Elements();
|
||||
for _,element in elements do
|
||||
begin
|
||||
x := current_page_.FtrPoint.X;
|
||||
y := current_page_.FtrPoint.Y;
|
||||
range := nil;
|
||||
if element.LocalName = "p" then range := {self.}TransformP(element, x, y, w, lb);
|
||||
if ifObj(range) then
|
||||
begin
|
||||
current_page_.FtrPoint.Y := range.EndY;
|
||||
ftr_range[length(ftr_range)] := range;
|
||||
end
|
||||
end
|
||||
end
|
||||
last_range := ftr_range[length(ftr_range)-1];
|
||||
y_offset := last_range.EndY - current_page_.SectPr.PgMar.Bottom;
|
||||
height := 0;
|
||||
for _,range in ftr_range do
|
||||
begin
|
||||
range.Offset(0, y_offset);
|
||||
range.Do();
|
||||
height += range.DynamicHeight;
|
||||
end
|
||||
current_page_.FtrPoint.Y := current_page_.SectPr.PgMar.Bottom + height;
|
||||
if not ifObj(footer_reference) then return;
|
||||
rels_adapter := docx_components_module_.GetDocumentRelsAdapter();
|
||||
rel := rels_adapter.GetRelationshipById(footer_reference.Id);
|
||||
ftr := docx_components_module_.GetFtr(rel.Target);
|
||||
xml_file_ := rel.Target;
|
||||
|
||||
w := current_page_.SectPr.PgSz.W - current_page_.SectPr.PgMar.Right - current_page_.SectPr.PgMar.Left;
|
||||
ftr_range := new FtrRange(self, ftr);
|
||||
ftr_range.Width := w;
|
||||
ftr_range.Parent := self;
|
||||
ftr_range.StartX := current_page_.SectPr.PgMar.Left;
|
||||
ftr_range.StartY := current_page_.SectPr.PgSz.H;
|
||||
ftr_range.StartPage := current_page_;
|
||||
ftr_range.LowerBound := 0;
|
||||
if ftr_range.Calc() then
|
||||
ftr_range.Do();
|
||||
else
|
||||
realtime_range_array_[length(realtime_range_array_)] := ftr_range;
|
||||
|
||||
current_page_.FtrPoint.Y := ftr_range.EndY;
|
||||
end;
|
||||
|
||||
function TSDocxToPdf.SetHdr(type: string);
|
||||
begin
|
||||
// 正文、页眉页脚坐标
|
||||
// 页眉:从上往下,不需要调整
|
||||
current_page_.HdrPoint.X := current_page_.SectPr.PgMar.Left;
|
||||
current_page_.HdrPoint.Y := current_page_.SectPr.PgSz.H - current_page_.SectPr.PgMar.Header;
|
||||
|
||||
header_reference := current_sect_pr_adapter_.GetHeaderReferenceByType(type);
|
||||
if ifObj(header_reference) then
|
||||
if not ifObj(header_reference) then return;
|
||||
rels_adapter := docx_components_module_.GetDocumentRelsAdapter();
|
||||
rel := rels_adapter.GetRelationshipById(header_reference.Id);
|
||||
hdr := docx_components_module_.GetHdr(rel.Target);
|
||||
xml_file_ := rel.Target;
|
||||
|
||||
w := current_page_.SectPr.PgSz.W - current_page_.SectPr.PgMar.Right - current_page_.SectPr.PgMar.Left;
|
||||
hdr_range := new HdrRange(self, hdr);
|
||||
hdr_range.Width := w;
|
||||
hdr_range.Parent := self;
|
||||
hdr_range.StartX := current_page_.SectPr.PgMar.Left;
|
||||
hdr_range.StartY := current_page_.SectPr.PgSz.H - current_page_.SectPr.PgMar.Header;
|
||||
hdr_range.StartPage := current_page_;
|
||||
hdr_range.LowerBound := 0;
|
||||
if hdr_range.Calc() then
|
||||
hdr_range.Do();
|
||||
else
|
||||
realtime_range_array_[length(realtime_range_array_)] := hdr_range;
|
||||
|
||||
current_page_.HdrPoint.Y := hdr_range.EndY;
|
||||
end;
|
||||
|
||||
function TSDocxToPdf.RangesSpacing(range: BasicRange);
|
||||
begin
|
||||
if last_range_ then
|
||||
begin
|
||||
rels_adapter := docx_components_module_.GetDocumentRelsAdapter();
|
||||
rel := rels_adapter.GetRelationshipById(header_reference.Id);
|
||||
w := current_page_.SectPr.PgSz.W - current_page_.SectPr.PgMar.Right - current_page_.SectPr.PgMar.Left;
|
||||
lb := 0;
|
||||
obj := docx_components_module_.GetHdr(rel.Target);
|
||||
xml_file_ := rel.Target;
|
||||
elements := obj.Elements();
|
||||
for _,element in elements do
|
||||
if last_range_ is class(PRange) and not ifnil(last_range_.PPrUnitDecorator.OutlineLvl.Val) and (range is class(TblRange) or ifnil(range.PPrUnitDecorator.OutlineLvl.Val)) then
|
||||
begin
|
||||
x := current_page_.HdrPoint.X;
|
||||
y := current_page_.HdrPoint.Y;
|
||||
range := nil;
|
||||
if element.LocalName = "p" then range := {self.}TransformP(element, x, y, w, lb);
|
||||
if ifObj(range) then
|
||||
if last_range_.PPrUnitDecorator.Spacing.AfterAutospacing then
|
||||
begin
|
||||
current_page_.HdrPoint.Y := range.EndY;
|
||||
range.Do();
|
||||
current_page_.TextPoint.Y := min(current_page_.TextPoint.Y, range.EndY);
|
||||
line_range := last_range_.PLineRanges();
|
||||
line_range := line_range[length(line_range)-1];
|
||||
y := line_range.EndY - line_range.TextMaxSize;
|
||||
if y >= 0 then current_page_.TextPoint.Y := y;
|
||||
end
|
||||
end
|
||||
if range is class(PRange) and not ifnil(range.PPrUnitDecorator.OutlineLvl.Val) and (last_range_ is class(TblRange) or ifnil(last_range_.PPrUnitDecorator.OutlineLvl.Val)) then
|
||||
begin
|
||||
if range.PPrUnitDecorator.Spacing.BeforeAutospacing then
|
||||
begin
|
||||
line_range := range.PLineRanges();
|
||||
line_range := line_range[length(line_range)-1];
|
||||
y := last_range_.EndY - line_range.TextMaxSize;
|
||||
if y >= 0 then current_page_.TextPoint.Y := y;
|
||||
end
|
||||
end
|
||||
end
|
||||
last_range_ := range;
|
||||
end;
|
||||
|
||||
function TSDocxToPdf.TransformP(paragraph: P; x: real; y: real; w: real; lb: real): ParagraphRange;
|
||||
function TSDocxToPdf.TransformP(p: P);
|
||||
begin
|
||||
range := new ParagraphRange(self, current_page_, docx_components_module_, paragraph);
|
||||
range.StartX := x;
|
||||
range.StartY := y;
|
||||
w := current_page_.SectPr.PgSz.W - current_page_.SectPr.PgMar.Right - current_page_.SectPr.PgMar.Left;
|
||||
range := new PRange(self, p);
|
||||
range.Width := w;
|
||||
range.LowerBound := lb;
|
||||
range.Parent := self;
|
||||
r := range.Calc();
|
||||
if r then return range;
|
||||
else range_page_number_array_[length(range_page_number_array_)] := range;
|
||||
return nil;
|
||||
fg := range.Calc();
|
||||
{self.}RangesSpacing(range);
|
||||
range.StartX := current_page_.TextPoint.X;
|
||||
range.StartY := current_page_.TextPoint.Y;
|
||||
range.StartPage := current_page_;
|
||||
range.LowerBound := current_page_.LowerBound;
|
||||
range.Run();
|
||||
if fg then
|
||||
range.Do();
|
||||
else
|
||||
realtime_range_array_[length(realtime_range_array_)] := range;
|
||||
current_page_.TextPoint.Y := range.EndY;
|
||||
end;
|
||||
|
||||
function TSDocxToPdf.TransformTbl(table: Tbl; x: real; y: real; w: real; lb: real): TableRange;
|
||||
function TSDocxToPdf.TransformTbl(tbl: Tbl);
|
||||
begin
|
||||
range := new TableRange(self, current_page_, docx_components_module_, table);
|
||||
range.StartX := x;
|
||||
range.StartY := y;
|
||||
w := current_page_.SectPr.PgSz.W - current_page_.SectPr.PgMar.Right - current_page_.SectPr.PgMar.Left;
|
||||
range := new TblRange(self, tbl);
|
||||
range.Width := w;
|
||||
range.LowerBound := lb;
|
||||
range.Parent := self;
|
||||
range.Calc();
|
||||
return range;
|
||||
fg := range.Calc();
|
||||
{self.}RangesSpacing(range);
|
||||
range.StartX := current_page_.TextPoint.X;
|
||||
range.StartY := current_page_.TextPoint.Y;
|
||||
range.StartPage := current_page_;
|
||||
range.LowerBound := current_page_.LowerBound;
|
||||
range.Run();
|
||||
range.Do();
|
||||
current_page_.TextPoint.Y := range.EndY;
|
||||
end;
|
||||
|
||||
function TSDocxToPdf.TransformSdt(sdt: Sdt; x: real; y: real; w: real; lb: real): array of ParagraphRange;
|
||||
function TSDocxToPdf.TransformSdt(sdt: Sdt);
|
||||
begin
|
||||
ps := sdt.SdtContent.Ps();
|
||||
arr := array();
|
||||
for _,p in ps do
|
||||
begin
|
||||
range := {self.}TransformP(p, x, y, w, lb);
|
||||
if ifObj(range) then arr[length(arr)] := range;
|
||||
end
|
||||
return arr;
|
||||
range := {self.}TransformP(p);
|
||||
end;
|
||||
|
||||
function TSDocxToPdf.ProcessNumpages();
|
||||
function TSDocxToPdf.ProcessRealtimeRange();
|
||||
begin
|
||||
nums := page_manager_module_[page_manager_module_.Count() - 1].Number;
|
||||
for _,range in range_page_number_array_ do
|
||||
for _,range in realtime_range_array_ do
|
||||
begin
|
||||
range.SetNumPages(nums);
|
||||
range.RangesToLines();
|
||||
range.Offset(0, current_page_.SectPr.PgSz.H - current_page_.SectPr.PgMar.Bottom);
|
||||
range.ProcessRealtimeArray();
|
||||
range.Do();
|
||||
end
|
||||
end;
|
||||
|
|
@ -398,14 +411,9 @@ begin
|
|||
return docx_components_module_.SaveAs(alias, file);
|
||||
end;
|
||||
|
||||
function TSDocxToPdf.GetCurrentNoteModule(): NoteModule;
|
||||
begin
|
||||
if ifnil(note_module_) then note_module_ := new NoteModule(current_sect_module_);
|
||||
return note_module_;
|
||||
end;
|
||||
|
||||
function TSDocxToPdf.ClassifyCols(var point: Point; cols: Cols);
|
||||
begin
|
||||
return;
|
||||
bk_page := current_page_;
|
||||
columns := array();
|
||||
x := point.X;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,6 +1,6 @@
|
|||
unit DTPModules;
|
||||
interface
|
||||
uses TSPdfEnumerations, DocxMLAdapter, SharedMLAdapter;
|
||||
uses DTPAdvancedRanges, DocxMLAdapter, SharedMLAdapter;
|
||||
|
||||
type DocxComponentsModule = class(DocxComponents)
|
||||
public
|
||||
|
|
@ -57,19 +57,21 @@ end;
|
|||
|
||||
type NoteModule = class
|
||||
public
|
||||
function Create(sect_module: SectModule);
|
||||
function Create(docx_to_pdf: TSDocxToPdf);
|
||||
function AddFootnoteId(id: string);
|
||||
function GetFootnoteOrderNumber(): string;
|
||||
function GetFootnoteIndex(): string;
|
||||
function AddFootnote();
|
||||
|
||||
private
|
||||
function CalculateNumber(num_fmt: string; num: integer): string;
|
||||
function ChineseCountingThousand(n: integer): string;
|
||||
|
||||
private
|
||||
footnote_reference_hash_: hash;
|
||||
[weakref]docx_to_pdf_: TSDocxToPdf;
|
||||
footnote_hash_: hash;
|
||||
footnote_index_: integer;
|
||||
[weakref]sect_module_: SectModule;
|
||||
endnote_hash_: hash;
|
||||
endnote_index_: integer;
|
||||
end;
|
||||
|
||||
type NumberingModule = class
|
||||
|
|
@ -89,35 +91,21 @@ end;
|
|||
type SectModule = class
|
||||
public
|
||||
function Create();
|
||||
function Destroy();
|
||||
function Do();
|
||||
function AddElement(element: tslobj);
|
||||
|
||||
public
|
||||
Elements: array of tslobj;
|
||||
SectPr: SectPrUnitDecorator;
|
||||
end;
|
||||
|
||||
type Toc = class
|
||||
public
|
||||
function Create(ppr: PPrUnitDecorator; rect: array of real; page: Page; x: real; y: real; font: PdfFont);
|
||||
function LinkAnnot(dst: PdfDestination);
|
||||
function AddPageNumber(page: Page);
|
||||
|
||||
private
|
||||
[weakref]page_: Page;
|
||||
ppr_: PPrUnitDecorator;
|
||||
rect_: array of real;
|
||||
font_: PdfFont;
|
||||
x_;
|
||||
y_;
|
||||
Elements: array of tslobj;
|
||||
BaseSize: real;
|
||||
end;
|
||||
|
||||
type TocModule = class
|
||||
public
|
||||
function Create();
|
||||
function UpdateDocxNumPages();
|
||||
function LinkToToc(anchor: string; pg: Page; left: real; top: real);
|
||||
function CalculateRect(anchor: string);
|
||||
|
||||
function LinkToToc(anchor: string; range: BasicRange);
|
||||
function AddToc(anchor: string; toc: Toc);
|
||||
|
||||
function AddDocxPage(anchor: string; r: R);
|
||||
|
|
@ -154,11 +142,13 @@ public
|
|||
Index: integer;
|
||||
Number: integer;
|
||||
SectPr: SectPrUnitDecorator;
|
||||
BaseSize: real;
|
||||
TextPoint: Point; // 正文坐标
|
||||
FtrPoint: Point; // 页脚坐标
|
||||
HdrPoint: Point; // 页眉坐标
|
||||
|
||||
UpperBound: real; // 上界
|
||||
LowerBound: real; // 下界
|
||||
|
||||
private
|
||||
[weakref]pdf_file_: PdfFile;
|
||||
pdf_page_: PdfPage;
|
||||
|
|
@ -371,9 +361,12 @@ begin
|
|||
if bold and italic then
|
||||
font_name := "Times-BoldItalic";
|
||||
else if bold then
|
||||
font_name += "Times-Bold";
|
||||
font_name := "Times-Bold";
|
||||
else if italic then
|
||||
font_name += "Times-Italic";
|
||||
font_name := "Times-Italic";
|
||||
end
|
||||
else begin
|
||||
font_name := "Courier";
|
||||
end
|
||||
return pdf_.GetFont(font_name, "");
|
||||
end;
|
||||
|
|
@ -394,16 +387,65 @@ begin
|
|||
end;
|
||||
|
||||
// NoteModule
|
||||
function NoteModule.Create(sect_module: SectModule);
|
||||
function NoteModule.Create(docx_to_pdf: TSDocxToPdf);
|
||||
begin
|
||||
sect_module_ := sect_module;
|
||||
footnote_reference_hash_ := array();
|
||||
docx_to_pdf_ := docx_to_pdf;
|
||||
footnote_hash_ := array();
|
||||
endnote_hash_ := array();
|
||||
footnote_index_ := 0;
|
||||
endnote_index_ := 0;
|
||||
end;
|
||||
|
||||
function NoteModule.AddFootnoteId(id: string);
|
||||
begin
|
||||
footnotes_adapter := docx_to_pdf_.DocxComponents.GetFootnotesAdapter();
|
||||
footnote := footnotes_adapter.GetFootnoteById(id);
|
||||
sect_pr := docx_to_pdf_.CurrentSect.SectPr;
|
||||
w := sect_pr.SectPr.PgSz.W - sect_pr.SectPr.PgMar.Right - sect_pr.SectPr.PgMar.Left;
|
||||
lb := 0;
|
||||
arr := array();
|
||||
elements := footnote.Elements();
|
||||
for _,element in elements do
|
||||
begin
|
||||
if element.LocalName = "p" then
|
||||
begin
|
||||
range := new PRange(docx_to_pdf_, element);
|
||||
range.Width := w;
|
||||
range.LowerBound := lb;
|
||||
range.Parent := self;
|
||||
range.Calc();
|
||||
arr[length(arr)] := range;
|
||||
end
|
||||
end
|
||||
footnote_hash_[id] := arr;
|
||||
end;
|
||||
|
||||
// function NoteModule.RunFootnote(id: string; x: real; y: real; pg: Page);
|
||||
// begin
|
||||
// sx := x;
|
||||
// sy := y;
|
||||
// spg := pg;
|
||||
// height := 0;
|
||||
// arr := array();
|
||||
// hash := footnote_hash_[id];
|
||||
// for id,range in hash do
|
||||
// begin
|
||||
// range.StartX := x;
|
||||
// range.StartY := y;
|
||||
// range.StartPage := spg;
|
||||
// range.LowerBound := 0;
|
||||
// range.Run();
|
||||
// sy := range.EndY;
|
||||
// height += range.DynamicHeight;
|
||||
// arr union= range.PLineRanges();
|
||||
// footnote_hash_[id] := arr;
|
||||
// end
|
||||
// return height;
|
||||
// end;
|
||||
|
||||
function NoteModule.GetFootnoteOrderNumber();
|
||||
begin
|
||||
num_fmt := sect_module_.SectPr.FootnotePr.NumFmt.Val;
|
||||
num_fmt := docx_to_pdf_.CurrentSect.SectPr.FootnotePr.NumFmt.Val;
|
||||
if ifnil(num_fmt) then num_fmt := "decimal";
|
||||
return CalculateNumber(num_fmt, ++footnote_index_);
|
||||
end;
|
||||
|
|
@ -640,16 +682,24 @@ begin
|
|||
update_docx_num_pages_ := true;
|
||||
end;
|
||||
|
||||
function TocModule.LinkToToc(anchor: string; pg: Page; left: real; top: real);
|
||||
function TocModule.CalculateRect(anchor: string);
|
||||
begin
|
||||
arr := toc_hash_[anchor];
|
||||
for _,toc in arr do
|
||||
toc.CalculateRect();
|
||||
end;
|
||||
|
||||
function TocModule.LinkToToc(anchor: string; range: BasicRange);
|
||||
begin
|
||||
arr := toc_hash_[anchor];
|
||||
if ifnil(arr) then
|
||||
begin
|
||||
toc_unmatched_hash_[anchor] := array(pg, left, top);
|
||||
toc_unmatched_hash_[anchor] := range;
|
||||
return;
|
||||
end
|
||||
pg := range.EndPage;
|
||||
dst := pg.PdfPage.CreateDestination();
|
||||
dst.SetXYZ(left, top, 1);
|
||||
dst.SetXYZ(range.EndX, range.EndY + range.RPr.Sz.Val, 1);
|
||||
for _,toc in arr do
|
||||
toc.LinkAnnot(dst);
|
||||
toc.AddPageNumber(pg);
|
||||
|
|
@ -679,41 +729,4 @@ begin
|
|||
docx_page_hash_[anchor] := r;
|
||||
end;
|
||||
|
||||
// Toc
|
||||
function Toc.Create(ppr: PPrUnitDecorator; rect: array of real; pg: Page; x: real; y: real; font: PdfFont);
|
||||
begin
|
||||
ppr_ := ppr;
|
||||
rect_ := rect;
|
||||
page_ := pg;
|
||||
x_ := x;
|
||||
y_ := y;
|
||||
font_ := font;
|
||||
end;
|
||||
|
||||
function Toc.LinkAnnot(dst: PdfDestination);
|
||||
begin
|
||||
annot := page_.PdfPage.CreateLinkAnnot(rect_, dst);
|
||||
annot.LinkAnnotSetHighlightMode(TSPdfEnumerations.ANNOT_NO_HIGHTLIGHT);
|
||||
annot.LinkAnnotSetBorderStyle(0, 0, 0);
|
||||
end;
|
||||
|
||||
function Toc.AddPageNumber(pg: Page);
|
||||
begin
|
||||
number := tostring(pg.Number);
|
||||
page_.PdfPage.SetFontAndSize(font_, ppr_.RPr.Sz.Val);
|
||||
number_sz := page_.PdfPage.TextWidth(number);
|
||||
x := rect_[2] - number_sz;
|
||||
page_.PdfPage.BeginText();
|
||||
page_.PdfPage.TextOut(x, y_, number);
|
||||
page_.PdfPage.EndText();
|
||||
|
||||
page_.PdfPage.SetRGBStroke(0, 0, 0);
|
||||
page_.PdfPage.SetDash(array(0.5, 2), 2, 0);
|
||||
page_.PdfPage.SetLineWidth(0.5);
|
||||
page_.PdfPage.SetLineCap(TSPdfEnumerations.ROUND_END);
|
||||
page_.PdfPage.MoveTo(x_+1, y_);
|
||||
page_.PdfPage.LineTo(x-0.5, y_);
|
||||
page_.PdfPage.Stroke();
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
|
|||
|
|
@ -11,13 +11,14 @@ public
|
|||
RPr: RPr;
|
||||
Text: string;
|
||||
Font: PdfFont;
|
||||
Type: integer; // 0:默认,1: 数字,2:英文,3:中文,4:中文标点
|
||||
Type: integer; // 0:默认,1: 数字,2:英文,3:中文,4:中文标点,5:,.英文逗号和点
|
||||
end;
|
||||
|
||||
type BordersRange = class(BasicRange)
|
||||
public
|
||||
function Create();
|
||||
function Do();override;
|
||||
function DoFill();
|
||||
public
|
||||
TcPr: TcPr;
|
||||
Left: boolean;
|
||||
|
|
@ -65,7 +66,8 @@ public
|
|||
DynamicHeight: real;
|
||||
LowerBound: real;
|
||||
[weakref]Parent: tslobj;
|
||||
[weakref]Page: Page;
|
||||
[weakref]StartPage: Page; // 起始page
|
||||
[weakref]EndPage: Page; // 结束page
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
|
@ -81,7 +83,7 @@ begin
|
|||
{self.}DynamicHeight := 0;
|
||||
{self.}LowerBound := 0;
|
||||
{self.}FixedHeight := 0;
|
||||
{self.}Page := nil;
|
||||
{self.}EndPage := nil;
|
||||
end;
|
||||
|
||||
// ImageRange
|
||||
|
|
@ -96,18 +98,18 @@ function ImageRange.Do();override;
|
|||
begin
|
||||
// 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.}Page.PdfPage.DrawEmf({self.}Image, {self.}EndX, {self.}EndY, {self.}Width, {self.}DynamicHeight);
|
||||
{self.}EndPage.PdfPage.DrawEmf({self.}Image, {self.}EndX, {self.}EndY, {self.}Width, {self.}DynamicHeight);
|
||||
else if {self.}Type = "wmf" then
|
||||
{self.}Page.PdfPage.DrawWmf({self.}Image, {self.}EndX, {self.}EndY, {self.}Width, {self.}DynamicHeight);
|
||||
{self.}EndPage.PdfPage.DrawWmf({self.}Image, {self.}EndX, {self.}EndY, {self.}Width, {self.}DynamicHeight);
|
||||
else
|
||||
{self.}Page.PdfPage.DrawImage({self.}Image, {self.}EndX, {self.}EndY, {self.}Width, {self.}DynamicHeight);
|
||||
{self.}EndPage.PdfPage.DrawImage({self.}Image, {self.}EndX, {self.}EndY, {self.}Width, {self.}DynamicHeight);
|
||||
|
||||
if sysparams["_PDF_IMAGE_DEBUG_"] then
|
||||
begin
|
||||
{self.}Page.PdfPage.SetLineWidth(0.1);
|
||||
{self.}Page.PdfPage.SetRGBStroke(0.8, 0.8, 0);
|
||||
{self.}Page.PdfPage.Rectangle({self.}EndX, {self.}EndY, {self.}Width, {self.}DynamicHeight);
|
||||
{self.}Page.PdfPage.Stroke();
|
||||
{self.}EndPage.PdfPage.SetLineWidth(0.1);
|
||||
{self.}EndPage.PdfPage.SetRGBStroke(0.8, 0.8, 0);
|
||||
{self.}EndPage.PdfPage.Rectangle({self.}EndX, {self.}EndY, {self.}Width, {self.}DynamicHeight);
|
||||
{self.}EndPage.PdfPage.Stroke();
|
||||
end
|
||||
end;
|
||||
|
||||
|
|
@ -122,32 +124,37 @@ begin
|
|||
{self.}Bottom := false;
|
||||
end;
|
||||
|
||||
function BordersRange.Do();override;
|
||||
function BordersRange.DoFill();
|
||||
begin
|
||||
// println("Left = {}, Top = {}, Right = {}, Bottom = {}, Tl2Br = {}, Tr2Bl = {}", Left, Top, Right, Bottom, Tl2Br, Tr2Bl);
|
||||
borders := {self.}TcPr.TcBorders;
|
||||
if {self.}TcPr.Shd.Fill and {self.}TcPr.Shd.Fill <> "auto" then
|
||||
begin
|
||||
[r, g, b] := DTPColorToolKit.HexToRGB({self.}TcPr.Shd.Fill);
|
||||
{self.}Page.PdfPage.SetRGBFill(r/255, g/255, b/255);
|
||||
{self.}EndPage.PdfPage.SetRGBFill(r/255, g/255, b/255);
|
||||
x := {self.}EndX;
|
||||
y := {self.}EndY - {self.}DynamicHeight;
|
||||
w := {self.}Width;
|
||||
h := {self.}DynamicHeight;
|
||||
tmp := borders.Left.Sz ? borders.Left.Sz / 2 : 0.25;
|
||||
x += tmp;
|
||||
w -= tmp;
|
||||
w -= borders.Right.Sz ? borders.Right.Sz / 2 : 0.25;
|
||||
tmp := borders.Bottom.Sz ? borders.Bottom.Sz / 2 : 0.25;
|
||||
y += tmp;
|
||||
h -= tmp;
|
||||
h -= borders.Top.Sz ? borders.Top.Sz / 2 : 0.25;
|
||||
// tmp := borders.Left.Sz ? borders.Left.Sz / 2 : 0.25;
|
||||
// x += tmp;
|
||||
// w -= tmp;
|
||||
// w -= borders.Right.Sz ? borders.Right.Sz / 2 : 0.25;
|
||||
// tmp := borders.Bottom.Sz ? borders.Bottom.Sz / 2 : 0.25;
|
||||
// y += tmp;
|
||||
// h -= tmp;
|
||||
// h -= borders.Top.Sz ? borders.Top.Sz / 2 : 0.25;
|
||||
|
||||
{self.}Page.PdfPage.Rectangle(x, y, w, h);
|
||||
{self.}Page.PdfPage.Fill();
|
||||
{self.}Page.PdfPage.SetRGBFill(0, 0, 0);
|
||||
{self.}Left := true;
|
||||
{self.}EndPage.PdfPage.Rectangle(x, y, w, h);
|
||||
{self.}EndPage.PdfPage.Fill();
|
||||
{self.}EndPage.PdfPage.SetRGBFill(0, 0, 0);
|
||||
// {self.}Left := true;
|
||||
end
|
||||
end;
|
||||
|
||||
function BordersRange.Do();override;
|
||||
begin
|
||||
// println("Left = {}, Top = {}, Right = {}, Bottom = {}, Tl2Br = {}, Tr2Bl = {}", Left, Top, Right, Bottom, Tl2Br, Tr2Bl);
|
||||
borders := {self.}TcPr.TcBorders;
|
||||
if {self.}Left then
|
||||
{self.}DrawLine(borders.Left, {self.}EndX, {self.}EndY, {self.}EndX, {self.}EndY - {self.}DynamicHeight);
|
||||
if {self.}Top then
|
||||
|
|
@ -165,9 +172,9 @@ end;
|
|||
function BordersRange.SetDash(val: string);
|
||||
begin
|
||||
if val = "single" or ifnil(val) then
|
||||
{self.}Page.PdfPage.SetDash(array(), 0, 0);
|
||||
if val = "dashed" then
|
||||
{self.}Page.PdfPage.SetDash(array(1), 1, 0);
|
||||
{self.}EndPage.PdfPage.SetDash(array(), 0, 0);
|
||||
else if val = "dashed" then
|
||||
{self.}EndPage.PdfPage.SetDash(array(1), 1, 0);
|
||||
end;
|
||||
|
||||
function BordersRange.DrawLine(border: Border; x1: real; y1: real; x2: real; y2: real);
|
||||
|
|
@ -176,12 +183,12 @@ begin
|
|||
line_width := border.Sz ?: 0.5;
|
||||
{self.}SetDash(border.Val);
|
||||
if border.Color and border.Color <> "auto" then [r, g, b] := DTPColorToolKit.HexToRGB(border.Color);
|
||||
{self.}Page.PdfPage.SetRGBStroke(r, g, b);
|
||||
{self.}Page.PdfPage.SetLineWidth(line_width);
|
||||
{self.}Page.PdfPage.MoveTo(x1, y1);
|
||||
{self.}Page.PdfPage.LineTo(x2, y2);
|
||||
{self.}Page.PdfPage.Stroke();
|
||||
{self.}Page.PdfPage.SetRGBStroke(0, 0, 0);
|
||||
{self.}EndPage.PdfPage.SetRGBStroke(r/255, g/255, b/255);
|
||||
{self.}EndPage.PdfPage.SetLineWidth(line_width);
|
||||
{self.}EndPage.PdfPage.MoveTo(x1, y1);
|
||||
{self.}EndPage.PdfPage.LineTo(x2, y2);
|
||||
{self.}EndPage.PdfPage.Stroke();
|
||||
{self.}EndPage.PdfPage.SetRGBStroke(0, 0, 0);
|
||||
end;
|
||||
|
||||
// TextRange
|
||||
|
|
@ -207,21 +214,21 @@ begin
|
|||
y += sz / 3;
|
||||
sz := sz * 2 / 3;
|
||||
end
|
||||
{self.}Page.PdfPage.SetRGBFill(r / 255, g / 255, b / 255);
|
||||
{self.}Page.PdfPage.SetFontAndSize({self.}Font, sz);
|
||||
{self.}Page.PdfPage.BeginText();
|
||||
{self.}Page.PdfPage.TextOut({self.}EndX, y, {self.}Text);
|
||||
{self.}Page.PdfPage.EndText();
|
||||
{self.}Page.PdfPage.SetRGBFill(0, 0, 0);
|
||||
{self.}EndPage.PdfPage.SetRGBFill(r / 255, g / 255, b / 255);
|
||||
{self.}EndPage.PdfPage.SetFontAndSize({self.}Font, sz);
|
||||
{self.}EndPage.PdfPage.BeginText();
|
||||
{self.}EndPage.PdfPage.TextOut({self.}EndX, y, {self.}Text);
|
||||
{self.}EndPage.PdfPage.EndText();
|
||||
{self.}EndPage.PdfPage.SetRGBFill(0, 0, 0);
|
||||
|
||||
|
||||
if sysparams["_PDF_TEXT_DEBUG_"] then
|
||||
begin
|
||||
{self.}Page.PdfPage.SetLineWidth(0.1);
|
||||
{self.}Page.PdfPage.SetRGBStroke(1.0, 0.5, 0.0);
|
||||
{self.}Page.PdfPage.MoveTo(0, {self.}EndY);
|
||||
{self.}Page.PdfPage.LineTo(600, {self.}EndY);
|
||||
{self.}Page.PdfPage.Stroke();
|
||||
{self.}EndPage.PdfPage.SetLineWidth(0.1);
|
||||
{self.}EndPage.PdfPage.SetRGBStroke(1.0, 0.5, 0.0);
|
||||
{self.}EndPage.PdfPage.MoveTo(0, {self.}EndY);
|
||||
{self.}EndPage.PdfPage.LineTo(600, {self.}EndY);
|
||||
{self.}EndPage.PdfPage.Stroke();
|
||||
end
|
||||
end;
|
||||
|
||||
|
|
@ -235,11 +242,11 @@ end;
|
|||
function LineRange.Do();override;
|
||||
begin
|
||||
// println("endx = {}, endy = {}, width = {}", EndX, EndY, Width);
|
||||
{self.}Page.PdfPage.SetLineWidth({self.}LineWidth);
|
||||
{self.}Page.PdfPage.SetRGBStroke(0, 0, 0);
|
||||
{self.}Page.PdfPage.MoveTo({self.}EndX, {self.}EndY);
|
||||
{self.}Page.PdfPage.LineTo({self.}EndX + {self.}Width, {self.}EndY);
|
||||
{self.}Page.PdfPage.Stroke();
|
||||
{self.}EndPage.PdfPage.SetLineWidth({self.}LineWidth);
|
||||
{self.}EndPage.PdfPage.SetRGBStroke(0, 0, 0);
|
||||
{self.}EndPage.PdfPage.MoveTo({self.}EndX, {self.}EndY);
|
||||
{self.}EndPage.PdfPage.LineTo({self.}EndX + {self.}Width, {self.}EndY);
|
||||
{self.}EndPage.PdfPage.Stroke();
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
|
|||
|
|
@ -27,20 +27,6 @@ private
|
|||
index_: integer;
|
||||
end;
|
||||
|
||||
type FldStruct = class
|
||||
public
|
||||
function Create();
|
||||
public
|
||||
FldLock: boolean;
|
||||
MergeFormat: boolean;
|
||||
Quote: boolean;
|
||||
Separate: boolean;
|
||||
PageArabicMergeFormat: boolean;
|
||||
NumPages: boolean;
|
||||
ArabicMergeFormat: boolean;
|
||||
EndFld: boolean;
|
||||
end;
|
||||
|
||||
type FldType = class
|
||||
public
|
||||
function Create();
|
||||
|
|
@ -52,7 +38,7 @@ public
|
|||
PageRef: boolean;
|
||||
end;
|
||||
|
||||
type FldStruct2 = class
|
||||
type FldStruct = class
|
||||
public
|
||||
function Create();
|
||||
|
||||
|
|
@ -60,6 +46,7 @@ public
|
|||
Type: FldType;
|
||||
Arabic: boolean;
|
||||
MergeFormat: boolean;
|
||||
Status: integer; // 0: begin 1: separate 2: end
|
||||
end;
|
||||
|
||||
type TrProperty = class
|
||||
|
|
@ -155,19 +142,6 @@ begin
|
|||
return index_ = 0;
|
||||
end;
|
||||
|
||||
// FldStruct
|
||||
function FldStruct.Create();
|
||||
begin
|
||||
FldLock := false;
|
||||
MergeFormat := false;
|
||||
Quote := false;
|
||||
Separate := false;
|
||||
PageArabicMergeFormat := false;
|
||||
NumPages := false;
|
||||
ArabicMergeFormat := false;
|
||||
EndFld := false;
|
||||
end;
|
||||
|
||||
// FldType
|
||||
function FldType.Create();
|
||||
begin
|
||||
|
|
@ -178,11 +152,12 @@ begin
|
|||
end;
|
||||
|
||||
// FldStruct
|
||||
function FldStruct2.Create();
|
||||
function FldStruct.Create();
|
||||
begin
|
||||
{self.}Type := new FldType();
|
||||
{self.}Arabic := false;
|
||||
{self.}MergeFormat := false;
|
||||
{self.}Status := 0;
|
||||
end;
|
||||
|
||||
// TrProperty
|
||||
|
|
|
|||
Loading…
Reference in New Issue