1. 支持分栏

2. 支持简单的单个脚注
This commit is contained in:
csh
2024-12-13 17:19:52 +08:00
parent a677e5a843
commit 4c002f803f
8 changed files with 359 additions and 68 deletions
+64
View File
@@ -0,0 +1,64 @@
type TSPdfColumnRange = class(TSPdfBasicRange)
public
function Create(docx_to_pdf: TSDocxToPdf; pg: TSPage; components: TSDocxComponentsWare);
function AddElement(ele: Element);
function Elements(): array of Element;
function GetLastPage(): TSPage;
function Do();override;
private
[weakref]docx_to_pdf_: TSDocxToPdf;
[weakref]docx_components_ware_: TSDocxComponentsWare;
[weakref]page_: TSPage;
elements_: array of Elements;
paragraph_: P;
last_y_: real;
end;
function TSPdfColumnRange.Create(docx_to_pdf: TSDocxToPdf; pg: TSPage; components: TSDocxComponentsWare);
begin
docx_to_pdf_ := docx_to_pdf;
page_ := pg;
docx_components_ware_ := components;
elements_ := array();
last_y_ := 0;
end;
function TSPdfColumnRange.AddElement(ele: Element);
begin
elements_[length(elements_)] := ele;
end;
function TSPdfColumnRange.Elements(): array of Element;
begin
return elements_;
end;
function TSPdfColumnRange.Do();override;
begin
x := {self.}StartX;
y := {self.}StartY;
for _,element in elements_ do
begin
range := nil;
if element.LocalName = "p" then
range := new TSPdfParagraphRange(docx_to_pdf_, page_, docx_components_ware_, element);
else if element.LocalName = "tbl" then
range := new TSPdfTableRange(docx_to_pdf_, page_, docx_components_ware_, element);
if ifnil(range) then continue;
range.StartX := x;
range.StartY := y;
range.Width := {self.}Width;
range.LowerBound := {self.}LowerBound;
range.Calc();
range.Do();
y := range.EndY;
page_ := range.GetLastPage();
end
{self.}EndY := y;
end;
function TSPdfColumnRange.GetLastPage(): TSPage;
begin
return page_;
end;
+10
View File
@@ -7,6 +7,7 @@ public
function Align(jc: string);
function AdjustRangeOffset(page: TSPage; x_offset: real; y_offset: real);
function AlignRightBound(right_bound: real);
function Offset(x_offset: real; y_offset; real);
private
range_array_: array of TSPdfBasicRange;
@@ -81,3 +82,12 @@ begin
range_array_[i].EndX += avg * i;
end
end;
function TSPdfLineRange.Offset(x_offset: real; y_offset; real);
begin
for _,range in range_array_ do
begin
range.EndX += x_offset;
range.EndY -= y_offset;
end
end;
+55 -11
View File
@@ -10,6 +10,7 @@ public
function AdjustRangeOffset(page: TSPage; x_offset: real; y_offset: real);
function GetLineRangeArr(): array of TSPdfLineRange;
function Empty(): boolean;
function Offset(x: real; y: real);
private
function SetPPr(var ppr: PPr);
@@ -31,6 +32,7 @@ private
function RFootnoteReference(r: R);
function RObject(r: R);
function RFldChar(r: R; stack: Stack);
function RFootnoteRef(r: R);
function SetLinesAlignment();
function ResetCoordinates();
function NewLineRange(): TSPdfLineRange;
@@ -39,6 +41,7 @@ private
function HyperlinkToTextRange(hyperlink: Hyperlink; ppr: PPrUnitDecorator);
function GetXYCordinates(): array of real;
function AlignRightBound();
function Init();
private
[weakref]docx_to_pdf_: TSDocxToPdf;
@@ -125,14 +128,10 @@ begin
{self.}TSPage := page_;
end;
function TSPdfParagraphRange.Calc(): tableArray;
function TSPdfParagraphRange.Init();
begin
// ppr.rpr是无效的,应该以ppr.pStyle为准
range_array_ := array();
right_bound_ := {self.}StartX + {self.}Width;
if ifnil(paragraph_.XmlChildPPr) then paragraph_.XmlChildPPr := new PPr();
{self.}SetPPr(paragraph_.PPr);
ppr_unit_decorator_ := new PPrUnitDecorator(paragraph_.PPr);
if not ppr_unit_decorator_.RPr.Sz.Val then ppr_unit_decorator_.RPr.Sz.Val := docx_to_pdf_.Font.GetDefaultSz();
{self.}ResetCoordinates();
{self.}EndX := {self.}StartX;
{self.}EndY := {self.}StartY;
@@ -140,9 +139,18 @@ begin
{self.}EndY -= ppr_unit_decorator_.Spacing.Before;
{self.}DynamicHeight += ppr_unit_decorator_.Spacing.Before;
{self.}SetLvlText();
end;
function TSPdfParagraphRange.Calc(): tableArray;
begin
// ppr.rpr是无效的,应该以ppr.pStyle为准
if ifnil(paragraph_.XmlChildPPr) then paragraph_.XmlChildPPr := new PPr();
{self.}SetPPr(paragraph_.PPr);
ppr_unit_decorator_ := new PPrUnitDecorator(paragraph_.PPr);
if not ppr_unit_decorator_.RPr.Sz.Val then ppr_unit_decorator_.RPr.Sz.Val := docx_to_pdf_.Font.GetDefaultSz();
if paragraph_.PPr.PageBreakBefore then
{self.}CheckAndAddPage({self.}LowerBound, 1);
{self.}Init();
elements := paragraph_.Elements();
empty_flag := true;
@@ -170,12 +178,13 @@ begin
end
if element.Br.Type = "page" then
// {self.}EndY := {self.}LowerBound;
{self.}CheckAndAddPage({self.}LowerBound, 1);
{self.}EndY := {self.}LowerBound;
// {self.}CheckAndAddPage({self.}LowerBound, 1);
else if ifObj(element.Drawing) then {self.}RDrawing(element);
else if ifObj(element.AlternateContent) then {self.}RAlternateContent(element);
else if ifObj(element.FootnoteReference) then {self.}RFootnoteReference(element);
else if ifObj(element.Object) then {self.}RObject(element);
else if element.FootnoteRef then {self.}RFootnoteRef(element);
else {self.}RToTextRange(element, bookmark_name);
end
else if element.LocalName = "fldSimple" then
@@ -540,7 +549,7 @@ end;
function TSPdfParagraphRange.RDrawing(r: R);
begin
if ifObj(r.Drawing._Inline.XmlNode) then
if ifObj(r.Drawing._Inline) then
begin
id := r.Drawing._Inline.Graphic.GraphicData.Pic.BlipFill.Blip.Embed;
[image_type, image] := {self.}GetImageData(id);
@@ -555,7 +564,7 @@ begin
image_range.DynamicHeight := xfrm.Ext.CY;
range_array_[length(range_array_)] := image_range;
end
else if ifObj(r.Drawing.Anchor.XmlNode) then
else if ifObj(r.Drawing.Anchor) then
begin
anchor := r.Drawing.Anchor;
id := anchor.Graphic.GraphicData.Pic.BlipFill.Blip.Embed;
@@ -619,8 +628,29 @@ begin
footnote := footnotes_adapter.GetFootnoteById(id);
sect_ware := docx_to_pdf_.GetCurrentSectWare();
w := sect_ware.SectPr.PgSz.W - sect_ware.SectPr.PgMar.Right - sect_ware.SectPr.PgMar.Left;
lb := 0;
lb := {self.}LowerBound;
[x, y] := docx_to_pdf_.CalculateTextCoordinates();
elements := footnote.Elements();
for _,element in elements do
begin
if element.LocalName = "p" then
begin
range := new TSPdfParagraphRange(docx_to_pdf_, page_, docx_components_ware_, element);
range.StartX := x;
range.StartY := y;
range.Width := w;
range.LowerBound := {self.}LowerBound;
range.Calc();
range.Offset(0, y - range.DynamicHeight - {self.}LowerBound);
range.Do();
{self.}LowerBound += range.DynamicHeight;
rpr := new RPrUnitDecorator(r.RPr);
text := docx_to_pdf_.GetCurrentNoteWare().GetIndex();
if ifString(text) then {self.}SplitTextToTextRange(text, rpr, nil);
return;
// break;
end
end
// range := new TSPdfParagraphRange(self, page_, docx_components_ware_, );
end;
@@ -914,3 +944,17 @@ function TSPdfParagraphRange.Empty(): boolean;
begin
return empty_;
end;
function TSPdfParagraphRange.Offset(x: real; y: real);
begin
for _,line_range in line_range_array_ do
line_range.Offset(x, y);
end;
function TSPdfParagraphRange.RFootnoteRef(r: R);
begin
note_ware := docx_to_pdf_.GetCurrentNoteWare();
rpr := new RPrUnitDecorator(r.RPr);
text := note_ware.GetFootnoteOrderNumber();
if ifString(text) then {self.}SplitTextToTextRange(text, rpr, nil);
end;
+9 -2
View File
@@ -24,10 +24,17 @@ begin
// println("Text = {}, sz = {}, szcs = {}, rpr.I = {}, color = {}", ansiToUtf8({self.}Text), {self.}RPr.Sz.Val, {self.}RPr.SzCs.Val, {self.}RPr.I, {self.}RPr.Color.Val);
[r, g, b] := array(0, 0, 0);
if {self.}RPr.Color.Val and {self.}RPr.Color.Val <> "auto" then [r, g, b] := TSColorToolKit.HexToRGB({self.}RPr.Color.Val);
y := {self.}EndY;
sz := {self.}RPr.Sz.Val;
if {self.}RPr.VertAlign.Val = "superscript" then
begin
y += sz / 3;
sz := sz * 2 / 3;
end
{self.}TSPage.PdfPage.SetRGBFill(r / 255, g / 255, b / 255);
{self.}TSPage.PdfPage.SetFontAndSize({self.}Font, {self.}RPr.Sz.Val);
{self.}TSPage.PdfPage.SetFontAndSize({self.}Font, sz);
{self.}TSPage.PdfPage.BeginText();
{self.}TSPage.PdfPage.TextOut({self.}EndX, {self.}EndY, {self.}Text);
{self.}TSPage.PdfPage.TextOut({self.}EndX, y, {self.}Text);
{self.}TSPage.PdfPage.EndText();
{self.}TSPage.PdfPage.SetRGBFill(0, 0, 0);