unit DTPPrimitiveRanges; interface uses DTPColorToolKit, DTPUtils; type TextRange = class(BasicRange) public function Create(); function Do();override; public RPr: RPr; Text: string; Font: PdfFont; Type: integer; // 0:默认,1: 数字,2:英文,3:中文,4:中文标点 end; type BordersRange = class(BasicRange) 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; type ImageRange = class(BasicRange) public function Create(); function Do();override; public Image: PdfImage; Type: string; end; type LineRange = class(BasicRange) public function Create(); function Do();override; public LineWidth: real; end; type BasicRange = 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]Parent: tslobj; [weakref]Page: Page; end; implementation // BasicRange function BasicRange.Create(); begin {self.}StartX := 0; {self.}StartY := 0; {self.}EndX := 0; {self.}EndY := 0; {self.}Width := 0; {self.}DynamicHeight := 0; {self.}LowerBound := 0; {self.}FixedHeight := 0; {self.}Page := nil; end; // ImageRange function ImageRange.Create(); begin class(BasicRange).Create(); {self.}Image := nil; {self.}Type := ""; end; function ImageRange.Do();override; 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.}Page.PdfPage.DrawEmf({self.}Image, {self.}EndX, {self.}EndY, {self.}Width, {self.}DynamicHeight); else if {self.}Type = "wmf" then {self.}Page.PdfPage.DrawWmf({self.}Image, {self.}EndX, {self.}EndY, {self.}Width, {self.}DynamicHeight); else {self.}Page.PdfPage.DrawImage({self.}Image, {self.}EndX, {self.}EndY, {self.}Width, {self.}DynamicHeight); if sysparams["_PDF_IMAGE_DEBUG_"] then begin {self.}Page.PdfPage.SetLineWidth(0.1); {self.}Page.PdfPage.SetRGBStroke(0.8, 0.8, 0); {self.}Page.PdfPage.Rectangle({self.}EndX, {self.}EndY, {self.}Width, {self.}DynamicHeight); {self.}Page.PdfPage.Stroke(); end end; // BordersRange function BordersRange.Create(); begin class(BasicRange).Create(); {self.}TcPr := nil; {self.}Left := false; {self.}Top := false; {self.}Right := false; {self.}Bottom := false; end; function BordersRange.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] := DTPColorToolKit.HexToRGB({self.}TcPr.Shd.Fill); {self.}Page.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.}Page.PdfPage.Rectangle(x, y, w, h); {self.}Page.PdfPage.Fill(); {self.}Page.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 BordersRange.SetDash(val: string); begin if val = "single" or ifnil(val) then {self.}Page.PdfPage.SetDash(array(), 0, 0); if val = "dashed" then {self.}Page.PdfPage.SetDash(array(1), 1, 0); end; function BordersRange.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] := DTPColorToolKit.HexToRGB(border.Color); {self.}Page.PdfPage.SetRGBStroke(r, g, b); {self.}Page.PdfPage.SetLineWidth(line_width); {self.}Page.PdfPage.MoveTo(x1, y1); {self.}Page.PdfPage.LineTo(x2, y2); {self.}Page.PdfPage.Stroke(); {self.}Page.PdfPage.SetRGBStroke(0, 0, 0); end; // TextRange function TextRange.Create(); begin class(BasicRange).Create(); {self.}RPr := nil; {self.}Text := ""; {self.}Font := nil; {self.}Type := -1; end; function TextRange.Do();override; begin // println("text = {}, endx = {}, endy = {}, width = {}, page = {}", ansiToUtf8(text), endx, endy, width, page); // println("Text = {}, sz = {}, szcs = {}, rpr.I = {}, rpr.B = {}, color = {}", ansiToUtf8({self.}Text), {self.}RPr.Sz.Val, {self.}RPr.SzCs.Val, {self.}RPr.I, {self.}RPr.B, {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] := DTPColorToolKit.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.}Page.PdfPage.SetRGBFill(r / 255, g / 255, b / 255); {self.}Page.PdfPage.SetFontAndSize({self.}Font, sz); {self.}Page.PdfPage.BeginText(); {self.}Page.PdfPage.TextOut({self.}EndX, y, {self.}Text); {self.}Page.PdfPage.EndText(); {self.}Page.PdfPage.SetRGBFill(0, 0, 0); if sysparams["_PDF_TEXT_DEBUG_"] then begin {self.}Page.PdfPage.SetLineWidth(0.1); {self.}Page.PdfPage.SetRGBStroke(1.0, 0.5, 0.0); {self.}Page.PdfPage.MoveTo(0, {self.}EndY); {self.}Page.PdfPage.LineTo(600, {self.}EndY); {self.}Page.PdfPage.Stroke(); end end; // LineRange function LineRange.Create(); begin class(BasicRange).Create(); {self.}LineWidth := 0; end; function LineRange.Do();override; begin // println("endx = {}, endy = {}, width = {}", EndX, EndY, Width); {self.}Page.PdfPage.SetLineWidth({self.}LineWidth); {self.}Page.PdfPage.SetRGBStroke(0, 0, 0); {self.}Page.PdfPage.MoveTo({self.}EndX, {self.}EndY); {self.}Page.PdfPage.LineTo({self.}EndX + {self.}Width, {self.}EndY); {self.}Page.PdfPage.Stroke(); end; end.