1. 支持中文的“一二”等项目符号

2. 完善对页码类型的支持
This commit is contained in:
csh 2024-11-11 14:40:16 +08:00
parent 222577dd74
commit da65b2b6c3
2 changed files with 51 additions and 12 deletions

View File

@ -20,7 +20,7 @@ private
function SetLvlText();
function GetImageFileType(data: binary): string;
function GetImageData(id: string): PdfImage;
function GetParagraphLineSpace(size: real; line: integer): real;
function GetParagraphLineSpace(size: real; line: integer; line_rule: string): real;
function BasicRangesToLineRange(): tableArray;
function CheckAndAddPage(y: real; offset: real): boolean;
function GetUtf8CharLength(byte: string): integer;
@ -206,7 +206,7 @@ begin
end
if empty_flag then
begin
line_space := {self.}GetParagraphLineSpace(ppr_unit_decorator_.RPr.Sz.Val, ppr_unit_decorator_.Spacing.Line);
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;
@ -254,7 +254,7 @@ begin
bottom := {self.}StartY;
x := arr[0].EndX;
y := arr[0].EndY;
if top - {self.}GetParagraphLineSpace(arr[0].RPr.Sz.Val, ppr.Spacing.Line) then
if top - {self.}GetParagraphLineSpace(arr[0].RPr.Sz.Val, ppr.Spacing.Line, ppr.Spacing.LineRule) then
begin
top := docx_to_pdf_.GetCurrentTextPoint().Y;
bottom := top;
@ -263,7 +263,7 @@ begin
begin
if x + range.Width - {self.}StartX > {self.}Width + 1e-6 then // 换行
begin
line_space := {self.}GetParagraphLineSpace(max_size, ppr.Spacing.Line);
line_space := {self.}GetParagraphLineSpace(max_size, ppr.Spacing.Line, ppr.Spacing.LineRule);
bottom -= line_space;
max_size := 0;
if range.TSPage <> pg then
@ -281,7 +281,7 @@ begin
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);
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));
@ -386,7 +386,7 @@ begin
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);
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;
@ -649,6 +649,8 @@ begin
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
@ -757,13 +759,20 @@ begin
return '';
end;
function TSPdfParagraphRange.GetParagraphLineSpace(size: real; line: integer): real;
function TSPdfParagraphRange.GetParagraphLineSpace(size: real; line: integer; line_rule: string): real;
begin
sect_ware := docx_to_pdf_.GetCurrentSectWare();
if not line then line := 12;
lines := roundto(line / 12, -1);
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 / sect_ware.BaseSize) * lines;
return sect_ware.SectPr.DocGrid.LinePitch * multi;
end
end;
function TSPdfParagraphRange.SetPPr(var ppr: PPr);

View File

@ -3,6 +3,10 @@ public
function Create(number: NumberingAdapter);
function GetNumberLvl(ppr: PPr);
private
function CalculateNumber(num_fmt: string; num: integer): string;
function ChineseCountingThousand(n: integer): string;
private
numbering_adapter_: NumberingAdapter;
num_hash_: array of tslobj;
@ -44,7 +48,7 @@ begin
num_hash_[num_id][j] := 0;
end
n := i = ilvl_int ? num_hash_[num_id][i] + 1 : num_hash_[num_id][i];
dest_str := format("%d", n);
dest_str := {self.}CalculateNumber(v.NumFmt.Val, n);
lvl_text := replaceStr(lvl_text, source_str, dest_str);
end
num_hash_[num_id][ilvl_int]++;
@ -54,3 +58,29 @@ begin
end
return array("", nil);
end
function TSNumberingWare.CalculateNumber(num_fmt: string; num: integer): string;
begin
if num_fmt = "decimal" then
return format("%d", num);
else if num_fmt = "chineseCountingThousand" then
return {self.}ChineseCountingThousand(num);
end;
function TSNumberingWare.ChineseCountingThousand(n: integer): string;
begin
chinese_digits := array("零", "一", "二", "三", "四", "五", "六", "七", "八", "九");
chinese_units := array("", "十", "百", "千");
if n < 10 then return chinese_digits[n];
result := "";
num_str := inttostr(n);
len := length(num_str);
for i:=1 to len do
begin
digit_int := strtoint(num_str[i]);
if digit_int <> 0 then
result += chinese_digits[digit_int] + chinese_units[len - i];
end
if length(result) >= 6 and result[:6] = "一十" then result := result[4:];
return result;
end;