修复目录链接跳转位置不正确

This commit is contained in:
csh 2024-08-06 16:19:24 +08:00
parent 1eee1efc3a
commit d687f45b3b
2 changed files with 37 additions and 29 deletions

View File

@ -12,7 +12,7 @@ public
function AddPage(): TSPage;overload; function AddPage(): TSPage;overload;
function AddPage(sect_ware: TSSectWare): TSPage;overload; function AddPage(sect_ware: TSSectWare): TSPage;overload;
function AdjustPageNumber(page: TSPage; num: integer); function AdjustPageNumber(page: TSPage; num: integer);
function LinkToToc(anchor: string; page: TSPage); function LinkToToc(anchor: string; page: TSPage; left: real; top: real);
function AddToc(anchor: string; toc: TSToc); function AddToc(anchor: string; toc: TSToc);
function SetHeaderAndFooter(); function SetHeaderAndFooter();
function ProcessNumpages(); function ProcessNumpages();
@ -100,7 +100,6 @@ begin
elements := sect_ware.Elements; elements := sect_ware.Elements;
for _,element in elements do for _,element in elements do
begin begin
// if _ = 150 then return;
if element.LocalName = "p" then {self.}TransformP(sect_ware, element); if element.LocalName = "p" then {self.}TransformP(sect_ware, element);
else if element.LocalName = "tbl" then {self.}TransformTbl(sect_ware, element); else if element.LocalName = "tbl" then {self.}TransformTbl(sect_ware, element);
else if element.LocalName = "sdt" then {self.}TransformSdt(sect_ware, element); else if element.LocalName = "sdt" then {self.}TransformSdt(sect_ware, element);
@ -227,7 +226,6 @@ begin
elements := header.Elements(); elements := header.Elements();
for _,element in elements do for _,element in elements do
begin begin
// if _ = 150 then return;
if element.LocalName = "p" then {self.}TransformHeaderAndFooter(element, "header"); if element.LocalName = "p" then {self.}TransformHeaderAndFooter(element, "header");
end end
end end
@ -242,7 +240,6 @@ begin
elements := header.Elements(); elements := header.Elements();
for _,element in elements do for _,element in elements do
begin begin
// if _ = 150 then return;
if element.LocalName = "p" then {self.}TransformHeaderAndFooter(element, "footer"); if element.LocalName = "p" then {self.}TransformHeaderAndFooter(element, "footer");
end end
end end
@ -389,20 +386,22 @@ begin
else toc_array_[anchor] := array(toc); else toc_array_[anchor] := array(toc);
if toc_unmacthed_array_[anchor] then if toc_unmacthed_array_[anchor] then
begin begin
{self.}LinkToToc(anchor, toc_unmacthed_array_[anchor]); toc := toc_unmacthed_array_[anchor];
{self.}LinkToToc(anchor, toc[0], toc[1], toc[2]);
toc_unmacthed_array_[anchor] := nil; toc_unmacthed_array_[anchor] := nil;
end end
end; end;
function TSDocxToPdf.LinkToToc(anchor: string; page: TSPage); function TSDocxToPdf.LinkToToc(anchor: string; page: TSPage; left: real; top: real);
begin begin
arr := toc_array_[anchor]; arr := toc_array_[anchor];
if ifnil(arr) then if ifnil(arr) then
begin begin
toc_unmacthed_array_[anchor] := page; toc_unmacthed_array_[anchor] := array(page, left, top);
return; return;
end end
dst := page.PdfPage.CreateDestination(); dst := page.PdfPage.CreateDestination();
dst.SetXYZ(left, top, 1);
for _,toc in arr do for _,toc in arr do
toc.LinkAnnot(dst); toc.LinkAnnot(dst);
toc.AddPageNumber(page); toc.AddPageNumber(page);

View File

