支持目录
This commit is contained in:
@@ -13,15 +13,18 @@ private
|
||||
function SetLvlText();
|
||||
function GetImageFileType(data: binary): string;
|
||||
function GetParagraphLineSpace(size: real; line: integer): real;
|
||||
function RangesToLines(ppr: PPr): tableArray;
|
||||
function RangesToLines(ppr: PPrUnitDecorator): tableArray;
|
||||
function CheckAndAddPage(y: real; offset: real): boolean;
|
||||
function GetUtf8CharLength(byte: string): integer;
|
||||
function RToTextRange(r: R; ppr: PPr);
|
||||
function SplitTextToTextRange(text: string; rpr: RPr);
|
||||
function RToDrawingRange(r: R; ppr: PPr);
|
||||
function SetLinesAlignment(ppr: PPr);
|
||||
function ResetCoordinates(ppr: PPr);
|
||||
function RToTextRange(r: R; ppr: PPrUnitDecorator; link: string);
|
||||
function SplitTextToTextRange(text: string; rpr: RPrUnitDecorator; link: string);
|
||||
function RToDrawingRange(r: R; ppr: PPrUnitDecorator);
|
||||
function SetLinesAlignment(ppr: PPrUnitDecorator);
|
||||
function ResetCoordinates(ppr: PPrUnitDecorator);
|
||||
function NewLineRange(): TSPdfLineRange;
|
||||
function BookMarkLinkToc();
|
||||
function HyperlinkToToc(ppr: PPrUnitDecorator);
|
||||
function HyperlinkToTextRange(hyperlink: Hyperlink; ppr: PPrUnitDecorator);
|
||||
|
||||
private
|
||||
[weakref]docx_to_pdf_: TSDocxToPdf;
|
||||
@@ -32,6 +35,8 @@ private
|
||||
extra_style_id_: string;
|
||||
range_array_: array of TSPdfBasicRange;
|
||||
line_range_array_: array of TSPdfLineRange;
|
||||
hyperlink_array_: tableArray;
|
||||
bookmark_array_: tableArray;
|
||||
end;
|
||||
|
||||
function TSPdfParagraphRange.Create(docx_to_pdf: TSDocxToPdf; pg: TSPage; components: TSDocxComponentsWare; sect_ware: TSSectWare; paragraph: P);
|
||||
@@ -44,11 +49,14 @@ begin
|
||||
extra_style_id_ := "";
|
||||
range_array_ := array();
|
||||
line_range_array_ := array();
|
||||
hyperlink_array_ := array();
|
||||
bookmark_array_ := array();
|
||||
{self.}TSPage := page_;
|
||||
end;
|
||||
|
||||
function TSPdfParagraphRange.Calc(): tableArray;
|
||||
begin
|
||||
// ppr.rpr是无效的,应该以ppr.pStyle为准
|
||||
{self.}SetPPr(paragraph_.PPr);
|
||||
{self.}SetLvlText();
|
||||
ppr := new PPrUnitDecorator(paragraph_.PPr);
|
||||
@@ -58,37 +66,115 @@ begin
|
||||
{self.}CheckAndAddPage({self.}EndY, ppr.Spacing.Before);
|
||||
{self.}EndY -= ppr.Spacing.Before;
|
||||
{self.}DynamicHeight += ppr.Spacing.Before;
|
||||
rs := paragraph_.Rs();
|
||||
if length(rs) = 0 then
|
||||
|
||||
elements := paragraph_.Elements();
|
||||
empty_flag := true;
|
||||
bookmark_id := '';
|
||||
bookmark_name := '';
|
||||
bookmark_flag := false;
|
||||
for _,element in elements do
|
||||
begin
|
||||
if not ifObj(element.XmlNode) then continue;
|
||||
if element.LocalName = "r" then
|
||||
begin
|
||||
empty_flag := false;
|
||||
{self.}SetRPr(element.RPr, ppr);
|
||||
if element.Br.Type = "page" then
|
||||
{self.}CheckAndAddPage(sect_ware_.SectPr.PgMar.Bottom, 1);
|
||||
else if ifObj(element.Drawing.XmlNode) then {self.}RToDrawingRange(element, ppr);
|
||||
else {self.}RToTextRange(element, ppr, bookmark_name);
|
||||
end
|
||||
else if element.LocalName = "hyperlink" then
|
||||
begin
|
||||
empty_flag := false;
|
||||
{self.}HyperlinkToTextRange(element, ppr);
|
||||
end
|
||||
else if element.LocalName = "bookmarkStart" then
|
||||
begin
|
||||
bookmark_id := element.Id;
|
||||
bookmark_name := element.Name;
|
||||
bookmark_array_[bookmark_name] := array();
|
||||
end
|
||||
else if element.LocalName = "bookmarkEnd" then
|
||||
begin
|
||||
bookmark_id := '';
|
||||
bookmark_name := '';
|
||||
end
|
||||
end
|
||||
if empty_flag then
|
||||
begin
|
||||
line_space := {self.}GetParagraphLineSpace(ppr.RPr.Sz.Val, ppr.Spacing.Line);
|
||||
{self.}DynamicHeight += ppr.Spacing.After + line_space;
|
||||
{self.}EndY -= {self.}DynamicHeight;
|
||||
end
|
||||
else begin
|
||||
for _, r in rs do
|
||||
begin
|
||||
{self.}SetRPr(r.RPr, paragraph_.PPr);
|
||||
if r.Br.Type = "page" then
|
||||
{self.}CheckAndAddPage(sect_ware_.SectPr.PgMar.Bottom, 1);
|
||||
else if ifObj(r.Drawing.XmlNode) then {self.}RToDrawingRange(r, ppr);
|
||||
else {self.}RToTextRange(r, ppr);
|
||||
end
|
||||
end
|
||||
{self.}RangesToLines(ppr);
|
||||
// hyperlinks := paragraph_.Hyperlinks(); // TOC
|
||||
// for _,hyperlink in hyperlinks do
|
||||
// begin
|
||||
// rs := hyperlink.Rs();
|
||||
// for _,r in rs do
|
||||
// begin
|
||||
// if r.FldChar.FldCharType = "begin" then break;
|
||||
// {self.}RToTextRange(r, ppr);
|
||||
// end
|
||||
// end
|
||||
if hyperlink_array_ then {self.}HyperlinkToToc(ppr);
|
||||
if bookmark_array_ then {self.}BookMarkLinkToc();
|
||||
end;
|
||||
|
||||
function TSPdfParagraphRange.Do();
|
||||
function TSPdfParagraphRange.BookMarkLinkToc();
|
||||
begin
|
||||
for name,arr in bookmark_array_ do
|
||||
if arr[0] then docx_to_pdf_.LinkToToc(name, arr[0].TSPage);
|
||||
end;
|
||||
|
||||
function TSPdfParagraphRange.HyperlinkToToc(ppr: PPrUnitDecorator);
|
||||
begin
|
||||
for anchor,arr in hyperlink_array_ do // 整理hyperlink发送到docx_to_pdf_
|
||||
begin
|
||||
pg := arr[0].TSPage;
|
||||
left := {self.}StartX;
|
||||
bottom := arr[0].EndY;
|
||||
right := left + {self.}Width;
|
||||
top := bottom + arr[0].RPr.Sz.Val;
|
||||
x := arr[0].EndX + arr[0].Width;
|
||||
y := arr[0].EndY;
|
||||
for _,range in arr do
|
||||
begin
|
||||
if range.TSPage <> pg then // 说明目录文字换页
|
||||
begin
|
||||
rect := array(left, bottom, right, top);
|
||||
toc := new TSToc(ppr, rect, pg, x, y);
|
||||
docx_to_pdf_.AddToc(anchor, toc);
|
||||
pg := range.TSPage;
|
||||
left := range.EndX;
|
||||
top := range.EndY + range.RPr.Sz.Val;
|
||||
right := left;
|
||||
bottom := range.EndY;
|
||||
continue;
|
||||
end
|
||||
top := range.EndY + arr[0].RPr.Sz.Val;
|
||||
x := range.EndX + range.Width;
|
||||
end
|
||||
rect := array(left, bottom, right, top);
|
||||
font_name := ppr.RPr.RFonts.EastAsia ? ppr.RPr.RFonts.EastAsia : ppr.RPr.RFonts.Ascii;
|
||||
font_obj := docx_to_pdf_.Font.GetFont(font_name, ppr.RPr.B, ppr.RPr.I);
|
||||
toc := new TSToc(ppr, rect, pg, x, y, font_obj);
|
||||
docx_to_pdf_.AddToc(anchor, toc);
|
||||
end
|
||||
end;
|
||||
|
||||
function TSPdfParagraphRange.HyperlinkToTextRange(hyperlink: Hyperlink; ppr: PPrUnitDecorator);
|
||||
begin
|
||||
i := length(range_array_);
|
||||
rs := hyperlink.Rs();
|
||||
for _,r in rs do
|
||||
begin
|
||||
if r.FldChar.FldCharType = "begin" then break;
|
||||
r.RPr := new RPr();
|
||||
{self.}SetRPr(r.RPr, ppr);
|
||||
{self.}RToTextRange(r, ppr, hyperlink.Anchor);
|
||||
end
|
||||
arr := array();
|
||||
while i < length(range_array_) do
|
||||
begin
|
||||
arr[length(arr)] := range_array_[i];
|
||||
i++;
|
||||
end
|
||||
hyperlink_array_[hyperlink.Anchor] := arr;
|
||||
end;
|
||||
|
||||
function TSPdfParagraphRange.Do();override;
|
||||
begin
|
||||
for _,line_range in line_range_array_ do
|
||||
line_range.Do();
|
||||
@@ -108,7 +194,7 @@ begin
|
||||
return line_range;
|
||||
end;
|
||||
|
||||
function TSPdfParagraphRange.RangesToLines(ppr: PPr);
|
||||
function TSPdfParagraphRange.RangesToLines(ppr: PPrUnitDecorator);
|
||||
begin
|
||||
line_range := {self.}NewLineRange();
|
||||
i := 0;
|
||||
@@ -167,7 +253,7 @@ begin
|
||||
{self.}SetLinesAlignment(ppr);
|
||||
end;
|
||||
|
||||
function TSPdfParagraphRange.SetLinesAlignment(ppr: PPr);
|
||||
function TSPdfParagraphRange.SetLinesAlignment(ppr: PPrUnitDecorator);
|
||||
begin
|
||||
if length(line_range_array_) = 0 then return;
|
||||
idx := length(line_range_array_)-1;
|
||||
@@ -200,14 +286,20 @@ begin
|
||||
return 4;
|
||||
end;
|
||||
|
||||
function TSPdfParagraphRange.RToTextRange(r: R; ppr: PPr);
|
||||
function TSPdfParagraphRange.RToTextRange(r: R; ppr: PPrUnitDecorator; link: string);
|
||||
begin
|
||||
rpr := new RPrUnitDecorator(r.RPr);
|
||||
text := r.T.Text;
|
||||
if ifString(text) then {self.}SplitTextToTextRange(text, rpr);
|
||||
if r.Anchor then
|
||||
begin
|
||||
{self.}HyperlinkToTextRange(r, ppr);
|
||||
end
|
||||
else begin
|
||||
rpr := new RPrUnitDecorator(r.RPr);
|
||||
text := r.T.Text;
|
||||
if ifString(text) then {self.}SplitTextToTextRange(text, rpr, link);
|
||||
end
|
||||
end;
|
||||
|
||||
function TSPdfParagraphRange.SplitTextToTextRange(text: string; rpr: RPr);
|
||||
function TSPdfParagraphRange.SplitTextToTextRange(text: string; rpr: RPrUnitDecorator; link: string);
|
||||
begin
|
||||
pos := 1;
|
||||
while pos <= length(text) do
|
||||
@@ -219,7 +311,6 @@ begin
|
||||
font_name := rpr.RFonts.EastAsia ? rpr.RFonts.EastAsia : rpr.RFonts.Ascii;
|
||||
font_obj := docx_to_pdf_.Font.GetFont(font_name, rpr.B, rpr.I);
|
||||
if not rpr.Sz.Val then rpr.Sz.Val := rpr.SzCs.Val ? rpr.SzCs.Val : docx_to_pdf_.Font.GetDefaultSz();
|
||||
// println("page_.PdfPage = {}, font_obj = {}, sz = {}", page_.PdfPage, font_obj, rpr.Sz.Val);
|
||||
page_.PdfPage.SetFontAndSize(font_obj, rpr.Sz.Val);
|
||||
word_width := page_.PdfPage.TextWidth(word);
|
||||
text_range := new TSPdfTextRange();
|
||||
@@ -228,10 +319,11 @@ begin
|
||||
text_range.Font := font_obj;
|
||||
text_range.Width := word_width;
|
||||
range_array_[length(range_array_)] := text_range;
|
||||
if ifarray(bookmark_array_[link]) then bookmark_array_[link] union= array(text_range);
|
||||
end
|
||||
end;
|
||||
|
||||
function TSPdfParagraphRange.RToDrawingRange(r: R; ppr: PPr);
|
||||
function TSPdfParagraphRange.RToDrawingRange(r: R; ppr: PPrUnitDecorator);
|
||||
begin
|
||||
xfrm := new XfrmUnitDecorator(r.Drawing._Inline.Graphic.GraphicData.Pic.SpPr.Xfrm);
|
||||
rels_adapter := docx_components_ware_.GetDocumentRelsAdapter();
|
||||
@@ -318,11 +410,11 @@ end;
|
||||
|
||||
function TSPdfParagraphRange.SetRPr(var rpr; ppr: PPr);
|
||||
begin
|
||||
// rpr,先继承ppr,再继承样式,最后继承自己
|
||||
new_rpr := new RPr();
|
||||
style_id := rpr.RStyle.Val;
|
||||
new_rpr.Copy(ppr.RPr);
|
||||
{self.}SetRPrByStyleId(new_rpr, style_id);
|
||||
styles := docx_components_ware_.GetStyles();
|
||||
new_rpr.Copy(styles.DocDefaults.RPrDefault.RPr);
|
||||
{self.}SetRPrByStyleId(new_rpr, ppr.PStyle.Val);
|
||||
{self.}SetRPrByStyleId(new_rpr, rpr.RStyle.Val);
|
||||
new_rpr.Copy(rpr);
|
||||
rpr.Copy(new_rpr);
|
||||
end;
|
||||
@@ -350,7 +442,7 @@ begin
|
||||
{self.}SplitTextToTextRange(lvl_text, rpr);
|
||||
end;
|
||||
|
||||
function TSPdfParagraphRange.ResetCoordinates(ppr: PPr);
|
||||
function TSPdfParagraphRange.ResetCoordinates(ppr: PPrUnitDecorator);
|
||||
begin
|
||||
// 根据段落的间距确定新的坐标
|
||||
sz := ppr.RPr.SzCs.Val ? ppr.RPr.SzCs.Val : ppr.RPr.Sz.Val ? ppr.RPr.Sz.Val : docx_to_pdf_.Font.GetDefaultSz();
|
||||
|
||||
@@ -7,7 +7,6 @@ public
|
||||
private
|
||||
function ProcessTrData(grid_cols: array of GridCol; tr: Tr; tbl_pr: TblPr): array of TSPdfAbstractRange;
|
||||
function ResetCoordinates(tbl_pr: TblPr; grid_cols: array of GridCol);
|
||||
function CheckAndAddPage(y: real; offset: real): boolean;
|
||||
function SetTblPr(tbl_pr: TblPr);
|
||||
function SetTblPrByStyleId(var tbl_pr: TblPr; style_id: string);
|
||||
function SetTrPr(var tr_pr: TrPr);
|
||||
@@ -22,7 +21,6 @@ private
|
||||
[weakref]table_: Tbl;
|
||||
[weakref]page_: TSPage;
|
||||
[weakref]range_array_: tableArray;
|
||||
point_: TSPoint;
|
||||
end;
|
||||
|
||||
function TSPdfTableRange.Create(docx_to_pdf: TSDocxToPdf; pg: PdfPage; components: Components; sect_ware: TSSectWare; table: Tbl);
|
||||
@@ -60,19 +58,6 @@ begin
|
||||
range.Do();
|
||||
end;
|
||||
|
||||
function TSPdfTableRange.CheckAndAddPage(y: real; offset: real): boolean;
|
||||
begin
|
||||
if y - offset < sect_ware_.SectPr.PgMar.Bottom then
|
||||
begin
|
||||
page_ := docx_to_pdf_.GetNextPage(page_);
|
||||
if ifnil(page_) then page_ := docx_to_pdf_.AddPage(sect_ware_);
|
||||
point := docx_to_pdf_.GetCurrentPoint();
|
||||
{self.}EndY := point.Y;
|
||||
return true;
|
||||
end
|
||||
return false;
|
||||
end;
|
||||
|
||||
function TSPdfTableRange.ProcessTrData(grid_cols: array of GridCol; tr: Tr; tbl_pr: TblPr): array of TSPdfAbstractRange;
|
||||
begin
|
||||
{self.}SetTrPr(tr.TrPr);
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
type TSPdfTocRange = class(TSPdfBasicRange)
|
||||
public
|
||||
function Create();
|
||||
|
||||
public
|
||||
TSPage: TSPage;
|
||||
end;
|
||||
|
||||
function TSPdfTocRange.Create();
|
||||
|
||||
Reference in New Issue
Block a user