745 lines
21 KiB
Plaintext
745 lines
21 KiB
Plaintext
unit DTPModules;
|
||
interface
|
||
uses DTPAdvancedRanges, DocxMLAdapter, SharedMLAdapter;
|
||
|
||
type DocxComponentsModule = class(DocxComponents)
|
||
public
|
||
function Create();
|
||
function GetStyles(): Styles;
|
||
function GetStylesAdapter(): StylesAdapter;
|
||
function GetDocumentRelsAdapter(): RelationShipsAdapter;
|
||
function GetNumberingModule(): NumberingModule;
|
||
function GetTblStylePrByType(style_id: string; type: string): TblStylePr;
|
||
function GetFtr(target: string): Ftr;
|
||
function GetHdr(target: string): Hdr;
|
||
function GetFtrRelsAdapter(target: string): RelationShipsAdapter;
|
||
function GetHdrRelsAdapter(target: string): RelationShipsAdapter;
|
||
function GetFootnotesAdapter(): FootnotesAdapter;
|
||
private
|
||
styles_deserialize_flag_: boolean;
|
||
styles_adapter_: StylesAdapter;
|
||
document_rels_adapter_: RelationShipsAdapter;
|
||
numbering_module_: NumberingModule;
|
||
tbl_style_pr_hash_: array of TblStylePr;
|
||
ftr_hash_: array of Ftr;
|
||
hdr_hash_: array of Hdr;
|
||
hdr_rel_hash_: array of RelationShipsAdapter;
|
||
ftr_rel_hash_: array of RelationShipsAdapter;
|
||
footnotes_adapter_: FootnotesAdapter;
|
||
end;
|
||
|
||
type FontModule = class
|
||
public
|
||
function Create(pdf: PdfFile);
|
||
|
||
function GetAsciiFont(name: string; bold: boolean; italic: boolean): PdfFont;
|
||
function GetCNSFont(name: string; bold: boolean; italic: boolean): PdfFont;
|
||
function GetSymbolFont(): PdfFont;
|
||
function GetZapfDingbatsFont(): PdfFont;
|
||
function UseExternalFont();
|
||
function SetSubstitutionRules(source: string; target: string);
|
||
function SetDefaultSz(value: real);
|
||
function GetDefaultSz(): real;
|
||
|
||
private
|
||
function GetExternalFont(name:string; bold: boolean; italic: boolean): PdfFont;
|
||
function GetBuiltInCNSFont(name:string; bold: boolean; italic: boolean): PdfFont;
|
||
function GetBuiltInAsciiFont(name:string; bold: boolean; italic: boolean): PdfFont;
|
||
|
||
private
|
||
[weakref]pdf_: PdfFile;
|
||
|
||
use_built_in_font_: boolean; // 是否使用内置字体
|
||
substitution_rules_: array of string; // 替换规则
|
||
external_reference_: array of string;
|
||
default_sz_: real;
|
||
end;
|
||
|
||
type NoteModule = class
|
||
public
|
||
function Create(docx_to_pdf: TSDocxToPdf);
|
||
function AddFootnoteId(id: string);
|
||
function GetFootnoteOrderNumber(): string;
|
||
function GetFootnoteIndex(): string;
|
||
|
||
private
|
||
function CalculateNumber(num_fmt: string; num: integer): string;
|
||
function ChineseCountingThousand(n: integer): string;
|
||
|
||
private
|
||
[weakref]docx_to_pdf_: TSDocxToPdf;
|
||
footnote_hash_: hash;
|
||
footnote_index_: integer;
|
||
endnote_hash_: hash;
|
||
endnote_index_: integer;
|
||
end;
|
||
|
||
type NumberingModule = class
|
||
public
|
||
function Create(number: NumberingAdapter);
|
||
function GetNumberLvl(ppr: PPr);
|
||
|
||
private
|
||
function CalculateNumber(num_fmt: string; num: integer): string;
|
||
function ChineseCountingThousand(n: integer): string;
|
||
|
||
private
|
||
numbering_adapter_: NumberingAdapter;
|
||
num_hash_: hash;
|
||
end;
|
||
|
||
type SectModule = class
|
||
public
|
||
function Create();
|
||
function AddElement(element: tslobj);
|
||
|
||
public
|
||
SectPr: SectPr;
|
||
Elements: array of tslobj;
|
||
BaseSize: real;
|
||
end;
|
||
|
||
type TocModule = class
|
||
public
|
||
function Create();
|
||
function UpdateDocxNumPages();
|
||
function CalculateRect(anchor: string);
|
||
|
||
function LinkToToc(anchor: string; range: BasicRange);overload;
|
||
function LinkToToc(anchor: string);overload;
|
||
function AddToc(anchor: string; toc: Toc);overload;
|
||
|
||
function AddDocxPage(anchor: string; r: R);
|
||
|
||
private
|
||
toc_hash_: hash;
|
||
toc_unmatched_hash_: hash;
|
||
|
||
update_docx_num_pages_: boolean; // 开放给docx文件是否更新docx文件的页码
|
||
docx_page_hash_: hash;
|
||
end;
|
||
|
||
// 坐标
|
||
type Point = class
|
||
public
|
||
function Create();
|
||
|
||
public
|
||
X: real;
|
||
Y: real;
|
||
end;
|
||
|
||
// Page延迟建立,存基本信息即可
|
||
type Page = class
|
||
public
|
||
function Create(pdf_file: PdfFile);
|
||
function OriginalTextCoordinates(): array of real;
|
||
function PrintGrid();
|
||
|
||
property PdfPage read ReadPdfPage;
|
||
function ReadPdfPage(): PdfPage;
|
||
|
||
public
|
||
Index: integer;
|
||
Number: integer;
|
||
SectPr: SectPr;
|
||
TextPoint: Point; // 正文坐标
|
||
FtrPoint: Point; // 页脚坐标
|
||
HdrPoint: Point; // 页眉坐标
|
||
|
||
UpperBound: real; // 上界
|
||
LowerBound: real; // 下界
|
||
|
||
private
|
||
[weakref]pdf_file_: PdfFile;
|
||
pdf_page_: PdfPage;
|
||
end;
|
||
|
||
type PageManagerModule = class
|
||
public
|
||
function Create(pdf_file: PdfFile);
|
||
function Operator[](index: uinteger): Page;
|
||
function NewPage(): Page;
|
||
function NextPage(page: Page): Page;
|
||
function Count(): integer;
|
||
|
||
private
|
||
[weakref]pdf_file_: PdfFile;
|
||
page_array_: array of Page;
|
||
end;
|
||
|
||
implementation
|
||
|
||
// DocxComponentsModule
|
||
function DocxComponentsModule.Create();
|
||
begin
|
||
class(DocxComponents).Create();
|
||
tbl_style_pr_hash_ := array();
|
||
ftr_hash_ := array();
|
||
hdr_hash_ := array();
|
||
hdr_rel_hash_ := array();
|
||
ftr_rel_hash_ := array();
|
||
end;
|
||
|
||
function DocxComponentsModule.GetStyles(): Styles;
|
||
begin
|
||
if styles_deserialize_flag_ then return {self.}Styles;
|
||
{self.}Styles.Deserialize();
|
||
{self.}Styles.ConvertToPoint();
|
||
styles_deserialize_flag_ := true;
|
||
return {self.}Styles;
|
||
end;
|
||
|
||
function DocxComponentsModule.GetStylesAdapter(): StylesAdapter;
|
||
begin
|
||
if styles_adapter_ then return styles_adapter_;
|
||
styles_adapter_ := new StylesAdapter({self.}GetStyles());
|
||
return styles_adapter_;
|
||
end;
|
||
|
||
function DocxComponentsModule.GetDocumentRelsAdapter(): RelationShipsAdapter;
|
||
begin
|
||
if document_rels_adapter_ then return document_rels_adapter_;
|
||
{self.}DocumentRels.Deserialize();
|
||
document_rels_adapter_ := new RelationShipsAdapter({self.}DocumentRels);
|
||
return document_rels_adapter_;
|
||
end;
|
||
|
||
function DocxComponentsModule.GetNumberingModule(): NumberingModule;
|
||
begin
|
||
if numbering_module_ then return numbering_module_;
|
||
if not {self.}Numbering then return nil;
|
||
{self.}Numbering.Deserialize();
|
||
{self.}Numbering.ConvertToPoint();
|
||
numbering_module_ := new NumberingModule({self.}Numbering);
|
||
return numbering_module_;
|
||
end;
|
||
|
||
function DocxComponentsModule.GetTblStylePrByType(style_id: string; type: string): TblStylePr;
|
||
begin
|
||
if tbl_style_pr_hash_[style_id][type] then return tbl_style_pr_hash_[style_id][type];
|
||
styles_adapter := {self.}GetStylesAdapter();
|
||
style := styles_adapter.GetStyleByStyleId(style_id);
|
||
style := new StyleAdapter(style);
|
||
tbl_style_pr := style.GetTblStylePrByType(type);
|
||
tbl_style_pr_hash_[style_id][type] := tbl_style_pr;
|
||
return tbl_style_pr;
|
||
end;
|
||
|
||
function DocxComponentsModule.GetFtr(target: string): Ftr;
|
||
begin
|
||
if ftr_hash_[target] then return ftr_hash_[target];
|
||
index := replaceStr(replaceStr(target, "footer", ""), ".xml", "");
|
||
obj := {self.}Footers(strtoint(index));
|
||
obj.Deserialize();
|
||
obj.ConvertToPoint();
|
||
ftr_hash_[target] := obj;
|
||
return obj;
|
||
end;
|
||
|
||
function DocxComponentsModule.GetHdr(target: string): Hdr;
|
||
begin
|
||
if hdr_hash_[target] then return hdr_hash_[target];
|
||
index := replaceStr(replaceStr(target, "header", ""), ".xml", "");
|
||
obj := {self.}Headers(strtoint(index));
|
||
obj.Deserialize();
|
||
obj.ConvertToPoint();
|
||
hdr_hash_[target] := obj;
|
||
return obj;
|
||
end;
|
||
|
||
function DocxComponentsModule.GetHdrRelsAdapter(target: string): RelationShipsAdapter;
|
||
begin
|
||
if hdr_rel_hash_[target] then return hdr_rel_hash_[target];
|
||
index := replaceStr(replaceStr(target, "header", ""), ".xml", "");
|
||
obj := {self.}HeaderRels(strtoint(index));
|
||
obj.Deserialize();
|
||
rels_adapter := new RelationShipsAdapter(obj);
|
||
hdr_rel_hash_[target] := rels_adapter;
|
||
return rels_adapter;
|
||
end;
|
||
|
||
function DocxComponentsModule.GetFtrRelsAdapter(target: string): RelationShipsAdapter;
|
||
begin
|
||
if ftr_rel_hash_[target] then return ftr_rel_hash_[target];
|
||
index := replaceStr(replaceStr(target, "footer", ""), ".xml", "");
|
||
obj := {self.}FooterRels(strtoint(index));
|
||
obj.Deserialize();
|
||
rels_adapter := new RelationShipsAdapter(obj);
|
||
ftr_rel_hash_[target] := rels_adapter;
|
||
return rels_adapter;
|
||
end;
|
||
|
||
function DocxComponentsModule.GetFootnotesAdapter(): FootnotesAdapter;
|
||
begin
|
||
if footnotes_adapter_ then return footnotes_adapter_;
|
||
obj := {self.}Footnotes;
|
||
obj.Deserialize();
|
||
obj.ConvertToPoint();
|
||
footnotes_adapter_ := new FootnotesAdapter(obj);
|
||
return footnotes_adapter_;
|
||
end;
|
||
|
||
// FontModule
|
||
function FontModule.Create(pdf: PdfFile);
|
||
begin
|
||
pdf_ := pdf;
|
||
use_built_in_font_ := true;
|
||
substitution_rules_ := array("宋体": "SimSun",
|
||
"黑体": "SimHei",
|
||
"Courier New": "Courier",
|
||
"Helvetica": "Helvetica",
|
||
"Times New Roman": "Times-Roman",
|
||
);
|
||
external_reference_ := array();
|
||
default_sz_ := 10.5;
|
||
end;
|
||
|
||
function FontModule.SetDefaultSz(value: real);
|
||
begin
|
||
default_sz_ := value;
|
||
end;
|
||
|
||
function FontModule.GetDefaultSz();
|
||
begin
|
||
return default_sz_;
|
||
end;
|
||
|
||
function FontModule.UseExternalFont();
|
||
begin
|
||
use_built_in_font_ := false;
|
||
end;
|
||
|
||
function FontModule.GetExternalFont(name:string; bold: boolean; italic: boolean);
|
||
begin
|
||
if ifnil(name) or name = '' then name := "等线";
|
||
if not ifnil(external_font_cache_[name]) then return external_font_cache_[name];
|
||
value := external_reference_[name];
|
||
if ifnil(value) then return nil;
|
||
if value["ext"] = ".ttf" then
|
||
font_name := pdf_.LoadTTFontFromFile("", value["path"], true);
|
||
else if value["ext"] = ".ttc" then
|
||
font_name := pdf_.LoadTTFontFromFile2("", value["path"], 0, true);
|
||
if not ifString(font_name) then return nil;
|
||
font := pdf_.GetFont(font_name, "UTF-8");
|
||
external_font_cache_[name] := font;
|
||
return font;
|
||
end;
|
||
|
||
function FontModule.GetCNSFont(name: string; bold: boolean; italic: boolean): PdfFont;
|
||
begin
|
||
return use_built_in_font_ ? {self.}GetBuiltInCNSFont(name, bold, italic) : {self.}GetExternalFont(name, bold, italic);
|
||
end;
|
||
|
||
function FontModule.GetBuiltInCNSFont(name: string; bold: boolean; italic: boolean): PdfFont;
|
||
begin
|
||
font_name := substitution_rules_[name];
|
||
if ifnil(font_name) then font_name := "SimSun";
|
||
if bold and italic then
|
||
font_name += ",BoldItalic";
|
||
else if bold then
|
||
font_name += ",Bold";
|
||
else if italic then
|
||
font_name += ",Italic";
|
||
return pdf_.GetFont(font_name, "GBK-EUC-H");
|
||
end;
|
||
|
||
function FontModule.GetAsciiFont(name: string; bold: boolean; italic: boolean): PdfFont;
|
||
begin
|
||
return use_built_in_font_ ? {self.}GetBuiltInAsciiFont(name, bold, italic) : {self.}GetExternalFont(name, bold, italic);
|
||
end;
|
||
|
||
function FontModule.GetBuiltInAsciiFont(name:string; bold: boolean; italic: boolean): PdfFont;
|
||
begin
|
||
font_name := substitution_rules_[name];
|
||
if ifnil(font_name) then font_name := "Times-Roman";
|
||
if font_name = "Courier" or font_name = "Helvetica" then
|
||
begin
|
||
if bold and italic then
|
||
font_name += "-BoldOblique";
|
||
else if bold then
|
||
font_name += "-Bold";
|
||
else if italic then
|
||
font_name += "-Oblique";
|
||
end
|
||
else if font_name = "Times-Roman" then
|
||
begin
|
||
if bold and italic then
|
||
font_name := "Times-BoldItalic";
|
||
else if bold then
|
||
font_name := "Times-Bold";
|
||
else if italic then
|
||
font_name := "Times-Italic";
|
||
end
|
||
else begin
|
||
font_name := "Courier";
|
||
end
|
||
return pdf_.GetFont(font_name, "");
|
||
end;
|
||
|
||
function FontModule.SetSubstitutionRules(source: string; target: string);
|
||
begin
|
||
substitution_rules_[source] := target;
|
||
end;
|
||
|
||
function FontModule.GetSymbolFont(): PdfFont;
|
||
begin
|
||
return pdf_.GetFont("Symbol", "");
|
||
end;
|
||
|
||
function FontModule.GetZapfDingbatsFont(): PdfFont;
|
||
begin
|
||
return pdf_.GetFont("ZapfDingbats", "");
|
||
end;
|
||
|
||
// NoteModule
|
||
function NoteModule.Create(docx_to_pdf: TSDocxToPdf);
|
||
begin
|
||
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 := docx_to_pdf_.CurrentSect.SectPr.FootnotePr.NumFmt.Val;
|
||
if ifnil(num_fmt) then num_fmt := "decimal";
|
||
return CalculateNumber(num_fmt, ++footnote_index_);
|
||
end;
|
||
|
||
function NoteModule.GetFootnoteIndex(): string;
|
||
begin
|
||
return inttostr(footnote_index_);
|
||
end;
|
||
|
||
function NoteModule.CalculateNumber(num_fmt: string; num: integer): string;
|
||
begin
|
||
if num_fmt = "decimal" then
|
||
return format("%d", num);
|
||
else if num_fmt = "chineseCountingThousand" then
|
||
return {self.}ChineseCountingThousand(num);
|
||
else
|
||
return format("%d", num);
|
||
end;
|
||
|
||
function NoteModule.ChineseCountingThousand(n: integer): string;
|
||
begin
|
||
chinese_digits := array("零", "一", "二", "三", "四", "五", "六", "七", "八", "九");
|
||
chinese_units := array("", "十", "百", "千");
|
||
if n < 10 then return chinese_digits[n];
|
||
result := "";
|
||
num_str := inttostr(n);
|
||
len := length(num_str);
|
||
for i:=1 to len do
|
||
begin
|
||
digit_int := strtoint(num_str[i]);
|
||
if digit_int <> 0 then
|
||
result += chinese_digits[digit_int] + chinese_units[len - i];
|
||
end
|
||
if length(result) >= 6 and result[:6] = "一十" then result := result[4:];
|
||
return result;
|
||
end;
|
||
|
||
// SectModule
|
||
function SectModule.Create();
|
||
begin
|
||
{self.}Elements := array();
|
||
{self.}SectPr := nil;
|
||
end;
|
||
|
||
function SectModule.AddElement(element: tslobj);
|
||
begin
|
||
{self.}Elements[length({self.}Elements)] := element;
|
||
end;
|
||
|
||
// NumberingModule
|
||
function NumberingModule.Create(number: NumberingAdapter);
|
||
begin
|
||
numbering_adapter_ := new NumberingAdapter(number);
|
||
num_hash_ := array();
|
||
end;
|
||
|
||
function NumberingModule.GetNumberLvl(ppr: PPr);
|
||
begin
|
||
num_id := ppr.NumPr.NumId.Val;
|
||
if ifnil(num_id) then return array("", nil);
|
||
ilvl := ppr.NumPr.Ilvl.Val;
|
||
pstyle := ppr.PStyle.Val;
|
||
num := numbering_adapter_.GetNumByNumId(num_id);
|
||
if ifnil(num) then return array("", nil);
|
||
abstract_id := num.AbstractNumId.Val;
|
||
abstract_num := numbering_adapter_.GetAbstractNumByAbstractNumId(abstract_id);
|
||
lvls := abstract_num.Lvls();
|
||
if ifnil(ilvl) then ilvl := "0";
|
||
for k,v in lvls do
|
||
begin
|
||
if ilvl and v.Ilvl = ilvl then
|
||
begin
|
||
lvl_text := v.LvlText.Val;
|
||
if not ifarray(num_hash_[num_id]) then num_hash_[num_id] := array(0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||
ilvl_int := strtoint(ilvl);
|
||
for i:=0 to ilvl_int do
|
||
begin
|
||
source_str := "%" $ (i + 1);
|
||
n := num_hash_[num_id][i];
|
||
if i = ilvl_int then
|
||
begin
|
||
n := num_hash_[num_id][i] + 1;
|
||
for j:=i+1 to length(num_hash_[num_id])-1 do
|
||
num_hash_[num_id][j] := 0;
|
||
end
|
||
n := i = ilvl_int ? num_hash_[num_id][i] + 1 : num_hash_[num_id][i];
|
||
dest_str := {self.}CalculateNumber(v.NumFmt.Val, n);
|
||
lvl_text := replaceStr(lvl_text, source_str, dest_str);
|
||
end
|
||
num_hash_[num_id][ilvl_int]++;
|
||
if v.Suff.Val = "space" then lvl_text += " ";
|
||
return array(lvl_text, v);
|
||
end
|
||
end
|
||
return array("", nil);
|
||
end
|
||
|
||
function NumberingModule.CalculateNumber(num_fmt: string; num: integer): string;
|
||
begin
|
||
if num_fmt = "decimal" then
|
||
return format("%d", num);
|
||
else if num_fmt = "chineseCountingThousand" then
|
||
return {self.}ChineseCountingThousand(num);
|
||
else
|
||
return format("%d", num);
|
||
end;
|
||
|
||
function NumberingModule.ChineseCountingThousand(n: integer): string;
|
||
begin
|
||
chinese_digits := array("零", "一", "二", "三", "四", "五", "六", "七", "八", "九");
|
||
chinese_units := array("", "十", "百", "千");
|
||
if n < 10 then return chinese_digits[n];
|
||
result := "";
|
||
num_str := inttostr(n);
|
||
len := length(num_str);
|
||
for i:=1 to len do
|
||
begin
|
||
digit_int := strtoint(num_str[i]);
|
||
if digit_int <> 0 then
|
||
result += chinese_digits[digit_int] + chinese_units[len - i];
|
||
end
|
||
if length(result) >= 6 and result[:6] = "一十" then result := result[4:];
|
||
return result;
|
||
end;
|
||
|
||
// Page
|
||
function Page.Create(pdf_file: PdfFile);
|
||
begin
|
||
pdf_file_ := pdf_file;
|
||
{self.}TextPoint := new Point();
|
||
{self.}FtrPoint := new Point();
|
||
{self.}HdrPoint := new Point();
|
||
end;
|
||
|
||
function Page.OriginalTextCoordinates(): array of real;
|
||
begin
|
||
x := {self.}SectPr.PgMar.Left;
|
||
y := min({self.}SectPr.PgSz.H - max({self.}SectPr.PgMar.Top, {self.}SectPr.PgMar.Header), {self.}HdrPoint.Y);
|
||
return array(x, y);
|
||
end;
|
||
|
||
function Page.ReadPdfPage(): PdfPage;
|
||
begin
|
||
if ifnil(pdf_page_) then
|
||
begin
|
||
pdf_page_ := pdf_file_.AddPage();
|
||
pdf_page_.SetWidth({self.}SectPr.PgSz.W);
|
||
pdf_page_.SetHeight({self.}SectPr.PgSz.H);
|
||
|
||
if sysparams["_PDF_PAGE_GRID_DEBUG_"] then
|
||
{self.}PrintGrid();
|
||
|
||
end
|
||
return pdf_page_;
|
||
end;
|
||
|
||
function Page.PrintGrid();
|
||
begin
|
||
i := 0;
|
||
while true do
|
||
begin
|
||
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);
|
||
pdf_page_.MoveTo({self.}SectPr.PgMar.Left, y);
|
||
pdf_page_.LineTo({self.}SectPr.PgSz.W- {self.}SectPr.PgMar.Right, y);
|
||
pdf_page_.Stroke();
|
||
i++;
|
||
end
|
||
|
||
x1 := {self.}SectPr.PgMar.Left;
|
||
y1 := {self.}SectPr.PgSz.H - {self.}SectPr.PgMar.Top;
|
||
x2 := {self.}SectPr.PgSz.W - {self.}SectPr.PgMar.Right;
|
||
y2 := y1;
|
||
x3 := x1;
|
||
y3 := {self.}SectPr.PgMar.Bottom;
|
||
x4 := x2;
|
||
y4 := y3;
|
||
pdf_page_.SetLineWidth(0.05);
|
||
pdf_page_.SetGrayStroke(0.70);
|
||
pdf_page_.MoveTo(x1, y1);
|
||
pdf_page_.LineTo(x2, y2);
|
||
pdf_page_.Stroke();
|
||
pdf_page_.MoveTo(x1, y1);
|
||
pdf_page_.LineTo(x3, y3);
|
||
pdf_page_.Stroke();
|
||
pdf_page_.MoveTo(x2, y2);
|
||
pdf_page_.LineTo(x4, y4);
|
||
pdf_page_.Stroke();
|
||
pdf_page_.MoveTo(x3, y3);
|
||
pdf_page_.LineTo(x4, y4);
|
||
pdf_page_.Stroke();
|
||
end;
|
||
|
||
// PageManagerModule
|
||
function PageManagerModule.Create(pdf_file: PdfFile);
|
||
begin
|
||
pdf_file_ := pdf_file;
|
||
page_array_ := array();
|
||
end;
|
||
|
||
function Operator PageManagerModule.[](index: uinteger): Page;
|
||
begin
|
||
return page_array_[index];
|
||
end;
|
||
|
||
function PageManagerModule.NewPage(): Page;
|
||
begin
|
||
len := length(page_array_);
|
||
page := new Page(pdf_file_);
|
||
page.Index := len;
|
||
page_array_[len] := page;
|
||
return page;
|
||
end;
|
||
|
||
function PageManagerModule.Count(): integer;
|
||
begin
|
||
return length(page_array_);
|
||
end;
|
||
|
||
// TocModule
|
||
function TocModule.Create();
|
||
begin
|
||
toc_hash_ := array();
|
||
toc_unmatched_hash_ := array();
|
||
|
||
update_docx_num_pages_ := false;
|
||
docx_page_hash_ := array();
|
||
end;
|
||
|
||
function TocModule.UpdateDocxNumPages();
|
||
begin
|
||
update_docx_num_pages_ := true;
|
||
end;
|
||
|
||
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);overload;
|
||
begin
|
||
arr := toc_hash_[anchor];
|
||
if ifnil(arr) then // 未匹配到链接,说明链接可能在后面
|
||
begin
|
||
toc_unmatched_hash_[anchor] := range;
|
||
return;
|
||
end
|
||
pg := range.EndPage;
|
||
dst := pg.PdfPage.CreateDestination();
|
||
dst.SetXYZ(range.EndX, range.EndY + range.RPr.Sz.Val, 1);
|
||
for _,toc in arr do
|
||
toc.LinkAnnot(dst);
|
||
toc.AddPageNumber(pg);
|
||
|
||
if update_docx_num_pages_ then
|
||
begin
|
||
r := docx_page_hash_[anchor];
|
||
r.T.Text := pg.Number;
|
||
r.Serialize();
|
||
end
|
||
end;
|
||
|
||
function TocModule.LinkToToc(anchor: string);overload;
|
||
begin
|
||
range := toc_unmatched_hash_[anchor];
|
||
if range then
|
||
begin
|
||
{self.}LinkToToc(anchor, range);
|
||
toc_unmatched_hash_[anchor] := nil;
|
||
end
|
||
end;
|
||
|
||
function TocModule.AddToc(anchor: string; toc: Toc);
|
||
begin
|
||
if ifarray(toc_hash_[anchor]) then toc_hash_[anchor] union= array(toc);
|
||
else toc_hash_[anchor] := array(toc);
|
||
end;
|
||
|
||
function TocModule.AddDocxPage(anchor: string; r: R);
|
||
begin
|
||
docx_page_hash_[anchor] := r;
|
||
end;
|
||
|
||
end.
|