644 lines
24 KiB
Plaintext
644 lines
24 KiB
Plaintext
type TSPdfParagraphRange = class(TSPdfBasicRange)
|
||
public
|
||
function Create(docx_to_pdf: TSDocxToPdf; pg: TSPage; components: TSDocxComponentsWare; paragraph: P);
|
||
function Calc();
|
||
function Do();override;
|
||
function SetExtraStyleId(style_id: string);
|
||
function SetNumPages(num: integer);
|
||
function RangesToLines();
|
||
|
||
private
|
||
function SetPPr(var ppr: PPr);
|
||
function SetPPrByStyleId(var ppr: PPr; style_id: string);
|
||
function SetRPr(var rpr; ppr: PPrUnitDecorator);
|
||
function SetRPrByStyleId(var rpr: RPr; style_id: string);
|
||
function SetLvlText();
|
||
function GetImageFileType(data: binary): string;
|
||
function GetImageData(id: string): PdfImage;
|
||
function GetParagraphLineSpace(size: real; line: integer): real;
|
||
function BasicRangesToLineRange(): tableArray;
|
||
function CheckAndAddPage(y: real; offset: real): boolean;
|
||
function GetUtf8CharLength(byte: string): integer;
|
||
function RToTextRange(r: R; link: string);
|
||
function SplitTextToTextRange(text: string; rpr: RPrUnitDecorator; link: string);
|
||
function RToDrawingRange(r: R);
|
||
function RAlternateContentToRange(r: R);
|
||
function SetLinesAlignment();
|
||
function ResetCoordinates();
|
||
function NewLineRange(): TSPdfLineRange;
|
||
function BookMarkLinkToc();
|
||
function HyperlinkToToc();
|
||
function HyperlinkToTextRange(hyperlink: Hyperlink; ppr: PPrUnitDecorator);
|
||
function GetXYCordinates(): array of real;
|
||
|
||
private
|
||
[weakref]docx_to_pdf_: TSDocxToPdf;
|
||
[weakref]docx_components_ware_: TSDocxComponentsWare;
|
||
[weakref]paragraph_: P;
|
||
[weakref]page_: TSPage;
|
||
extra_style_id_: string;
|
||
range_array_: array of TSPdfBasicRange;
|
||
line_range_array_: array of TSPdfLineRange;
|
||
hyperlink_array_: tableArray;
|
||
bookmark_array_: tableArray;
|
||
ppr_unit_decorator_: PPrUnitDecorator;
|
||
placeholder_array_: tableArray;
|
||
end;
|
||
|
||
function TSPdfParagraphRange.Create(docx_to_pdf: TSDocxToPdf; pg: TSPage; components: TSDocxComponentsWare; paragraph: P);
|
||
begin
|
||
docx_to_pdf_ := docx_to_pdf;
|
||
page_ := pg;
|
||
docx_components_ware_ := components;
|
||
paragraph_ := paragraph;
|
||
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_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;
|
||
{self.}CheckAndAddPage({self.}EndY, ppr_unit_decorator_.Spacing.Before);
|
||
{self.}EndY -= ppr_unit_decorator_.Spacing.Before;
|
||
{self.}DynamicHeight += ppr_unit_decorator_.Spacing.Before;
|
||
|
||
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_unit_decorator_);
|
||
if element.FldChar.FldCharType = "begin" then
|
||
continue;
|
||
else if element.FldChar.FldCharType = "separate" then
|
||
fld := true;
|
||
else if element.FldChar.FldCharType = "end" then
|
||
fld := false;
|
||
else if ifString(element.InstrText.Text) and trim(element.InstrText.Text) = "PAGE \\* Arabic \\* MERGEFORMAT" then
|
||
page_number := true;
|
||
else if ifString(element.InstrText.Text) and trim(element.InstrText.Text) = "NUMPAGES" then
|
||
numpages := true;
|
||
else if fld and page_number then
|
||
begin
|
||
element.T.Text := tostring(page_.Number);
|
||
{self.}RToTextRange(element, nil);
|
||
page_number := false;
|
||
end
|
||
else if fld and numpages then
|
||
begin
|
||
rpr := new RPrUnitDecorator(element.RPr);
|
||
numpages_index := length(range_array_);
|
||
placeholder_array_ := array(numpages_index, rpr);
|
||
numpages := false;
|
||
end
|
||
else if element.Br.Type = "page" then
|
||
{self.}CheckAndAddPage({self.}LowerBound, 1);
|
||
else if ifObj(element.Drawing.XmlNode) then {self.}RToDrawingRange(element);
|
||
else if ifObj(element.AlternateContent.XmlNode) then {self.}RAlternateContentToRange(element);
|
||
else if not fld then {self.}RToTextRange(element, bookmark_name);
|
||
end
|
||
else if element.LocalName = "fldSimple" then
|
||
begin
|
||
if ifString(element.Instr) and trim(element.Instr) = "NUMPAGES \\* Arabic \\* MERGEFORMAT" then
|
||
begin
|
||
rpr := new RPrUnitDecorator(element.Rs(0).RPr);
|
||
numpages_index := length(range_array_);
|
||
placeholder_array_ := array(numpages_index, rpr);
|
||
numpages := false;
|
||
end
|
||
end
|
||
else if element.LocalName = "hyperlink" then
|
||
begin
|
||
empty_flag := false;
|
||
{self.}HyperlinkToTextRange(element, ppr_unit_decorator_);
|
||
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_unit_decorator_.RPr.Sz.Val, ppr_unit_decorator_.Spacing.Line);
|
||
{self.}DynamicHeight += line_space;
|
||
{self.}EndY -= {self.}DynamicHeight;
|
||
end
|
||
if placeholder_array_ then return false;
|
||
{self.}RangesToLines();
|
||
if hyperlink_array_ then {self.}HyperlinkToToc();
|
||
if bookmark_array_ then {self.}BookMarkLinkToc();
|
||
return true;
|
||
end;
|
||
|
||
function TSPdfParagraphRange.SetNumPages(num: integer);
|
||
begin
|
||
text := tostring(num);
|
||
last_index := length(range_array_);
|
||
{self.}SplitTextToTextRange(text, placeholder_array_[1], link);
|
||
arr := array();
|
||
len := length(range_array_);
|
||
for i:=last_index to len-1 do
|
||
arr[length(arr)] := range_array_[i];
|
||
diff := len - last_index;
|
||
for i:=len-1 downto placeholder_array_[0] do
|
||
range_array_[i] := range_array_[i-diff];
|
||
k := 0;
|
||
for i:=placeholder_array_[0] to placeholder_array_[0]+diff-1 do
|
||
range_array_[i] := arr[k++];
|
||
end;
|
||
|
||
function TSPdfParagraphRange.BookMarkLinkToc();
|
||
begin
|
||
for name,arr in bookmark_array_ do
|
||
if arr[0] then docx_to_pdf_.LinkToToc(name, arr[0].TSPage, arr[0].EndX, arr[0].EndY + arr[0].RPr.Sz.Val);
|
||
end;
|
||
|
||
function TSPdfParagraphRange.HyperlinkToToc();
|
||
begin
|
||
ppr := ppr_unit_decorator_;
|
||
max_size := 0;
|
||
for anchor,arr in hyperlink_array_ do // 整理hyperlink发送到docx_to_pdf_
|
||
begin
|
||
pg := arr[0].TSPage;
|
||
left := {self.}StartX;
|
||
right := {self.}StartX + {self.}Width;
|
||
top := {self.}StartY;
|
||
bottom := {self.}StartY;
|
||
x := arr[0].EndX;
|
||
y := arr[0].EndY;
|
||
if top - {self.}GetParagraphLineSpace(arr[0].RPr.Sz.Val, ppr.Spacing.Line) then
|
||
begin
|
||
top := docx_to_pdf_.GetCurrentTextPoint().Y;
|
||
bottom := top;
|
||
end
|
||
for _,range in arr do
|
||
begin
|
||
if x + range.Width - {self.}StartX > {self.}Width + 1e-6 then // 换行
|
||
begin
|
||
line_space := {self.}GetParagraphLineSpace(max_size, ppr.Spacing.Line);
|
||
bottom -= line_space;
|
||
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
|
||
if range.RPr.Sz.Val > max_size then max_size := range.RPr.Sz.Val;
|
||
x := range.EndX + range.Width;
|
||
y := range.EndY;
|
||
end
|
||
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);
|
||
line_space := {self.}GetParagraphLineSpace(max_size, ppr.Spacing.Line);
|
||
pg.PdfPage.SetFontAndSize(font_obj, max_size);
|
||
bottom -= line_space;
|
||
num_width := pg.PdfPage.TextWidth("." + tostring(pg.Number));
|
||
if x + num_width - {self.}StartX > {self.}Width + 1e-6 then // 换行
|
||
begin
|
||
offset := (line_space - max_size) / 2 + max_size - max_size / 5;
|
||
diff := {self.}EndY - {self.}LowerBound;
|
||
if {self.}CheckAndAddPage({self.}EndY, line_space) then
|
||
begin
|
||
{self.}DynamicHeight += diff;
|
||
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
|
||
else begin
|
||
bottom -= line_space;
|
||
x := {self.}StartX;
|
||
y := {self.}EndY - offset;
|
||
{self.}EndY -= line_space;
|
||
{self.}DynamicHeight += line_space;
|
||
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;
|
||
|
||
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_unit_decorator_);
|
||
{self.}RToTextRange(r, 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();
|
||
end;
|
||
|
||
function TSPdfParagraphRange.SetExtraStyleId(style_id: string);
|
||
begin
|
||
extra_style_id_ := style_id;
|
||
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();overload;
|
||
begin
|
||
{self.}BasicRangesToLineRange();
|
||
{self.}DynamicHeight += ppr_unit_decorator_.Spacing.After;
|
||
{self.}EndY -= ppr_unit_decorator_.Spacing.After;
|
||
if ppr_unit_decorator_.PBdr.Bottom.Val = "single" then
|
||
begin
|
||
sect_ware := docx_to_pdf_.GetCurrentSectWare();
|
||
page_.PdfPage.SetLineWidth(0.05);
|
||
page_.PdfPage.SetGrayStroke(0.25);
|
||
page_.PdfPage.MoveTo(sect_ware.SectPr.PgMar.Left, {self.}EndY);
|
||
page_.PdfPage.LineTo(sect_ware.SectPr.PgSz.W - sect_ware.SectPr.PgMar.Right, {self.}EndY);
|
||
page_.PdfPage.Stroke();
|
||
end
|
||
end;
|
||
|
||
function TSPdfParagraphRange.BasicRangesToLineRange();
|
||
begin
|
||
ppr := ppr_unit_decorator_;
|
||
line_range := {self.}NewLineRange();
|
||
i := 0;
|
||
max_size := 0;
|
||
max_y := 0;
|
||
while i <= length(range_array_)-1 do
|
||
begin
|
||
range := range_array_[i];
|
||
if i = 0 then {self.}EndX += ppr.Ind.FirstLine;
|
||
if range is class(TSPdfTextRange) and range.RPr.Sz.Val > max_size then
|
||
max_size := range.RPr.Sz.Val;
|
||
if range.DynamicHeight > max_y then max_y := range.DynamicHeight;
|
||
line_space := {self.}GetParagraphLineSpace(max_size, ppr.Spacing.Line);
|
||
diff := {self.}EndY - {self.}LowerBound;
|
||
if {self.}CheckAndAddPage({self.}EndY, max(line_space, range.DynamicHeight)) then
|
||
{self.}DynamicHeight += diff;
|
||
if_newline := {self.}EndX + range.Width - {self.}StartX > {self.}Width + 1e-6;
|
||
if if_newline and range.Width < {self.}Width then
|
||
begin
|
||
offset := line_space > max_y ? (line_space - max_size) / 2 + max_size - max_size / 5 : max_y;
|
||
max_value := max(line_space, max_y);
|
||
line_range.TSPage := 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_y := 0;
|
||
{self.}DynamicHeight += max_value;
|
||
{self.}EndY -= max_value;
|
||
{self.}EndX := {self.}StartX;
|
||
// w:hanging
|
||
sz := range.RPr.SzCs.Val ? range.RPr.SzCs.Val : range.RPr.Sz.Val ? range.RPr.Sz.Val : docx_to_pdf_.Font.GetDefaultSz();
|
||
{self.}EndX -= ppr.Ind.HangingChars ? ppr.Ind.HangingChars * sz : ppr.Ind.Hanging;
|
||
continue;
|
||
end
|
||
range.EndX := {self.}EndX - range.StartX;
|
||
{self.}EndX += range.Width;
|
||
line_range.AddRange(range);
|
||
i++;
|
||
if i = length(range_array_) then
|
||
begin
|
||
offset := line_space > max_y ? (line_space - max_size) / 2 + max_size - max_size / 5 : max_y;
|
||
max_value := max(line_space, max_y);
|
||
line_range.TSPage := 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;
|
||
{self.}DynamicHeight += max_value;
|
||
{self.}EndY -= max_value;
|
||
end
|
||
end
|
||
{self.}SetLinesAlignment();
|
||
end;
|
||
|
||
function TSPdfParagraphRange.SetLinesAlignment();
|
||
begin
|
||
if length(line_range_array_) = 0 then return;
|
||
idx := length(line_range_array_)-1;
|
||
line_range := line_range_array_[idx];
|
||
line_range.Align(ppr_unit_decorator_.Jc.Val);
|
||
end;
|
||
|
||
function TSPdfParagraphRange.CheckAndAddPage(y: real; offset: real): boolean;
|
||
begin
|
||
if y - offset < {self.}LowerBound then
|
||
begin
|
||
page_ := docx_to_pdf_.GetNextPage(page_);
|
||
if ifnil(page_) then page_ := docx_to_pdf_.AddTSPage();
|
||
point := docx_to_pdf_.GetCurrentTextPoint();
|
||
{self.}EndY := point.Y;
|
||
return true;
|
||
end
|
||
return false;
|
||
end;
|
||
|
||
function TSPdfParagraphRange.GetUtf8CharLength(byte: string): integer;
|
||
begin
|
||
if (_and(ord(byte), 0b10000000)) = 0 then
|
||
return 1;
|
||
else if (_and(ord(byte), 0b11100000)) = 0b11000000 then
|
||
return 2;
|
||
else if (_and(ord(byte), 0b11110000)) = 0b11100000 then
|
||
return 3;
|
||
else if (_and(ord(byte), 0b11111000)) = 0b11110000 then
|
||
return 4;
|
||
end;
|
||
|
||
function TSPdfParagraphRange.RToTextRange(r: R; link: string);
|
||
begin
|
||
if r.Anchor then
|
||
begin
|
||
{self.}HyperlinkToTextRange(r);
|
||
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: RPrUnitDecorator; link: string);
|
||
begin
|
||
pos := 1;
|
||
while pos <= length(text) do
|
||
begin
|
||
num := {self.}GetUtf8CharLength(text[pos]);
|
||
word := text[pos : pos+num-1];
|
||
word := utf8ToAnsi(word);
|
||
pos += num;
|
||
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();
|
||
page_.PdfPage.SetFontAndSize(font_obj, rpr.Sz.Val);
|
||
word_width := page_.PdfPage.TextWidth(word);
|
||
text_range := new TSPdfTextRange();
|
||
text_range.RPr := rpr;
|
||
text_range.Text := word;
|
||
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);
|
||
begin
|
||
if ifObj(r.Drawing._Inline.XmlNode) then
|
||
begin
|
||
id := r.Drawing._Inline.Graphic.GraphicData.Pic.BlipFill.Blip.Embed;
|
||
image := {self.}GetImageData(id);
|
||
if not image then return;
|
||
xfrm := new XfrmUnitDecorator(r.Drawing._Inline.Graphic.GraphicData.Pic.SpPr.Xfrm);
|
||
image_range := new TSPdfImageRange();
|
||
image_range.Image := image;
|
||
image_range.StartX := xfrm.Off.X;
|
||
image_range.StartY := xfrm.Off.Y;
|
||
image_range.Width := xfrm.Ext.CX;
|
||
image_range.DynamicHeight := xfrm.Ext.CY;
|
||
range_array_[length(range_array_)] := image_range;
|
||
end
|
||
else if ifObj(r.Drawing.Anchor.XmlNode) then
|
||
begin
|
||
anchor := r.Drawing.Anchor;
|
||
id := anchor.Graphic.GraphicData.Pic.BlipFill.Blip.Embed;
|
||
image := {self.}GetImageData(id);
|
||
if not image then return;
|
||
[x, y] := {self.}GetXYCordinates();
|
||
xfrm := new XfrmUnitDecorator(anchor.Graphic.GraphicData.Pic.SpPr.Xfrm);
|
||
position_h := new PositionHUnitDecorator(anchor.PositionH);
|
||
position_v := new PositionVUnitDecorator(anchor.PositionV);
|
||
image_range := new TSPdfImageRange();
|
||
image_range.Image := image;
|
||
image_range.EndX := x + position_h.PosOffset.Text;
|
||
image_range.EndY := y - position_v.PosOffset.Text - xfrm.Ext.CY;
|
||
image_range.Width := xfrm.Ext.CX;
|
||
image_range.DynamicHeight := xfrm.Ext.CY;
|
||
image_range.TSPage := page_;
|
||
image_range.Do();
|
||
end
|
||
end;
|
||
|
||
function TSPdfParagraphRange.RAlternateContentToRange(r: R);
|
||
begin
|
||
anchor := r.AlternateContent.Choice.Drawing.Anchor;
|
||
wsp := anchor.Graphic.GraphicData.Wsp;
|
||
[x, y] := {self.}GetXYCordinates();
|
||
xfrm := new XfrmUnitDecorator(wsp.SpPr.Xfrm);
|
||
position_h := new PositionHUnitDecorator(anchor.PositionH);
|
||
position_v := new PositionVUnitDecorator(anchor.PositionV);
|
||
x += position_h.PosOffset.Text;
|
||
y -= position_v.PosOffset.Text;
|
||
w := xfrm.Ext.CX;
|
||
body_pr := new BodyPrUnitDecorator(wsp.BodyPr);
|
||
x += body_pr.LIns;
|
||
w -= (body_pr.LIns + body_pr.RIns);
|
||
ps := wsp.Txbx.TxbxContent.Ps();
|
||
for _,p in ps do
|
||
begin
|
||
range := new TSPdfParagraphRange(docx_to_pdf_, page_, docx_components_ware_, p);
|
||
range.StartX := x;
|
||
range.StartY := y;
|
||
range.Width := w;
|
||
range.Calc();
|
||
range.Do();
|
||
y := range.EndY;
|
||
end
|
||
end;
|
||
|
||
function TSPdfParagraphRange.GetXYCordinates(): array of real;
|
||
begin
|
||
xml_file := docx_to_pdf_.GetCurrentXmlFile();
|
||
if xml_file = "document.xml" then
|
||
[x, y] := docx_to_pdf_.CalculateTextCoordinates();
|
||
else begin
|
||
sect_ware := docx_to_pdf_.GetCurrentSectWare();
|
||
x := sect_ware.SectPr.PgMar.Left;
|
||
if ansiContainsStr(xml_file, "footer") then
|
||
y := sect_ware.SectPr.PgMar.Bottom;
|
||
else if ansiContainsStr(xml_file, "header") then
|
||
y := sect_ware.SectPr.PgSz.H - sect_ware.SectPr.PgMar.Header;
|
||
end
|
||
return array(x, y);
|
||
end;
|
||
|
||
function TSPdfParagraphRange.GetImageData(id: string): PdfImage;
|
||
begin
|
||
xml_file := docx_to_pdf_.GetCurrentXmlFile();
|
||
if xml_file = "document.xml" then
|
||
rels_adapter := docx_components_ware_.GetDocumentRelsAdapter();
|
||
else if ansiContainsStr(xml_file, "footer") then
|
||
rels_adapter := docx_components_ware_.GetFtrRelsAdapter(xml_file);
|
||
else if ansiContainsStr(xml_file, "header") then
|
||
rels_adapter := docx_components_ware_.GetHdrRelsAdapter(xml_file);
|
||
rel := rels_adapter.GetRelationshipById(id);
|
||
image_path := "word/" + rel.Target;
|
||
image := docx_components_ware_.Zip().Get(image_path);
|
||
data := image.Data();
|
||
image_path := docx_to_pdf_.GetCachePath(image_path);
|
||
writeFile(rwBinary(), "", image_path, 0, length(data)-1, data);
|
||
image := nil;
|
||
case {self.}GetImageFileType(data) of
|
||
"png":
|
||
image := docx_to_pdf_.GetPdf().LoadPngImageFromFile("", image_path);
|
||
"jpg":
|
||
image := docx_to_pdf_.GetPdf().LoadJpegImageFromFile("", image_path);
|
||
end;
|
||
fileDelete("", image_path);
|
||
return image;
|
||
end;
|
||
|
||
function TSPdfParagraphRange.GetImageFileType(data: binary): string;
|
||
begin
|
||
stream := new TMemoryStream();
|
||
size := length(data);
|
||
stream.Write(data[0:size-1], size);
|
||
def := array(
|
||
('name': 'png', 'position': 0, 'value': array(0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A)),
|
||
('name': 'jpg', 'position': 0, 'value': array(0xFF, 0xD8)),
|
||
);
|
||
for i:=0 to length(def)-1 do
|
||
begin
|
||
value := def[i]['value'];
|
||
stream.Seek(def[i]['position']);
|
||
for j:=0 to length(value)-1 do
|
||
begin
|
||
r := 0;
|
||
stream.Read(r, 1);
|
||
if r <> value[j] then break;
|
||
if j = length(value)-1 then return def[i]['name'];
|
||
end
|
||
end
|
||
return '';
|
||
end;
|
||
|
||
function TSPdfParagraphRange.GetParagraphLineSpace(size: real; line: integer): real;
|
||
begin
|
||
sect_ware := docx_to_pdf_.GetCurrentSectWare();
|
||
if not line then line := 12;
|
||
lines := roundto(line / 12, -1);
|
||
multi := ceil(size / sect_ware.BaseSize) * lines;
|
||
return sect_ware.SectPr.DocGrid.LinePitch * multi;
|
||
end;
|
||
|
||
function TSPdfParagraphRange.SetPPr(var ppr: PPr);
|
||
begin
|
||
new_ppr := new PPr();
|
||
styles := docx_components_ware_.GetStyles();
|
||
new_ppr.Copy(styles.DocDefaults.PPrDefault.PPr);
|
||
new_ppr.RPr.Copy(styles.DocDefaults.RPrDefault.RPr);
|
||
{self.}SetPPrByStyleId(new_ppr, extra_style_id_);
|
||
{self.}SetPPrByStyleId(new_ppr, ppr.PStyle.Val);
|
||
new_ppr.Copy(ppr);
|
||
ppr.Copy(new_ppr);
|
||
end;
|
||
|
||
function TSPdfParagraphRange.SetPPrByStyleId(var ppr: PPr; style_id: string);
|
||
begin
|
||
styles := docx_components_ware_.GetStylesAdapter();
|
||
style := styles.GetStyleByStyleId(style_id);
|
||
if ifObj(style) then
|
||
begin
|
||
based_on := style.BasedOn.Val;
|
||
{self.}SetPPrByStyleId(ppr, based_on);
|
||
ppr.Copy(style.PPr);
|
||
ppr.RPr.Copy(style.RPr);
|
||
end
|
||
end;
|
||
|
||
function TSPdfParagraphRange.SetRPr(var rpr; ppr: PPrUnitDecorator);
|
||
begin
|
||
new_rpr := new RPr();
|
||
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;
|
||
|
||
function TSPdfParagraphRange.SetRPrByStyleId(var rpr: RPr; style_id: string);
|
||
begin
|
||
styles := docx_components_ware_.GetStylesAdapter();
|
||
style := styles.GetStyleByStyleId(style_id);
|
||
if ifObj(style) then
|
||
begin
|
||
based_on := style.BasedOn.Val;
|
||
{self.}SetRPrByStyleId(rpr, based_on);
|
||
rpr.Copy(style.RPr);
|
||
end
|
||
end;
|
||
|
||
function TSPdfParagraphRange.SetLvlText();
|
||
begin
|
||
numbering_ware := docx_components_ware_.GetNumberingWare();
|
||
if not ifObj(numbering_ware) then return;
|
||
[lvl_text, lvl] := numbering_ware.GetNumberLvl(paragraph_.PPr);
|
||
if lvl_text = "" and ifnil(lvl) then return;
|
||
{self.}SetRPr(lvl.RPr, paragraph_.PPr);
|
||
rpr := new RPrUnitDecorator(lvl.RPr);
|
||
{self.}SplitTextToTextRange(lvl_text, rpr);
|
||
end;
|
||
|
||
function TSPdfParagraphRange.ResetCoordinates();
|
||
begin
|
||
// 根据段落的间距确定新的坐标
|
||
ppr := ppr_unit_decorator_;
|
||
sz := ppr.RPr.SzCs.Val ? ppr.RPr.SzCs.Val : ppr.RPr.Sz.Val ? ppr.RPr.Sz.Val : docx_to_pdf_.Font.GetDefaultSz();
|
||
{self.}StartX += ppr.Ind.LeftChars ? ppr.Ind.LeftChars * sz : ppr.Ind.Left;
|
||
{self.}Width -= ppr.Ind.LeftChars ? ppr.Ind.LeftChars * sz : ppr.Ind.Left;
|
||
{self.}Width -= ppr.Ind.RightChars ? ppr.Ind.RightChars * sz : ppr.Ind.Right;
|
||
end;
|