2408 lines
80 KiB
Plaintext
2408 lines
80 KiB
Plaintext
unit DTPAdvancedRanges;
|
||
interface
|
||
uses DTPPrimitiveRanges, DTPUtils, DTPModules, SharedML, DocxML, DrawingMLUnitDecorator, DocxMLUnitDecorator;
|
||
|
||
type RangeCollection = class(BasicRange)
|
||
public
|
||
function Create();
|
||
function Do();override;
|
||
function Add(range: BasicRange);
|
||
|
||
private
|
||
range_array_: array of BasicRange;
|
||
end;
|
||
|
||
type ParagraphLineRange = class(BasicRange)
|
||
public
|
||
function Create(pg: Page);
|
||
function Do();override;
|
||
function AddRange(range: BasicRange);
|
||
function SetAllRangeProp(pg: Page; sx: real; sy: real; ex: real; ey: real; w: real; fh: real; dh: real);
|
||
function Align(jc: string);
|
||
function AdjustRangeOffset(pg: Page; x_offset: real; y_offset: real);
|
||
function AlignRightBound(right_bound: real);
|
||
function Offset(x_offset: real; y_offset; real);
|
||
|
||
private
|
||
range_array_: array of BasicRange;
|
||
end;
|
||
|
||
type ParagraphRange = class(BasicRange)
|
||
public
|
||
function Create(docx_to_pdf: TSDocxToPdf; pg: Page; components: DocxComponentsModule; paragraph: P);
|
||
function Calc();
|
||
function Do();override;
|
||
function SetTblStyleIdAndType(style_id: string; type: string);
|
||
function SetNumPages(num: integer);
|
||
function RangesToLines();
|
||
function GetLastPage(): Page;
|
||
function AdjustRangeOffset(pg: Page; x_offset: real; y_offset: real);
|
||
function GetParagraphLineRangeArr(): array of ParagraphLineRange;
|
||
function Empty(): boolean;
|
||
function Offset(x: real; y: real);
|
||
|
||
private
|
||
function SetPPPr(var p: P);
|
||
function SetPPrByStyleId(var ppr: PPr; style_id: string);
|
||
function SetRRPr(var r: R; ppr_unit_decorator: PPrUnitDecorator);
|
||
function SetRPrByStyleId(var rpr: RPr; style_id: string);
|
||
function SetRPrByTblStyleId(var rpr: RPr; style_id: string);
|
||
function SetLvlText();
|
||
function GetImageFileType(data: binary): string;
|
||
function GetImageData(id: string): PdfImage;
|
||
function GetParagraphLineSpace(size: real; line: integer; line_rule: string): real;
|
||
function BasicRangesToParagraphLineRange(): tableArray;
|
||
function UpdateTextRangeWidth();
|
||
function CheckAndAddPage(y: real; offset: real): boolean;
|
||
function SplitTextToTextRange(range_arr: array of BasicRange; text: string; rpr: RPrUnitDecorator; link: string);
|
||
function RAlternateContent(r: R);
|
||
function RDrawing(r: R);
|
||
function RFldChar(r: R; stack: Stack);
|
||
function RFootnoteReference(r: R);
|
||
function RFootnoteRef(r: R);
|
||
function RObject(r: R);
|
||
function RT(r: R; link: string);
|
||
function FldSimple(fld_simple: FldSimple);
|
||
function Hyperlink(hyperlink: Hyperlink);
|
||
|
||
function SetLinesAlignment();
|
||
function ResetCoordinates();
|
||
function NewParagraphLineRange(): ParagraphLineRange;
|
||
function BookMarkLinkToc();
|
||
function HyperlinkToToc();
|
||
function HyperlinkToTextRange(hyperlink: Hyperlink; ppr: PPrUnitDecorator);
|
||
function GetXYCordinates(): array of real;
|
||
function AlignRightBound();
|
||
function Init();
|
||
function OMathPara(element: OMathPara);
|
||
|
||
private
|
||
[weakref]docx_to_pdf_: TSDocxToPdf;
|
||
[weakref]docx_components_module_: DocxComponentsModule;
|
||
[weakref]paragraph_: P;
|
||
[weakref]page_: Page;
|
||
body_range_array_: array of BasicRange; // 正文的range
|
||
bullet_range_array_: array of BasicRange; // 项目符号的range
|
||
line_range_array_: array of ParagraphLineRange;
|
||
|
||
hyperlink_array_: tableArray;
|
||
bookmark_array_: tableArray;
|
||
ppr_unit_decorator_: PPrUnitDecorator;
|
||
placeholder_array_: tableArray;
|
||
table_style_id_: string;
|
||
table_style_type_: string;
|
||
empty_: boolean;
|
||
right_bound_: real;
|
||
footnote_reference_hash_: hash;
|
||
end;
|
||
|
||
type TableRange = class(BasicRange)
|
||
public
|
||
function Create(docx_to_pdf: TSDocxToPdf; pg: Page; components: DocxComponentsModule; table: Tbl);
|
||
function Do();override;
|
||
function Calc();
|
||
function GetLastPage(): Page;
|
||
function Rows(): integer;
|
||
function Cols(): integer;
|
||
function RowLowerBound(row: integer): real;
|
||
|
||
private
|
||
function CreateTableMatrix(grid_cols: array of GridColUnitDecorator; trs: array of Tr);
|
||
function ComputeMatrixCells();
|
||
function ResetCoordinates(tbl_pr: TblPrUnitDecorator; grid_cols: array of GridCol);
|
||
function SetTblTblPr(var table: Tbl);
|
||
function SetTblPrByStyleId(var tbl_pr: TblPr; style_id: string);
|
||
function SetTrTrPr(var tr_pr: TrPr);
|
||
function SetTrPrByStyleId(var tr_pr: TrPr; style_id: string);
|
||
function SetTcTcPr(var tc: Tc);
|
||
function SetTcPrByStyleId(var tc_pr: TcPr; style_id: string);
|
||
function OverrideTcPrByTblStylePrType(var tc_pr: TcPr; type: string);
|
||
|
||
private
|
||
[weakref]docx_to_pdf_: TSDocxToPdf;
|
||
[weakref]last_page_: Page;
|
||
[weakref]docx_components_module_: DocxComponentsModule;
|
||
[weakref]table_: Tbl;
|
||
tbl_pr_unit_decorator_: TblPrUnitDecorator;
|
||
ts_trpr_array_: array of TSTrProperty;
|
||
cell_range_matrix_: array of CellRange;
|
||
row_lower_bound_: hash;
|
||
rows_: integer;
|
||
cols_: integer;
|
||
end;
|
||
|
||
type CellRange = class(BasicRange)
|
||
public
|
||
function Create(docx_to_pdf: TSDocxToPdf; pg: Page; components: DocxComponentsModule; tc: Tc; tbl_pr: TblPr; trp: TSTrProperty);
|
||
function Calc();
|
||
function Do();override;
|
||
function SetPage(pg: Page);
|
||
function GetLastPage();
|
||
function AlignHeight(height: real; lb: real);
|
||
function SetVAlign();
|
||
function IsReComputeByCantSplit(): boolean;
|
||
function IfRemoveEmptyRectangle(): boolean;
|
||
function SetTop();
|
||
|
||
property Tc read tc_;
|
||
|
||
private
|
||
function GetCellPrType(): string;
|
||
function SetBorderRange(range: BordersRange);
|
||
|
||
public
|
||
RemoveFlag: boolean;
|
||
Row: integer;
|
||
Col: integer;
|
||
VMerge: integer;
|
||
[weakref]TSTrPr: TSTrProperty;
|
||
|
||
private
|
||
[weakref]docx_to_pdf_: TSDocxToPdf;
|
||
[weakref]last_page_: Page;
|
||
[weakref]docx_components_module_: DocxComponentsModule;
|
||
[weakref]tc_: Tc;
|
||
[weakref]tbl_pr_: TblPr;
|
||
tc_pr_unit_decorator_: TcPrUnitDecorator;
|
||
region_array_: array of Region; // 单元格可能跨页,所以可能存在多个
|
||
top_: boolean;
|
||
end;
|
||
|
||
type ColumnRange = class(BasicRange)
|
||
public
|
||
function Create(docx_to_pdf: TSDocxToPdf; pg: Page; components: DocxComponentsModule);
|
||
function AddElement(ele: Element);
|
||
function Elements(): array of Element;
|
||
function GetLastPage(): Page;
|
||
function Do();override;
|
||
|
||
private
|
||
[weakref]docx_to_pdf_: TSDocxToPdf;
|
||
[weakref]docx_components_module_: DocxComponentsModule;
|
||
[weakref]page_: Page;
|
||
elements_: array of Elements;
|
||
paragraph_: P;
|
||
last_y_: real;
|
||
end;
|
||
|
||
type MathRange = class(BasicRange)
|
||
public
|
||
function Create(docx_to_pdf: TSDocxToPdf; pg: Page; o_math_para: OMathPara);
|
||
function Calc();
|
||
function Do();override;
|
||
|
||
private
|
||
[weakref]docx_to_pdf_: TSDocxToPdf;
|
||
[weakref]o_math_para_: OMathPara;
|
||
sub_math_range_: SubMathRange;
|
||
end;
|
||
|
||
type SubMathRange = class(BasicRange)
|
||
public
|
||
function Create(docx_to_pdf: TSDocxToPdf; pg: Page; element: OpenXmlElement; sz: real);
|
||
function Do();override;
|
||
function Calc();
|
||
|
||
private
|
||
function MathR(r: R; sz: real; x: real; y: real): RangeCollection;
|
||
function MathF(f: F; sz: real; x: real; y: real): RangeCollection;
|
||
function MathRad(rad: Rad; sz: real; x: real; y: real): RangeCollection;
|
||
function MathNary(nary: Nary; sz: real; x: real; y: real): RangeCollection;
|
||
function MathSSup(s_sup: SSup; sz: real; x: real; y: real): RangeCollection;
|
||
|
||
private
|
||
[weakref]docx_to_pdf_: TSDocxToPdf;
|
||
[weakref]ts_page_: Page;
|
||
[weakref]openxml_element_: OpenXmlElement;
|
||
range_collection_: RangeCollection;
|
||
sz_: real;
|
||
end;
|
||
|
||
implementation
|
||
|
||
function MathRange.Create(docx_to_pdf: TSDocxToPdf; pg: Page; o_math_para: OMathPara);
|
||
begin
|
||
class(BasicRange).Create();
|
||
docx_to_pdf_ := docx_to_pdf;
|
||
o_math_para_ := o_math_para;
|
||
sub_math_range_ := nil;
|
||
{self.}Page := pg;
|
||
end;
|
||
|
||
function MathRange.Calc();
|
||
begin
|
||
sub_math_range_ := new SubMathRange(docx_to_pdf_, {self.}Page, o_math_para_.OMath, 11);
|
||
sub_math_range_.StartX := {self.}StartX;
|
||
sub_math_range_.StartY := {self.}StartY;
|
||
sub_math_range_.EndX := {self.}EndX;
|
||
sub_math_range_.EndY := {self.}EndY;
|
||
sub_math_range_.DynamicHeight := 100;
|
||
sub_math_range_.Calc();
|
||
|
||
{self.}EndX := sub_math_range_.EndX;
|
||
{self.}EndY := sub_math_range_.EndY;
|
||
{self.}Width := sub_math_range_.Width;
|
||
{self.}DynamicHeight := sub_math_range_.DynamicHeight;
|
||
end;
|
||
|
||
function MathRange.Do();override;
|
||
begin
|
||
sub_math_range_.Do();
|
||
end;
|
||
|
||
function SubMathRange.Create(docx_to_pdf: TSDocxToPdf; pg: Page; element: OpenXmlElement; sz: real);
|
||
begin
|
||
class(BasicRange).Create();
|
||
docx_to_pdf_ := docx_to_pdf;
|
||
ts_page_ := pg;
|
||
openxml_element_ := element;
|
||
{self.}Page := pg;
|
||
range_collection_ := new RangeCollection();
|
||
sz_ := sz;
|
||
end;
|
||
|
||
function SubMathRange.Do();override;
|
||
begin
|
||
range_collection_.Do();
|
||
end;
|
||
|
||
function SubMathRange.Calc();
|
||
begin
|
||
elements := openxml_element_.Elements();
|
||
min_y := {self.}StartY;
|
||
max_y := {self.}StartY;
|
||
{self.}EndX := {self.}StartX;
|
||
{self.}EndY := {self.}StartY;
|
||
for _,element in elements do
|
||
begin
|
||
range := nil;
|
||
if element.LocalName = "r" then
|
||
range := {self.}MathR(element, sz_, {self.}EndX, {self.}EndY);
|
||
else if element.LocalName = "f" then
|
||
range := {self.}MathF(element, sz_, {self.}EndX, {self.}EndY);
|
||
else if element.LocalName = "rad" then
|
||
range := {self.}MathRad(element, sz_, {self.}EndX, {self.}EndY);
|
||
else if element.LocalName = "nary" then
|
||
range := {self.}MathNary(element, sz_, {self.}EndX, {self.}EndY);
|
||
else if element.LocalName = "sSup" then
|
||
range := {self.}MathSSup(element, sz_, {self.}EndX, {self.}EndY);
|
||
|
||
if not ifObj(range) then
|
||
begin
|
||
echo forma("Not support <%s>\n", element.ElementName);
|
||
continue;
|
||
end
|
||
if min_y > range.EndY then min_y := range.EndY;
|
||
if max_y < range.EndY + range.DynamicHeight then max_y := range.EndY + range.DynamicHeight;
|
||
|
||
{self.}EndX := range.EndX;
|
||
{self.}EndY := range.EndY;
|
||
{self.}Width += range.Width;
|
||
range_collection_.Add(range);
|
||
end
|
||
range_collection_.DynamicHeight := max_y - min_y;
|
||
{self.}DynamicHeight := range_collection_.DynamicHeight;
|
||
end;
|
||
|
||
function SubMathRange.MathSSup(s_sup: SSup; sz: real; x: real; y: real): RangeCollection;
|
||
begin
|
||
prange := new RangeCollection();
|
||
prange.StartX := x;
|
||
prange.StartY := y;
|
||
prange.EndX := x;
|
||
prange.EndY := y;
|
||
|
||
e_range := new SubMathRange(docx_to_pdf_, {self.}Page, s_sup.E, sz);
|
||
e_range.StartX := x;
|
||
e_range.StartY := y;
|
||
e_range.Calc();
|
||
|
||
sup_range := new SubMathRange(docx_to_pdf_, {self.}Page, s_sup.Sup, sz * 0.4);
|
||
sup_range.StartX := x + e_range.Width;
|
||
sup_range.StartY := y + sz * 0.57;
|
||
sup_range.Calc();
|
||
|
||
prange.Add(e_range);
|
||
prange.Add(sup_range);
|
||
prange.EndX := maxValue(array(e_range.EndX, sup_range.EndX));
|
||
prange.EndY := e_range.EndY;
|
||
prange.Width := prange.EndX - prange.StartX;
|
||
prange.DynamicHeight := e_range.DynamicHeight + sup_range.DynamicHeight * 0.5;
|
||
|
||
return prange;
|
||
end;
|
||
|
||
function SubMathRange.MathR(r: R; sz: real; x: real; y: real): RangeCollection;
|
||
begin
|
||
// println("x = {}, y = {}", x, y);
|
||
prange := new RangeCollection();
|
||
prange.StartX := x;
|
||
prange.StartY := y;
|
||
prange.EndX := x;
|
||
prange.EndY := y;
|
||
text := r.T.Text();
|
||
pos := 1;
|
||
// println("text = {}", text);
|
||
while pos <= length(text) do
|
||
begin
|
||
num := Utf8CharLengthFromByte(text[pos]);
|
||
a_word := text[pos : pos+num-1];
|
||
if num = 1 or DTPUtils.IsChineseChar(a_word) or DTPUtils.IsChinesePunctuation(a_word) then
|
||
begin
|
||
word := utf8ToAnsi(a_word);
|
||
font_obj := docx_to_pdf_.Font.GetCNSFont("SimSun", false, true);
|
||
end
|
||
else begin
|
||
word := class(SymbolMapper).SymbolChr(a_word);
|
||
if ifnil(word) then raise format("error symbol {{%s}}", a_word);
|
||
font_obj := docx_to_pdf_.Font.GetSymbolFont();
|
||
end
|
||
rpr := new RPr();
|
||
rpr.Sz.Val := sz;
|
||
ts_page_.PdfPage.SetFontAndSize(font_obj, rpr.Sz.Val);
|
||
word_width := ts_page_.PdfPage.TextWidth(word);
|
||
text_range := new TextRange();
|
||
text_range.RPr := rpr;
|
||
text_range.Text := word;
|
||
text_range.Font := font_obj;
|
||
text_range.StartX := prange.EndX;
|
||
text_range.StartY := prange.EndY;
|
||
text_range.Page := {self.}Page;
|
||
text_range.EndX := text_range.StartX;
|
||
text_range.EndY := text_range.StartY;
|
||
text_range.Width := word_width;
|
||
pos += num;
|
||
prange.Add(text_range);
|
||
prange.EndX += text_range.Width;
|
||
prange.Width += text_range.Width;
|
||
end
|
||
prange.DynamicHeight := sz;
|
||
return prange;
|
||
end;
|
||
|
||
function SubMathRange.MathF(f: F; sz: real; x: real; y: real);
|
||
begin
|
||
prange := new ParagraphLineRange();
|
||
prange.StartX := x;
|
||
prange.StartY := y;
|
||
prange.EndX := x;
|
||
prange.EndY := y;
|
||
|
||
den_range := new SubMathRange(docx_to_pdf_, {self.}Page, f.Den, sz);
|
||
den_range.StartX := x;
|
||
den_range.StartY := y;
|
||
den_range.Calc();
|
||
|
||
num_range := new SubMathRange(docx_to_pdf_, {self.}Page, f.Num, sz);
|
||
num_range.StartX := x;
|
||
num_range.StartY := y + 1.418 * sz;
|
||
num_range.Calc();
|
||
|
||
max_len := max(den_range.Width, num_range.Width);
|
||
bar := max_len / 0.9;
|
||
line_range := new LineRange();
|
||
line_range.StartX := x - (bar - max_len) / 2;
|
||
line_range.StartY := y + 0.928 * sz;
|
||
line_range.EndX := line_range.StartX;
|
||
line_range.EndY := line_range.StartY;
|
||
line_range.Width := bar;
|
||
line_range.Page := {self.}Page;
|
||
line_range.LineWidth := 0.04 * sz;
|
||
|
||
prange.EndX := maxValue(array(den_range.EndX, num_range.EndX, line_range.EndX));
|
||
prange.AddRange(den_range);
|
||
prange.AddRange(num_range);
|
||
prange.AddRange(line_range);
|
||
|
||
return prange;
|
||
|
||
// TODO: delete
|
||
// pg := {self.}Page.PdfPage;
|
||
// pg.SetFontAndSize(font, sz);
|
||
// len1 := pg.TextWidth(range1.Text);
|
||
// len2 := pg.TextWidth(range2.Text);
|
||
// max_len := len1 > len2 ? len1 : len2;
|
||
// bar := max_len / 0.9;
|
||
// pg.SetLineWidth(0.05*sz);
|
||
// pg.SetRGBStroke(0, 0, 0);
|
||
// x := {self.}StartX - (bar - max_len) / 2;
|
||
// y := {self.}StartY + 0.928 * sz;
|
||
// pg.MoveTo(x, y);
|
||
// pg.LineTo(x + bar, y);
|
||
// pg.Stroke();
|
||
|
||
// elements := f.Den.Elements();
|
||
// {self.}TraverseElement(elements);
|
||
// elements := f.Num.Elements();
|
||
// {self.}TraverseElement(elements);
|
||
|
||
// for _,element in elements do
|
||
// begin
|
||
// if
|
||
// range1 := new TextRange();
|
||
// range1.Text := "a";
|
||
// range1.EndX := {self.}StartX;
|
||
// range1.EndY := {self.}StartY;
|
||
// rpr := new RPr();
|
||
// rpr.Sz.Val := sz;
|
||
// range1.RPr := rpr;
|
||
// range1.Page := {self.}Page;
|
||
// range1.Font := font;
|
||
// range1.Do();
|
||
// end
|
||
// for _,element in elements do
|
||
// begin
|
||
// range2 := new TextRange();
|
||
// range2.Text := "b";
|
||
// range2.EndX := {self.}StartX;
|
||
// range2.EndY := {self.}StartY + 1.418*sz;
|
||
// rpr := new RPr();
|
||
// rpr.Sz.Val := sz;
|
||
// range2.RPr := rpr;
|
||
// range2.Page := {self.}Page;
|
||
// range2.Font := font;
|
||
// range2.Do();
|
||
// // if element.LocalName = "r" then
|
||
// // begin
|
||
// // range1 := new TextRange();
|
||
// // range1.Text := element.T.Text();
|
||
// // end
|
||
// end
|
||
end;
|
||
|
||
function SubMathRange.MathRad(rad: Rad; sz: real; x: real; y: real): ParagraphLineRange;
|
||
begin
|
||
prange := new ParagraphLineRange();
|
||
prange.StartX := x;
|
||
prange.StartY := y;
|
||
prange.EndX := x;
|
||
prange.EndY := y;
|
||
|
||
symbol := chr(0xD6);
|
||
symbol_font := docx_to_pdf_.Font.GetSymbolFont();
|
||
pg := {self.}Page.PdfPage;
|
||
pg.SetFontAndSize(symbol_font, sz);
|
||
symbol_range := new TextRange();
|
||
symbol_range.Text := symbol;
|
||
symbol_range.EndX := x;
|
||
symbol_range.EndY := y;
|
||
symbol_range.Font := symbol_font;
|
||
symbol_range.Width := pg.TextWidth(symbol);
|
||
symbol_range.RPr := new RPr();
|
||
symbol_range.RPr.Sz.Val := sz;
|
||
symbol_range.Page := {self.}Page;
|
||
|
||
deg_range := new SubMathRange(docx_to_pdf_, {self.}Page, rad.Deg, sz * 0.5);
|
||
deg_range.StartX := x;
|
||
deg_range.StartY := y + sz * 0.57;
|
||
deg_range.Calc();
|
||
|
||
e_range := new SubMathRange(docx_to_pdf_, {self.}Page, rad.E, sz);
|
||
e_range.StartX := x + symbol_range.Width;
|
||
e_range.StartY := y;
|
||
e_range.Calc();
|
||
|
||
line_range := new LineRange();
|
||
line_range.StartX := x + symbol_range.Width * 0.9;
|
||
line_range.StartY := y + sz * 0.9;
|
||
line_range.EndX := line_range.StartX;
|
||
line_range.EndY := line_range.StartY;
|
||
line_range.Width := e_range.Width + symbol_range.Width / 3;
|
||
line_range.Page := {self.}Page;
|
||
line_range.LineWidth := 0.04 * sz;
|
||
|
||
prange.EndX := maxValue(array(symbol_range.EndX, e_range.EndX, deg_range.EndX, line_range.EndX));
|
||
prange.AddRange(symbol_range);
|
||
prange.AddRange(deg_range);
|
||
prange.AddRange(e_range);
|
||
prange.AddRange(line_range);
|
||
|
||
return prange;
|
||
|
||
// TODO: delete
|
||
// range := new TextRange();
|
||
// range.Text := chr_hash_['α'];
|
||
// range.EndX := {self.}StartX;
|
||
// range.EndY := {self.}StartY + sz * 0.57;
|
||
// range.Font := symbol_font;
|
||
// range.RPr := new RPr();
|
||
// range.RPr.Sz.Val := sz / 2;
|
||
// range.Page := {self.}Page;
|
||
// range.Do();
|
||
|
||
// range := new TextRange();
|
||
// range.Text := "abcd";
|
||
// range.EndX := {self.}StartX + symbol_w;
|
||
// range.EndY := {self.}StartY;
|
||
// range.Font := font;
|
||
// range.RPr := new RPr();
|
||
// range.RPr.Sz.Val := sz;
|
||
// range.Page := {self.}Page;
|
||
// range.Do();
|
||
|
||
// pg.SetFontAndSize(font, sz);
|
||
// pg.SetLineWidth(0.04*sz);
|
||
// pg.SetRGBStroke(0, 0, 0);
|
||
// x := {self.}StartX + symbol_w * 0.9;
|
||
// y := {self.}StartY + sz * 0.9;
|
||
// pg.MoveTo(x, y);
|
||
// pg.LineTo(x + pg.TextWidth(range.Text)+symbol_w/3, y);
|
||
// pg.Stroke();
|
||
|
||
end;
|
||
|
||
function SubMathRange.MathNary(nary: Nary; sz: real; x: real; y: real): ParagraphLineRange;
|
||
begin
|
||
prange := new ParagraphLineRange();
|
||
prange.StartX := x;
|
||
prange.StartY := y;
|
||
prange.EndX := x;
|
||
prange.EndY := y;
|
||
|
||
val := nary.NaryPr.Chr.Val ?: "Į";
|
||
symbol := class(SymbolMapper).SymbolChr(val);
|
||
if ifnil(symbol) then raise format("error = %s", val);
|
||
symbol_font := docx_to_pdf_.Font.GetSymbolFont();
|
||
pg := {self.}Page.PdfPage;
|
||
pg.SetFontAndSize(symbol_font, sz * 1.5);
|
||
symbol_range := new TextRange();
|
||
symbol_range.Text := symbol;
|
||
symbol_range.EndX := x;
|
||
symbol_range.EndY := y;
|
||
symbol_range.Font := symbol_font;
|
||
symbol_range.RPr := new DocxML.RPr();
|
||
symbol_range.RPr.Sz.Val := 1.5 * sz;
|
||
symbol_range.Page := {self.}Page;
|
||
symbol_range.Width := pg.TextWidth(symbol);
|
||
|
||
if nary.NaryPr.LimLoc.Val = "subSup" then
|
||
begin
|
||
sup_start_x := x + symbol_range.Width * 1.2;
|
||
sup_start_y := y + sz * 1.5 * 0.73;
|
||
sub_start_x := x + symbol_range.Width * 0.7;
|
||
sub_start_y := y - sz * 1.5 * 0.2;
|
||
end
|
||
// else if nary.Nary.LimLoc.Val = "undOvr" then
|
||
else begin // undOvr
|
||
sup_start_x := x + symbol_range.Width * 0.5;
|
||
sup_start_y := y + sz * 1.5 * 0.8;
|
||
sub_start_x := x;
|
||
sub_start_y := y - sz * 1.5 * 0.5;
|
||
end
|
||
|
||
sup_range := new SubMathRange(docx_to_pdf_, {self.}Page, nary.Sup, sz * 0.7);
|
||
sup_range.StartX := sup_start_x;
|
||
sup_range.StartY := sup_start_y;
|
||
sup_range.Calc();
|
||
|
||
sub_range := new SubMathRange(docx_to_pdf_, {self.}Page, nary.Sub, sz * 0.7);
|
||
sub_range.StartX := sub_start_x;
|
||
sub_range.StartY := sub_start_y;
|
||
sub_range.Calc();
|
||
|
||
if nary.NaryPr.LimLoc.Val = "subSup" then
|
||
begin
|
||
e_start_x := x + symbol_range.Width * 0.5 + max(sup_range.Width, sub_range.Width);
|
||
e_start_y := y + sz * 0.3;
|
||
end
|
||
else begin
|
||
e_start_x := x + symbol_range.Width;
|
||
e_start_y := y + sz * 0.3;
|
||
end
|
||
|
||
e_range := new SubMathRange(docx_to_pdf_, {self.}Page, nary.E, sz);
|
||
e_range.StartX := e_start_x;
|
||
e_range.StartY := e_start_y;
|
||
e_range.Calc();
|
||
|
||
prange.EndX := maxValue(array(symbol_range.EndX, sup_range.EndX, sub_range.EndX, e_range.EndX));
|
||
prange.AddRange(symbol_range);
|
||
prange.AddRange(sup_range);
|
||
prange.AddRange(sub_range);
|
||
prange.AddRange(e_range);
|
||
|
||
return prange;
|
||
// TODO: delete
|
||
// val := nary.NaryPr.Chr.Val;
|
||
// symbol := class(SymbolMapper).SymbolChr(nary.NaryPr.Chr.Val);
|
||
// sz := 11;
|
||
// symbol_font := docx_to_pdf_.PdfFile().GetFont("Symbol", "");
|
||
// symbol_range := new TextRange();
|
||
// symbol_range.Text := symbol;
|
||
// symbol_range.EndX := {self.}StartX;
|
||
// symbol_range.EndY := {self.}StartY;
|
||
// symbol_range.Font := symbol_font;
|
||
// symbol_range.RPr := new RPr();
|
||
// symbol_range.RPr.Sz.Val := 1.5 * sz;
|
||
// symbol_range.Page := {self.}Page;
|
||
// symbol_range.Do();
|
||
|
||
// pg := {self.}Page.PdfPage;
|
||
// pg.SetFontAndSize(symbol_font, sz * 1.5);
|
||
// symbol_w := pg.TextWidth(symbol);
|
||
// font := docx_to_pdf_.PdfFile().GetFont("SimSun,Italic", "GBK-EUC-H");
|
||
|
||
// range := new TextRange();
|
||
// range.Text := chr_hash_["∞"];
|
||
// range.EndX := {self.}StartX + symbol_w / 5;
|
||
// range.EndY := {self.}StartY + sz * 0.8 * 1.5;
|
||
// range.Font := symbol_font;
|
||
// range.RPr := new RPr();
|
||
// range.RPr.Sz.Val := sz * 0.7;
|
||
// range.Page := {self.}Page;
|
||
// range.Do();
|
||
|
||
// range := new TextRange();
|
||
// range.Text := "n=1";
|
||
// pg.SetFontAndSize(font, sz*0.7);
|
||
// tw := pg.TextWidth(range.Text);
|
||
// range.EndX := {self.}StartX + (symbol_w - tw)/2;
|
||
// range.EndY := {self.}StartY - sz * 0.5 * 1.5;
|
||
// range.Font := font;
|
||
// range.RPr := new RPr();
|
||
// range.RPr.Sz.Val := sz * 0.7;
|
||
// range.Page := {self.}Page;
|
||
// range.Do();
|
||
|
||
// range := new TextRange();
|
||
// range.Text := chr_hash_["f"];
|
||
// pg.SetFontAndSize(font, sz);
|
||
// tw := pg.TextWidth(range.Text);
|
||
// range.EndX := {self.}StartX + symbol_w;
|
||
// range.EndY := {self.}StartY + sz * 0.3;
|
||
// range.Font := symbol_font;
|
||
// range.RPr := new RPr();
|
||
// range.RPr.Sz.Val := sz;
|
||
// range.Page := {self.}Page;
|
||
// range.Do();
|
||
|
||
end;
|
||
|
||
// ColumnRange
|
||
function ColumnRange.Create(docx_to_pdf: TSDocxToPdf; pg: Page; components: DocxComponentsModule);
|
||
begin
|
||
docx_to_pdf_ := docx_to_pdf;
|
||
page_ := pg;
|
||
docx_components_module_ := components;
|
||
elements_ := array();
|
||
last_y_ := 0;
|
||
end;
|
||
|
||
function ColumnRange.AddElement(ele: Element);
|
||
begin
|
||
elements_[length(elements_)] := ele;
|
||
end;
|
||
|
||
function ColumnRange.Elements(): array of Element;
|
||
begin
|
||
return elements_;
|
||
end;
|
||
|
||
function ColumnRange.Do();override;
|
||
begin
|
||
x := {self.}StartX;
|
||
y := {self.}StartY;
|
||
for _,element in elements_ do
|
||
begin
|
||
range := nil;
|
||
if element.LocalName = "p" then
|
||
range := new ParagraphRange(docx_to_pdf_, page_, docx_components_module_, element);
|
||
else if element.LocalName = "tbl" then
|
||
range := new TableRange(docx_to_pdf_, page_, docx_components_module_, 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 ColumnRange.GetLastPage(): Page;
|
||
begin
|
||
return page_;
|
||
end;
|
||
|
||
// TableRange
|
||
function TableRange.Create(docx_to_pdf: TSDocxToPdf; pg: Page; components: Components; table: Tbl);
|
||
begin
|
||
docx_to_pdf_ := docx_to_pdf;
|
||
last_page_ := pg;
|
||
docx_components_module_ := Components;
|
||
table_ := table;
|
||
ts_trpr_array_ := array();
|
||
cell_range_matrix_ := array();
|
||
row_lower_bound_ := array();
|
||
rows_ := 0;
|
||
cols_ := 0;
|
||
{self.}Page := last_page_;
|
||
end;
|
||
|
||
function TableRange.Calc();
|
||
begin
|
||
{self.}SetTblTblPr(table_);
|
||
tbl_pr_unit_decorator_ := new TblPrUnitDecorator(table_.TblPr);
|
||
tbl_grid_unit_decorator := new TblGridUnitDecorator(table_.TblGrid);
|
||
grid_cols := tbl_grid_unit_decorator.GridCols();
|
||
{self.}ResetCoordinates(tbl_pr_unit_decorator_, grid_cols);
|
||
{self.}EndX := {self.}StartX;
|
||
{self.}EndY := {self.}StartY;
|
||
// 如果是根据内容自适应,应该计算并调整grid_cols的值
|
||
trs := table_.Trs();
|
||
rows_ := length(trs);
|
||
cols_ := length(grid_cols);
|
||
cell_range_matrix_ := nils(rows_, cols_);
|
||
// 先构建一个矩阵
|
||
{self.}CreateTableMatrix(grid_cols, trs);
|
||
// 遍历矩阵后进行计算合并
|
||
{self.}ComputeMatrixCells();
|
||
end;
|
||
|
||
function TableRange.Do();override;
|
||
begin
|
||
for _,row in cell_range_matrix_ do
|
||
begin
|
||
flag := nil;
|
||
for __,range in row do
|
||
begin
|
||
if ifnil(flag) and ifObj(range) then flag := range.IfRemoveEmptyRectangle();
|
||
if not ifObj(range) then continue;
|
||
if flag <> range.IfRemoveEmptyRectangle() then
|
||
begin
|
||
flag := false;
|
||
break;
|
||
end
|
||
end
|
||
for __,range in row do
|
||
begin
|
||
if ifObj(range) then
|
||
begin
|
||
range.RemoveFlag := flag;
|
||
range.Do();
|
||
end
|
||
end
|
||
end
|
||
end;
|
||
|
||
function TableRange.CreateTableMatrix(grid_cols: array of GridColUnitDecorator; trs: array of Tr);
|
||
begin
|
||
for i,tr in trs do
|
||
begin
|
||
{self.}SetTrTrPr(tr);
|
||
tr_pr := new TrPrUnitDecorator(tr.TrPr);
|
||
tc_x := {self.}EndX;
|
||
tcs := tr.Tcs();
|
||
trp := new DTPUtils.TrProperty();
|
||
trp.TrPr := tr_pr;
|
||
ts_trpr_array_[i] := trp;
|
||
pos := 0;
|
||
for j,tc in tcs do
|
||
begin
|
||
{self.}SetTcTcPr(tc);
|
||
if i = 0 then {self.}OverrideTcPrByTblStylePrType(tc.TcPr, "firstRow");
|
||
else if i = length(trs)-1 then {self.}OverrideTcPrByTblStylePrType(tc.TcPr, "lastRow")
|
||
else if (i + 1) % 2 = 0 then {self.}OverrideTcPrByTblStylePrType(tc.TcPr, "band1Horz");
|
||
else {self.}OverrideTcPrByTblStylePrType(tc.TcPr, "band2Horz");
|
||
|
||
grid_span := new GridSpanUnitDecorator(tc.TcPr.GridSpan);
|
||
if tc.TcPr.VMerge and tc.TcPr.VMerge <> "restart" then
|
||
begin
|
||
tc_x += grid_cols[pos++].W;
|
||
for k:=grid_span.Val-1 downto 1 do
|
||
begin
|
||
cell_range_matrix_[i][pos] := 0;
|
||
tc_x += grid_cols[pos++].W;
|
||
end
|
||
continue;
|
||
end
|
||
cell_range := new CellRange(docx_to_pdf_, last_page_, docx_components_module_, tc, tbl_pr_unit_decorator_, trp);
|
||
cell_range.StartX := tc_x;
|
||
cell_range.Width := grid_cols[pos].W;
|
||
cell_range.LowerBound := {self.}LowerBound;
|
||
cell_range.FixedHeight := tr_pr.TrHeight.Val;
|
||
cell_range.Parent := self;
|
||
cell_range.Row := i;
|
||
cell_range.Col := pos;
|
||
cell_range_matrix_[i][pos] := cell_range;
|
||
pos++;
|
||
// 水平合并的单元格,占位需要和垂直的区分
|
||
for k:=grid_span.Val-1 downto 1 do
|
||
begin
|
||
cell_range_matrix_[i][pos] := 0;
|
||
cell_range.Width += grid_cols[pos++].W;
|
||
end
|
||
tc_x += cell_range.Width;
|
||
end
|
||
end
|
||
|
||
// for i,arr in cell_range_matrix_ do
|
||
// println("i = {}, arr = {}", i, arr);
|
||
// println("\n");
|
||
return;
|
||
end;
|
||
|
||
function TableRange.ComputeMatrixCells();
|
||
begin
|
||
i := 0;
|
||
merge_arr := array();
|
||
vmerge_height := array();
|
||
while i < rows_ do
|
||
begin
|
||
j := 0;
|
||
tc_y := {self.}EndY;
|
||
recompute_flag := false;
|
||
while j < cols_ do
|
||
begin
|
||
range := cell_range_matrix_[i][j];
|
||
if not ifObj(range) then
|
||
begin
|
||
j++;
|
||
continue;
|
||
end
|
||
range.StartY := tc_y;
|
||
range.SetPage(last_page_);
|
||
range.Calc();
|
||
if range.IsReComputeByCantSplit() then
|
||
begin
|
||
// 调整上一行的下边界
|
||
arr := cell_range_matrix_[i-1];
|
||
for _,r in arr do
|
||
begin
|
||
if ifnil(r) then
|
||
begin
|
||
pos := i-2;
|
||
while pos > 0 do
|
||
begin
|
||
rr := cell_range_matrix_[pos][_];
|
||
pos--;
|
||
if ifnil(rr) then continue;
|
||
rr.LowerBound := tc_y;
|
||
break;
|
||
end
|
||
end
|
||
if not ifnil(r) then r.LowerBound := tc_y;
|
||
end
|
||
last_page_ := docx_to_pdf_.PageManager[last_page_.Index + 1];
|
||
[x, y] := docx_to_pdf_.CalculateTextCoordinates();
|
||
{self.}EndY := y;
|
||
j := 0;
|
||
recompute_flag := true;
|
||
arr := cell_range_matrix_[i];
|
||
for _,r in arr do
|
||
if not ifnil(r) then r.SetTop();
|
||
break;
|
||
end
|
||
if range.Tc.TcPr.VMerge then
|
||
begin
|
||
b_merge_index := i;
|
||
e_merge_index := i + 1;
|
||
while ifnil(cell_range_matrix_[e_merge_index+1][j]) and e_merge_index < rows_-1 do
|
||
e_merge_index++;
|
||
merge_arr[e_merge_index][j] := b_merge_index;
|
||
range.VMerge := e_merge_index;
|
||
if ifnil(vmerge_height[e_merge_index]) or range.DynamicHeight > vmerge_height[e_merge_index] then
|
||
vmerge_height[e_merge_index] := range.DynamicHeight;
|
||
end
|
||
j++;
|
||
end
|
||
if recompute_flag then continue;
|
||
i_height := 0;
|
||
for k,v in merge_arr[i] do
|
||
begin
|
||
i_height := ts_trpr_array_[i].Height;
|
||
r := cell_range_matrix_[v][k];
|
||
total_height := 0;
|
||
for index:=v to i-1 do
|
||
total_height += ts_trpr_array_[index].Height;
|
||
h := vmerge_height[i];
|
||
if h > total_height + i_height then
|
||
i_height := h - total_height;
|
||
else
|
||
h := total_height + i_height;
|
||
r.AlignHeight(h, row_lower_bound_[i-1]);
|
||
r.SetVAlign();
|
||
end
|
||
if i_height then ts_trpr_array_[i].Height := i_height;
|
||
for _,range in cell_range_matrix_[i] do
|
||
begin
|
||
if not ifObj(range) or range.Tc.TcPr.VMerge then continue;
|
||
range.AlignHeight(ts_trpr_array_[i].Height, row_lower_bound_[i]);
|
||
range.SetVAlign();
|
||
{self.}EndY := range.EndY;
|
||
last_page_ := range.GetLastPage();
|
||
row_lower_bound_[i] := range.LowerBound;
|
||
end
|
||
i++;
|
||
end
|
||
end;
|
||
|
||
function TableRange.RowLowerBound(row: integer): real;
|
||
begin
|
||
return row_lower_bound_[row];
|
||
end;
|
||
|
||
function TableRange.OverrideTcPrByTblStylePrType(var tc_pr: TcPr; type: string);
|
||
begin
|
||
// tc_pr应该是经过外层copy的
|
||
tbl_style_pr := docx_components_module_.GetTblStylePrByType(tbl_pr_unit_decorator_.TblStyle.Val, type);
|
||
if tbl_style_pr then tc_pr.Copy(tbl_style_pr.TcPr);
|
||
end;
|
||
|
||
function TableRange.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 TableRange.SetTblTblPr(var tbl: Tbl);
|
||
begin
|
||
new_tbl_pr := new TblPr();
|
||
{self.}SetTblPrByStyleId(new_tbl_pr, tbl.TblPr.TblStyle.Val);
|
||
new_tbl_pr.Copy(tbl.TblPr);
|
||
tbl.TblPr.Copy(new_tbl_pr);
|
||
end;
|
||
|
||
function TableRange.SetTblPrByStyleId(var tbl_pr: TblPr; style_id: string);
|
||
begin
|
||
styles := docx_components_module_.GetStylesAdapter();
|
||
style := styles.GetStyleByStyleId(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 TableRange.SetTrTrPr(var tr: Tr);
|
||
begin
|
||
new_tr_pr := new TrPr();
|
||
{self.}SetTrPrByStyleId(new_tr_pr, tbl_pr_unit_decorator_.TblStyle.Val);
|
||
new_tr_pr.Copy(tr.TrPr);
|
||
tr.TrPr.Copy(new_tr_pr);
|
||
end;
|
||
|
||
function TableRange.SetTrPrByStyleId(var tr_pr: TrPr; style_id: string);
|
||
begin
|
||
styles := docx_components_module_.GetStylesAdapter();
|
||
style := styles.GetStyleByStyleId(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 TableRange.SetTcTcPr(var tc: Tc);
|
||
begin
|
||
new_tc_pr := new TcPr();
|
||
{self.}SetTcPrByStyleId(new_tc_pr, tbl_pr_unit_decorator_.TblStyle.Val);
|
||
new_tc_pr.Copy(tc.TcPr);
|
||
tc.TcPr.Copy(new_tc_pr);
|
||
end;
|
||
|
||
function TableRange.SetTcPrByStyleId(var tc_pr: TcPr; style_id: string);
|
||
begin
|
||
styles := docx_components_module_.GetStylesAdapter();
|
||
style := styles.GetStyleByStyleId(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;
|
||
|
||
function TableRange.GetLastPage(): Page;
|
||
begin
|
||
return last_page_;
|
||
end;
|
||
|
||
function TableRange.Rows(): integer;
|
||
begin
|
||
return rows_;
|
||
end;
|
||
|
||
function TableRange.Cols(): integer;
|
||
begin
|
||
return cols_;
|
||
end;
|
||
|
||
// CellRange
|
||
function CellRange.Create(docx_to_pdf: TSDocxToPdf; pg: Page; components: TSDocxComponentsModule; tc: Tc; tbl_pr: TblPr; trp: TSTrProperty);
|
||
begin
|
||
docx_to_pdf_ := docx_to_pdf;
|
||
last_page_ := pg;
|
||
docx_components_module_ := components;
|
||
tc_ := tc;
|
||
tbl_pr_ := tbl_pr;
|
||
region_array_ := array();
|
||
top_ := false;
|
||
tc_pr_unit_decorator_ := new TcPrUnitDecorator(tc_.TcPr);
|
||
{self.}TSTrPr := trp;
|
||
{self.}Tc := tc;
|
||
{self.}VMerge := 1;
|
||
{self.}Page := last_page_;
|
||
end;
|
||
|
||
function CellRange.Calc();
|
||
begin
|
||
region_array_ := array();
|
||
region := new DTPUtils.Region();
|
||
region.BordersRange.EndX := {self.}StartX;
|
||
region.BordersRange.EndY := {self.}StartY;
|
||
region.BordersRange.Width := {self.}Width;
|
||
region.BordersRange.FixedHeight := {self.}FixedHeight;
|
||
region.BordersRange.Page := last_page_;
|
||
region.BordersRange.TcPr := tc_pr_unit_decorator_;
|
||
{self.}SetBorderRange(region.BordersRange);
|
||
region_array_[length(region_array_)] := region;
|
||
|
||
{self.}EndX := {self.}StartX;
|
||
{self.}EndY := {self.}StartY;
|
||
{self.}DynamicHeight := 0;
|
||
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 ParagraphRange(docx_to_pdf_, last_page_, docx_components_module_, element);
|
||
range.SetTblStyleIdAndType(tbl_pr_.TblStyle.Val, {self.}GetCellPrType());
|
||
end
|
||
else if element.LocalName = "tbl" then
|
||
begin
|
||
range := new TableRange(docx_to_pdf_, last_page_, docx_components_module_, element);
|
||
continue; // TODO:表中表存在不可靠问题
|
||
end
|
||
if ifObj(range) then
|
||
begin
|
||
range.StartX := cell_x;
|
||
range.StartY := cell_y;
|
||
range.Width := cell_w;
|
||
range.FixedHeight := cell_h;
|
||
range.LowerBound := {self.}LowerBound;
|
||
range.Parent := self;
|
||
range.Calc();
|
||
region.RangeArr[length(region.RangeArr)] := range;
|
||
{self.}DynamicHeight += range.DynamicHeight;
|
||
cell_y := range.EndY;
|
||
last_page_ := range.GetLastPage();
|
||
end
|
||
end
|
||
{self.}EndY := cell_y - tbl_pr_.TblCellMar.Bottom.W;
|
||
{self.}DynamicHeight += tbl_pr_.TblCellMar.Top.W + tbl_pr_.TblCellMar.Bottom.W;
|
||
|
||
if {self.}EndY < {self.}LowerBound and not range.Empty() then
|
||
begin
|
||
last_page_ := docx_to_pdf_.PageManager[last_page_.Index + 1];
|
||
if ifnil(last_page_) then last_page_ := docx_to_pdf_.AddPage();
|
||
{self.}StartY := last_page_.TextPoint.Y;
|
||
{self.}Calc();
|
||
end
|
||
if {self.}TSTrPr.TrPr.TrHeight.HRule <> "exact" and {self.}DynamicHeight > {self.}FixedHeight then
|
||
begin
|
||
region.BordersRange.FixedHeight := {self.}DynamicHeight;
|
||
{self.}FixedHeight := {self.}DynamicHeight;
|
||
end
|
||
if not {self.}Tc.TcPr.VMerge and {self.}DynamicHeight > {self.}TSTrPr.Height then
|
||
{self.}TSTrPr.Height := {self.}DynamicHeight;
|
||
end;
|
||
|
||
function CellRange.Do();override;
|
||
begin
|
||
for _,region in region_array_ do
|
||
begin
|
||
if _ = 0 and {self.}RemoveFlag then continue;
|
||
// println("Row = {}, Col = {}", {self.}Row, {self.}Col);
|
||
region.BordersRange.Do();
|
||
for _,range in region.RangeArr do
|
||
range.Do();
|
||
end
|
||
end;
|
||
|
||
function CellRange.SetPage(pg: Page);
|
||
begin
|
||
last_page_ := pg;
|
||
{self.}Page := pg;
|
||
end;
|
||
|
||
function CellRange.AlignHeight(height: real; lb: real);
|
||
begin
|
||
region := region_array_[0];
|
||
y_lowerbound := {self.}StartY - {self.}LowerBound;
|
||
surplus := height - y_lowerbound;
|
||
if surplus < 1e-6 then
|
||
begin
|
||
region.BordersRange.DynamicHeight := height;
|
||
{self.}SetBorderRange(region.BordersRange);
|
||
{self.}EndY := {self.}StartY - region.BordersRange.DynamicHeight;
|
||
{self.}LowerBound := {self.}StartY - height;
|
||
return;
|
||
end
|
||
// if lb then y_lowerbound := {self.}StartY - lb;
|
||
region.BordersRange.DynamicHeight := y_lowerbound;
|
||
arr := region.RangeArr;
|
||
region.RangeArr := array();
|
||
hash := array(region.BordersRange.Page.Index: region);
|
||
last_page_ := {self.}Page;
|
||
[x, y] := last_page_.OriginalTextCoordinates();
|
||
span := y - last_page_.FtrPoint.Y;
|
||
while surplus > span do
|
||
begin
|
||
last_page_ := docx_to_pdf_.PageManager[last_page_.Index + 1];
|
||
region := new DTPUtils.Region();
|
||
region.BordersRange.EndX := {self.}StartX;
|
||
region.BordersRange.EndY := y;
|
||
region.BordersRange.Width := {self.}Width;
|
||
region.BordersRange.DynamicHeight := span;
|
||
region.BordersRange.Page := last_page_;
|
||
region.BordersRange.TcPr := tc_pr_unit_decorator_;
|
||
region.BordersRange.Top := true;
|
||
region.BordersRange.Bottom := true;
|
||
{self.}SetBorderRange(region.BordersRange);
|
||
region_array_[length(region_array_)] := region;
|
||
surplus -= span;
|
||
hash[region.BordersRange.Page.Index] := region;
|
||
end
|
||
if surplus > 1e-6 then
|
||
begin
|
||
last_page_ := docx_to_pdf_.PageManager[last_page_.Index + 1];
|
||
region := new DTPUtils.Region();
|
||
region.BordersRange.EndX := {self.}StartX;
|
||
region.BordersRange.EndY := y;
|
||
region.BordersRange.Width := {self.}Width;
|
||
region.BordersRange.DynamicHeight := surplus;
|
||
region.BordersRange.Page := last_page_;
|
||
region.BordersRange.TcPr := tc_pr_unit_decorator_;
|
||
region.BordersRange.Top := true;
|
||
{self.}SetBorderRange(region.BordersRange);
|
||
region_array_[length(region_array_)] := region;
|
||
hash[region.BordersRange.Page.Index] := region;
|
||
{self.}EndY := region.BordersRange.EndY - surplus;
|
||
end
|
||
for _,range in arr do
|
||
begin
|
||
if range is class(ParagraphRange) then
|
||
begin
|
||
line_arr := range.GetParagraphLineRangeArr();
|
||
for _,r in line_arr do
|
||
begin
|
||
region := hash[r.Page.Index];
|
||
region.RangeArr[length(region.RangeArr)] := r;
|
||
end
|
||
end
|
||
end
|
||
end;
|
||
|
||
function CellRange.GetLastPage();
|
||
begin
|
||
return last_page_;
|
||
end;
|
||
|
||
function CellRange.SetVAlign();
|
||
begin
|
||
val := tc_.TcPr.VAlign.Val;
|
||
region := region_array_[0];
|
||
arr := region.RangeArr;
|
||
if length(arr) = 0 then return;
|
||
last_y := arr[length(arr)-1].EndY;
|
||
offset := last_y - (region.BordersRange.EndY - region.BordersRange.DynamicHeight) - tbl_pr_.TblCellMar.Bottom.W;
|
||
case val of
|
||
"center":
|
||
begin
|
||
offset /= 2;
|
||
for _,range in arr do
|
||
range.AdjustRangeOffset(region.BordersRange.Page, nil, -offset);
|
||
end
|
||
end;
|
||
end;
|
||
|
||
function CellRange.IsReComputeByCantSplit(): boolean;
|
||
begin
|
||
if {self.}Tc.TcPr.VMerge then return false;
|
||
return {self.}TSTrPr.TrPr.CantSplit and last_page_ <> {self.}Page;
|
||
end;
|
||
|
||
function CellRange.IfRemoveEmptyRectangle(): boolean;
|
||
begin
|
||
if length(region_array_) < 2 then return false;
|
||
return length(region_array_[0].RangeArr) ? false : true;
|
||
end;
|
||
|
||
function CellRange.GetCellPrType(): string;
|
||
begin
|
||
if {self.}Row = 0 then return "firstRow";
|
||
else if ({self.}Row + 1) % 2 = 0 then return "band1Horz";
|
||
else return "band2Horz";
|
||
end;
|
||
|
||
function CellRange.SetBorderRange(range: BordersRange);
|
||
begin
|
||
if top_ then range.Top := true;
|
||
if ifObj(tbl_pr_.TblBorders) then
|
||
begin
|
||
if {self.}Row = 0 then
|
||
begin
|
||
if tbl_pr_.TblBorders.Top then
|
||
begin
|
||
if not tc_pr_unit_decorator_.TcBorders.Top then
|
||
tc_pr_unit_decorator_.TcBorders.Top.Copy(tbl_pr_.TblBorders.Top);
|
||
range.Top := true;
|
||
end
|
||
if tbl_pr_.TblBorders.InsideH and {self.}VMerge <> {self.}Parent.Rows()-1 then
|
||
begin
|
||
if not tc_pr_unit_decorator_.TcBorders.Bottom then
|
||
tc_pr_unit_decorator_.TcBorders.Bottom.Copy(tbl_pr_.TblBorders.InsideH);
|
||
range.Bottom := true;
|
||
end
|
||
if tbl_pr_.TblBorders.InsideV and {self.}Col <> {self.}Parent.Cols()-1 then
|
||
begin
|
||
if not tc_pr_unit_decorator_.TcBorders.Right then
|
||
tc_pr_unit_decorator_.TcBorders.Right.Copy(tbl_pr_.TblBorders.InsideV);
|
||
range.Right := true;
|
||
end
|
||
if tbl_pr_.TblBorders.Bottom and {self.}VMerge = {self.}Parent.Rows()-1 then
|
||
begin
|
||
if not tc_pr_unit_decorator_.TcBorders.Bottom then
|
||
tc_pr_unit_decorator_.TcBorders.Bottom.Copy(tbl_pr_.TblBorders.Bottom);
|
||
range.Bottom := true;
|
||
end
|
||
end
|
||
else if {self.}Row = {self.}Parent.Rows()-1 then
|
||
begin
|
||
if tbl_pr_.TblBorders.Bottom then
|
||
begin
|
||
if not tc_pr_unit_decorator_.TcBorders.Bottom then
|
||
tc_pr_unit_decorator_.TcBorders.Bottom.Copy(tbl_pr_.TblBorders.Bottom);
|
||
range.Bottom := true;
|
||
end
|
||
if tbl_pr_.TblBorders.InsideV and {self.}Col <> {self.}Parent.Cols()-1 then
|
||
begin
|
||
if not tc_pr_unit_decorator_.TcBorders.Right then
|
||
tc_pr_unit_decorator_.TcBorders.Right.Copy(tbl_pr_.TblBorders.InsideV);
|
||
range.Right := true;
|
||
end
|
||
end
|
||
else begin
|
||
if tbl_pr_.TblBorders.Bottom and {self.}VMerge = {self.}Parent.Rows()-1 then
|
||
begin
|
||
if not tc_pr_unit_decorator_.TcBorders.Bottom then
|
||
tc_pr_unit_decorator_.TcBorders.Bottom.Copy(tbl_pr_.TblBorders.Bottom);
|
||
range.Bottom := true;
|
||
end
|
||
if tbl_pr_.TblBorders.InsideH and {self.}VMerge <> {self.}Parent.Rows()-1 then
|
||
begin
|
||
if not tc_pr_unit_decorator_.TcBorders.Bottom then
|
||
tc_pr_unit_decorator_.TcBorders.Bottom.Copy(tbl_pr_.TblBorders.InsideH);
|
||
range.Bottom := true;
|
||
end
|
||
if tbl_pr_.TblBorders.InsideV and {self.}Col <> {self.}Parent.Cols()-1 then
|
||
begin
|
||
if not tc_pr_unit_decorator_.TcBorders.Right then
|
||
tc_pr_unit_decorator_.TcBorders.Right.Copy(tbl_pr_.TblBorders.InsideV);
|
||
range.Right := true;
|
||
end
|
||
end
|
||
|
||
if {self.}Col = 0 then
|
||
begin
|
||
if tbl_pr_.TblBorders.Left then
|
||
begin
|
||
if not tc_pr_unit_decorator_.TcBorders.Left then
|
||
tc_pr_unit_decorator_.TcBorders.Left.Copy(tbl_pr_.TblBorders.Left);
|
||
range.Left := true;
|
||
end
|
||
end
|
||
if {self.}Col = {self.}Parent.Cols()-1 then
|
||
begin
|
||
if tbl_pr_.TblBorders.Right then
|
||
begin
|
||
if not tc_pr_unit_decorator_.TcBorders.Right then
|
||
tc_pr_unit_decorator_.TcBorders.Right.Copy(tbl_pr_.TblBorders.Right);
|
||
range.Right := true;
|
||
end
|
||
end
|
||
end
|
||
else begin
|
||
range.Left := {self.}Col = 0;
|
||
range.Top := {self.}Row = 0;
|
||
range.Right := true;
|
||
range.Bottom := true;
|
||
end
|
||
end;
|
||
|
||
function CellRange.SetTop();
|
||
begin
|
||
top_ := true;
|
||
end;
|
||
|
||
// RangeCollection;
|
||
function RangeCollection.Create();
|
||
begin
|
||
class(BasicRange).Create();
|
||
range_array_ := array();
|
||
end;
|
||
|
||
function RangeCollection.Do();override;
|
||
begin
|
||
for _,range in range_array_ do
|
||
range.Do();
|
||
end;
|
||
|
||
function RangeCollection.Add(range: BasicRange);
|
||
begin
|
||
range_array_[length(range_array_)] := range;
|
||
end;
|
||
|
||
// ParagraphLineRange
|
||
function ParagraphLineRange.Create(pg: Page);
|
||
begin
|
||
class(BasicRange).Create();
|
||
{self.}Page := pg;
|
||
range_array_ := array();
|
||
end;
|
||
|
||
function ParagraphLineRange.AddRange(range: BasicRange);
|
||
begin
|
||
range_array_[length(range_array_)] := range;
|
||
end;
|
||
|
||
function ParagraphLineRange.Do();override;
|
||
begin
|
||
for _,range in range_array_ do
|
||
range.Do();
|
||
end;
|
||
|
||
function ParagraphLineRange.SetAllRangeProp(pg: Page; 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 ParagraphLineRange.Align(jc: string);
|
||
begin
|
||
offset := 0;
|
||
first := range_array_[0];
|
||
last := range_array_[length(range_array_)-1];
|
||
case jc of
|
||
"center":
|
||
offset := ({self.}Width + StartX - last.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;
|
||
|
||
function ParagraphLineRange.AdjustRangeOffset(pg: Page; x_offset: real; y_offset: real);
|
||
begin
|
||
if pg <> {self.}Page then return;
|
||
for _,range in range_array_ do
|
||
begin
|
||
if not ifnil(x_offset) then range.EndX += x_offset;
|
||
if not ifnil(y_offset) then range.EndY += y_offset;
|
||
end;
|
||
end;
|
||
|
||
function ParagraphLineRange.AlignRightBound(right_bound: real);
|
||
begin
|
||
last := range_array_[length(range_array_)-1];
|
||
diff := right_bound - (last.EndX + last.Width);
|
||
if diff > 1e-6 then
|
||
begin
|
||
avg := diff / (length(range_array_) - 1);
|
||
for i:=1 to length(range_array_)-1 do
|
||
range_array_[i].EndX += avg * i;
|
||
end
|
||
end;
|
||
|
||
function ParagraphLineRange.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;
|
||
|
||
|
||
// ParagraphRange
|
||
function ParagraphRange.Create(docx_to_pdf: TSDocxToPdf; pg: Page; components: DocxComponentsModule; paragraph: P);
|
||
begin
|
||
docx_to_pdf_ := docx_to_pdf;
|
||
page_ := pg;
|
||
docx_components_module_ := components;
|
||
paragraph_ := paragraph;
|
||
table_style_id_ := "";
|
||
table_style_type_ := "";
|
||
body_range_array_ := array();
|
||
bullet_range_array_ := array();
|
||
line_range_array_ := array();
|
||
hyperlink_array_ := array();
|
||
bookmark_array_ := array();
|
||
empty_ := false;
|
||
{self.}Page := page_;
|
||
footnote_reference_hash_ := array();
|
||
end;
|
||
|
||
function ParagraphRange.Init();
|
||
begin
|
||
body_range_array_ := array();
|
||
right_bound_ := {self.}StartX + {self.}Width;
|
||
{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;
|
||
|
||
// TODO:项目符号应该单独写入
|
||
{self.}SetLvlText();
|
||
end;
|
||
|
||
function ParagraphRange.Calc(): tableArray;
|
||
begin
|
||
// ppr.rpr是无效的,应该以ppr.pStyle为准
|
||
{self.}SetPPPr(paragraph_);
|
||
ppr_unit_decorator_ := new DocxMLUnitDecorator.PPrUnitDecorator(paragraph_.PPr);
|
||
{self.}Init();
|
||
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);
|
||
|
||
elements := paragraph_.Elements();
|
||
empty_flag := true;
|
||
bookmark_id := '';
|
||
bookmark_name := '';
|
||
bookmark_flag := false;
|
||
fld_stack := new DTPUtils.Stack();
|
||
for _,element in elements do
|
||
begin
|
||
// println("LocalName = {}", element.LocalName);
|
||
if element.LocalName = "r" then
|
||
begin
|
||
empty_flag := false;
|
||
{self.}SetRRPr(element, ppr_unit_decorator_);
|
||
|
||
if element.FldChar.FldCharType = "begin" then
|
||
begin
|
||
fld_struct := new DTPUtils.FldStruct();
|
||
fld_stack.Push(fld_struct);
|
||
end
|
||
if not fld_stack.Empty() then
|
||
begin
|
||
{self.}RFldChar(element, fld_stack);
|
||
continue;
|
||
end
|
||
|
||
if element.Br.Type = "page" then
|
||
{self.}EndY := {self.}LowerBound;
|
||
else if element.Drawing then {self.}RDrawing(element);
|
||
else if element.AlternateContent then {self.}RAlternateContent(element);
|
||
else if element.FootnoteReference then {self.}RFootnoteReference(element);
|
||
else if element.Object then {self.}RObject(element);
|
||
else if element.FootnoteRef then {self.}RFootnoteRef(element);
|
||
else if element.Anchor then {self.}Hyperlink(element); // <r w:anchor>
|
||
else if element.T then {self.}RT(element, bookmark_name);
|
||
end
|
||
else if element.LocalName = "fldSimple" then
|
||
begin
|
||
{self.}FldSimple(element);
|
||
end
|
||
else if element.LocalName = "hyperlink" then
|
||
begin
|
||
empty_flag := false;
|
||
{self.}Hyperlink(element);
|
||
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
|
||
else if element.LocalName = "oMathPara" then
|
||
begin
|
||
{self.}OMathPara(element);
|
||
end
|
||
else if element.LocalName = "oMath" then
|
||
begin
|
||
o_math_para := new OMathPara();
|
||
o_math_para.XmlChildOMath := element;
|
||
// o_math_para.OMath.Copy(element);
|
||
{self.}OMathPara(o_math_para);
|
||
end
|
||
end
|
||
if empty_flag then
|
||
begin
|
||
line_space := {self.}GetParagraphLineSpace(ppr_unit_decorator_.RPr.Sz.Val, ppr_unit_decorator_.Spacing.Line, ppr_unit_decorator_.Spacing.LineRule);
|
||
{self.}DynamicHeight += line_space;
|
||
{self.}EndY -= {self.}DynamicHeight;
|
||
empty_ := true;
|
||
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 ParagraphRange.SetNumPages(num: integer);
|
||
begin
|
||
text := tostring(num);
|
||
last_index := length(body_range_array_);
|
||
{self.}SplitTextToTextRange(body_range_array_, text, placeholder_array_[1], link);
|
||
arr := array();
|
||
len := length(body_range_array_);
|
||
for i:=last_index to len-1 do
|
||
arr[length(arr)] := body_range_array_[i];
|
||
diff := len - last_index;
|
||
for i:=len-1 downto placeholder_array_[0] do
|
||
body_range_array_[i] := body_range_array_[i-diff];
|
||
k := 0;
|
||
for i:=placeholder_array_[0] to placeholder_array_[0]+diff-1 do
|
||
body_range_array_[i] := arr[k++];
|
||
end;
|
||
|
||
function ParagraphRange.BookMarkLinkToc();
|
||
begin
|
||
for name,arr in bookmark_array_ do
|
||
if arr[0] then docx_to_pdf_.Toc.LinkToToc(name, arr[0].Page, arr[0].EndX, arr[0].EndY + arr[0].RPr.Sz.Val);
|
||
end;
|
||
|
||
function ParagraphRange.HyperlinkToToc();
|
||
begin
|
||
ppr := ppr_unit_decorator_;
|
||
max_size := 0;
|
||
for anchor,arr in hyperlink_array_ do // 整理hyperlink发送到docx_to_pdf_
|
||
begin
|
||
pg := arr[0].Page;
|
||
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, ppr.Spacing.LineRule) then
|
||
begin
|
||
top := pg.TextPoint.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, ppr.Spacing.LineRule);
|
||
bottom -= line_space;
|
||
max_size := 0;
|
||
if range.Page <> pg then
|
||
begin
|
||
rect := array(left, bottom, right, top);
|
||
toc := new DTPModules.Toc(ppr, rect, pg, x, y);
|
||
docx_to_pdf_.Toc.AddToc(anchor, toc);
|
||
pg := range.Page;
|
||
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.GetCNSFont(font_name, ppr.RPr.B, ppr.RPr.I);
|
||
line_space := {self.}GetParagraphLineSpace(max_size, ppr.Spacing.Line, ppr.Spacing.LineRule);
|
||
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_.Toc.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 DTPModules.Toc(ppr, rect, pg, x, y, font_obj);
|
||
docx_to_pdf_.Toc.AddToc(anchor, toc);
|
||
end
|
||
end;
|
||
|
||
function ParagraphRange.FldSimple(fld_simple: FldSimple);
|
||
begin
|
||
if fld_simple.Instr then
|
||
begin
|
||
fields := str2array(fld_simple.Instr, " ");
|
||
fld_struct := new DTPUtils.FldStruct2();
|
||
for _,field in fields do
|
||
begin
|
||
fld := trim(field);
|
||
if fld = "NUMPAGES" then
|
||
fld_struct.Type.NumPages := true;
|
||
else if fld = "Arabic" then
|
||
fld_struct.Arabic := true;
|
||
else if fld = "MERGEFORMAT" then
|
||
fld_struct.MergeFormat := true;
|
||
end
|
||
end
|
||
r := fld_simple.Rs(0);
|
||
{self.}SetRRPr(r, ppr_unit_decorator_);
|
||
rpr := new RPrUnitDecorator(r.RPr);
|
||
if fld_struct.Type.NumPages then
|
||
begin
|
||
if fld_struct.Arabic then
|
||
begin
|
||
placeholder_array_ := array(length(body_range_array_), rpr);
|
||
end
|
||
end
|
||
end;
|
||
|
||
function ParagraphRange.Hyperlink(hyperlink: Hyperlink);
|
||
begin
|
||
i := length(body_range_array_);
|
||
rs := hyperlink.Rs();
|
||
separate := false;
|
||
stack := new DTPUtils.Stack();
|
||
for _,r in rs do
|
||
begin
|
||
if r.FldChar.FldCharType = "begin" then
|
||
begin
|
||
fld_struct := new FldStruct2();
|
||
stack.Push(fld_struct);
|
||
end
|
||
// if r.InstrText.Text
|
||
else if r.FldChar.FldCharType = "end" then
|
||
begin
|
||
stack.Pop();
|
||
end
|
||
else if r.FldChar.FldCharType = "separate" then
|
||
begin
|
||
separate := true;
|
||
end
|
||
else if separate then
|
||
begin
|
||
docx_to_pdf_.Toc.AddDocxPage(hyperlink.Anchor, r);
|
||
end
|
||
else if stack.Empty() then
|
||
begin
|
||
{self.}SetRRPr(r, ppr_unit_decorator_);
|
||
r.RPr.Color.Val := nil;
|
||
{self.}RT(r, hyperlink.Anchor);
|
||
end
|
||
end
|
||
arr := array();
|
||
while i < length(body_range_array_) do
|
||
begin
|
||
arr[length(arr)] := body_range_array_[i];
|
||
i++;
|
||
end
|
||
hyperlink_array_[hyperlink.Anchor] := arr;
|
||
end;
|
||
|
||
function ParagraphRange.Do();override;
|
||
begin
|
||
for _,line_range in line_range_array_ do
|
||
line_range.Do();
|
||
end;
|
||
|
||
function ParagraphRange.SetTblStyleIdAndType(style_id: string; type: string);
|
||
begin
|
||
table_style_id_ := style_id;
|
||
table_style_type_ := type;
|
||
end;
|
||
|
||
function ParagraphRange.NewParagraphLineRange(): ParagraphLineRange;
|
||
begin
|
||
line_range := new ParagraphLineRange(page_);
|
||
line_range.StartX := {self.}StartX;
|
||
line_range.StartY := {self.}EndY;
|
||
line_range.Width := {self.}Width;
|
||
return line_range;
|
||
end;
|
||
|
||
function ParagraphRange.UpdateTextRangeWidth();
|
||
begin
|
||
head_range := body_range_array_[0];
|
||
i := 1;
|
||
while i < length(body_range_array_) do
|
||
begin
|
||
tail_range := body_range_array_[i];
|
||
if not tail_range is class(TextRange) then
|
||
begin
|
||
head_range := body_range_array_[i+1];
|
||
i += 2;
|
||
continue;
|
||
end
|
||
if not last_range is class(TextRange) then
|
||
begin
|
||
head_range := tail_range;
|
||
i++;
|
||
continue;
|
||
end
|
||
if head_range then
|
||
begin
|
||
if head_range.Type in array(1, 2) and tail_range.Type = 3 then
|
||
head_range.Width += head_range.Width / 2;
|
||
else if head_range.Type = 3 and tail_range.Type in array(1, 2) then
|
||
head_range.Width += tail_range.Width / 2;
|
||
end
|
||
head_range := tail_range;
|
||
i++;
|
||
end
|
||
end;
|
||
|
||
function ParagraphRange.RangesToLines();overload;
|
||
begin
|
||
{self.}UpdateTextRangeWidth();
|
||
{self.}BasicRangesToParagraphLineRange();
|
||
{self.}DynamicHeight += ppr_unit_decorator_.Spacing.After;
|
||
{self.}EndY -= ppr_unit_decorator_.Spacing.After;
|
||
if not {self.}Empty() and ppr_unit_decorator_.PBdr.Bottom.Val = "single" then
|
||
begin
|
||
sect_pr := page_.SectPr;
|
||
page_.PdfPage.SetLineWidth(0.05);
|
||
page_.PdfPage.SetGrayStroke(0.25);
|
||
page_.PdfPage.MoveTo(sect_pr.PgMar.Left, {self.}EndY);
|
||
page_.PdfPage.LineTo(sect_pr.PgSz.W - sect_pr.PgMar.Right, {self.}EndY);
|
||
page_.PdfPage.Stroke();
|
||
end
|
||
end;
|
||
|
||
function ParagraphRange.BasicRangesToParagraphLineRange();
|
||
begin
|
||
ppr := ppr_unit_decorator_;
|
||
line_range := {self.}NewParagraphLineRange();
|
||
i := 0;
|
||
max_size := 0;
|
||
max_y := 0;
|
||
while i <= length(body_range_array_)-1 do
|
||
begin
|
||
range := body_range_array_[i];
|
||
if i = 0 then {self.}EndX += ppr.Ind.FirstLine;
|
||
if range is class(TextRange) 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, ppr.Spacing.LineRule);
|
||
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 i = 0 then if_newline := 0;
|
||
if if_newline and (range is class(TextRange)) and (AnsiToUtf8(range.Text) in array(";", ":", "。", "“", "”", "!", "?", ",")) then
|
||
if_newline := 0;
|
||
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.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.}NewParagraphLineRange();
|
||
max_size := 0;
|
||
max_y := 0;
|
||
{self.}DynamicHeight += max_value;
|
||
{self.}EndY -= max_value;
|
||
{self.}EndX := {self.}StartX;
|
||
// w:hanging
|
||
if range is class(TextRange) then
|
||
sz := range.RPr.SzCs.Val ? range.RPr.SzCs.Val : range.RPr.Sz.Val ? range.RPr.Sz.Val : docx_to_pdf_.Font.GetDefaultSz();
|
||
else
|
||
sz := 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(body_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.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;
|
||
{self.}DynamicHeight += max_value;
|
||
{self.}EndY -= max_value;
|
||
end
|
||
end
|
||
{self.}SetLinesAlignment();
|
||
if not {self.}Parent is class(CellRange) then
|
||
{self.}AlignRightBound();
|
||
end;
|
||
|
||
function ParagraphRange.SetLinesAlignment();
|
||
begin
|
||
for _,line_range in line_range_array_ do
|
||
line_range.Align(ppr_unit_decorator_.Jc.Val);
|
||
end;
|
||
|
||
function ParagraphRange.AlignRightBound();
|
||
begin
|
||
len := length(line_range_array_);
|
||
if len = 1 then return;
|
||
for i:=0 to len-2 do
|
||
line_range_array_[i].AlignRightBound(right_bound_);
|
||
end;
|
||
|
||
function ParagraphRange.CheckAndAddPage(y: real; offset: real): boolean;
|
||
begin
|
||
if y - offset < {self.}LowerBound then
|
||
begin
|
||
page_ := docx_to_pdf_.PageManager[page_.Index + 1];
|
||
if ifnil(page_) then page_ := docx_to_pdf_.AddPage();
|
||
{self.}EndY := page_.TextPoint.Y;
|
||
return true;
|
||
end
|
||
return false;
|
||
end;
|
||
|
||
function ParagraphRange.RT(r: R; link: string);
|
||
begin
|
||
rpr := new RPrUnitDecorator(r.RPr);
|
||
text := r.T.Text;
|
||
if ifString(text) then {self.}SplitTextToTextRange(body_range_array_, text, rpr, link);
|
||
end;
|
||
|
||
function ParagraphRange.SplitTextToTextRange(range_arr: array of BasicRange; text: string; rpr: RPrUnitDecorator; link: string);
|
||
begin
|
||
pos := 1;
|
||
if not rpr.Sz.Val then rpr.Sz.Val := rpr.SzCs.Val ? rpr.SzCs.Val : docx_to_pdf_.Font.GetDefaultSz();
|
||
while pos <= length(text) do
|
||
begin
|
||
text_range := new TextRange();
|
||
num := DTPUtils.Utf8CharLengthFromByte(text[pos]);
|
||
a_word := text[pos : pos+num-1];
|
||
if num = 1 then
|
||
begin
|
||
char := ord(a_word);
|
||
if char >= 0x30 and char <= 0x39 then
|
||
text_range.Type := 1;
|
||
else if char >= 0x41 and char <= 0x5A then
|
||
text_range.Type := 2;
|
||
else if char >= 0x61 and char <= 0x7A then
|
||
text_range.Type := 2;
|
||
word := a_word;
|
||
font_name := rpr.RFonts.EastAsia ? rpr.RFonts.EastAsia : rpr.RFonts.Ascii;
|
||
font_obj := docx_to_pdf_.Font.GetCNSFont(font_name, rpr.B, rpr.I);
|
||
end
|
||
else if DTPUtils.IsChineseChar(a_word) then
|
||
begin
|
||
text_range.Type := 3;
|
||
word := utf8ToAnsi(a_word);
|
||
font_name := rpr.RFonts.EastAsia ? rpr.RFonts.EastAsia : rpr.RFonts.Ascii;
|
||
font_obj := docx_to_pdf_.Font.GetCNSFont(font_name, rpr.B, rpr.I);
|
||
end
|
||
else if DTPUtils.IsChinesePunctuation(a_word) then
|
||
begin
|
||
text_range.Type := 4;
|
||
word := utf8ToAnsi(a_word);
|
||
font_name := rpr.RFonts.EastAsia ? rpr.RFonts.EastAsia : rpr.RFonts.Ascii;
|
||
font_obj := docx_to_pdf_.Font.GetCNSFont(font_name, rpr.B, rpr.I);
|
||
end
|
||
else begin
|
||
word := utf8ToAnsi(a_word);
|
||
if word = "?" then
|
||
begin
|
||
word := class(SymbolMapper).ZapfDingbatsChr(a_word);
|
||
if ifnil(word) then word := "u";
|
||
font_obj := docx_to_pdf_.Font.GetZapfDingbatsFont();
|
||
end
|
||
else begin
|
||
font_name := rpr.RFonts.EastAsia ? rpr.RFonts.EastAsia : rpr.RFonts.Ascii;
|
||
font_obj := docx_to_pdf_.Font.GetCNSFont(font_name, rpr.B, rpr.I);
|
||
end
|
||
end
|
||
page_.PdfPage.SetFontAndSize(font_obj, rpr.Sz.Val);
|
||
word_width := page_.PdfPage.TextWidth(word);
|
||
text_range.RPr := rpr;
|
||
text_range.Text := word;
|
||
text_range.Font := font_obj;
|
||
text_range.Width := word_width;
|
||
pos += num;
|
||
range_arr[length(range_arr)] := text_range;
|
||
if ifarray(bookmark_array_[link]) then bookmark_array_[link] union= array(text_range);
|
||
end
|
||
end;
|
||
|
||
function ParagraphRange.RDrawing(r: R);
|
||
begin
|
||
if r.Drawing._Inline then
|
||
begin
|
||
id := r.Drawing._Inline.Graphic.GraphicData.Pic.BlipFill.Blip.Embed;
|
||
[image_type, image] := {self.}GetImageData(id);
|
||
if not image then return;
|
||
xfrm := new XfrmUnitDecorator(r.Drawing._Inline.Graphic.GraphicData.Pic.SpPr.Xfrm);
|
||
image_range := new ImageRange();
|
||
image_range.Image := image;
|
||
image_range.Type := image_type;
|
||
image_range.StartX := 0;
|
||
image_range.StartY := 0;
|
||
image_range.Width := xfrm.Ext.CX;
|
||
image_range.DynamicHeight := xfrm.Ext.CY;
|
||
body_range_array_[length(body_range_array_)] := image_range;
|
||
end
|
||
else if r.Drawing.Anchor then
|
||
begin
|
||
anchor := r.Drawing.Anchor;
|
||
id := anchor.Graphic.GraphicData.Pic.BlipFill.Blip.Embed;
|
||
[image_type, 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);
|
||
if position_h.RelativeFrom = "paragraph" then
|
||
x := {self.}StartY;
|
||
if position_v.RelativeFrom = "paragraph" then
|
||
y := {self.}StartY;
|
||
image_range := new ImageRange();
|
||
image_range.Image := image;
|
||
image_range.Type := image_type;
|
||
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.Page := page_;
|
||
image_range.Do();
|
||
end
|
||
end;
|
||
|
||
function ParagraphRange.RAlternateContent(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);
|
||
if position_h.RelativeFrom = "paragraph" then
|
||
x := {self.}StartY;
|
||
if position_v.RelativeFrom = "paragraph" then
|
||
y := {self.}StartY;
|
||
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 ParagraphRange(docx_to_pdf_, page_, docx_components_module_, p);
|
||
range.StartX := x;
|
||
range.StartY := y;
|
||
range.Width := w;
|
||
range.Calc();
|
||
range.Do();
|
||
y := range.EndY;
|
||
end
|
||
end;
|
||
|
||
function ParagraphRange.RFootnoteReference(r: R);
|
||
begin
|
||
return;
|
||
id := R.FootnoteReference.Id;
|
||
footnotes_adapter := docx_components_module_.GetFootnotesAdapter();
|
||
footnote := footnotes_adapter.GetFootnoteById(id);
|
||
sect_pr := page_.SectPr;
|
||
w := sect_pr.SectPr.PgSz.W - sect_pr.SectPr.PgMar.Right - sect_pr.SectPr.PgMar.Left;
|
||
lb := 0;
|
||
x := sect_pr.SectPr.PgMar.Left;
|
||
y := sect_pr.SectPr.PgSz.H;
|
||
|
||
arr := array();
|
||
elements := footnote.Elements();
|
||
for _,element in elements do
|
||
begin
|
||
if element.LocalName = "p" then
|
||
begin
|
||
range := new ParagraphRange(docx_to_pdf_, page_, docx_components_module_, element);
|
||
range.StartX := x;
|
||
range.StartY := y;
|
||
range.Width := w;
|
||
range.LowerBound := 0;
|
||
range.Calc();
|
||
arr[length(arr)] := arr;
|
||
end
|
||
end
|
||
rpr := new RPrUnitDecorator(r.RPr);
|
||
note := docx_to_pdf_.Note;
|
||
text := docx_to_pdf_.GetCurrentNoteModule().GetIndex();
|
||
i := length(body_range_array_);
|
||
if ifString(text) then {self.}SplitTextToTextRange(body_range_array_, text, rpr, nil);
|
||
footnote_reference_hash_[body_range_array_[i]] := arr;
|
||
|
||
// range := new ParagraphRange(self, page_, docx_components_module_, );
|
||
end;
|
||
|
||
function ParagraphRange.RFootnoteRef(r: R);
|
||
begin
|
||
return;
|
||
note_module := docx_to_pdf_.GetCurrentNoteModule();
|
||
rpr := new RPrUnitDecorator(r.RPr);
|
||
text := note_module.GetFootnoteOrderNumber();
|
||
if ifString(text) then {self.}SplitTextToTextRange(body_range_array_, text, rpr, nil);
|
||
end;
|
||
|
||
function ParagraphRange.RObject(r: R);
|
||
begin
|
||
id := r.Object.Shape.Imagedata.Id;
|
||
[image_type, image] := {self.}GetImageData(id);
|
||
if not image then return;
|
||
style := r.Object.Shape.Style;
|
||
style_arr := str2array(style, ";");
|
||
for _,str in style_arr do
|
||
begin
|
||
if startsStr("width:", str) then w := strtofloat(str[7:length(str)-2]);
|
||
else if startsStr("height:", str) then h := strtofloat(str[8:length(str)-2]);
|
||
end
|
||
image_range := new ImageRange();
|
||
image_range.Image := image;
|
||
image_range.Type := image_type;
|
||
image_range.StartX := 0;
|
||
image_range.StartY := 0;
|
||
image_range.Width := w;
|
||
image_range.DynamicHeight := h;
|
||
body_range_array_[length(body_range_array_)] := image_range;
|
||
end;
|
||
|
||
function ParagraphRange.RFldChar(r: R; stack: Stack);
|
||
begin
|
||
fld_struct := stack.Pop();
|
||
|
||
if r.FldChar.FldCharType = "begin" then
|
||
fld_struct.EndFld := false;
|
||
else if r.FldChar.FldCharType = "end" then
|
||
fld_struct.EndFld := true;
|
||
else if r.FldChar.FldCharType = "separate" then
|
||
fld_struct.Separate := true;
|
||
|
||
instr_text := ifString(r.InstrText.Text) ? trim(r.InstrText.Text) : "";
|
||
if instr_text <> "" then
|
||
begin
|
||
if instr_text = "QUOTE" then
|
||
fld_struct.Quote := true;
|
||
else if instr_text = "\\* MERGEFORMAT" then
|
||
fld_struct.MergeFormat := true;
|
||
else if instr_text = "PAGE \\* Arabic \\* MERGEFORMAT" or instr_text = "PAGE \\* MERGEFORMAT" then
|
||
fld_struct.PageArabicMergeFormat := true;
|
||
else if instr_text = "NUMPAGES" then
|
||
fld_struct.NumPages := true;
|
||
else if instr_text = "\\* Arabic \\* MERGEFORMAT" then
|
||
fld_struct.ArabicMergeFormat := true;
|
||
else if instr_text = "NUMPAGES \\* Arabic \\* MERGEFORMAT" then
|
||
fld_struct.NumPages := fld_struct.ArabicMergeFormat := true;
|
||
end
|
||
if fld_struct.Quote then
|
||
begin
|
||
if not fld_struct.EndFld and not fld_struct.Separate then
|
||
begin
|
||
stack.Push(fld_struct);
|
||
return;
|
||
end
|
||
end
|
||
else if fld_struct.PageArabicMergeFormat then
|
||
begin
|
||
if fld_struct.Separate then
|
||
begin
|
||
r.T.Text := tostring(page_.Number);
|
||
{self.}RT(r, nil);
|
||
fld_struct.PageArabicMergeFormat := false;
|
||
end
|
||
end
|
||
else if fld_struct.ArabicMergeFormat then
|
||
begin
|
||
if fld_struct.Separate then
|
||
begin
|
||
rpr := new RPrUnitDecorator(r.RPr);
|
||
numpages_index := length(body_range_array_);
|
||
placeholder_array_ := array(numpages_index, rpr);
|
||
fld_struct.NumPages := false;
|
||
end
|
||
end
|
||
if not fld_struct.EndFld then
|
||
begin
|
||
stack.Push(fld_struct);
|
||
end
|
||
if ifObj(r.Drawing) then {self.}RDrawing(r);
|
||
else if ifObj(r.AlternateContent) then {self.}RAlternateContent(r);
|
||
else if ifObj(r.FootnoteReference) then {self.}RFootnoteReference(r);
|
||
else if ifObj(r.Object) then {self.}RObject(r);
|
||
end;
|
||
|
||
function ParagraphRange.GetXYCordinates(): array of real;
|
||
begin
|
||
xml_file := docx_to_pdf_.GetCurrentXmlFile();
|
||
if xml_file = "document.xml" then
|
||
begin
|
||
[x, y] := page_.OriginalTextPoint();
|
||
end
|
||
else begin
|
||
x := page_.SectPr.PgMar.Left;
|
||
if ansiContainsStr(xml_file, "footer") then
|
||
y := page_.SectPr.PgMar.Bottom;
|
||
else if ansiContainsStr(xml_file, "header") then
|
||
y := page_.SectPr.PgSz.H - page_.SectPr.PgMar.Header;
|
||
end
|
||
return array(x, y);
|
||
end;
|
||
|
||
function ParagraphRange.GetImageData(id: string): PdfImage;
|
||
begin
|
||
xml_file := docx_to_pdf_.GetCurrentXmlFile();
|
||
if xml_file = "document.xml" then
|
||
rels_adapter := docx_components_module_.GetDocumentRelsAdapter();
|
||
else if ansiContainsStr(xml_file, "footer") then
|
||
rels_adapter := docx_components_module_.GetFtrRelsAdapter(xml_file);
|
||
else if ansiContainsStr(xml_file, "header") then
|
||
rels_adapter := docx_components_module_.GetHdrRelsAdapter(xml_file);
|
||
rel := rels_adapter.GetRelationshipById(id);
|
||
image_path := "word/" + rel.Target;
|
||
image := docx_components_module_.Zip().Get(image_path);
|
||
data := image.Data();
|
||
image_path := docx_to_pdf_.GetCachePath(image_path);
|
||
writeFile(rwBinary(), "", image_path, 0, length(data), data);
|
||
image := nil;
|
||
image_type := GetImageFileType(data);
|
||
case image_type of
|
||
"png":
|
||
image := docx_to_pdf_.PdfFile().LoadPngImageFromFile("", image_path);
|
||
"jpg":
|
||
image := docx_to_pdf_.PdfFile().LoadJpegImageFromFile("", image_path);
|
||
"emf":
|
||
image := docx_to_pdf_.PdfFile().LoadEmfImageFromFile("", image_path);
|
||
"wmf":
|
||
image := docx_to_pdf_.PdfFile().LoadWmfImageFromFile("", image_path);
|
||
end;
|
||
fileDelete("", image_path);
|
||
return array(image_type, image);
|
||
end;
|
||
|
||
function ParagraphRange.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)),
|
||
('name': 'emf', 'position': 40, 'value': array(0x20, 0x45, 0x4d, 0x46)),
|
||
('name': 'wmf', 'position': 0, 'value': array(0xd7, 0xcd, 0xc6, 0x9a)),
|
||
);
|
||
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 ParagraphRange.GetParagraphLineSpace(size: real; line: integer; line_rule: string): real;
|
||
begin
|
||
if not line then line := 240;
|
||
if line_rule = "exact" or line_rule = "atLeast" then
|
||
begin
|
||
lines := line / 240;
|
||
return size + lines;
|
||
end
|
||
else begin
|
||
lines := roundto(line / 240, -1);
|
||
multi := ceil(size / page_.BaseSize);
|
||
if (not ifnil(ppr_unit_decorator_.SnapToGrid) and not ppr_unit_decorator_.SnapToGrid) or
|
||
((ifnil(ppr_unit_decorator_.SnapToGrid) or ppr_unit_decorator_.SnapToGrid) and lines > multi) then
|
||
multi *= lines;
|
||
return page_.SectPr.DocGrid.LinePitch * multi;
|
||
end
|
||
end;
|
||
|
||
function ParagraphRange.SetPPPr(var p: P);
|
||
begin
|
||
new_ppr := new PPr();
|
||
styles := docx_components_module_.GetStyles();
|
||
new_ppr.Copy(styles.DocDefaults.PPrDefault.PPr);
|
||
new_ppr.RPr.Copy(styles.DocDefaults.RPrDefault.RPr);
|
||
{self.}SetPPrByStyleId(new_ppr, table_style_id_);
|
||
{self.}SetPPrByStyleId(new_ppr, p.PPr.PStyle.Val);
|
||
new_ppr.Copy(p.PPr);
|
||
p.PPr.Copy(new_ppr);
|
||
end;
|
||
|
||
function ParagraphRange.SetPPrByStyleId(var ppr: PPr; style_id: string);
|
||
begin
|
||
styles := docx_components_module_.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 ParagraphRange.SetRRPr(var r: R; ppr_unit_decorator: PPrUnitDecorator);
|
||
begin
|
||
new_rpr := new RPr();
|
||
styles := docx_components_module_.GetStyles();
|
||
new_rpr.Copy(styles.DocDefaults.RPrDefault.RPr);
|
||
{self.}SetRPrByTblStyleId(new_rpr, table_style_id_);
|
||
{self.}SetRPrByStyleId(new_rpr, ppr_unit_decorator.PStyle.Val);
|
||
{self.}SetRPrByStyleId(new_rpr, r.RPr.RStyle.Val);
|
||
new_rpr.Copy(r.RPr);
|
||
r.RPr.Copy(new_rpr);
|
||
end;
|
||
|
||
function ParagraphRange.SetRPrByTblStyleId(var rpr: RPr; style_id: string);
|
||
begin
|
||
styles := docx_components_module_.GetStylesAdapter();
|
||
style := styles.GetStyleByStyleId(style_id);
|
||
if ifObj(style) then
|
||
begin
|
||
based_on := style.BasedOn.Val;
|
||
{self.}SetRPrByTblStyleId(rpr, based_on);
|
||
rpr.Copy(style.RPr);
|
||
end
|
||
if table_style_type_ then
|
||
begin
|
||
tbl_style_pr := docx_components_module_.GetTblStylePrByType(table_style_id_, table_style_type_);
|
||
if tbl_style_pr then rpr.Copy(tbl_style_pr.RPr);
|
||
end
|
||
end;
|
||
|
||
function ParagraphRange.SetRPrByStyleId(var rpr: RPr; style_id: string);
|
||
begin
|
||
styles := docx_components_module_.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 ParagraphRange.SetLvlText();
|
||
begin
|
||
numbering_module := docx_components_module_.GetNumberingModule();
|
||
if not ifObj(numbering_module) then return;
|
||
[lvl_text, lvl] := numbering_module.GetNumberLvl(paragraph_.PPr);
|
||
if lvl_text = "" and ifnil(lvl) then return;
|
||
{self.}SetRRPr(lvl, ppr_unit_decorator_);
|
||
rpr := new RPrUnitDecorator(lvl.RPr);
|
||
// {self.}SplitTextToTextRange(bullet_range_array_, lvl_text, rpr);
|
||
{self.}SplitTextToTextRange(body_range_array_, lvl_text, rpr);
|
||
end;
|
||
|
||
function ParagraphRange.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;
|
||
|
||
function ParagraphRange.GetLastPage(): Page;
|
||
begin
|
||
return page_;
|
||
end;
|
||
|
||
function ParagraphRange.AdjustRangeOffset(pg: Page; x_offset: real; y_offset: real);
|
||
begin
|
||
for _,line_range in line_range_array_ do
|
||
line_range.AdjustRangeOffset(pg, x_offset, y_offset);
|
||
end;
|
||
|
||
function ParagraphRange.GetParagraphLineRangeArr(): array of ParagraphLineRange;
|
||
begin
|
||
return line_range_array_;
|
||
end;
|
||
|
||
function ParagraphRange.Empty(): boolean;
|
||
begin
|
||
return empty_;
|
||
end;
|
||
|
||
function ParagraphRange.Offset(x: real; y: real);
|
||
begin
|
||
for _,line_range in line_range_array_ do
|
||
line_range.Offset(x, y);
|
||
end;
|
||
|
||
function ParagraphRange.OMathPara(element: OMathPara);
|
||
begin
|
||
math_range := new MathRange(docx_to_pdf_, page_, element);
|
||
math_range.StartX := {self.}StartX;
|
||
math_range.StartY := {self.}StartY - 15.6;
|
||
math_range.Calc();
|
||
// math_range.Do();
|
||
body_range_array_[length(body_range_array_)] := math_range;
|
||
end;
|
||
|
||
end.
|