From 5c93255461afe8f9963cf021dfd2e6fc526a6b34 Mon Sep 17 00:00:00 2001 From: csh Date: Tue, 18 Feb 2025 10:23:49 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E9=87=8D=E6=9E=84=E4=BB=A3=E7=A0=81=202.?= =?UTF-8?q?=20=E4=BC=98=E5=8C=96=E4=B8=AD=E6=96=87=E5=92=8C=E8=A5=BF?= =?UTF-8?q?=E6=96=87=E5=AD=97=E7=AC=A6=E9=97=B4=E8=B7=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TSDocxToPdf.tsf | 469 +++++------- range/Advanced/TSPdfCellRange.tsf | 360 --------- range/Advanced/TSPdfColumnRange.tsf | 64 -- range/Advanced/TSPdfLineRange.tsf | 93 --- range/Advanced/TSPdfParagraphRange.tsf | 963 ------------------------- range/Advanced/TSPdfTableRange.tsf | 342 --------- range/basic/TSPdfBasicRange.tsf | 29 - range/basic/TSPdfBordersRange.tsf | 88 --- range/basic/TSPdfImageRange.tsf | 35 - range/basic/TSPdfTextRange.tsf | 51 -- utils/TSColorToolKit.tsf | 23 - utils/TSPage.tsf | 6 - utils/TSToc.tsf | 51 -- utils/TSTrProperty.tsf | 12 - ware/TSDocxComponentsWare.tsf | 129 ---- ware/TSFontWare.tsf | 127 ---- ware/TSNoteWare.tsf | 60 -- ware/TSNumberingWare.tsf | 88 --- ware/TSSectWare.tsf | 34 - 19 files changed, 174 insertions(+), 2850 deletions(-) delete mode 100644 range/Advanced/TSPdfCellRange.tsf delete mode 100644 range/Advanced/TSPdfColumnRange.tsf delete mode 100644 range/Advanced/TSPdfLineRange.tsf delete mode 100644 range/Advanced/TSPdfParagraphRange.tsf delete mode 100644 range/Advanced/TSPdfTableRange.tsf delete mode 100644 range/basic/TSPdfBasicRange.tsf delete mode 100644 range/basic/TSPdfBordersRange.tsf delete mode 100644 range/basic/TSPdfImageRange.tsf delete mode 100644 range/basic/TSPdfTextRange.tsf delete mode 100644 utils/TSColorToolKit.tsf delete mode 100644 utils/TSPage.tsf delete mode 100644 utils/TSToc.tsf delete mode 100644 utils/TSTrProperty.tsf delete mode 100644 ware/TSDocxComponentsWare.tsf delete mode 100644 ware/TSFontWare.tsf delete mode 100644 ware/TSNoteWare.tsf delete mode 100644 ware/TSNumberingWare.tsf delete mode 100644 ware/TSSectWare.tsf diff --git a/TSDocxToPdf.tsf b/TSDocxToPdf.tsf index 95acd50..657bc64 100644 --- a/TSDocxToPdf.tsf +++ b/TSDocxToPdf.tsf @@ -1,116 +1,89 @@ type TSDocxToPdf = class +uses TSPdfEnumerations, DocxML, DocxMLAdapter, DocxMLUnitDecorator, DTPModules, DTPUtils, DTPAdvancedRanges; public function Create(alias: string; file: string); function Destroy(); function SaveToFile(alias: string; file: string): integer; function Transform(); - function GetPdf(): PdfFile; - function GetCurrentSectWare(): TSSectWare; - function GetCurrentTextPoint(): Point; - function GetCurrentHdrPoint(): Point; - function GetCurrentFtrPoint(): Point; - function GetCurrentNoteWare(): TSNoteWare; function GetCachePath(image_path: string): string; - function GetNextPage(page: TSPage): TSPage; function GetCurrentXmlFile(): string; + function GetCurrentNoteModule(): NoteModule; - function AddTSPage(flag: boolean): TSPage; - function LinkToToc(anchor: string; page: TSPage; left: real; top: real); - function AddToc(anchor: string; toc: TSToc); - function SetHeaderAndFooter(); + function AddPage(flag: boolean): Page; function ProcessNumpages(); - function CalculateTextCoordinates(): array of real; - function GetSymbol(symbol: string); - function AddDocxPage(pg: TSPage; r: R); - function AddColIndex(); - function UpdateDocxPageNumpages(); + // docx页码扩展 + function UpdateDocxPageNumPages(); function SaveDocxFile();overload; function SaveDocxFile(alias: string; file: string);overload; - property Font read ReadFont; - function ReadFont(); + property PdfFile read pdf_; + property Font read font_module_; + property PageManager read page_manager_module_; + property Toc read toc_module_; + property Note read note_module_; private function InitDocxComponents(alias: string; file: string); function InitCachePath(file: string); function InitPdfEncoder(); - function InitSectWare(); - function InitSymbol(); - function AllocateElementsToSectWare(); + function InitSectModule(); + function AllocateElementsToSectModule(); function ClassifyCols(var point: Point; cols: Cols); function SetHdr(type: string); function SetFtr(type: string); - function TransformP(var point: Point; paragraph: P; w: real; lb: real); - function TransformTbl(var point: Point; table: Tbl; w: real; lb: real); - function TransformSdt(var point: Point; sdt: Sdt; w: real; lb: real); - - function PrintGrid(page: PdfPage; sect_ware: TSSectWare); // test + function TransformP(paragraph: P; x: real; y: real; w: real; lb: real): ParagraphRange; + function TransformTbl(table: Tbl; x: real; y: real; w: real; lb: real): TableRange; + function TransformSdt(sdt: Sdt; x: real; y: real; w: real; lb: real): array of ParagraphRange; private pdf_: PdfFile; - docx_components_ware_: TSDocxComponentsWare; // TSDocxComponentsWare + docx_components_module_: DocxComponentsModule; // TSDocxComponentsModule cache_path_: string; // 临时目录,用来存放临时文件 - font_ware_: TSFontWare; // 字体部件 - sect_ware_array_: array of TSSectWare; // 页面布局部件数组 - current_sect_ware_: TSSectWare; + font_module_: FontModule; // 字体模块 + sect_module_array_: array of SectModule; // 页面布局模块数组 + current_sect_module_: SectModule; current_sect_pr_adapter_: SectPrAdapter; - symbol_: tableArray; - current_page_: TSPage; - page_array_: array of TSPage; - toc_array_: tableArray; - toc_unmacthed_array_: tableArray; + page_manager_module_: PageManagerModule; + current_page_: Page; + + toc_module_: TocModule; // 目录模块 + note_module_: NoteModule; // 脚注/尾注 + range_page_number_array_: tableArray; - text_point_: Point; // 定位坐标点 - hdr_point_: Point; // 页眉坐标 - ftr_point_: Point; // 页脚坐标 xml_file_: string; even_and_odd_flag_: boolean; - note_ware_: TSNoteWare; // 脚注/尾注 // 回写docx docx_page_arr_: tableArray; update_docx_pages_: boolean; end; -type Point = class - function Create(); - begin - {self.}X := 0; - {self.}Y := 0; - end - X: real; - Y: real; -end; - function TSDocxToPdf.Create(alias: string; file: string); begin pdf_ := new PdfFile(); - font_ware_ := new TSFontWare(pdf_); + pdf_.SetCompressionMode(TSPdfEnumerations.COMP_ALL); + font_module_ := new DTPModules.FontModule(pdf_); {self.}InitPdfEncoder(); {self.}InitDocxComponents(alias, file); {self.}InitCachePath(file); - {self.}InitSectWare(); - {self.}InitSymbol(); + {self.}InitSectModule(); current_page_ := nil; - page_array_ := array(); - toc_array_ := array(); - toc_unmacthed_array_ := array(); + page_manager_module_ := new DTPModules.PageManagerModule(pdf_); + + toc_module_ := new DTPModules.TocModule(); range_page_number_array_ := array(); - text_point_ := new Point(); - hdr_point_ := new Point(); - ftr_point_ := new Point(); xml_file_ := "document.xml"; - settings := docx_components_ware_.Settings; + settings := docx_components_module_.Settings; settings.XmlChildEvenAndOddHeaders.Deserialize(); even_and_odd_flag_ := settings.EvenAndOddHeaders ? true : false; - note_ware_ := nil; + note_module_ := new ; // 回写docx docx_page_arr_ := array(); @@ -129,60 +102,48 @@ end; function TSDocxToPdf.Transform(); begin - for _,sect_ware in sect_ware_array_ do + for _,sect_module in sect_module_array_ do begin - if current_sect_ware_ <> sect_ware then + if current_sect_module_ <> sect_module then begin - current_sect_ware_ := sect_ware; - current_sect_pr_adapter_ := new SectPrAdapter(current_sect_ware_.SectPr.GetObject()); - {self.}AddTSPage(true); + current_sect_module_ := sect_module; + current_sect_pr_adapter_ := new SectPrAdapter(current_sect_module_.SectPr.GetObject()); + {self.}AddPage(true); xml_file_ := "document.xml"; end // 分栏 - elements := sect_ware.Elements(); - cols := current_sect_ware_.SectPr.Cols; + elements := sect_module.Elements(); + cols := current_sect_module_.SectPr.Cols; if cols.Num > 1 then begin - columns := {self.}ClassifyCols(text_point_, cols); + columns := {self.}ClassifyCols(current_page_.TextPoint, cols); end else begin - w := current_sect_ware_.SectPr.PgSz.W - current_sect_ware_.SectPr.PgMar.Right - current_sect_ware_.SectPr.PgMar.Left; - lb := current_sect_ware_.SectPr.PgMar.Bottom; + w := current_page_.SectPr.PgSz.W - current_page_.SectPr.PgMar.Right - current_page_.SectPr.PgMar.Left; + lb := max(current_page_.SectPr.PgMar.Bottom, current_page_.FtrPoint.Y); for _,element in elements do begin - // if _ = 8 then break; - // if _ = 3 then - // println("_ = {}, xml_file_ = {}", _, xml_file_); - if element.LocalName = "p" then {self.}TransformP(text_point_, element, w, lb); - else if element.LocalName = "tbl" then {self.}TransformTbl(text_point_, element, w, lb); - else if element.LocalName = "sdt" then {self.}TransformSdt(text_point_, element, w, lb); + x := current_page_.TextPoint.X; + y := current_page_.TextPoint.Y; + // if _ = 266 then break; + // if _ = 20 then + // println("_ = {}, xml_file_ = {}, error = {}", _, xml_file_, pdf_.GetError()); + range := nil; + if element.LocalName = "p" then range := {self.}TransformP(element, x, y, w, lb); + else if element.LocalName = "tbl" then range := {self.}TransformTbl(element, x, y, w, lb); + else if element.LocalName = "sdt" then {self.}TransformSdt(element, x, y, w, lb); + if ifObj(range) then + begin + current_page_.TextPoint.Y := range.EndY; + range.Do(); + end end end end {self.}ProcessNumpages(); end; -function TSDocxToPdf.GetCurrentTextPoint(): Point; -begin - return text_point_; -end; - -function TSDocxToPdf.GetCurrentHdrPoint(): Point; -begin - return hdr_point_; -end; - -function TSDocxToPdf.GetCurrentFtrPoint(): Point; -begin - return ftr_point_; -end; - -function TSDocxToPdf.GetCurrentSectWare(): TSSectWare; -begin - return current_sect_ware_; -end; - function TSDocxToPdf.GetCachePath(image_path: string): string; begin return cache_path_ + extractFileName(image_path); @@ -193,16 +154,6 @@ begin return xml_file_; end; -function TSDocxToPdf.GetPdf(): PdfFile; -begin - return pdf_; -end; - -function TSDocxToPdf.ReadFont(); -begin - return font_ware_; -end; - function TSDocxToPdf.InitPdfEncoder(); begin pdf_.UseCNSFonts(); @@ -212,9 +163,8 @@ end; function TSDocxToPdf.InitDocxComponents(alias: string; file: string); begin - namespace "DOCX"; - docx_components_ware_ := new TSDocxComponentsWare(); - [err, msg] := docx_components_ware_.Open(alias, file, nil); + docx_components_module_ := new DTPModules.DocxComponentsModule(); + [err, msg] := docx_components_module_.Open(alias, file, nil); if err then raise "Open file error."; end; @@ -227,78 +177,72 @@ begin createDir("", cache_path_); end; -function TSDocxToPdf.InitSectWare(); +function TSDocxToPdf.InitSectModule(); begin - sect_ware_array_ := array(); - current_sect_ware_ := nil; + sect_module_array_ := array(); + current_sect_module_ := nil; current_sect_pr_adapter_ := nil; - document := docx_components_ware_.Document; + document := docx_components_module_.Document; document.Deserialize(); - {self.}AllocateElementsToSectWare(); + {self.}AllocateElementsToSectModule(); end; -function TSDocxToPdf.InitSymbol(); +function TSDocxToPdf.AllocateElementsToSectModule(); begin - symbol_ := array( - "": chr(118), - "": chr(110), - "": chr(108), - "": chr(117), - "": chr(108), - "o": chr(109), - "": chr(110), - ); -end; - -function TSDocxToPdf.AllocateElementsToSectWare(); -begin - elements := docx_components_ware_.Document.Body.Elements(); - ware := new TSSectWare(); - fp := function(ware, sect); + elements := docx_components_module_.Document.Body.Elements(); + module := new DTPModules.SectModule(); + fp := function(module, sect); begin sect := new SectPrUnitDecorator(sect); sect.PgSz.Orient := sect.PgSz.Orient ? "portrait" : "landscape"; sect.Type.Val := sect.Type.Val ?: "nextPage"; - ware.SectPr := sect; - ware.Do(); + module.SectPr := sect; end for i:=0 to length(elements)-1 do begin element := elements[i]; - ware.AddElement(element); + module.AddElement(element); if element.LocalName = "p" and ifObj(element.PPr.SectPr) then begin - ##fp(ware, element.PPr.SectPr); - sect_ware_array_[length(sect_ware_array_)] := ware; - ware := new TSSectWare(); + ##fp(module, element.PPr.SectPr); + sect_module_array_[length(sect_module_array_)] := module; + module := new DTPModules.SectModule(); end else if element.LocalName = "sectPr" and i = length(elements)-1 then begin - ##fp(ware, element); - sect_ware_array_[length(sect_ware_array_)] := ware; + ##fp(module, element); + sect_module_array_[length(sect_module_array_)] := module; end end - // println("sect_ware_array_ = {}", sect_ware_array_); + // println("sect_module_array_ = {}", sect_module_array_); end; -function TSDocxToPdf.AddTSPage(flag: boolean = false): TSPage; +function TSDocxToPdf.AddPage(flag: boolean = false): Page; begin - if current_sect_ware_.SectPr.Type.Val = "continuous" and length(page_array_) <> 0 then return; - page := pdf_.AddPage(); - page.SetWidth(current_sect_ware_.SectPr.PgSz.W); - page.SetHeight(current_sect_ware_.SectPr.PgSz.H); - // println("W = {}, H = {}", current_sect_ware_.SectPr.PgSz.W, current_sect_ware_.SectPr.PgSz.H); + if current_sect_module_.SectPr.Type.Val = "continuous" and page_manager_module_.Count <> 0 then return; - len := length(page_array_); - current_page_ := new TSPage(); - current_page_.Index := len; - current_page_.PdfPage := page; - current_page_.Number := flag ? ifnil(current_sect_ware_.SectPr.PgNumType.Start) ? 1 : current_sect_ware_.SectPr.PgNumType.Start : page_array_[len-1].Number + 1; - // println("len = {}, Number = {}", len, current_page_.Number); - page_array_[len] := current_page_; + page := page_manager_module_.NewPage(); + page.SectPr := current_sect_module_.SectPr; + page.Number := flag ? ifnil(current_sect_module_.SectPr.PgNumType.Start) ? 1 : current_sect_module_.SectPr.PgNumType.Start : page_manager_module_[page_manager_module_.Count() - 2].Number + 1; + page.BaseSize := round(page.SectPr.DocGrid.LinePitch * 0.75); + + // 正文、页眉页脚坐标 + // 页眉:从上往下,不需要调整 + page.HdrPoint.X := page.SectPr.PgMar.Left; + page.HdrPoint.Y := page.SectPr.PgSz.H - page.SectPr.PgMar.Header; + // 页脚:从下往上,需要调整 + page.FtrPoint.X := page.SectPr.PgMar.Left; + page.FtrPoint.Y := page.SectPr.PgSz.H; + // 正文:运行完页眉页脚后需要再次计算 + page.TextPoint.X := page.SectPr.PgMar.Left; + page.TextPoint.Y := page.SectPr.PgSz.H - max(page.SectPr.PgMar.Top, page.SectPr.PgMar.Header); + + current_page_ := page; + // println("TextPoint.X = {}, TextPoint.Y = {}", current_page_.TextPoint.X, current_page_.TextPoint.Y); + // println("len = {}, Number = {}", page_manager_module_.Count(), current_page_.Number); // 页眉页脚 - if current_sect_ware_.SectPr.TitlePg and current_page_.Index = 0 then + if current_sect_module_.SectPr.TitlePg and current_page_.Index = 0 then type_name := "first"; else if not even_and_odd_flag_ then type_name := "default"; @@ -312,217 +256,152 @@ begin {self.}SetFtr(type_name); xml_file_ := bk_file; - // 正文坐标 - [x, y] := {self.}CalculateTextCoordinates(); - text_point_.X := x; - text_point_.Y := y; - -if sysparams["_PDF_PAGE_GRID_DEBUG_"] then - {self.}PrintGrid(page, current_sect_ware_); + // println("W = {}, H = {}", current_page_.SectPr.PgSz.W, current_page_.SectPr.PgSz.H); + // println("Top = {}, Bottom = {}", current_page_.SectPr.PgMar.Top, current_page_.SectPr.PgMar.Bottom); + // println("Left = {}, Right = {}", current_page_.SectPr.PgMar.Left, current_page_.SectPr.PgMar.Right); + // println("Header = {}", current_page_.SectPr.PgMar.Header); + // println("TextPoint.X = {}, TextPoint.Y = {}", current_page_.TextPoint.X, current_page_.TextPoint.Y); + // println("HdrPoint.X = {}, HdrPoint.Y = {}", current_page_.HdrPoint.X, current_page_.HdrPoint.Y); + // println("FtrPoint.X = {}, FtrPoint.Y = {}", current_page_.FtrPoint.X, current_page_.FtrPoint.Y); return current_page_; end; -function TSDocxToPdf.CalculateTextCoordinates(): array of real; -begin - x := current_sect_ware_.SectPr.PgMar.Left; - y := min(current_sect_ware_.SectPr.PgSz.H - max(current_sect_ware_.SectPr.PgMar.Top, current_sect_ware_.SectPr.PgMar.Header), hdr_point_.Y); - return array(x, y); -end; - function TSDocxToPdf.SetFtr(type: string); begin - ftr_point_.X := current_sect_ware_.SectPr.PgMar.Left; - ftr_point_.Y := current_sect_ware_.SectPr.PgMar.Bottom; footer_reference := current_sect_pr_adapter_.GetFooterReferenceByType(type); + ftr_range := array(); if ifObj(footer_reference) then begin - rels_adapter := docx_components_ware_.GetDocumentRelsAdapter(); + rels_adapter := docx_components_module_.GetDocumentRelsAdapter(); rel := rels_adapter.GetRelationshipById(footer_reference.Id); - w := current_sect_ware_.SectPr.PgSz.W - current_sect_ware_.SectPr.PgMar.Right - current_sect_ware_.SectPr.PgMar.Left; + w := current_page_.SectPr.PgSz.W - current_page_.SectPr.PgMar.Right - current_page_.SectPr.PgMar.Left; lb := 0; - obj := docx_components_ware_.GetFtr(rel.Target); + obj := docx_components_module_.GetFtr(rel.Target); xml_file_ := rel.Target; elements := obj.Elements(); for _,element in elements do begin - if element.LocalName = "p" then {self.}TransformP(ftr_point_, element, w, lb); + x := current_page_.FtrPoint.X; + y := current_page_.FtrPoint.Y; + range := nil; + if element.LocalName = "p" then range := {self.}TransformP(element, x, y, w, lb); + if ifObj(range) then + begin + current_page_.FtrPoint.Y := range.EndY; + ftr_range[length(ftr_range)] := range; + end end end + last_range := ftr_range[length(ftr_range)-1]; + y_offset := last_range.EndY - current_page_.SectPr.PgMar.Bottom; + height := 0; + for _,range in ftr_range do + begin + range.Offset(0, y_offset); + range.Do(); + height += range.DynamicHeight; + end + current_page_.FtrPoint.Y := current_page_.SectPr.PgMar.Bottom + height; end; function TSDocxToPdf.SetHdr(type: string); begin - hdr_point_.X := current_sect_ware_.SectPr.PgMar.Left; - hdr_point_.Y := current_sect_ware_.SectPr.PgSz.H - current_sect_ware_.SectPr.PgMar.Header; header_reference := current_sect_pr_adapter_.GetHeaderReferenceByType(type); if ifObj(header_reference) then begin - rels_adapter := docx_components_ware_.GetDocumentRelsAdapter(); + rels_adapter := docx_components_module_.GetDocumentRelsAdapter(); rel := rels_adapter.GetRelationshipById(header_reference.Id); - w := current_sect_ware_.SectPr.PgSz.W - current_sect_ware_.SectPr.PgMar.Right - current_sect_ware_.SectPr.PgMar.Left; + w := current_page_.SectPr.PgSz.W - current_page_.SectPr.PgMar.Right - current_page_.SectPr.PgMar.Left; lb := 0; - obj := docx_components_ware_.GetHdr(rel.Target); + obj := docx_components_module_.GetHdr(rel.Target); xml_file_ := rel.Target; elements := obj.Elements(); for _,element in elements do begin - if element.LocalName = "p" then {self.}TransformP(hdr_point_, element, w, lb); + x := current_page_.HdrPoint.X; + y := current_page_.HdrPoint.Y; + range := nil; + if element.LocalName = "p" then range := {self.}TransformP(element, x, y, w, lb); + if ifObj(range) then + begin + current_page_.HdrPoint.Y := range.EndY; + range.Do(); + current_page_.TextPoint.Y := min(current_page_.TextPoint.Y, range.EndY); + end end end end; -function TSDocxToPdf.TransformP(var point: Point; paragraph: P; w: real; lb: real); +function TSDocxToPdf.TransformP(paragraph: P; x: real; y: real; w: real; lb: real): ParagraphRange; begin - range := new TSPdfParagraphRange(self, current_page_, docx_components_ware_, paragraph); - range.StartX := point.X; - range.StartY := point.Y; + range := new ParagraphRange(self, current_page_, docx_components_module_, paragraph); + range.StartX := x; + range.StartY := y; range.Width := w; range.LowerBound := lb; + range.Parent := self; r := range.Calc(); - if r then range.Do(); + if r then return range; else range_page_number_array_[length(range_page_number_array_)] := range; - point.Y := range.EndY; + return nil; end; -function TSDocxToPdf.TransformTbl(var point: Point; table: Tbl; w: real; lb: real); +function TSDocxToPdf.TransformTbl(table: Tbl; x: real; y: real; w: real; lb: real): TableRange; begin - range := new TSPdfTableRange(self, current_page_, docx_components_ware_, table); - range.StartX := point.X; - range.StartY := point.Y; + range := new TableRange(self, current_page_, docx_components_module_, table); + range.StartX := x; + range.StartY := y; range.Width := w; range.LowerBound := lb; + range.Parent := self; range.Calc(); - range.Do(); - point.Y := range.EndY; + return range; end; -function TSDocxToPdf.TransformSdt(var point: Point; sdt: Sdt; w: real; lb: real); +function TSDocxToPdf.TransformSdt(sdt: Sdt; x: real; y: real; w: real; lb: real): array of ParagraphRange; begin ps := sdt.SdtContent.Ps(); + arr := array(); for _,p in ps do - {self.}TransformP(point, p, w, lb); + begin + range := {self.}TransformP(p, x, y, w, lb); + if ifObj(range) then arr[length(arr)] := range; + end + return arr; end; function TSDocxToPdf.ProcessNumpages(); begin - nums := page_array_[length(page_array_)-1].Number; + nums := page_manager_module_[page_manager_module_.Count() - 1].Number; for _,range in range_page_number_array_ do begin range.SetNumPages(nums); range.RangesToLines(); + range.Offset(0, current_page_.SectPr.PgSz.H - current_page_.SectPr.PgMar.Bottom); range.Do(); end end; -function TSDocxToPdf.GetNextPage(page: TSPage); +function TSDocxToPdf.UpdateDocxPageNumPages(); begin - return page_array_[page.Index + 1]; -end; - -function TSDocxToPdf.PrintGrid(page: PdfPage; sect_ware: TSSectWare); -begin - i := 0; - while true do - begin - y := text_point_.Y - i * sect_ware.SectPr.DocGrid.LinePitch; - if y <= sect_ware.SectPr.PgMar.Bottom then break; - page.SetLineWidth(0.05); - page.SetGrayStroke(0.75); - page.MoveTo(sect_ware.SectPr.PgMar.Left, y); - page.LineTo(sect_ware.SectPr.PgSz.W- sect_ware.SectPr.PgMar.Right, y); - page.Stroke(); - i++; - end - - x1 := sect_ware.SectPr.PgMar.Left; - y1 := sect_ware.SectPr.PgSz.H - sect_ware.SectPr.PgMar.Top; - x2 := sect_ware.SectPr.PgSz.W - sect_ware.SectPr.PgMar.Right; - y2 := y1; - x3 := x1; - y3 := sect_ware.SectPr.PgMar.Bottom; - x4 := x2; - y4 := y3; - page.SetLineWidth(0.05); - page.SetGrayStroke(0.5); - page.MoveTo(x1, y1); - page.LineTo(x2, y2); - page.Stroke(); - page.MoveTo(x1, y1); - page.LineTo(x3, y3); - page.Stroke(); - page.MoveTo(x2, y2); - page.LineTo(x4, y4); - page.Stroke(); - page.MoveTo(x3, y3); - page.LineTo(x4, y4); - page.Stroke(); -end; - -function TSDocxToPdf.AddToc(anchor: string; toc: TSToc); -begin - if ifarray(toc_array_[anchor]) then toc_array_[anchor] union= array(toc); - else toc_array_[anchor] := array(toc); - if toc_unmacthed_array_[anchor] then - begin - toc := toc_unmacthed_array_[anchor]; - {self.}LinkToToc(anchor, toc[0], toc[1], toc[2]); - toc_unmacthed_array_[anchor] := nil; - end -end; - -function TSDocxToPdf.LinkToToc(anchor: string; page: TSPage; left: real; top: real); -begin - arr := toc_array_[anchor]; - if ifnil(arr) then - begin - toc_unmacthed_array_[anchor] := array(page, left, top); - return; - end - dst := page.PdfPage.CreateDestination(); - dst.SetXYZ(left, top, 1); - for _,toc in arr do - toc.LinkAnnot(dst); - toc.AddPageNumber(page); - - if update_docx_pages_ then - begin - r := docx_page_arr_[anchor]; - r.T.Text := page.Number; - r.Serialize(); - end -end; - -function TSDocxToPdf.GetSymbol(symbol: string); -begin - // println("symbol = {}, symbol_ = {}", symbol, symbol_); - return symbol_[symbol]; -end; - -function TSDocxToPdf.AddDocxPage(anchor: string; r: R); -begin - docx_page_arr_[anchor] := r; -end; - -function TSDocxToPdf.UpdateDocxPageNumpages(); -begin - update_docx_pages_ := true; + toc_module_.UpdateDocxNumPages(); end; function TSDocxToPdf.SaveDocxFile();overload; begin - return docx_components_ware_.Save(); + return docx_components_module_.Save(); end; function TSDocxToPdf.SaveDocxFile(alias: string; file: string);overload; begin - return docx_components_ware_.SaveAs(alias, file); + return docx_components_module_.SaveAs(alias, file); end; -function TSDocxToPdf.GetCurrentNoteWare(): TSNoteWare; +function TSDocxToPdf.GetCurrentNoteModule(): NoteModule; begin - if ifnil(note_ware_) then note_ware_ := new TSNoteWare(current_sect_ware_); - return note_ware_; + if ifnil(note_module_) then note_module_ := new NoteModule(current_sect_module_); + return note_module_; end; function TSDocxToPdf.ClassifyCols(var point: Point; cols: Cols); @@ -531,8 +410,8 @@ begin columns := array(); x := point.X; y := point.Y; - w := current_sect_ware_.SectPr.PgSz.W - current_sect_ware_.SectPr.PgMar.Right - current_sect_ware_.SectPr.PgMar.Left; - lb := current_sect_ware_.SectPr.PgMar.Bottom; + w := current_page_.SectPr.PgSz.W - current_page_.SectPr.PgMar.Right - current_page_.SectPr.PgMar.Left; + lb := current_page_.SectPr.PgMar.Bottom; w_array := array(); ccols := cols.Cols(); for i:=0 to cols.Num-1 do @@ -547,7 +426,7 @@ begin rw := w / 3; x := point.X + i * rw + i * cols.Space; end - range := new TSPdfColumnRange(self, current_page_, docx_components_ware_); + range := new ColumnRange(self, current_page_, docx_components_module_); range.StartX := x; range.StartY := y; range.Width := rw; @@ -555,7 +434,7 @@ begin columns[length(columns)] := range; end i := 0; - elements := current_sect_ware_.Elements(); + elements := current_sect_module_.Elements(); range := columns[0]; for _,element in elements do begin diff --git a/range/Advanced/TSPdfCellRange.tsf b/range/Advanced/TSPdfCellRange.tsf deleted file mode 100644 index b11de3f..0000000 --- a/range/Advanced/TSPdfCellRange.tsf +++ /dev/null @@ -1,360 +0,0 @@ -type TSPdfCellRange = class(TSPdfBasicRange) -public - function Create(table_range: TSPdfTableRange; docx_to_pdf: TSDocxToPdf; pg: TSPage; components: TSDocxComponentsWare; tc: Tc; tbl_pr: TblPr; trp: TSTrProperty); - function Calc(); - function Do();override; - function SetTSPage(page: TSPage); - function GetLastPage(); - function AlignHeight(height: real); - function SetVAlign(); - function IsReComputeByCantSplit(): boolean; - function IfRemoveEmptyRectangle(): boolean; - function SetTop(); - - property Tc read tc_; - -private - function GetCellPrType(): string; - function SetBorderRange(range: TSPdfBordersRange); - -public - RemoveFlag: boolean; - Row: integer; - Col: integer; - VMerge: integer; - [weakref]TSTrPr: TSTrProperty; - -private - [weakref]parent_: TSPdfTableRange; - [weakref]docx_to_pdf_: TSDocxToPdf; - [weakref]last_page_: TSPage; - [weakref]docx_components_ware_: TSDocxComponentsWare; - [weakref]tc_: Tc; - [weakref]tbl_pr_: TblPr; - tc_pr_unit_decorator_: TcPrUnitDecorator; - region_array_: array of Region; // 单元格可能跨页,所以可能存在多个 - top_: boolean; -end; - -type Region = class - function Create(); - begin - BordersRange := new TSPdfBordersRange(); - RangeArr := array(); - end - - BordersRange: TSPdfBordersRange; - RangeArr: array of TSPdfBasicRange; -end; - -function TSPdfCellRange.Create(table_range: TSPdfTableRange; docx_to_pdf: TSDocxToPdf; pg: TSPage; components: TSDocxComponentsWare; tc: Tc; tbl_pr: TblPr; trp: TSTrProperty); -begin - parent_ := table_range; - docx_to_pdf_ := docx_to_pdf; - last_page_ := pg; - docx_components_ware_ := 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.}TSPage := last_page_; -end; - -function TSPdfCellRange.Calc(); -begin - region_array_ := array(); - region := new Region(); - region.BordersRange.EndX := {self.}StartX; - region.BordersRange.EndY := {self.}StartY; - region.BordersRange.Width := {self.}Width; - region.BordersRange.FixedHeight := {self.}FixedHeight; - region.BordersRange.TSPage := 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 TSPdfParagraphRange(docx_to_pdf_, last_page_, docx_components_ware_, element); - range.SetTblStyleIdAndType(tbl_pr_.TblStyle.Val, {self.}GetCellPrType()); - end - else if element.LocalName = "tbl" then - begin - range := new TSPdfTableRange(docx_to_pdf_, last_page_, docx_components_ware_, 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.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_.GetNextPage(last_page_); - if ifnil(last_page_) then last_page_ := docx_to_pdf_.AddTSPage(); - point := docx_to_pdf_.GetCurrentTextPoint(); - {self.}StartY := point.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 TSPdfCellRange.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 TSPdfCellRange.SetTSPage(page: TSPage); -begin - last_page_ := page; - {self.}TSPage := page; -end; - -function TSPdfCellRange.AlignHeight(height: 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; - return; - end - region.BordersRange.DynamicHeight := y_lowerbound; - arr := region.RangeArr; - region.RangeArr := array(); - hash := array(region.BordersRange.TSPage.Index: region); - last_page_ := {self.}TSPage; - [x, y] := docx_to_pdf_.CalculateTextCoordinates(); - ftr_point := docx_to_pdf_.GetCurrentFtrPoint(); - span := y - ftr_point.Y; - while surplus > span do - begin - last_page_ := docx_to_pdf_.GetNextPage(last_page_); - region := new Region(); - region.BordersRange.EndX := {self.}StartX; - region.BordersRange.EndY := y; - region.BordersRange.Width := {self.}Width; - region.BordersRange.DynamicHeight := span; - region.BordersRange.TSPage := 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.TSPage.Index] := region; - end - if surplus > 1e-6 then - begin - last_page_ := docx_to_pdf_.GetNextPage(last_page_); - region := new Region(); - region.BordersRange.EndX := {self.}StartX; - region.BordersRange.EndY := y; - region.BordersRange.Width := {self.}Width; - region.BordersRange.DynamicHeight := surplus; - region.BordersRange.TSPage := 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.TSPage.Index] := region; - {self.}EndY := region.BordersRange.EndY - surplus; - end - for _,range in arr do - begin - if range is class(TSPdfParagraphRange) then - begin - line_arr := range.GetLineRangeArr(); - for _,r in line_arr do - begin - region := hash[r.TSPage.Index]; - region.RangeArr[length(region.RangeArr)] := r; - end - end - end -end; - -function TSPdfCellRange.GetLastPage(); -begin - return last_page_; -end; - -function TSPdfCellRange.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.TSPage, nil, -offset); - end - end; -end; - -function TSPdfCellRange.IsReComputeByCantSplit(): boolean; -begin - if {self.}Tc.TcPr.VMerge then return false; - return {self.}TSTrPr.TrPr.CantSplit and last_page_ <> {self.}TSPage; -end; - -function TSPdfCellRange.IfRemoveEmptyRectangle(): boolean; -begin - if length(region_array_) < 2 then return false; - return length(region_array_[0].RangeArr) ? false : true; -end; - -function TSPdfCellRange.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 TSPdfCellRange.SetBorderRange(range: TSPdfBordersRange); -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 <> 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 <> 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 = 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 = 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 <> 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 = 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 <> 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 <> 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 = 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 TSPdfCellRange.SetTop(); -begin - top_ := true; -end; diff --git a/range/Advanced/TSPdfColumnRange.tsf b/range/Advanced/TSPdfColumnRange.tsf deleted file mode 100644 index ce264ee..0000000 --- a/range/Advanced/TSPdfColumnRange.tsf +++ /dev/null @@ -1,64 +0,0 @@ -type TSPdfColumnRange = class(TSPdfBasicRange) -public - function Create(docx_to_pdf: TSDocxToPdf; pg: TSPage; components: TSDocxComponentsWare); - function AddElement(ele: Element); - function Elements(): array of Element; - function GetLastPage(): TSPage; - function Do();override; - -private - [weakref]docx_to_pdf_: TSDocxToPdf; - [weakref]docx_components_ware_: TSDocxComponentsWare; - [weakref]page_: TSPage; - elements_: array of Elements; - paragraph_: P; - last_y_: real; -end; - -function TSPdfColumnRange.Create(docx_to_pdf: TSDocxToPdf; pg: TSPage; components: TSDocxComponentsWare); -begin - docx_to_pdf_ := docx_to_pdf; - page_ := pg; - docx_components_ware_ := components; - elements_ := array(); - last_y_ := 0; -end; - -function TSPdfColumnRange.AddElement(ele: Element); -begin - elements_[length(elements_)] := ele; -end; - -function TSPdfColumnRange.Elements(): array of Element; -begin - return elements_; -end; - -function TSPdfColumnRange.Do();override; -begin - x := {self.}StartX; - y := {self.}StartY; - for _,element in elements_ do - begin - range := nil; - if element.LocalName = "p" then - range := new TSPdfParagraphRange(docx_to_pdf_, page_, docx_components_ware_, element); - else if element.LocalName = "tbl" then - range := new TSPdfTableRange(docx_to_pdf_, page_, docx_components_ware_, element); - if ifnil(range) then continue; - range.StartX := x; - range.StartY := y; - range.Width := {self.}Width; - range.LowerBound := {self.}LowerBound; - range.Calc(); - range.Do(); - y := range.EndY; - page_ := range.GetLastPage(); - end - {self.}EndY := y; -end; - -function TSPdfColumnRange.GetLastPage(): TSPage; -begin - return page_; -end; diff --git a/range/Advanced/TSPdfLineRange.tsf b/range/Advanced/TSPdfLineRange.tsf deleted file mode 100644 index af47d50..0000000 --- a/range/Advanced/TSPdfLineRange.tsf +++ /dev/null @@ -1,93 +0,0 @@ -type TSPdfLineRange = class(TSPdfBasicRange) -public - function Create(pg: TSPage); - function Do();override; - function AddRange(range: TSPdfBasicRange); - function SetAllRangeProp(pg: TSPage; sx: real; sy: real; ex: real; ey: real; w: real; fh: real; dh: real); - function Align(jc: string); - function AdjustRangeOffset(page: TSPage; x_offset: real; y_offset: real); - function AlignRightBound(right_bound: real); - function Offset(x_offset: real; y_offset; real); - -private - range_array_: array of TSPdfBasicRange; -end; - -function TSPdfLineRange.Create(pg: TSPage); -begin - {self.}TSPage := pg; - range_array_ := array(); -end; - -function TSPdfLineRange.AddRange(range: TSPdfBasicRange); -begin - range_array_[length(range_array_)] := range; -end; - -function TSPdfLineRange.Do();override; -begin - for _,range in range_array_ do - range.Do(); -end; - -function TSPdfLineRange.SetAllRangeProp(pg: TSPage; 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.TSPage := pg; - if not ifnil(sx) then range.StartX := sx; - if not ifnil(sy) then range.StartY := sy; - if not ifnil(ex) then range.EndX := ex; - if not ifnil(ey) then range.EndY := ey; - if not ifnil(w) then range.Width := w; - if not ifnil(fh) then range.FixedHeight := fh; - if not ifnil(dh) then range.DynamicHeight := dh; - end -end; - -function TSPdfLineRange.Align(jc: string); -begin - offset := 0; - first := range_array_[0]; - last := range_array_[length(range_array_)-1]; - case jc of - "center": - offset := ({self.}Width + 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 TSPdfLineRange.AdjustRangeOffset(page: TSPage; x_offset: real; y_offset: real); -begin - if page <> {self.}TSPage 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 TSPdfLineRange.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 TSPdfLineRange.Offset(x_offset: real; y_offset; real); -begin - for _,range in range_array_ do - begin - range.EndX += x_offset; - range.EndY -= y_offset; - end -end; diff --git a/range/Advanced/TSPdfParagraphRange.tsf b/range/Advanced/TSPdfParagraphRange.tsf deleted file mode 100644 index 7d785ef..0000000 --- a/range/Advanced/TSPdfParagraphRange.tsf +++ /dev/null @@ -1,963 +0,0 @@ -type TSPdfParagraphRange = class(TSPdfBasicRange) -public - function Create(docx_to_pdf: TSDocxToPdf; pg: TSPage; components: TSDocxComponentsWare; paragraph: P); - function Calc(); - function Do();override; - function SetTblStyleIdAndType(style_id: string; type: string); - function SetNumPages(num: integer); - function RangesToLines(); - function GetLastPage(): TSPage; - function AdjustRangeOffset(page: TSPage; x_offset: real; y_offset: real); - function GetLineRangeArr(): array of TSPdfLineRange; - function Empty(): boolean; - function Offset(x: real; y: real); - -private - function SetPPr(var ppr: PPr); - function SetPPrByStyleId(var ppr: PPr; style_id: string); - function SetRPr(var rpr; ppr: 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 BasicRangesToLineRange(): tableArray; - function CheckAndAddPage(y: real; offset: real): boolean; - function GetUtf8CharLength(byte: string): integer; - function SplitTextToTextRange(text: string; rpr: RPrUnitDecorator; link: string); - function RToTextRange(r: R; link: string); - function RDrawing(r: R); - function RAlternateContent(r: R); - function RFootnoteReference(r: R); - function RObject(r: R); - function RFldChar(r: R; stack: Stack); - function RFootnoteRef(r: R); - function SetLinesAlignment(); - function ResetCoordinates(); - function NewLineRange(): TSPdfLineRange; - function BookMarkLinkToc(); - function HyperlinkToToc(); - function HyperlinkToTextRange(hyperlink: Hyperlink; ppr: PPrUnitDecorator); - function GetXYCordinates(): array of real; - function AlignRightBound(); - function Init(); - -private - [weakref]docx_to_pdf_: TSDocxToPdf; - [weakref]docx_components_ware_: TSDocxComponentsWare; - [weakref]paragraph_: P; - [weakref]page_: TSPage; - range_array_: array of TSPdfBasicRange; - line_range_array_: array of TSPdfLineRange; - 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; -end; - -type FldStruct = class -public - function create(); - begin - FldLock := false; - MergeFormat := false; - Quote := false; - Separate := false; - PageArabicMergeFormat := false; - NumPages := false; - ArabicMergeFormat := false; - EndFld := false; - end; -public - FldLock: boolean; - MergeFormat: boolean; - Quote: boolean; - Separate: boolean; - PageArabicMergeFormat: boolean; - NumPages: boolean; - ArabicMergeFormat: boolean; - EndFld: boolean; -end; - -type Stack = class -public - function create(); - begin - arr_ := array(); - index_ := 0; - end; - function Pop(); - begin - if index_ = 0 then return nil; - index_--; - ret := arr_[index_]; - arr_[index_] := nil; - return ret; - end; - function Push(element: any); - begin - arr_[index_++] := element; - end; - function Empty(): boolean; - begin - return index_ = 0; - end; -private - arr_: tableArray; - index_: integer; -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; - table_style_id_ := ""; - table_style_type_ := ""; - range_array_ := array(); - line_range_array_ := array(); - hyperlink_array_ := array(); - bookmark_array_ := array(); - empty_ := false; - {self.}TSPage := page_; -end; - -function TSPdfParagraphRange.Init(); -begin - 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; - {self.}SetLvlText(); -end; - -function TSPdfParagraphRange.Calc(): tableArray; -begin - // ppr.rpr是无效的,应该以ppr.pStyle为准 - if ifnil(paragraph_.XmlChildPPr) then paragraph_.XmlChildPPr := new PPr(); - {self.}SetPPr(paragraph_.PPr); - ppr_unit_decorator_ := new PPrUnitDecorator(paragraph_.PPr); - {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 Stack(); - for _,element in elements do - begin - if element.LocalName = "r" then - begin - empty_flag := false; - if ifnil(element.XmlChildRPr) then element.XmlChildRPr := new RPr(); - {self.}SetRPr(element.RPr, ppr_unit_decorator_); - - if element.FldChar.FldCharType = "begin" then - begin - fld_struct := new 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; - // {self.}CheckAndAddPage({self.}LowerBound, 1); - else if ifObj(element.Drawing) then {self.}RDrawing(element); - else if ifObj(element.AlternateContent) then {self.}RAlternateContent(element); - else if ifObj(element.FootnoteReference) then {self.}RFootnoteReference(element); - else if ifObj(element.Object) then {self.}RObject(element); - else if element.FootnoteRef then {self.}RFootnoteRef(element); - else {self.}RToTextRange(element, bookmark_name); - end - else if element.LocalName = "fldSimple" then - 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); - 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, 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 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, ppr.Spacing.LineRule) 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, ppr.Spacing.LineRule); - 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.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_.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(); - char_type := false; - separate := false; - for _,r in rs do - begin - if r.FldChar.FldCharType = "begin" then char_type := true; - // TODO:officexml项目是否应该保留赋值接口,如何统一 - if char_type then - begin - if r.FldChar.FldCharType = "separate" then - begin - separate := true; - continue; - end - if r.FldChar.FldCharType = "end" then - separate := char_type := false; - if separate then - docx_to_pdf_.AddDocxPage(hyperlink.Anchor, r); - end - else begin - if ifnil(r.XmlChildRPr) then r.XmlChildRPr := new RPr(); - {self.}SetRPr(r.RPr, ppr_unit_decorator_); - r.RPr.Color.Val := nil; - {self.}RToTextRange(r, hyperlink.Anchor); - end - 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.SetTblStyleIdAndType(style_id: string; type: string); -begin - table_style_id_ := style_id; - table_style_type_ := type; -end; - -function TSPdfParagraphRange.NewLineRange(): TSPdfLineRange; -begin - line_range := new TSPdfLineRange(page_); - line_range.StartX := {self.}StartX; - 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, 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(TSPdfTextRange)) 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.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 - if range is class(TSPdfTextRange) 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(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(); - {self.}AlignRightBound(); -end; - -function TSPdfParagraphRange.SetLinesAlignment(); -begin - for _,line_range in line_range_array_ do - line_range.Align(ppr_unit_decorator_.Jc.Val); -end; - -function TSPdfParagraphRange.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 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]); - a_word := text[pos : pos+num-1]; - word := utf8ToAnsi(a_word); - if num <> 1 and word = "?" then - begin - word := docx_to_pdf_.GetSymbol(a_word); - if ifnil(word) then word := "u"; - font_obj := docx_to_pdf_.Font.GetSymbolFont(); - 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 - 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); - pos += num; - end -end; - -function TSPdfParagraphRange.RDrawing(r: R); -begin - if ifObj(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 TSPdfImageRange(); - image_range.Image := image; - image_range.Type := image_type; - 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) 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 TSPdfImageRange(); - 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.TSPage := page_; - image_range.Do(); - end -end; - -function TSPdfParagraphRange.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 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.RFootnoteReference(r: R); -begin - id := R.FootnoteReference.Id; - footnotes_adapter := docx_components_ware_.GetFootnotesAdapter(); - footnote := footnotes_adapter.GetFootnoteById(id); - sect_ware := docx_to_pdf_.GetCurrentSectWare(); - w := sect_ware.SectPr.PgSz.W - sect_ware.SectPr.PgMar.Right - sect_ware.SectPr.PgMar.Left; - lb := {self.}LowerBound; - [x, y] := docx_to_pdf_.CalculateTextCoordinates(); - elements := footnote.Elements(); - for _,element in elements do - begin - if element.LocalName = "p" then - begin - range := new TSPdfParagraphRange(docx_to_pdf_, page_, docx_components_ware_, element); - range.StartX := x; - range.StartY := y; - range.Width := w; - range.LowerBound := {self.}LowerBound; - range.Calc(); - range.Offset(0, y - range.DynamicHeight - {self.}LowerBound); - range.Do(); - {self.}LowerBound += range.DynamicHeight; - rpr := new RPrUnitDecorator(r.RPr); - text := docx_to_pdf_.GetCurrentNoteWare().GetIndex(); - if ifString(text) then {self.}SplitTextToTextRange(text, rpr, nil); - return; - // break; - end - end - // range := new TSPdfParagraphRange(self, page_, docx_components_ware_, ); -end; - -function TSPdfParagraphRange.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 TSPdfImageRange(); - 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; - range_array_[length(range_array_)] := image_range; -end; - -function TSPdfParagraphRange.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; - if r.FldChar.FldLock then - fld_struct.FldLock := 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.}RToTextRange(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(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 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), data); - image := nil; - image_type := GetImageFileType(data); - case image_type of - "png": - image := docx_to_pdf_.GetPdf().LoadPngImageFromFile("", image_path); - "jpg": - image := docx_to_pdf_.GetPdf().LoadJpegImageFromFile("", image_path); - "emf": - image := docx_to_pdf_.GetPdf().LoadEmfImageFromFile("", image_path); - "wmf": - image := docx_to_pdf_.GetPdf().LoadWmfImageFromFile("", image_path); - end; - fileDelete("", image_path); - return array(image_type, 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)), - ('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 TSPdfParagraphRange.GetParagraphLineSpace(size: real; line: integer; line_rule: string): real; -begin - sect_ware := docx_to_pdf_.GetCurrentSectWare(); - 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); - 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 sect_ware.SectPr.DocGrid.LinePitch * multi; - end -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, table_style_id_); - {self.}SetPPrByStyleId(new_ppr, ppr.PStyle.Val); - if ifObj(ppr) then - begin - new_ppr.Copy(ppr); - ppr.Copy(new_ppr); - end -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.}SetRPrByTblStyleId(new_rpr, table_style_id_); - {self.}SetRPrByStyleId(new_rpr, ppr.PStyle.Val); - {self.}SetRPrByStyleId(new_rpr, rpr.RStyle.Val); - if ifObj(rpr) then - begin - new_rpr.Copy(rpr); - rpr.Copy(new_rpr); - end -end; - -function TSPdfParagraphRange.SetRPrByTblStyleId(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.}SetRPrByTblStyleId(rpr, based_on); - rpr.Copy(style.RPr); - end - if table_style_type_ then - begin - tbl_style_pr := docx_components_ware_.GetTblStylePrByType(table_style_id_, table_style_type_); - if tbl_style_pr then rpr.Copy(tbl_style_pr.RPr); - end -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; - -function TSPdfParagraphRange.GetLastPage(): TSPage; -begin - return page_; -end; - -function TSPdfParagraphRange.AdjustRangeOffset(page: TSPage; x_offset: real; y_offset: real); -begin - for _,line_range in line_range_array_ do - line_range.AdjustRangeOffset(page, x_offset, y_offset); -end; - -function TSPdfParagraphRange.GetLineRangeArr(): array of TSPdfLineRange; -begin - return line_range_array_; -end; - -function TSPdfParagraphRange.Empty(): boolean; -begin - return empty_; -end; - -function TSPdfParagraphRange.Offset(x: real; y: real); -begin - for _,line_range in line_range_array_ do - line_range.Offset(x, y); -end; - -function TSPdfParagraphRange.RFootnoteRef(r: R); -begin - note_ware := docx_to_pdf_.GetCurrentNoteWare(); - rpr := new RPrUnitDecorator(r.RPr); - text := note_ware.GetFootnoteOrderNumber(); - if ifString(text) then {self.}SplitTextToTextRange(text, rpr, nil); -end; diff --git a/range/Advanced/TSPdfTableRange.tsf b/range/Advanced/TSPdfTableRange.tsf deleted file mode 100644 index b25561e..0000000 --- a/range/Advanced/TSPdfTableRange.tsf +++ /dev/null @@ -1,342 +0,0 @@ -type TSPdfTableRange = class(TSPdfBasicRange) -public - function Create(docx_to_pdf: TSDocxToPdf; pg: TSPage; components: Components; table: Tbl); - function Do();override; - function Calc(); - function GetLastPage(): TSPage; - function Rows(): integer; - function Cols(): integer; - -private - function GetCellMatrix(grid_cols: array of GridColUnitDecorator); - 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_: TSPage; - [weakref]docx_components_ware_: Components; - [weakref]table_: Tbl; - tbl_pr_unit_decorator_: TblPrUnitDecorator; - ts_trpr_array_: array of TSTrProperty; - cell_range_matrix_: array of TSPdfCellRange; - rows_: integer; - cols_: integer; -end; - -function TSPdfTableRange.Create(docx_to_pdf: TSDocxToPdf; pg: PdfPage; components: Components; table: Tbl); -begin - docx_to_pdf_ := docx_to_pdf; - last_page_ := pg; - docx_components_ware_ := Components; - table_ := table; - ts_trpr_array_ := array(); - cell_range_matrix_ := array(); - rows_ := 0; - cols_ := 0; - {self.}TSPage := last_page_; -end; - -function TSPdfTableRange.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的值 - {self.}GetCellMatrix(grid_cols); -end; - -function TSPdfTableRange.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 ifnil(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 TSPdfTableRange.GetCellMatrix(grid_cols: array of GridColUnitDecorator); -begin - 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 TSPdfTableRange.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 TSTrProperty(); - 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 - tc_x += grid_cols[pos++].W; - continue; - end - cell_range := new TSPdfCellRange(self, docx_to_pdf_, last_page_, docx_components_ware_, 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.Row := i; - cell_range.Col := pos; - cell_range_matrix_[i][pos] := cell_range; - pos++; - for k:=grid_span.Val-1 downto 1 do - cell_range.Width += grid_cols[pos++].W; - 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 TSPdfTableRange.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 ifnil(range) then - begin - j++; - continue; - end - range.StartY := tc_y; - range.SetTSPage(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_.GetNextPage(last_page_); - [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); - 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); - range.SetVAlign(); - {self.}EndY := range.EndY; - last_page_ := range.GetLastPage(); - end - i++; - end -end; - -function TSPdfTableRange.OverrideTcPrByTblStylePrType(var tc_pr: TcPr; type: string); -begin - // tc_pr应该是经过外层copy的 - tbl_style_pr := docx_components_ware_.GetTblStylePrByType(tbl_pr_unit_decorator_.TblStyle.Val, type); - if tbl_style_pr then tc_pr.Copy(tbl_style_pr.TcPr); -end; - -function TSPdfTableRange.ResetCoordinates(tbl_pr: TblPr; grid_cols: array of GridCol); -begin - total_width := 0; - for _,grid_col in grid_cols do - total_width += grid_col.W; - diff := total_width - {self.}Width; - case tbl_pr.Jc.Val of - "center": - begin - offset := diff/2; - {self.}StartX -= offset; - end - "right": - begin - {self.}StartX -= diff; - end - end; - {self.}Width := total_width; -end; - -function TSPdfTableRange.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 TSPdfTableRange.SetTblPrByStyleId(var tbl_pr: TblPr; 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.}SetTblPrByStyleId(tbl_pr, based_on); - tbl_pr.Copy(style.TblPr); - end -end; - -function TSPdfTableRange.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 TSPdfTableRange.SetTrPrByStyleId(var tr_pr: TrPr; 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.}SetTrPrByStyleId(tr_pr, based_on); - tr_pr.Copy(style.TrPr); - end -end; - -function TSPdfTableRange.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 TSPdfTableRange.SetTcPrByStyleId(var tc_pr: TcPr; 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.}SetTcPrByStyleId(tc_pr, based_on); - tc_pr.Copy(style.TcPr); - end -end; - -function TSPdfTableRange.GetLastPage(): TSPage; -begin - return last_page_; -end; - -function TSPdfTableRange.Rows(): integer; -begin - return rows_; -end; - -function TSPdfTableRange.Cols(): integer; -begin - return cols_; -end; diff --git a/range/basic/TSPdfBasicRange.tsf b/range/basic/TSPdfBasicRange.tsf deleted file mode 100644 index 47aaab9..0000000 --- a/range/basic/TSPdfBasicRange.tsf +++ /dev/null @@ -1,29 +0,0 @@ -type TSPdfBasicRange = class -public - function Create(); - function Do();virtual; - -public - StartX: real; - StartY: real; // range的起始坐标(x,y) - EndX: real; - EndY: real; // range的结束坐标(x,y) - Width: real; - FixedHeight: real; - DynamicHeight: real; - LowerBound: real; - [weakref]TSPage: TSPage; -end; - -function TSPdfBasicRange.Create(); -begin - {self.}StartX := 0; - {self.}StartY := 0; - {self.}EndX := 0; - {self.}EndY := 0; - {self.}Width := 0; - {self.}FixedHeight := 0; - {self.}DynamicHeight := 0; - {self.}LowerBound := 0; - {self.}TSPage := nil; -end; diff --git a/range/basic/TSPdfBordersRange.tsf b/range/basic/TSPdfBordersRange.tsf deleted file mode 100644 index 8732b14..0000000 --- a/range/basic/TSPdfBordersRange.tsf +++ /dev/null @@ -1,88 +0,0 @@ -type TSPdfBordersRange = class(TSPdfBasicRange) -uses TSColorToolKit; -public - function Create(); - function Do();override; -public - TcPr: TcPr; - Left: boolean; - Top: boolean; - Right: boolean; - Bottom: boolean; - -private - function SetDash(val: string); - function DrawLine(border: Border; x1: real; y1: real; x2: real; y2: real); -end; - -function TSPdfBordersRange.Create(); -begin - class(TSPdfBasicRange).Create(); - {self.}TcPr := nil; - {self.}Left := false; - {self.}Top := false; - {self.}Right := false; - {self.}Bottom := false; -end; - -function TSPdfBordersRange.Do();override; -begin - // println("Left = {}, Top = {}, Right = {}, Bottom = {}, Tl2Br = {}, Tr2Bl = {}", Left, Top, Right, Bottom, Tl2Br, Tr2Bl); - borders := {self.}TcPr.TcBorders; - if {self.}TcPr.Shd.Fill and {self.}TcPr.Shd.Fill <> "auto" then - begin - [r, g, b] := TSColorToolKit.HexToRGB({self.}TcPr.Shd.Fill); - {self.}TSPage.PdfPage.SetRGBFill(r/255, g/255, b/255); - x := {self.}EndX; - y := {self.}EndY - {self.}DynamicHeight; - w := {self.}Width; - h := {self.}DynamicHeight; - tmp := borders.Left.Sz ? borders.Left.Sz / 2 : 0.25; - x += tmp; - w -= tmp; - w -= borders.Right.Sz ? borders.Right.Sz / 2 : 0.25; - tmp := borders.Bottom.Sz ? borders.Bottom.Sz / 2 : 0.25; - y += tmp; - h -= tmp; - h -= borders.Top.Sz ? borders.Top.Sz / 2 : 0.25; - - {self.}TSPage.PdfPage.Rectangle(x, y, w, h); - {self.}TSPage.PdfPage.Fill(); - {self.}TSPage.PdfPage.SetRGBFill(0, 0, 0); - {self.}Left := true; - end - if {self.}Left then - {self.}DrawLine(borders.Left, {self.}EndX, {self.}EndY, {self.}EndX, {self.}EndY - {self.}DynamicHeight); - if {self.}Top then - {self.}DrawLine(borders.Top, {self.}EndX, {self.}EndY, {self.}EndX + {self.}Width, {self.}EndY); - if {self.}Right then - {self.}DrawLine(borders.Right, {self.}EndX + {self.}Width, {self.}EndY, {self.}EndX + {self.}Width, {self.}EndY - {self.}DynamicHeight); - if {self.}Bottom then - {self.}DrawLine(borders.Bottom, {self.}EndX, {self.}EndY - {Self.}DynamicHeight, {self.}EndX + {self.}Width, {self.}EndY - {self.}DynamicHeight); - if borders.Tl2Br then - {self.}DrawLine(borders.Tl2Br, {self.}EndX, {self.}Y, {self.}EndX + {self.}Width, {self.}EndY - {self.}DynamicHeight); - if borders.Tr2Bl then - {self.}DrawLine(borders.Tr2Bl, {self.}EndX + {self.}Width, {self.}Y, {self.}EndX, {self.}EndY - {self.}DynamicHeight); -end; - -function TSPdfBordersRange.SetDash(val: string); -begin - if val = "single" or ifnil(val) then - {self.}TSPage.PdfPage.SetDash(array(), 0, 0); - if val = "dashed" then - {self.}TSPage.PdfPage.SetDash(array(1), 1, 0); -end; - -function TSPdfBordersRange.DrawLine(border: Border; x1: real; y1: real; x2: real; y2: real); -begin - [r, g, b] := array(0, 0, 0); - line_width := border.Sz ?: 0.5; - {self.}SetDash(border.Val); - if border.Color and border.Color <> "auto" then [r, g, b] := TSColorToolKit.HexToRGB(border.Color); - {self.}TSPage.PdfPage.SetRGBStroke(r, g, b); - {self.}TSPage.PdfPage.SetLineWidth(line_width); - {self.}TSPage.PdfPage.MoveTo(x1, y1); - {self.}TSPage.PdfPage.LineTo(x2, y2); - {self.}TSPage.PdfPage.Stroke(); - {self.}TSPage.PdfPage.SetRGBStroke(0, 0, 0); -end; diff --git a/range/basic/TSPdfImageRange.tsf b/range/basic/TSPdfImageRange.tsf deleted file mode 100644 index 4c386aa..0000000 --- a/range/basic/TSPdfImageRange.tsf +++ /dev/null @@ -1,35 +0,0 @@ -type TSPdfImageRange = class(TSPdfBasicRange) -public - function Create(); - function Do();override; - -public - Image: PdfImage; - Type: string; -end; - -function TSPdfImageRange.Create(); -begin - class(TSPdfBasicRange).Create(); - {self.}Image := nil; - {self.}Type := ""; -end; - -function TSPdfImageRange.Do(); -begin - // println("image = {}, type = {}, x = {}, y = {}, w = {}, h = {}", {self.}image, {self.}Type, {self.}endx, {self.}endy, {self.}width, {self.}DynamicHeight); - if {self.}Type = "emf" then - {self.}TSPage.PdfPage.DrawEmf({self.}Image, {self.}EndX, {self.}EndY, {self.}Width, {self.}DynamicHeight); - else if {self.}Type = "wmf" then - {self.}TSPage.PdfPage.DrawWmf({self.}Image, {self.}EndX, {self.}EndY, {self.}Width, {self.}DynamicHeight); - else - {self.}TSPage.PdfPage.DrawImage({self.}Image, {self.}EndX, {self.}EndY, {self.}Width, {self.}DynamicHeight); - -if sysparams["_PDF_IMAGE_DEBUG_"] then -begin - {self.}TSPage.PdfPage.SetLineWidth(0.1); - {self.}TSPage.PdfPage.SetRGBStroke(0.8, 0.8, 0); - {self.}TSPage.PdfPage.Rectangle({self.}EndX, {self.}EndY, {self.}Width, {self.}DynamicHeight); - {self.}TSPage.PdfPage.Stroke(); -end -end; diff --git a/range/basic/TSPdfTextRange.tsf b/range/basic/TSPdfTextRange.tsf deleted file mode 100644 index 0611ffc..0000000 --- a/range/basic/TSPdfTextRange.tsf +++ /dev/null @@ -1,51 +0,0 @@ -type TSPdfTextRange = class(TSPdfBasicRange) -uses TSColorToolKit; -public - function Create(); - function Do();override; - -public - RPr: RPr; - Text: string; - Font: PdfFont; -end; - -function TSPdfTextRange.Create(); -begin - class(TSPdfBasicRange).Create(); - {self.}RPr := nil; - {self.}Text := ""; - {self.}Font := nil; -end; - -function TSPdfTextRange.Do(); -begin - // println("text = {}, endx = {}, endy = {}, width = {}, page = {}", ansiToUtf8(text), endx, endy, width, page); - // println("Text = {}, sz = {}, szcs = {}, rpr.I = {}, color = {}", ansiToUtf8({self.}Text), {self.}RPr.Sz.Val, {self.}RPr.SzCs.Val, {self.}RPr.I, {self.}RPr.Color.Val); - [r, g, b] := array(0, 0, 0); - if {self.}RPr.Color.Val and {self.}RPr.Color.Val <> "auto" then [r, g, b] := TSColorToolKit.HexToRGB({self.}RPr.Color.Val); - y := {self.}EndY; - sz := {self.}RPr.Sz.Val; - if {self.}RPr.VertAlign.Val = "superscript" then - begin - y += sz / 3; - sz := sz * 2 / 3; - end - {self.}TSPage.PdfPage.SetRGBFill(r / 255, g / 255, b / 255); - {self.}TSPage.PdfPage.SetFontAndSize({self.}Font, sz); - {self.}TSPage.PdfPage.BeginText(); - {self.}TSPage.PdfPage.TextOut({self.}EndX, y, {self.}Text); - {self.}TSPage.PdfPage.EndText(); - {self.}TSPage.PdfPage.SetRGBFill(0, 0, 0); - - -if sysparams["_PDF_TEXT_DEBUG_"] then -begin - {self.}TSPage.PdfPage.SetLineWidth(0.1); - {self.}TSPage.PdfPage.SetRGBStroke(1.0, 0.5, 0.0); - {self.}TSPage.PdfPage.MoveTo(0, {self.}EndY); - {self.}TSPage.PdfPage.LineTo(600, {self.}EndY); - {self.}TSPage.PdfPage.Stroke(); -end -end; - diff --git a/utils/TSColorToolKit.tsf b/utils/TSColorToolKit.tsf deleted file mode 100644 index 65c2bd4..0000000 --- a/utils/TSColorToolKit.tsf +++ /dev/null @@ -1,23 +0,0 @@ -unit TSColorToolKit; -interface - function HexToRGB(hex); - -implementation - - function HexToRGB(hex); - begin - hex_string := ifnumber(hex) ? format("%x", hex) : hex; - if length(hex_string) = 7 then - begin - if hex_string[1] <> "#" then raise "Invalid hexadecimal parameter."; - hex_string := hex_string[1:]; - end - if length(hex_string) <> 6 then raise "Invalid hexadecimal parameter"; - r := eval(&"return 0x" + hex_string[1:2]); - g := eval(&"return 0x" + hex_string[3:4]); - b := eval(&"return 0x" + hex_string[5:6]); - return array(r, g, b); - end; - -end. - diff --git a/utils/TSPage.tsf b/utils/TSPage.tsf deleted file mode 100644 index 3c4c342..0000000 --- a/utils/TSPage.tsf +++ /dev/null @@ -1,6 +0,0 @@ -type TSPage = class -public - PdfPage: PdfPage; - Index: integer; - Number: integer; // 页码 -end; diff --git a/utils/TSToc.tsf b/utils/TSToc.tsf deleted file mode 100644 index 8433b5b..0000000 --- a/utils/TSToc.tsf +++ /dev/null @@ -1,51 +0,0 @@ -type TSToc = class -uses TSPdfEnumerations; -public - function Create(ppr: PPrUnitDecorator; rect: array of real; page: TSPage; x: real; y: real; font: PdfFont); - function LinkAnnot(dst: PdfDestination); - function AddPageNumber(page: TSPage); - -private - ppr_: PPrUnitDecorator; - rect_: array of real; - font_: PdfFont; - [weakref]tspage_: TSPage; - x_; - y_; -end; - -function TSToc.Create(ppr: PPrUnitDecorator; rect: array of real; page: TSPage; x: real; y: real; font: PdfFont); -begin - ppr_ := ppr; - rect_ := rect; - tspage_ := page; - x_ := x; - y_ := y; - font_ := font; -end; - -function TSToc.LinkAnnot(dst: PdfDestination); -begin - annot := tspage_.PdfPage.CreateLinkAnnot(rect_, dst); - annot.LinkAnnotSetHighlightMode(TSPdfEnumerations.ANNOT_NO_HIGHTLIGHT); - annot.LinkAnnotSetBorderStyle(0, 0, 0); -end; - -function TSToc.AddPageNumber(page: TSPage); -begin - number := tostring(page.Number); - tspage_.PdfPage.SetFontAndSize(font_, ppr_.RPr.Sz.Val); - number_sz := tspage_.PdfPage.TextWidth(number); - x := rect_[2] - number_sz; - tspage_.PdfPage.BeginText(); - tspage_.PdfPage.TextOut(x, y_, number); - tspage_.PdfPage.EndText(); - - tspage_.PdfPage.SetRGBStroke(0, 0, 0); - tspage_.PdfPage.SetDash(array(0.5, 2), 2, 0); - tspage_.PdfPage.SetLineWidth(0.5); - tspage_.PdfPage.SetLineCap(TSPdfEnumerations.ROUND_END); - tspage_.PdfPage.MoveTo(x_+1, y_); - tspage_.PdfPage.LineTo(x-0.5, y_); - tspage_.PdfPage.Stroke(); -end; diff --git a/utils/TSTrProperty.tsf b/utils/TSTrProperty.tsf deleted file mode 100644 index 529bde9..0000000 --- a/utils/TSTrProperty.tsf +++ /dev/null @@ -1,12 +0,0 @@ -type TSTrProperty = class - function Create(); -public - TrPr: TrPrUnitDecorator; - Height: real; -end; - -function TSTrProperty.Create(); -begin - {self.}TrPr := nil; - {self.}Height := 0; -end; diff --git a/ware/TSDocxComponentsWare.tsf b/ware/TSDocxComponentsWare.tsf deleted file mode 100644 index 14753a8..0000000 --- a/ware/TSDocxComponentsWare.tsf +++ /dev/null @@ -1,129 +0,0 @@ -type TSDocxComponentsWare = class(Components) -public - function Create(); - function GetStyles(): Styles; - function GetStylesAdapter(): StylesAdapter; - function GetDocumentRelsAdapter(): RelationShipsAdapter; - function GetNumberingWare(): TSNumberingWare; - function GetTblStylePrByType(style_id: string; type: string): TblStylePr; - function GetFtr(target: string): Ftr; - function GetHdr(target: string): Hdr; - function GetFtrRelsAdapter(target: string): RelationShipsAdapter; - function GetHdrRelsAdapter(target: string): RelationShipsAdapter; - function GetFootnotesAdapter(): FootnotesAdapter; -private - styles_deserialize_flag_: boolean; - styles_adapter_: StylesAdapter; - document_rels_adapter_: RelationShipsAdapter; - numbering_ware_: TSNumberingWare; - tbl_style_pr_hash_: array of TblStylePr; - ftr_hash_: array of Ftr; - hdr_hash_: array of Hdr; - hdr_rel_hash_: array of RelationShipsAdapter; - ftr_rel_hash_: array of RelationShipsAdapter; - footnotes_adapter_: FootnotesAdapter; -end; - -function TSDocxComponentsWare.Create(); -begin - class(Components).Create(); - tbl_style_pr_hash_ := array(); - ftr_hash_ := array(); - hdr_hash_ := array(); - hdr_rel_hash_ := array(); - ftr_rel_hash_ := array(); -end; - -function TSDocxComponentsWare.GetStyles(): Styles; -begin - if styles_deserialize_flag_ then return {self.}Styles; - {self.}Styles.Deserialize(); - styles_deserialize_flag_ := true; - return {self.}Styles; -end; - -function TSDocxComponentsWare.GetStylesAdapter(): StylesAdapter; -begin - if styles_adapter_ then return styles_adapter_; - styles_adapter_ := new StylesAdapter({self.}GetStyles()); - return styles_adapter_; -end; - -function TSDocxComponentsWare.GetDocumentRelsAdapter(): RelationShipsAdapter; -begin - if document_rels_adapter_ then return document_rels_adapter_; - {self.}DocumentRels.Deserialize(); - document_rels_adapter_ := new RelationShipsAdapter({self.}DocumentRels); - return document_rels_adapter_; -end; - -function TSDocxComponentsWare.GetNumberingWare(): TSNumberingWare; -begin - if numbering_ware_ then return numbering_ware_; - if not {self.}Numbering then return nil; - {self.}Numbering.Deserialize(); - numbering_ware_ := new TSNumberingWare({self.}Numbering); - return numbering_ware_; -end; - -function TSDocxComponentsWare.GetTblStylePrByType(style_id: string; type: string): TblStylePr; -begin - if tbl_style_pr_hash_[style_id][type] then return tbl_style_pr_hash_[style_id][type]; - styles_adapter := {self.}GetStylesAdapter(); - style := styles_adapter.GetStyleByStyleId(style_id); - style := new StyleAdapter(style); - tbl_style_pr := style.GetTblStylePrByType(type); - tbl_style_pr_hash_[style_id][type] := tbl_style_pr; - return tbl_style_pr; -end; - -function TSDocxComponentsWare.GetFtr(target: string): Ftr; -begin - if ftr_hash_[target] then return ftr_hash_[target]; - index := replaceStr(replaceStr(target, "footer", ""), ".xml", ""); - obj := {self.}Footers(strtoint(index)); - obj.Deserialize(); - ftr_hash_[target] := obj; - return obj; -end; - -function TSDocxComponentsWare.GetHdr(target: string): Hdr; -begin - if hdr_hash_[target] then return hdr_hash_[target]; - index := replaceStr(replaceStr(target, "header", ""), ".xml", ""); - obj := {self.}Headers(strtoint(index)); - obj.Deserialize(); - hdr_hash_[target] := obj; - return obj; -end; - -function TSDocxComponentsWare.GetHdrRelsAdapter(target: string): RelationShipsAdapter; -begin - if hdr_rel_hash_[target] then return hdr_rel_hash_[target]; - index := replaceStr(replaceStr(target, "header", ""), ".xml", ""); - obj := {self.}HeaderRels(strtoint(index)); - obj.Deserialize(); - rels_adapter := new RelationShipsAdapter(obj); - hdr_rel_hash_[target] := rels_adapter; - return rels_adapter; -end; - -function TSDocxComponentsWare.GetFtrRelsAdapter(target: string): RelationShipsAdapter; -begin - if ftr_rel_hash_[target] then return ftr_rel_hash_[target]; - index := replaceStr(replaceStr(target, "footer", ""), ".xml", ""); - obj := {self.}FooterRels(strtoint(index)); - obj.Deserialize(); - rels_adapter := new RelationShipsAdapter(obj); - ftr_rel_hash_[target] := rels_adapter; - return rels_adapter; -end; - -function TSDocxComponentsWare.GetFootnotesAdapter(): FootnotesAdapter; -begin - if footnotes_adapter_ then return footnotes_adapter_; - obj := {self.}Footnotes; - obj.Deserialize(); - footnotes_adapter_ := new FootnotesAdapter(obj); - return footnotes_adapter_; -end; diff --git a/ware/TSFontWare.tsf b/ware/TSFontWare.tsf deleted file mode 100644 index 49624fa..0000000 --- a/ware/TSFontWare.tsf +++ /dev/null @@ -1,127 +0,0 @@ -type TSFontWare = class -public - function Create(pdf: PdfFile); - function GetAsciiFont(name: string; bold: boolean; italic: boolean): PdfFont; - function GetCNSFont(name: string; bold: boolean; italic: boolean): PdfFont; - function GetSymbolFont(): PdfFont; - function UseExternalFont(); - function SetSubstitutionRules(source: string; target: string); - function SetDefaultSz(value: real); - function GetDefaultSz(): real; - -private - function GetExternalFont(name:string; bold: boolean; italic: boolean): PdfFont; - function GetBuiltInCNSFont(name:string; bold: boolean; italic: boolean): PdfFont; - function GetBuiltInAsciiFont(name:string; bold: boolean; italic: boolean): PdfFont; - -private - [weakref]pdf_: PdfFile; - - use_built_in_font_: boolean; // 是否使用内置字体 - substitution_rules_: array of string; // 替换规则 - external_reference_: array of string; - default_sz_: real; -end; - -function TSFontWare.Create(pdf: PdfFile); -begin - pdf_ := pdf; - use_built_in_font_ := true; - substitution_rules_ := array("宋体": "SimSun", - "黑体": "SimHei", - "Courier New": "Courier", - "Helvetica": "Helvetica", - "Times New Roman": "Times-Roman", - ); - external_reference_ := array(); - default_sz_ := 10.5; -end; - -function TSFontWare.SetDefaultSz(value: real); -begin - default_sz_ := value; -end; - -function TSFontWare.GetDefaultSz(); -begin - return default_sz_; -end; - -function TSFontWare.UseExternalFont(); -begin - use_built_in_font_ := false; -end; - -function TSFontWare.GetExternalFont(name:string; bold: boolean; italic: boolean); -begin - if ifnil(name) or name = '' then name := "等线"; - if not ifnil(external_font_cache_[name]) then return external_font_cache_[name]; - value := external_reference_[name]; - if ifnil(value) then return nil; - if value["ext"] = ".ttf" then - font_name := pdf_.LoadTTFontFromFile("", value["path"], true); - else if value["ext"] = ".ttc" then - font_name := pdf_.LoadTTFontFromFile2("", value["path"], 0, true); - if not ifString(font_name) then return nil; - font := pdf_.GetFont(font_name, "UTF-8"); - external_font_cache_[name] := font; - return font; -end; - -function TSFontWare.GetCNSFont(name: string; bold: boolean; italic: boolean): PdfFont; -begin - return use_built_in_font_ ? {self.}GetBuiltInCNSFont(name, bold, italic) : {self.}GetExternalFont(name, bold, italic); -end; - -function TSFontWare.GetBuiltInCNSFont(name: string; bold: boolean; italic: boolean): PdfFont; -begin - font_name := substitution_rules_[name]; - if ifnil(font_name) then font_name := "SimSun"; - if bold and italic then - font_name += ",BoldItalic"; - else if bold then - font_name += ",Bold"; - else if italic then - font_name += ",Italic"; - return pdf_.GetFont(font_name, "GBK-EUC-H"); -end; - -function TSFontWare.GetAsciiFont(name: string; bold: boolean; italic: boolean): PdfFont; -begin - return use_built_in_font_ ? {self.}GetBuiltInAsciiFont(name, bold, italic) : {self.}GetExternalFont(name, bold, italic); -end; - -function TSFontWare.GetBuiltInAsciiFont(name:string; bold: boolean; italic: boolean): PdfFont; -begin - font_name := substitution_rules_[name]; - if ifnil(font_name) then font_name := "Times-Roman"; - if font_name = "Courier" or font_name = "Helvetica" then - begin - if bold and italic then - font_name += "-BoldOblique"; - else if bold then - font_name += "-Bold"; - else if italic then - font_name += "-Oblique"; - end - else if font_name = "Times-Roman" then - begin - if bold and italic then - font_name := "Times-BoldItalic"; - else if bold then - font_name += "Times-Bold"; - else if italic then - font_name += "Times-Italic"; - end - return pdf_.GetFont(font_name, ""); -end; - -function TSFontWare.SetSubstitutionRules(source: string; target: string); -begin - substitution_rules_[source] := target; -end; - -function TSFontWare.GetSymbolFont(): PdfFont; -begin - return pdf_.GetFont("ZapfDingbats", ""); -end; diff --git a/ware/TSNoteWare.tsf b/ware/TSNoteWare.tsf deleted file mode 100644 index 39e6086..0000000 --- a/ware/TSNoteWare.tsf +++ /dev/null @@ -1,60 +0,0 @@ -type TSNoteWare = class -public - function Create(sect_ware: TSSectWare); - function GetFootnoteOrderNumber(): string; - function GetIndex(): string; - -private - function CalculateNumber(num_fmt: string; num: integer): string; - function ChineseCountingThousand(n: integer): string; - -private - [weakref]sect_ware_: TSSectWare; - index_: integer; -end; - -function TSNoteWare.Create(sect_ware: TSSectWare); -begin - sect_ware_ := sect_ware; - index_ := 0; -end; - -function TSNoteWare.GetFootnoteOrderNumber(); -begin - num_fmt := sect_ware_.SectPr.FootnotePr.NumFmt.Val; - if ifnil(num_fmt) then num_fmt := "decimal"; - return CalculateNumber(num_fmt, ++index_); -end; - -function TSNoteWare.GetIndex(): string; -begin - return inttostr(index_); -end; - -function TSNoteWare.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); - else - return format("%d", num); -end; - -function TSNoteWare.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; diff --git a/ware/TSNumberingWare.tsf b/ware/TSNumberingWare.tsf deleted file mode 100644 index c6864a7..0000000 --- a/ware/TSNumberingWare.tsf +++ /dev/null @@ -1,88 +0,0 @@ -type TSNumberingWare = class -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; -end; - -function TSNumberingWare.Create(number: NumberingAdapter); -begin - numbering_adapter_ := new NumberingAdapter(number); - num_hash_ := array(); -end; - -function TSNumberingWare.GetNumberLvl(ppr: PPr); -begin - num_id := ppr.NumPr.NumId.Val; - if ifnil(num_id) then return array("", nil); - ilvl := ppr.NumPr.Ilvl.Val; - pstyle := ppr.PStyle.Val; - num := numbering_adapter_.GetNumByNumId(num_id); - if ifnil(num) then return array("", nil); - abstract_id := num.AbstractNumId.Val; - abstract_num := numbering_adapter_.GetAbstractNumByAbstractNumId(abstract_id); - lvls := abstract_num.Lvls(); - if ifnil(ilvl) then ilvl := "0"; - for k,v in lvls do - begin - if ilvl and v.Ilvl = ilvl then - begin - lvl_text := v.LvlText.Val; - if not ifarray(num_hash_[num_id]) then num_hash_[num_id] := array(0, 0, 0, 0, 0, 0, 0, 0, 0); - ilvl_int := strtoint(ilvl); - for i:=0 to ilvl_int do - begin - source_str := "%" $ (i + 1); - n := num_hash_[num_id][i]; - if i = ilvl_int then - begin - n := num_hash_[num_id][i] + 1; - for j:=i+1 to length(num_hash_[num_id])-1 do - num_hash_[num_id][j] := 0; - end - n := i = ilvl_int ? num_hash_[num_id][i] + 1 : num_hash_[num_id][i]; - dest_str := {self.}CalculateNumber(v.NumFmt.Val, n); - lvl_text := replaceStr(lvl_text, source_str, dest_str); - end - num_hash_[num_id][ilvl_int]++; - if v.Suff.Val = "space" then lvl_text += " "; - return array(lvl_text, v); - end - 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); - else - return format("%d", 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; diff --git a/ware/TSSectWare.tsf b/ware/TSSectWare.tsf deleted file mode 100644 index 11044b9..0000000 --- a/ware/TSSectWare.tsf +++ /dev/null @@ -1,34 +0,0 @@ -type TSSectWare = class -public - function Create(); - function Destroy(); - function Do(); - function AddElement(element: tslobj); - -public - Elements: array of tslobj; - SectPr: SectPrUnitDecorator; - BaseSize: integer; -end; - -function TSSectWare.Create(); -begin - {self.}Elements := array(); - {self.}SectPr := nil; - {self.}BaseSize := 0; -end; - -function TSSectWare.Do(); -begin - if ifObj({self.}SectPr) then - {self.}BaseSize := round({self.}SectPr.DocGrid.LinePitch * 0.75); - // println("LinePitch = {}, Type = {}", {self.}SectPr.DocGrid.LinePitch, {self.}SectPr.DocGrid.Type); - // println("Width = {}, Height = {}", {self.}SectPr.PgSz.W, {self.}SectPr.PgSz.H); - // println("Top = {}, Right = {}, Bottom = {}, Left = {}, Header = {}, Footer = {}\n", - // {self.}SectPr.PgMar.Top, {self.}SectPr.PgMar.Right, {self.}SectPr.PgMar.Bottom, {self.}SectPr.PgMar.Left, {self.}SectPr.PgMar.Header, {self.}SectPr.PgMar.Footer); -end; - -function TSSectWare.AddElement(element: tslobj); -begin - {self.}Elements[length({self.}Elements)] := element; -end;