对range进行重构
This commit is contained in:
parent
999a7ef2d0
commit
51dc8596be
|
|
@ -242,25 +242,23 @@ function TSDocxToPdf.TransformParagraph(sect_ware: TSSectWare; paragraph: P);
|
||||||
begin
|
begin
|
||||||
w := sect_ware.SectPr.PgSz.W - sect_ware.SectPr.PgMar.Right - sect_ware.SectPr.PgMar.Left;
|
w := sect_ware.SectPr.PgSz.W - sect_ware.SectPr.PgMar.Right - sect_ware.SectPr.PgMar.Left;
|
||||||
range := new TSPdfParagraphRange(self, current_page_, docx_components_, sect_ware, paragraph);
|
range := new TSPdfParagraphRange(self, current_page_, docx_components_, sect_ware, paragraph);
|
||||||
range.X := point_.X;
|
range.StartX := point_.X;
|
||||||
range.Y := point_.Y;
|
range.StartY := point_.Y;
|
||||||
range.W := w;
|
range.Width := w;
|
||||||
range.H := 0;
|
|
||||||
range.Calc();
|
range.Calc();
|
||||||
range.Do();
|
range.Do();
|
||||||
point_.Y := range.Y;
|
point_.Y := range.EndY;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSDocxToPdf.TransformTable(sect_ware: TSSectWare; table: Tbl);
|
function TSDocxToPdf.TransformTable(sect_ware: TSSectWare; table: Tbl);
|
||||||
begin
|
begin
|
||||||
w := sect_ware.SectPr.PgSz.W - sect_ware.SectPr.PgMar.Right - sect_ware.SectPr.PgMar.Left;
|
w := sect_ware.SectPr.PgSz.W - sect_ware.SectPr.PgMar.Right - sect_ware.SectPr.PgMar.Left;
|
||||||
range := new TSPdfTableRange(self, current_page_, docx_components_, sect_ware, table);
|
range := new TSPdfTableRange(self, current_page_, docx_components_, sect_ware, table);
|
||||||
range.X := point_.X;
|
range.StartX := point_.X;
|
||||||
range.Y := point_.Y;
|
range.StartY := point_.Y;
|
||||||
range.W := w;
|
range.Width := w;
|
||||||
range.H := 0;
|
|
||||||
range.Calc();
|
range.Calc();
|
||||||
range.Do();
|
range.Do();
|
||||||
point_.Y := range.Y;
|
point_.Y := range.EndY;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,147 @@
|
||||||
|
type TSPdfCellRange = class(TSPdfBasicRange)
|
||||||
|
public
|
||||||
|
function Create(docx_to_pdf: TSDocxToPdf; pg: PdfPage; components: Components; sect_ware: TSSectWare; tc: Tc; tbl_pr: TblPr);
|
||||||
|
function Calc();
|
||||||
|
function AlignHeight(surplus: real);
|
||||||
|
function GetLastPage();
|
||||||
|
function Do();override;
|
||||||
|
|
||||||
|
private
|
||||||
|
docx_to_pdf_: TSDocxToPdf;
|
||||||
|
page_: PdfPage;
|
||||||
|
docx_components_: Components;
|
||||||
|
sect_ware_: TSSectWare;
|
||||||
|
tc_: Tc;
|
||||||
|
tbl_pr_: TblPr;
|
||||||
|
region_array_: array of Region; // 单元格可能跨页,所以可能存在多个
|
||||||
|
end;
|
||||||
|
|
||||||
|
type Region = class
|
||||||
|
function Create();
|
||||||
|
begin
|
||||||
|
RectangleRange := new TSPdfRectangleRange();
|
||||||
|
RangeArr := array();
|
||||||
|
end
|
||||||
|
|
||||||
|
RectangleRange: TSPdfRectangleRange;
|
||||||
|
RangeArr: array of TSPdfAbstractRange;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSPdfCellRange.Create(docx_to_pdf: TSDocxToPdf; pg: PdfPage; components: Components; sect_ware: TSSectWare; tc: Tc; tbl_pr: TblPr);
|
||||||
|
begin
|
||||||
|
docx_to_pdf_ := docx_to_pdf;
|
||||||
|
page_ := pg;
|
||||||
|
docx_components_ := components;
|
||||||
|
sect_ware_ := sect_ware;
|
||||||
|
tc_ := tc;
|
||||||
|
tbl_pr_ := tbl_pr;
|
||||||
|
region_array_ := array();
|
||||||
|
self.Page := page_;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSPdfCellRange.Calc();
|
||||||
|
begin
|
||||||
|
region := new Region();
|
||||||
|
region.RectangleRange.EndX := self.StartX;
|
||||||
|
region.RectangleRange.EndY := self.StartY;
|
||||||
|
region.RectangleRange.Width := self.Width;
|
||||||
|
region.RectangleRange.FixedHeight := self.FixedHeight;
|
||||||
|
region.RectangleRange.Page := page_;
|
||||||
|
region_array_[length(region_array_)] := region;
|
||||||
|
|
||||||
|
self.EndX := self.StartX;
|
||||||
|
self.EndY := self.StartY;
|
||||||
|
cell_x := self.EndX + tbl_pr_.TblCellMar.Left.W;
|
||||||
|
cell_y := self.EndY - tbl_pr_.TblCellMar.Top.W;
|
||||||
|
cell_w := self.Width - tbl_pr_.TblCellMar.Right.W - tbl_pr_.TblCellMar.Left.W;
|
||||||
|
cell_h := self.FixedHeight;
|
||||||
|
elements := tc_.Elements();
|
||||||
|
for _,element in elements do
|
||||||
|
begin
|
||||||
|
range := nil;
|
||||||
|
if element.LocalName = "p" then
|
||||||
|
begin
|
||||||
|
range := new TSPdfParagraphRange(docx_to_pdf_, page_, docx_components_, sect_ware_, element);
|
||||||
|
range.SetExtraStyleId(tbl_pr_.TblStyle.Val);
|
||||||
|
end
|
||||||
|
else if element.LocalName = "tbl" then
|
||||||
|
begin
|
||||||
|
range := new TSPdfTableRange(docx_to_pdf_, page_, docx_components_, sect_ware_, element);
|
||||||
|
end
|
||||||
|
if ifObj(range) then
|
||||||
|
begin
|
||||||
|
range.StartX := cell_x;
|
||||||
|
range.StartY := cell_y;
|
||||||
|
range.Width := cell_w;
|
||||||
|
range.FixedHeight := cell_h;
|
||||||
|
range.Calc();
|
||||||
|
region.RangeArr[length(region.RangeArr)] := range;
|
||||||
|
self.DynamicHeight += range.DynamicHeight;
|
||||||
|
cell_y -= range.DynamicHeight;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self.EndY := cell_y;
|
||||||
|
self.DynamicHeight += tbl_pr_.TblCellMar.Top.W + tbl_pr_.TblCellMar.Bottom.W;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSPdfCellRange.Do();override;
|
||||||
|
begin
|
||||||
|
for _,region in region_array_ do
|
||||||
|
begin
|
||||||
|
region.RectangleRange.Do();
|
||||||
|
for _,range in region.RangeArr do
|
||||||
|
range.Do();
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSPdfCellRange.AlignHeight(surplus: real);
|
||||||
|
begin
|
||||||
|
region := region_array_[0];
|
||||||
|
if surplus < 1e-6 then
|
||||||
|
begin
|
||||||
|
if region.RectangleRange.FixedHeight then region.RectangleRange.DynamicHeight := region.RectangleRange.FixedHeight;
|
||||||
|
self.EndY := self.StartY - region.RectangleRange.DynamicHeight;
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
region.RectangleRange.DynamicHeight := self.StartY - sect_ware_.SectPr.PgMar.Bottom;
|
||||||
|
arr := region.RangeArr;
|
||||||
|
region.RangeArr := array();
|
||||||
|
span := sect_ware_.SectPr.PgSz.H - sect_ware_.SectPr.PgMar.Top - sect_ware_.SectPr.PgMar.Bottom;
|
||||||
|
hash := array(region.RectangleRange.Page: region);
|
||||||
|
while surplus > span do
|
||||||
|
begin
|
||||||
|
page_ := docx_to_pdf_.GetNextPage(page_);
|
||||||
|
region := new Region();
|
||||||
|
region.RectangleRange.EndX := self.StartX;
|
||||||
|
region.RectangleRange.EndY := self.StartY;
|
||||||
|
region.RectangleRange.Width := self.Width;
|
||||||
|
region.RectangleRange.DynamicHeight := span;
|
||||||
|
region.Page := page_;
|
||||||
|
region_array_[length(region_array_)] := region;
|
||||||
|
surplus -= span;
|
||||||
|
hash[region.RectangleRange.Page] := region;
|
||||||
|
end
|
||||||
|
if surplus > 1e-6 then
|
||||||
|
begin
|
||||||
|
page_ := docx_to_pdf_.GetNextPage(page_);
|
||||||
|
region := new Region();
|
||||||
|
region.RectangleRange.EndX := self.StartX;
|
||||||
|
region.RectangleRange.EndY := sect_ware_.SectPr.PgSz.H - sect_ware_.SectPr.PgMar.Top;
|
||||||
|
region.RectangleRange.Width := self.Width;
|
||||||
|
region.RectangleRange.DynamicHeight := surplus;
|
||||||
|
region.RectangleRange.Page := page_;
|
||||||
|
region_array_[length(region_array_)] := region;
|
||||||
|
hash[region.RectangleRange.Page] := region;
|
||||||
|
self.EndY := region.RectangleRange.EndY - surplus;
|
||||||
|
end
|
||||||
|
for _,range in arr do
|
||||||
|
begin
|
||||||
|
region := hash[range.Page];
|
||||||
|
region.RangeArr[length(region.RangeArr)] := range;
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSPdfCellRange.GetLastPage();
|
||||||
|
begin
|
||||||
|
return page_;
|
||||||
|
end;
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
type TSPdfLineRange = class(TSPdfBasicRange)
|
||||||
|
public
|
||||||
|
function Create(pg: PdfPage);
|
||||||
|
function Do();override;
|
||||||
|
function AddRange(range: TSPdfBasicRange);
|
||||||
|
function SetAllRangeProp(pg: PdfPage; sx: real; sy: real; ex: real; ey: real; w: real; fh: real; dh: real);
|
||||||
|
function Align(jc: string);
|
||||||
|
|
||||||
|
private
|
||||||
|
range_array_: array of TSPdfBasicRange;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSPdfLineRange.Create(pg: PdfPage);
|
||||||
|
begin
|
||||||
|
self.Page := pg;
|
||||||
|
range_array_ := array();
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSPdfLineRange.AddRange(range: TSPdfBasicRange);
|
||||||
|
begin
|
||||||
|
range_array_[length(range_array_)] := range;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSPdfLineRange.Do();override;
|
||||||
|
begin
|
||||||
|
for _,range in range_array_ do
|
||||||
|
range.Do();
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSPdfLineRange.SetAllRangeProp(pg: PdfPage; sx: real; sy: real; ex: real; ey: real; w: real; fh: real; dh: real);
|
||||||
|
begin
|
||||||
|
for _,range in range_array_ do
|
||||||
|
begin
|
||||||
|
if not ifnil(pg) then range.Page := pg;
|
||||||
|
if not ifnil(sx) then range.StartX := sx;
|
||||||
|
if not ifnil(sy) then range.StartY := sy;
|
||||||
|
if not ifnil(ex) then range.EndX := ex;
|
||||||
|
if not ifnil(ey) then range.EndY := ey;
|
||||||
|
if not ifnil(w) then range.Width := w;
|
||||||
|
if not ifnil(fh) then range.FixedHeight := fh;
|
||||||
|
if not ifnil(dh) then range.DynamicHeight := dh;
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSPdfLineRange.Align(jc: string);
|
||||||
|
begin
|
||||||
|
offset := 0;
|
||||||
|
first := range_array_[0];
|
||||||
|
last := range_array_[length(range_array_)-1];
|
||||||
|
case jc of
|
||||||
|
"center":
|
||||||
|
offset := (self.Width - last.EndX + first.EndX - last.Width) / 2;
|
||||||
|
"right":
|
||||||
|
offset := self.Width - last.EndX + first.EndX - last.Width;
|
||||||
|
end;
|
||||||
|
if offset <= 0 then return;
|
||||||
|
for _,range in range_array_ do
|
||||||
|
range.EndX += offset;
|
||||||
|
end;
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
type TSPdfParagraphRange = class(TSPdfAbstractRange)
|
type TSPdfParagraphRange = class(TSPdfBasicRange)
|
||||||
public
|
public
|
||||||
function Create(docx_to_pdf: TSDocxToPdf; page: PdfPage; components: Components; sect_ware: TSSectWare; paragraph: P);
|
function Create(docx_to_pdf: TSDocxToPdf; pg: PdfPage; components: Components; sect_ware: TSSectWare; paragraph: P);
|
||||||
function Calc();
|
function Calc();
|
||||||
function Do();override;
|
function Do();override;
|
||||||
function SetExtraStyleId(style_id: string);
|
function SetExtraStyleId(style_id: string);
|
||||||
|
|
@ -21,6 +21,7 @@ private
|
||||||
function RToDrawingRange(r: R; ppr: PPr);
|
function RToDrawingRange(r: R; ppr: PPr);
|
||||||
function SetLinesAlignment(ppr: PPr);
|
function SetLinesAlignment(ppr: PPr);
|
||||||
function ResetCoordinates(ppr);
|
function ResetCoordinates(ppr);
|
||||||
|
function NewLineRange(): TSPdfLineRange;
|
||||||
|
|
||||||
private
|
private
|
||||||
docx_to_pdf_: TSDocxToPdf;
|
docx_to_pdf_: TSDocxToPdf;
|
||||||
|
|
@ -28,23 +29,22 @@ private
|
||||||
sect_ware_: TSSectWare;
|
sect_ware_: TSSectWare;
|
||||||
paragraph_: P;
|
paragraph_: P;
|
||||||
extra_style_id_: string;
|
extra_style_id_: string;
|
||||||
range_array_: array of TSPdfAbstractRange;
|
|
||||||
page_: PdfPage;
|
page_: PdfPage;
|
||||||
point_: TSPoint;
|
range_array_: array of TSPdfBasicRange;
|
||||||
lines_range_array_: tableArray;
|
line_range_array_: array of TSPdfLineRange;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSPdfParagraphRange.Create(docx_to_pdf: TSDocxToPdf; page: PdfPage; components: Components; sect_ware: TSSectWare; paragraph: P);
|
function TSPdfParagraphRange.Create(docx_to_pdf: TSDocxToPdf; pg: PdfPage; components: Components; sect_ware: TSSectWare; paragraph: P);
|
||||||
begin
|
begin
|
||||||
docx_to_pdf_ := docx_to_pdf;
|
docx_to_pdf_ := docx_to_pdf;
|
||||||
page_ := page;
|
page_ := pg;
|
||||||
docx_components_ := Components;
|
docx_components_ := Components;
|
||||||
sect_ware_ := sect_ware;
|
sect_ware_ := sect_ware;
|
||||||
paragraph_ := paragraph;
|
paragraph_ := paragraph;
|
||||||
extra_style_id_ := "";
|
extra_style_id_ := "";
|
||||||
range_array_ := array();
|
range_array_ := array();
|
||||||
point_ := new TSPoint(); // 动态记录段落的坐标位置
|
line_range_array_ := array();
|
||||||
lines_range_array_ := array();
|
self.Page := page_;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSPdfParagraphRange.Calc(): tableArray;
|
function TSPdfParagraphRange.Calc(): tableArray;
|
||||||
|
|
@ -53,16 +53,17 @@ begin
|
||||||
self.SetLvlText();
|
self.SetLvlText();
|
||||||
ppr := new PPrUnitDecorator(paragraph_.PPr);
|
ppr := new PPrUnitDecorator(paragraph_.PPr);
|
||||||
self.ResetCoordinates(ppr);
|
self.ResetCoordinates(ppr);
|
||||||
point_.X := self.X;
|
self.EndX := self.StartX;
|
||||||
point_.Y := self.Y;
|
self.EndY := self.StartY;
|
||||||
self.CheckAndAddPage(point_.Y, ppr.Spacing.Before);
|
self.CheckAndAddPage(self.EndY, ppr.Spacing.Before);
|
||||||
point_.Y -= ppr.Spacing.Before;
|
self.EndY -= ppr.Spacing.Before;
|
||||||
|
self.DynamicHeight += ppr.Spacing.Before;
|
||||||
rs := paragraph_.Rs();
|
rs := paragraph_.Rs();
|
||||||
if length(rs) = 0 then
|
if length(rs) = 0 then
|
||||||
begin
|
begin
|
||||||
line_space := self.GetParagraphLineSpace(ppr.RPr.Sz.Val, ppr.Spacing.Line);
|
line_space := self.GetParagraphLineSpace(ppr.RPr.Sz.Val, ppr.Spacing.Line);
|
||||||
if not self.H then self.H := ppr.Spacing.After + line_space;
|
self.DynamicHeight += ppr.Spacing.After + line_space;
|
||||||
point_.Y -= self.H;
|
self.EndY -= self.DynamicHeight;
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
for _, r in rs do
|
for _, r in rs do
|
||||||
|
|
@ -79,9 +80,8 @@ end;
|
||||||
|
|
||||||
function TSPdfParagraphRange.Do();
|
function TSPdfParagraphRange.Do();
|
||||||
begin
|
begin
|
||||||
for _,line_range in lines_range_array_ do
|
for _,line_range in line_range_array_ do
|
||||||
for _,range in line_range do
|
line_range.Do();
|
||||||
range.Do();
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSPdfParagraphRange.SetExtraStyleId(style_id: string);
|
function TSPdfParagraphRange.SetExtraStyleId(style_id: string);
|
||||||
|
|
@ -89,94 +89,80 @@ begin
|
||||||
extra_style_id_ := style_id;
|
extra_style_id_ := style_id;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TSPdfParagraphRange.NewLineRange(): TSPdfLineRange;
|
||||||
|
begin
|
||||||
|
line_range := new TSPdfLineRange(page_);
|
||||||
|
line_range.StartX := self.EndX;
|
||||||
|
line_range.StartY := self.EndY;
|
||||||
|
line_range.Width := self.Width;
|
||||||
|
return line_range;
|
||||||
|
end;
|
||||||
|
|
||||||
function TSPdfParagraphRange.RangesToLines(ppr: PPr);
|
function TSPdfParagraphRange.RangesToLines(ppr: PPr);
|
||||||
begin
|
begin
|
||||||
lines_range_array_ := array();
|
line_range := self.NewLineRange();
|
||||||
i := 0;
|
i := 0;
|
||||||
max_size := 0;
|
max_size := 0;
|
||||||
max_y := 0;
|
max_y := 0;
|
||||||
line_range := array();
|
|
||||||
total_height := 0;
|
|
||||||
while i <= length(range_array_)-1 do
|
while i <= length(range_array_)-1 do
|
||||||
begin
|
begin
|
||||||
range := range_array_[i];
|
range := range_array_[i];
|
||||||
if i = 0 then point_.X += ppr.Ind.FirstLine;
|
if i = 0 then self.EndX += ppr.Ind.FirstLine;
|
||||||
if range is class(TSPdfTextRange) and range.RPr.Sz.Val > max_size then
|
if range is class(TSPdfTextRange) and range.RPr.Sz.Val > max_size then
|
||||||
max_size := range.RPr.Sz.Val;
|
max_size := range.RPr.Sz.Val;
|
||||||
if range.H > max_y then max_y := range.H;
|
if range.DynamicHeight > max_y then max_y := range.DynamicHeight;
|
||||||
line_space := self.GetParagraphLineSpace(max_size, ppr.Spacing.Line);
|
line_space := self.GetParagraphLineSpace(max_size, ppr.Spacing.Line);
|
||||||
diff := point_.Y - sect_ware_.SectPr.PgMar.Bottom;
|
diff := self.EndY - sect_ware_.SectPr.PgMar.Bottom;
|
||||||
if self.CheckAndAddPage(point_.Y, max(line_space, range.H)) then
|
if self.CheckAndAddPage(self.EndY, max(line_space, range.DynamicHeight)) then
|
||||||
total_height += diff;
|
self.DynamicHeight += diff;
|
||||||
if_newline := point_.X + range.W - self.X > self.W + 1e-6;
|
if_newline := self.EndX + range.Width - self.StartX > self.Width + 1e-6;
|
||||||
if if_newline and range.W < self.W then
|
if if_newline and range.Width < self.Width then
|
||||||
begin
|
begin
|
||||||
offset := line_space > max_y ? (line_space - max_size) / 2 + max_size - max_size / 5 : max_y;
|
offset := line_space > max_y ? (line_space - max_size) / 2 + max_size - max_size / 5 : max_y;
|
||||||
for _,item in line_range do
|
|
||||||
begin
|
|
||||||
item.Page := page_;
|
|
||||||
item.Y := point_.Y - offset;
|
|
||||||
end
|
|
||||||
lines_range_array_[length(lines_range_array_)] := line_range;
|
|
||||||
line_range := array();
|
|
||||||
max_value := max(line_space, max_y);
|
max_value := max(line_space, max_y);
|
||||||
|
line_range.Page := page_;
|
||||||
|
line_range.EndY := self.EndY - max_value;
|
||||||
|
line_range.DynamicHeight := max_value;
|
||||||
|
line_range.SetAllRangeProp(pg: page_, ey: self.EndY - offset);
|
||||||
|
line_range_array_[length(line_range_array_)] := line_range;
|
||||||
|
|
||||||
|
line_range := self.NewLineRange();
|
||||||
max_size := 0;
|
max_size := 0;
|
||||||
max_y := 0;
|
max_y := 0;
|
||||||
total_height += max_value;
|
self.DynamicHeight += max_value;
|
||||||
point_.Y -= max_value;
|
self.EndY -= max_value;
|
||||||
point_.X := self.X;
|
self.EndX := self.StartX;
|
||||||
// w:hanging
|
// w:hanging
|
||||||
sz := range.RPr.SzCs.Val ? range.RPr.SzCs.Val : range.RPr.Sz.Val ? range.RPr.Sz.Val : docx_to_pdf_.Font.GetDefaultSz();
|
sz := range.RPr.SzCs.Val ? range.RPr.SzCs.Val : range.RPr.Sz.Val ? range.RPr.Sz.Val : docx_to_pdf_.Font.GetDefaultSz();
|
||||||
point_.X -= ppr.Ind.HangingChars ? ppr.Ind.HangingChars * sz : ppr.Ind.Hanging;
|
self.EndX -= ppr.Ind.HangingChars ? ppr.Ind.HangingChars * sz : ppr.Ind.Hanging;
|
||||||
continue;
|
continue;
|
||||||
end
|
end
|
||||||
range.X := point_.X - range.X;
|
range.EndX := self.EndX - range.StartX;
|
||||||
point_.X += range.W;
|
self.EndX += range.Width;
|
||||||
line_range[length(line_range)] := range;
|
line_range.AddRange(range);
|
||||||
i++;
|
i++;
|
||||||
if i = length(range_array_) then
|
if i = length(range_array_) then
|
||||||
begin
|
begin
|
||||||
offset := line_space > max_y ? (line_space - max_size) / 2 + max_size - max_size / 5 : max_y;
|
offset := line_space > max_y ? (line_space - max_size) / 2 + max_size - max_size / 5 : max_y;
|
||||||
for _,item in line_range do
|
|
||||||
begin
|
|
||||||
item.Page := page_;
|
|
||||||
item.Y := point_.Y - offset;
|
|
||||||
end
|
|
||||||
lines_range_array_[length(lines_range_array_)] := line_range;
|
|
||||||
max_value := max(line_space, max_y) + ppr.Spacing.After;
|
max_value := max(line_space, max_y) + ppr.Spacing.After;
|
||||||
total_height += max_value;
|
line_range.Page := page_;
|
||||||
point_.Y -= max_value;
|
line_range.EndY := self.EndY - max_value;
|
||||||
|
line_range.DynamicHeight := max_value;
|
||||||
|
line_range.SetAllRangeProp(pg: page_, ey: self.EndY - offset);
|
||||||
|
line_range_array_[length(line_range_array_)] := line_range;
|
||||||
|
self.DynamicHeight += max_value;
|
||||||
|
self.EndY -= max_value;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
self.SetLinesAlignment(ppr);
|
self.SetLinesAlignment(ppr);
|
||||||
if not self.H then self.H := total_height;
|
|
||||||
self.Y := point_.Y;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSPdfParagraphRange.SetLinesAlignment(ppr: PPr);
|
function TSPdfParagraphRange.SetLinesAlignment(ppr: PPr);
|
||||||
begin
|
begin
|
||||||
if length(lines_range_array_) = 0 then return;
|
if length(line_range_array_) = 0 then return;
|
||||||
idx := length(lines_range_array_)-1;
|
idx := length(line_range_array_)-1;
|
||||||
line := lines_range_array_[idx];
|
line_range := line_range_array_[idx];
|
||||||
offset := 0;
|
line_range.Align(ppr.Jc.Val);
|
||||||
case ppr.Jc.Val of
|
|
||||||
"center":
|
|
||||||
begin
|
|
||||||
first := line[0];
|
|
||||||
last := line[length(line)-1];
|
|
||||||
offset := (self.W - last.X + first.X - last.W) / 2;
|
|
||||||
end
|
|
||||||
"right":
|
|
||||||
begin
|
|
||||||
first := line[0];
|
|
||||||
last := line[length(line)-1];
|
|
||||||
offset := self.W - last.X + first.X - last.W;
|
|
||||||
end
|
|
||||||
end;
|
|
||||||
if offset < 0 then return;
|
|
||||||
if offset then
|
|
||||||
for i:=0 to length(line)-1 do
|
|
||||||
line[i].X += offset;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSPdfParagraphRange.CheckAndAddPage(y: real; offset: real): boolean;
|
function TSPdfParagraphRange.CheckAndAddPage(y: real; offset: real): boolean;
|
||||||
|
|
@ -186,7 +172,7 @@ begin
|
||||||
page_ := docx_to_pdf_.GetNextPage(page_);
|
page_ := docx_to_pdf_.GetNextPage(page_);
|
||||||
if ifnil(page_) then page_ := docx_to_pdf_.AddPage(sect_ware_);
|
if ifnil(page_) then page_ := docx_to_pdf_.AddPage(sect_ware_);
|
||||||
point := docx_to_pdf_.GetCurrentPoint();
|
point := docx_to_pdf_.GetCurrentPoint();
|
||||||
point_.Y := point.Y;
|
self.EndY := point.Y;
|
||||||
return true;
|
return true;
|
||||||
end
|
end
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -229,10 +215,7 @@ begin
|
||||||
text_range.RPr := rpr;
|
text_range.RPr := rpr;
|
||||||
text_range.Text := word;
|
text_range.Text := word;
|
||||||
text_range.Font := font_obj;
|
text_range.Font := font_obj;
|
||||||
text_range.W := word_width;
|
text_range.Width := word_width;
|
||||||
text_range.H := 0;
|
|
||||||
text_range.X := 0;
|
|
||||||
text_range.Y := 0;
|
|
||||||
range_array_[length(range_array_)] := text_range;
|
range_array_[length(range_array_)] := text_range;
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
@ -257,10 +240,10 @@ begin
|
||||||
end;
|
end;
|
||||||
image_range := new TSPdfImageRange();
|
image_range := new TSPdfImageRange();
|
||||||
image_range.Image := image;
|
image_range.Image := image;
|
||||||
image_range.X := xfrm.Off.X;
|
image_range.StartX := xfrm.Off.X;
|
||||||
image_range.Y := xfrm.Off.Y;
|
image_range.StartY := xfrm.Off.Y;
|
||||||
image_range.W := xfrm.Ext.CX;
|
image_range.Width := xfrm.Ext.CX;
|
||||||
image_range.H := xfrm.Ext.CY;
|
image_range.DynamicHeight := xfrm.Ext.CY;
|
||||||
fileDelete("", image_path);
|
fileDelete("", image_path);
|
||||||
range_array_[length(range_array_)] := image_range;
|
range_array_[length(range_array_)] := image_range;
|
||||||
end;
|
end;
|
||||||
|
|
@ -360,7 +343,7 @@ function TSPdfParagraphRange.ResetCoordinates(ppr);
|
||||||
begin
|
begin
|
||||||
// 根据段落的间距确定新的坐标
|
// 根据段落的间距确定新的坐标
|
||||||
sz := ppr.RPr.SzCs.Val ? ppr.RPr.SzCs.Val : ppr.RPr.Sz.Val ? ppr.RPr.Sz.Val : docx_to_pdf_.Font.GetDefaultSz();
|
sz := ppr.RPr.SzCs.Val ? ppr.RPr.SzCs.Val : ppr.RPr.Sz.Val ? ppr.RPr.Sz.Val : docx_to_pdf_.Font.GetDefaultSz();
|
||||||
self.X += ppr.Ind.LeftChars ? ppr.Ind.LeftChars * sz : ppr.Ind.Left;
|
self.StartX += ppr.Ind.LeftChars ? ppr.Ind.LeftChars * sz : ppr.Ind.Left;
|
||||||
self.W -= ppr.Ind.LeftChars ? ppr.Ind.LeftChars * sz : ppr.Ind.Left;
|
self.Width -= ppr.Ind.LeftChars ? ppr.Ind.LeftChars * sz : ppr.Ind.Left;
|
||||||
self.W -= ppr.Ind.RightChars ? ppr.Ind.RightChars * sz : ppr.Ind.Right;
|
self.Width -= ppr.Ind.RightChars ? ppr.Ind.RightChars * sz : ppr.Ind.Right;
|
||||||
end;
|
end;
|
||||||
|
|
@ -0,0 +1,187 @@
|
||||||
|
type TSPdfTableRange = class(TSPdfBasicRange)
|
||||||
|
public
|
||||||
|
function Create(docx_to_pdf: TSDocxToPdf; pg: PdfPage; components: Components; sect_ware: TSSectWare; paragraph: P);
|
||||||
|
function Calc();
|
||||||
|
function Do();override;
|
||||||
|
|
||||||
|
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);
|
||||||
|
function SetTrPrByStyleId(var tr_pr: TrPr; style_id: string);
|
||||||
|
function SetTcPr(var tc_pr: TcPr);
|
||||||
|
function SetTcPrByStyleId(var tc_pr: TcPr; style_id: string);
|
||||||
|
|
||||||
|
private
|
||||||
|
docx_to_pdf_: TSDocxToPdf;
|
||||||
|
docx_components_: Components;
|
||||||
|
sect_ware_: TSSectWare;
|
||||||
|
table_: Tbl;
|
||||||
|
range_array_: tableArray;
|
||||||
|
page_: PdfPage;
|
||||||
|
point_: TSPoint;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSPdfTableRange.Create(docx_to_pdf: TSDocxToPdf; pg: PdfPage; components: Components; sect_ware: TSSectWare; table: Tbl);
|
||||||
|
begin
|
||||||
|
docx_to_pdf_ := docx_to_pdf;
|
||||||
|
page_ := pg;
|
||||||
|
docx_components_ := Components;
|
||||||
|
sect_ware_ := sect_ware;
|
||||||
|
table_ := table;
|
||||||
|
range_array_ := array();
|
||||||
|
self.Page := page_;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSPdfTableRange.Calc();
|
||||||
|
begin
|
||||||
|
self.SetTblPr(table_.TblPr);
|
||||||
|
tbl_pr := new TblPrUnitDecorator(table_.TblPr);
|
||||||
|
grid_cols := table_.TblGrid.GridCols();
|
||||||
|
for i:=0 to length(grid_cols)-1 do
|
||||||
|
grid_cols[i] := new GridColUnitDecorator(grid_cols[i]);
|
||||||
|
self.ResetCoordinates(tbl_pr, grid_cols);
|
||||||
|
self.EndX := self.StartX;
|
||||||
|
self.EndY := self.StartY;
|
||||||
|
// 如果是根据内容自适应,应该计算并调整grid_cols的值
|
||||||
|
trs := table_.Trs();
|
||||||
|
for i,tr in trs do
|
||||||
|
range_array_[i] := self.ProcessTrData(grid_cols, tr, tbl_pr);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSPdfTableRange.Do();
|
||||||
|
begin
|
||||||
|
for _,row in range_array_ do
|
||||||
|
for _,range in row do
|
||||||
|
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);
|
||||||
|
tr_pr := new TrPrUnitDecorator(tr.TrPr);
|
||||||
|
height := tr_pr.TrHeight.Val;
|
||||||
|
tc_x := self.EndX;
|
||||||
|
tc_y := self.EndY;
|
||||||
|
tc_h := height;
|
||||||
|
max_height := 0;
|
||||||
|
cell_range_array := array();
|
||||||
|
tcs := tr.Tcs();
|
||||||
|
for i,tc in tcs do
|
||||||
|
begin
|
||||||
|
cell_range := new TSPdfCellRange(docx_to_pdf_, page_, docx_components_, sect_ware_, tc, tbl_pr);
|
||||||
|
cell_range.StartX := tc_x;
|
||||||
|
cell_range.StartY := tc_y;
|
||||||
|
cell_range.Width := grid_cols[i].W;
|
||||||
|
cell_range.FixedHeight := tc_h;
|
||||||
|
cell_range.Calc();
|
||||||
|
tc_x += grid_cols[i].W;
|
||||||
|
if cell_range.DynamicHeight > max_height then max_height := cell_range.DynamicHeight;
|
||||||
|
cell_range_array[length(cell_range_array)] := cell_range;
|
||||||
|
end
|
||||||
|
if tc_h > max_height then max_height := tc_h;
|
||||||
|
surplus := max_height - (self.EndY - sect_ware_.SectPr.PgMar.Bottom);
|
||||||
|
for _,range in cell_range_array do
|
||||||
|
begin
|
||||||
|
range.AlignHeight(surplus);
|
||||||
|
self.EndY := range.EndY; // 理论上每个range.EndY都是一个值
|
||||||
|
page_ := range.GetLastPage();
|
||||||
|
end
|
||||||
|
return cell_range_array;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSPdfTableRange.ResetCoordinates(tbl_pr: TblPr; grid_cols: array of GridCol);
|
||||||
|
begin
|
||||||
|
total_width := 0;
|
||||||
|
for _,grid_col in grid_cols do
|
||||||
|
total_width += grid_col.W;
|
||||||
|
diff := total_width - self.Width;
|
||||||
|
case tbl_pr.jc.Val of
|
||||||
|
"center":
|
||||||
|
begin
|
||||||
|
offset := diff/2;
|
||||||
|
self.StartX -= offset;
|
||||||
|
end
|
||||||
|
"right":
|
||||||
|
begin
|
||||||
|
self.StartX -= diff;
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
self.Width := total_width;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSPdfTableRange.SetTblPr(var tbl_pr: TblPr);
|
||||||
|
begin
|
||||||
|
new_tbl_pr := new TblPr();
|
||||||
|
self.SetTblPrByStyleId(new_tbl_pr, tbl_pr.TblStyle.Val);
|
||||||
|
new_tbl_pr.Copy(tbl_pr);
|
||||||
|
tbl_pr.Copy(new_tbl_pr);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSPdfTableRange.SetTblPrByStyleId(var tbl_pr: TblPr; style_id: string);
|
||||||
|
begin
|
||||||
|
styles := class(TSPdfSingletonKit).GetComponent(docx_components_, "styles_adapter");
|
||||||
|
style := styles.StyleId(style_id);
|
||||||
|
if ifObj(style) then
|
||||||
|
begin
|
||||||
|
based_on := style.BasedOn.Val;
|
||||||
|
self.SetTblPrByStyleId(tbl_pr, based_on);
|
||||||
|
tbl_pr.Copy(style.TblPr);
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSPdfTableRange.SetTrPr(var tr_pr: TrPr);
|
||||||
|
begin
|
||||||
|
new_tr_pr := new TrPr();
|
||||||
|
self.SetTrPrByStyleId(new_tr_pr, table_.TblPr.TblStyle.Val);
|
||||||
|
new_tr_pr.Copy(tr_pr);
|
||||||
|
tr_pr.Copy(new_tr_pr);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSPdfTableRange.SetTrPrByStyleId(var tr_pr: TrPr; style_id: string);
|
||||||
|
begin
|
||||||
|
styles := class(TSPdfSingletonKit).GetComponent(docx_components_, "styles_adapter");
|
||||||
|
style := styles.StyleId(style_id);
|
||||||
|
if ifObj(style) then
|
||||||
|
begin
|
||||||
|
based_on := style.BasedOn.Val;
|
||||||
|
self.SetTrPrByStyleId(tr_pr, based_on);
|
||||||
|
tr_pr.Copy(style.TrPr);
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSPdfTableRange.SetTcPr(var tc_pr: TcPr);
|
||||||
|
begin
|
||||||
|
new_tc_pr := new TcPr();
|
||||||
|
self.SetTcPrByStyleId(new_tc_pr, table_.TblPr.TblStyle.Val);
|
||||||
|
new_tc_pr.Copy(tc_pr);
|
||||||
|
tc_pr.Copy(new_tc_pr);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSPdfTableRange.SetTcPrByStyleId(var tc_pr: TcPr; style_id: string);
|
||||||
|
begin
|
||||||
|
styles := class(TSPdfSingletonKit).GetComponent(docx_components_, "styles_adapter");
|
||||||
|
style := styles.StyleId(style_id);
|
||||||
|
if ifObj(style) then
|
||||||
|
begin
|
||||||
|
based_on := style.BasedOn.Val;
|
||||||
|
self.SetTcPrByStyleId(tc_pr, based_on);
|
||||||
|
tc_pr.Copy(style.TcPr);
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
type TSPdfAbstractRange = class
|
|
||||||
public
|
|
||||||
function Do();virtual;
|
|
||||||
public
|
|
||||||
X: real;
|
|
||||||
Y: real; // range的起始坐标(x,y)
|
|
||||||
W: real; // range的宽度
|
|
||||||
H: real; // range的高度
|
|
||||||
|
|
||||||
end;
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
type TSPdfImageRange = class(TSPdfAbstractRange)
|
|
||||||
public
|
|
||||||
function Do();override;
|
|
||||||
public
|
|
||||||
Page: PdfPage;
|
|
||||||
Image: PdfImage;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TSPdfImageRange.Do();
|
|
||||||
begin
|
|
||||||
// println("image = {}, x = {}, y = {}, w = {}, h = {}", image, x, y, w, h);
|
|
||||||
self.Page.DrawImage(self.Image, self.X, self.Y, self.W, self.H);
|
|
||||||
|
|
||||||
if sysparams["_PDF_IMAGE_DEBUG_"] then
|
|
||||||
begin
|
|
||||||
self.Page.SetLineWidth(0.1);
|
|
||||||
self.Page.SetRGBStroke(0.8, 0.8, 0);
|
|
||||||
self.Page.Rectangle(X, Y, W, H);
|
|
||||||
self.Page.Stroke();
|
|
||||||
end
|
|
||||||
end;
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
type TSPdfRectRange = class(TSPdfAbstractRange)
|
|
||||||
public
|
|
||||||
function Do();override;
|
|
||||||
public
|
|
||||||
Page: PdfPage;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TSPdfRectRange.Do();override;
|
|
||||||
begin
|
|
||||||
// self.Page.SetRGBStroke(1.0, 0.0, 0.0);
|
|
||||||
self.Page.SetGrayStroke(0.5);
|
|
||||||
self.Page.SetLineWidth(0.5);
|
|
||||||
self.Page.Rectangle(self.X, self.Y - self.H, self.W, self.H);
|
|
||||||
self.Page.Stroke();
|
|
||||||
self.Page.SetGrayStroke(0);
|
|
||||||
end;
|
|
||||||
|
|
@ -1,273 +0,0 @@
|
||||||
type TSPdfTableRange = class(TSPdfAbstractRange)
|
|
||||||
public
|
|
||||||
function Create(docx_to_pdf: TSDocxToPdf; page: PdfPage; components: Components; sect_ware: TSSectWare; paragraph: P);
|
|
||||||
function Calc();
|
|
||||||
function Do();override;
|
|
||||||
|
|
||||||
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);
|
|
||||||
function SetTrPrByStyleId(var tr_pr: TrPr; style_id: string);
|
|
||||||
function SetTcPr(var tc_pr: TcPr);
|
|
||||||
function SetTcPrByStyleId(var tc_pr: TcPr; style_id: string);
|
|
||||||
|
|
||||||
private
|
|
||||||
docx_to_pdf_: TSDocxToPdf;
|
|
||||||
docx_components_: Components;
|
|
||||||
sect_ware_: TSSectWare;
|
|
||||||
table_: Tbl;
|
|
||||||
range_array_: tableArray;
|
|
||||||
page_: PdfPage;
|
|
||||||
point_: TSPoint;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TSPdfTableRange.Create(docx_to_pdf: TSDocxToPdf; page: PdfPage; components: Components; sect_ware: TSSectWare; table: Tbl);
|
|
||||||
begin
|
|
||||||
docx_to_pdf_ := docx_to_pdf;
|
|
||||||
page_ := page;
|
|
||||||
docx_components_ := Components;
|
|
||||||
sect_ware_ := sect_ware;
|
|
||||||
table_ := table;
|
|
||||||
range_array_ := array();
|
|
||||||
point_ := new TSPoint(); // 动态记录段落的坐标位置
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TSPdfTableRange.Calc();
|
|
||||||
begin
|
|
||||||
self.SetTblPr(table_.TblPr);
|
|
||||||
tbl_pr := new TblPrUnitDecorator(table_.TblPr);
|
|
||||||
grid_cols := table_.TblGrid.GridCols();
|
|
||||||
for i:=0 to length(grid_cols)-1 do
|
|
||||||
grid_cols[i] := new GridColUnitDecorator(grid_cols[i]);
|
|
||||||
self.ResetCoordinates(tbl_pr, grid_cols);
|
|
||||||
point_.X := self.X;
|
|
||||||
point_.Y := self.Y;
|
|
||||||
// 如果是根据内容自适应,应该计算并调整grid_cols的值
|
|
||||||
trs := table_.Trs();
|
|
||||||
for i,tr in trs do
|
|
||||||
range_array_[i] := self.ProcessTrData(grid_cols, tr, tbl_pr);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TSPdfTableRange.Do();
|
|
||||||
begin
|
|
||||||
for _,row in range_array_ do
|
|
||||||
for _,range in row do
|
|
||||||
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();
|
|
||||||
point_.Y := 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);
|
|
||||||
tr_pr := new TrPrUnitDecorator(tr.TrPr);
|
|
||||||
height := tr_pr.TrHeight.Val;
|
|
||||||
tcs := tr.Tcs();
|
|
||||||
tc_x := point_.X;
|
|
||||||
tc_y := point_.Y;
|
|
||||||
tc_h := height;
|
|
||||||
max_height := tc_h;
|
|
||||||
rows_range_array := array();
|
|
||||||
for i,tc in tcs do
|
|
||||||
begin
|
|
||||||
tc_w := grid_cols[i].W;
|
|
||||||
elements := tc.Elements();
|
|
||||||
rect_range := new TSPdfRectRange();
|
|
||||||
rect_range.X := tc_x;
|
|
||||||
rect_range.Y := tc_y;
|
|
||||||
rect_range.W := tc_w;
|
|
||||||
rect_range.H := tc_h;
|
|
||||||
rect_range.Page := page_;
|
|
||||||
rows_range_array[length(rows_range_array)] := rect_range;
|
|
||||||
|
|
||||||
cell_x := tc_x + tbl_pr.TblCellMar.Left.W;
|
|
||||||
cell_y := tc_y - tbl_pr.TblCellMar.Top.W;
|
|
||||||
cell_w := tc_w - tbl_pr.TblCellMar.Right.W - tbl_pr.TblCellMar.Left.W;
|
|
||||||
cell_total_h := 0;
|
|
||||||
for _,element in elements do
|
|
||||||
begin
|
|
||||||
range := nil;
|
|
||||||
if element.LocalName = "p" then
|
|
||||||
begin
|
|
||||||
range := new TSPdfParagraphRange(docx_to_pdf_, page_, docx_components_, sect_ware_, element);
|
|
||||||
range.SetExtraStyleId(tbl_pr.TblStyle.Val);
|
|
||||||
end
|
|
||||||
else if element.LocalName = "tbl" then
|
|
||||||
begin
|
|
||||||
range := new TSPdfTableRange(docx_to_pdf_, page_, docx_components_, sect_ware_, element);
|
|
||||||
end
|
|
||||||
if ifObj(range) then
|
|
||||||
begin
|
|
||||||
range.X := cell_x;
|
|
||||||
range.Y := cell_y;
|
|
||||||
range.W := cell_w;
|
|
||||||
range.H := tc_h;
|
|
||||||
range.Calc();
|
|
||||||
rows_range_array[length(rows_range_array)] := range;
|
|
||||||
cell_total_h += range.H;
|
|
||||||
cell_y -= range.H;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
tc_x += tc_w;
|
|
||||||
if cell_total_h > max_height then max_height := cell_total_h;
|
|
||||||
end
|
|
||||||
// 判定是否跨页
|
|
||||||
total_height := max_height + tbl_pr.TblCellMar.Top.W + tbl_pr.TblCellMar.Bottom.W;
|
|
||||||
surplus := total_height - (point_.Y - sect_ware_.SectPr.PgMar.Bottom);
|
|
||||||
if not self.H and surplus > 0 then
|
|
||||||
begin
|
|
||||||
for _,range in rows_range_array do
|
|
||||||
range.H := point_.Y - sect_ware_.SectPr.PgMar.Bottom;
|
|
||||||
span := sect_ware_.SectPr.PgSz.H - sect_ware_.SectPr.PgMar.Top - sect_ware_.SectPr.PgMar.Bottom;
|
|
||||||
quotient := surplus div span;
|
|
||||||
remainder := surplus % span;
|
|
||||||
page := page_;
|
|
||||||
tc_y := point_.Y;
|
|
||||||
i := 0;
|
|
||||||
while i < quotient do
|
|
||||||
begin
|
|
||||||
tc_x := point_.X;
|
|
||||||
tc_y := sect_ware_.SectPr.PgSz.H - sect_ware_.SectPr.PgMar.Top;
|
|
||||||
tc_h := tc_y - sect_ware_.SectPr.PgMar.Bottom;
|
|
||||||
page := docx_to_pdf_.GetNextPage(page);
|
|
||||||
for j:=0 to length(tcs)-1 do
|
|
||||||
begin
|
|
||||||
tc_w := grid_cols[i].W;
|
|
||||||
rect_range := new TSPdfRectRange();
|
|
||||||
rect_range.X := tc_x;
|
|
||||||
rect_range.Y := tc_y;
|
|
||||||
rect_range.W := tc_w;
|
|
||||||
rect_range.H := tc_h;
|
|
||||||
rect_range.Page := page;
|
|
||||||
tc_x += tc_w;
|
|
||||||
rows_range_array[length(rows_range_array)] := rect_range;
|
|
||||||
end
|
|
||||||
i++;
|
|
||||||
end
|
|
||||||
if remainder then
|
|
||||||
begin
|
|
||||||
tc_x := point_.X;
|
|
||||||
tc_y := sect_ware_.SectPr.PgSz.H - sect_ware_.SectPr.PgMar.Top;
|
|
||||||
tc_h := remainder;
|
|
||||||
page := docx_to_pdf_.GetNextPage(page);
|
|
||||||
for j:=0 to length(tcs)-1 do
|
|
||||||
begin
|
|
||||||
tc_w := grid_cols[i].W;
|
|
||||||
rect_range := new TSPdfRectRange();
|
|
||||||
rect_range.X := tc_x;
|
|
||||||
rect_range.Y := tc_y;
|
|
||||||
rect_range.W := tc_w;
|
|
||||||
rect_range.H := tc_h;
|
|
||||||
rect_range.Page := page;
|
|
||||||
tc_x += tc_w;
|
|
||||||
rows_range_array[length(rows_range_array)] := rect_range;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
point_.Y := tc_y - remainder;
|
|
||||||
self.Y := point_.Y;
|
|
||||||
page_ := page;
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
tc_h := tc_h ? tc_h : max_height;
|
|
||||||
for _,range in rows_range_array do
|
|
||||||
range.H := tc_h;
|
|
||||||
point_.Y -= tc_h;
|
|
||||||
self.Y := point_.Y;
|
|
||||||
end
|
|
||||||
return rows_range_array;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TSPdfTableRange.ResetCoordinates(tbl_pr: TblPr; grid_cols: array of GridCol);
|
|
||||||
begin
|
|
||||||
total_width := 0;
|
|
||||||
for _,grid_col in grid_cols do
|
|
||||||
total_width += grid_col.W;
|
|
||||||
diff := total_width - self.W;
|
|
||||||
case tbl_pr.jc.Val of
|
|
||||||
"center":
|
|
||||||
begin
|
|
||||||
offset := diff/2;
|
|
||||||
self.X -= offset;
|
|
||||||
end
|
|
||||||
"right":
|
|
||||||
begin
|
|
||||||
self.X -= diff;
|
|
||||||
end
|
|
||||||
end;
|
|
||||||
self.W := total_width;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TSPdfTableRange.SetTblPr(var tbl_pr: TblPr);
|
|
||||||
begin
|
|
||||||
new_tbl_pr := new TblPr();
|
|
||||||
self.SetTblPrByStyleId(new_tbl_pr, tbl_pr.TblStyle.Val);
|
|
||||||
new_tbl_pr.Copy(tbl_pr);
|
|
||||||
tbl_pr.Copy(new_tbl_pr);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TSPdfTableRange.SetTblPrByStyleId(var tbl_pr: TblPr; style_id: string);
|
|
||||||
begin
|
|
||||||
styles := class(TSPdfSingletonKit).GetComponent(docx_components_, "styles_adapter");
|
|
||||||
style := styles.StyleId(style_id);
|
|
||||||
if ifObj(style) then
|
|
||||||
begin
|
|
||||||
based_on := style.BasedOn.Val;
|
|
||||||
self.SetTblPrByStyleId(tbl_pr, based_on);
|
|
||||||
tbl_pr.Copy(style.TblPr);
|
|
||||||
end
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TSPdfTableRange.SetTrPr(var tr_pr: TrPr);
|
|
||||||
begin
|
|
||||||
new_tr_pr := new TrPr();
|
|
||||||
self.SetTrPrByStyleId(new_tr_pr, table_.TblPr.TblStyle.Val);
|
|
||||||
new_tr_pr.Copy(tr_pr);
|
|
||||||
tr_pr.Copy(new_tr_pr);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TSPdfTableRange.SetTrPrByStyleId(var tr_pr: TrPr; style_id: string);
|
|
||||||
begin
|
|
||||||
styles := class(TSPdfSingletonKit).GetComponent(docx_components_, "styles_adapter");
|
|
||||||
style := styles.StyleId(style_id);
|
|
||||||
if ifObj(style) then
|
|
||||||
begin
|
|
||||||
based_on := style.BasedOn.Val;
|
|
||||||
self.SetTrPrByStyleId(tr_pr, based_on);
|
|
||||||
tr_pr.Copy(style.TrPr);
|
|
||||||
end
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TSPdfTableRange.SetTcPr(var tc_pr: TcPr);
|
|
||||||
begin
|
|
||||||
new_tc_pr := new TcPr();
|
|
||||||
self.SetTcPrByStyleId(new_tc_pr, table_.TblPr.TblStyle.Val);
|
|
||||||
new_tc_pr.Copy(tc_pr);
|
|
||||||
tc_pr.Copy(new_tc_pr);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TSPdfTableRange.SetTcPrByStyleId(var tc_pr: TcPr; style_id: string);
|
|
||||||
begin
|
|
||||||
styles := class(TSPdfSingletonKit).GetComponent(docx_components_, "styles_adapter");
|
|
||||||
style := styles.StyleId(style_id);
|
|
||||||
if ifObj(style) then
|
|
||||||
begin
|
|
||||||
based_on := style.BasedOn.Val;
|
|
||||||
self.SetTcPrByStyleId(tc_pr, based_on);
|
|
||||||
tc_pr.Copy(style.TcPr);
|
|
||||||
end
|
|
||||||
end;
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
type TSPdfBasicRange = class
|
||||||
|
public
|
||||||
|
function Create();
|
||||||
|
function Do();virtual;
|
||||||
|
|
||||||
|
public
|
||||||
|
StartX: real;
|
||||||
|
StartY: real; // range的起始坐标(x,y)
|
||||||
|
EndX: real;
|
||||||
|
EndY: real; // range的结束坐标(x,y)
|
||||||
|
Width: real;
|
||||||
|
FixedHeight: real;
|
||||||
|
DynamicHeight: real;
|
||||||
|
Page: PdfPage;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSPdfBasicRange.Create();
|
||||||
|
begin
|
||||||
|
self.StartX := 0;
|
||||||
|
self.StartY := 0;
|
||||||
|
self.EndX := 0;
|
||||||
|
self.EndY := 0;
|
||||||
|
self.Width := 0;
|
||||||
|
self.FixedHeight := 0;
|
||||||
|
self.DynamicHeight := 0;
|
||||||
|
self.Page := nil;
|
||||||
|
end;
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
type TSPdfImageRange = class(TSPdfBasicRange)
|
||||||
|
public
|
||||||
|
function Create();
|
||||||
|
function Do();override;
|
||||||
|
|
||||||
|
public
|
||||||
|
Image: PdfImage;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSPdfImageRange.Create();
|
||||||
|
begin
|
||||||
|
class(TSPdfBasicRange).Create();
|
||||||
|
self.Image := nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSPdfImageRange.Do();
|
||||||
|
begin
|
||||||
|
// println("image = {}, x = {}, y = {}, w = {}, h = {}", self.image, self.endx, self.endy, self.width, self.DynamicHeight);
|
||||||
|
self.Page.DrawImage(self.Image, self.EndX, self.EndY, self.Width, self.DynamicHeight);
|
||||||
|
|
||||||
|
if sysparams["_PDF_IMAGE_DEBUG_"] then
|
||||||
|
begin
|
||||||
|
self.Page.SetLineWidth(0.1);
|
||||||
|
self.Page.SetRGBStroke(0.8, 0.8, 0);
|
||||||
|
self.Page.Rectangle(self.EndX, self.EndY, self.Width, self.DynamicHeight);
|
||||||
|
self.Page.Stroke();
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
type TSPdfRectangleRange = class(TSPdfBasicRange)
|
||||||
|
public
|
||||||
|
function Create();
|
||||||
|
function Do();override;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSPdfRectangleRange.Create();
|
||||||
|
begin
|
||||||
|
class(TSPdfBasicRange).Create();
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSPdfRectangleRange.Do();override;
|
||||||
|
begin
|
||||||
|
// self.Page.SetRGBStroke(1.0, 0.0, 0.0);
|
||||||
|
// println("page = {}, endx = {}, endy = {}, DynamicHeight = {}, Width = {}", self.Page, self.EndX, self.EndY, self.DynamicHeight, self.Width);
|
||||||
|
self.Page.SetGrayStroke(0.5);
|
||||||
|
self.Page.SetLineWidth(0.5);
|
||||||
|
self.Page.Rectangle(self.EndX, self.EndY - self.DynamicHeight, self.Width, self.DynamicHeight);
|
||||||
|
self.Page.Stroke();
|
||||||
|
self.Page.SetGrayStroke(0);
|
||||||
|
end;
|
||||||
|
|
@ -1,23 +1,32 @@
|
||||||
type TSPdfTextRange = class(TSPdfAbstractRange)
|
type TSPdfTextRange = class(TSPdfBasicRange)
|
||||||
uses TSColorToolKit;
|
uses TSColorToolKit;
|
||||||
public
|
public
|
||||||
|
function Create();
|
||||||
function Do();override;
|
function Do();override;
|
||||||
|
|
||||||
public
|
public
|
||||||
RPr: RPr;
|
RPr: RPr;
|
||||||
Text: string;
|
Text: string;
|
||||||
Font: PdfFont;
|
Font: PdfFont;
|
||||||
Page: PdfPage;
|
end;
|
||||||
|
|
||||||
|
function TSPdfTextRange.Create();
|
||||||
|
begin
|
||||||
|
class(TSPdfBasicRange).Create();
|
||||||
|
self.RPr := nil;
|
||||||
|
self.Text := "";
|
||||||
|
self.Font := nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSPdfTextRange.Do();
|
function TSPdfTextRange.Do();
|
||||||
begin
|
begin
|
||||||
// println("text = {}, x = {}, y = {}, w = {}, sz = {}", ansiToUtf8(text), x, y, w);
|
// println("text = {}, endx = {}, endy = {}, width = {}, page = {}", ansiToUtf8(text), endx, endy, width, page);
|
||||||
[r, g, b] := array(0, 0, 0);
|
[r, g, b] := array(0, 0, 0);
|
||||||
if self.RPr.Color.Val then [r, g, b] := TSColorToolKit.HexToRGB(self.RPr.Color.Val);
|
if self.RPr.Color.Val then [r, g, b] := TSColorToolKit.HexToRGB(self.RPr.Color.Val);
|
||||||
self.Page.SetRGBFill(r / 255, g / 255, b / 255);
|
self.Page.SetRGBFill(r / 255, g / 255, b / 255);
|
||||||
self.Page.SetFontAndSize(self.Font, self.RPr.Sz.Val);
|
self.Page.SetFontAndSize(self.Font, self.RPr.Sz.Val);
|
||||||
self.Page.BeginText();
|
self.Page.BeginText();
|
||||||
self.Page.TextOut(self.X, self.Y, self.Text);
|
self.Page.TextOut(self.EndX, self.EndY, self.Text);
|
||||||
self.Page.EndText();
|
self.Page.EndText();
|
||||||
self.Page.SetRGBFill(0, 0, 0);
|
self.Page.SetRGBFill(0, 0, 0);
|
||||||
|
|
||||||
|
|
@ -26,8 +35,8 @@ if sysparams["_PDF_TEXT_DEBUG_"] then
|
||||||
begin
|
begin
|
||||||
self.Page.SetLineWidth(0.1);
|
self.Page.SetLineWidth(0.1);
|
||||||
self.Page.SetRGBStroke(1.0, 0.5, 0.0);
|
self.Page.SetRGBStroke(1.0, 0.5, 0.0);
|
||||||
self.Page.MoveTo(0, self.Y);
|
self.Page.MoveTo(0, self.EndY);
|
||||||
self.Page.LineTo(600, self.Y);
|
self.Page.LineTo(600, self.EndY);
|
||||||
self.Page.Stroke();
|
self.Page.Stroke();
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
Loading…
Reference in New Issue