@ -118,7 +118,7 @@ end;
function TSPdfParagraphRange.BookMarkLinkToc(); function TSPdfParagraphRange.BookMarkLinkToc();
begin begin
for name,arr in bookmark_array_ do for name,arr in bookmark_array_ do
if arr[0] then docx_to_pdf_.LinkToToc(name, arr[0].TSPage); if arr[0] then docx_to_pdf_.LinkToToc(name, arr[0].TSPage, arr[0].EndX, arr[0].EndY + arr[0].RPr.Sz.Val);
end; end;
function TSPdfParagraphRange.HyperlinkToToc(ppr: PPrUnitDecorator); function TSPdfParagraphRange.HyperlinkToToc(ppr: PPrUnitDecorator);
@ -128,57 +128,66 @@ begin
begin begin
pg := arr[0].TSPage; pg := arr[0].TSPage;
left := {self.}StartX; left := {self.}StartX;
right := {self.}StartX + {self.}Width;
top := {self.}StartY;
bottom := {self.}StartY; bottom := {self.}StartY;
right := left + {self.}Width; x := arr[0].EndX;
top := bottom;
x := arr[0].EndX + arr[0].Width;
y := arr[0].EndY; y := arr[0].EndY;
if top - {self.}GetParagraphLineSpace(arr[0].RPr.Sz.Val, ppr.Spacing.Line) then
begin
top := docx_to_pdf_.GetCurrentPoint().Y;
bottom := top;
end
for _,range in arr do for _,range in arr do
begin begin
if x + range.Width - {self.}StartX > {self.}Width + 1e-6 then // 换行 if x + range.Width - {self.}StartX > {self.}Width + 1e-6 then // 换行
begin begin
top += max_size; line_space := {self.}GetParagraphLineSpace(max_size, ppr.Spacing.Line);
bottom -= line_space;
max_size := 0; max_size := 0;
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;
bottom := {self.}StartY;
end
end end
if range.RPr.Sz.Val > max_size then max_size := range.RPr.Sz.Val; if range.RPr.Sz.Val > max_size then max_size := range.RPr.Sz.Val;
if range.TSPage <> pg then
begin
rect := array(left, bottom, right, top + max_size);
toc := new TSToc(ppr, rect, pg, x, y);
docx_to_pdf_.AddToc(anchor, toc);
top := bottom;
pg := range.TSPage;
continue;
end
x := range.EndX + range.Width; x := range.EndX + range.Width;
y := range.EndY; y := range.EndY;
end end
font_name := ppr.RPr.RFonts.EastAsia ? ppr.RPr.RFonts.EastAsia : ppr.RPr.RFonts.Ascii; 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); font_obj := docx_to_pdf_.Font.GetFont(font_name, ppr.RPr.B, ppr.RPr.I);
rect := array(left, bottom, right, top + max_size); line_space := {self.}GetParagraphLineSpace(max_size, ppr.Spacing.Line);
toc := new TSToc(ppr, rect, pg, x, y, font_obj);
docx_to_pdf_.AddToc(anchor, toc);
pg.PdfPage.SetFontAndSize(font_obj, max_size); pg.PdfPage.SetFontAndSize(font_obj, max_size);
bottom -= line_space;
num_width := pg.PdfPage.TextWidth("." + tostring(pg.Number)); num_width := pg.PdfPage.TextWidth("." + tostring(pg.Number));
if x + num_width - {self.}StartX > {self.}Width + 1e-6 then // 换行 if x + num_width - {self.}StartX > {self.}Width + 1e-6 then // 换行
begin begin
offset := (line_space - max_size) / 2 + max_size - max_size / 5; offset := (line_space - max_size) / 2 + max_size - max_size / 5;
line_space := {self.}GetParagraphLineSpace(max_size, ppr.Spacing.Line);
diff := {self.}EndY - sect_ware_.SectPr.PgMar.Bottom; diff := {self.}EndY - sect_ware_.SectPr.PgMar.Bottom;
if {self.}CheckAndAddPage({self.}EndY, line_space) then if {self.}CheckAndAddPage({self.}EndY, line_space) then
begin begin
{self.}DynamicHeight += diff; {self.}DynamicHeight += diff;
pg := page_; pg := page_;
rect := array(left, bottom, right, top);
toc := new TSToc(ppr, rect, pg, x, y);
docx_to_pdf_.AddToc(anchor, toc);
bottom := {self.}StartY;
end end
else begin else begin
{self.}EndY -= line_space; {self.}EndY -= line_space;
{self.}DynamicHeight += line_space; {self.}DynamicHeight += line_space;
bottom -= line_space;
x := {self.}StartX;
y := {self.}EndY + offset;
end end
rect := array({self.}StartX, {self.}StartY - line_space, {self.}StartX + {self.}Width, {self.}StartY);
toc := new TSToc(ppr, rect, pg, {self.}StartX, {self.}EndY + offset, font_obj);
docx_to_pdf_.AddToc(anchor, toc);
end end
rect := array(left, bottom, right, top);
toc := new TSToc(ppr, rect, pg, x, y, font_obj);
docx_to_pdf_.AddToc(anchor, toc);
end end
end; end;