unit DTPPrimitiveRanges; interface uses DTPColorToolKit, DTPUtils; type BasicRange = class public function Create(); function Do();virtual; function Offset(x: real; y: real; page: Page);virtual; function AdjustOffset(x: real; y: real);virtual; public [weakref]Parent: tslobj; [weakref]EndPage: Page; // 结束page XOffset: real; YOffset: real; // XOffset, YOffset是相对(0,0)的偏移位置 EndX: real; EndY: real; // range的结束坐标(x,y) Width: real; DynamicHeight: real; FixedHeight: real; // StartX: real; // StartY: real; // range的起始坐标(x,y) end; type TextRange = class(BasicRange) public function Create(); function Do();override; public RPr: RPr; Text: string; Font: PdfFont; Type: integer; // 0:默认,1: 数字,2:英文,3:中文,4:中文标点,5:,.英文逗号和点 end; type BordersRange = class(BasicRange) public function Create(); function Do();override; function DoFill(); 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 RPr: RPr; Image: PdfImage; Type: string; end; type LineRange = class(BasicRange) public function Create(); function Do();override; public LineWidth: real; end; implementation // BasicRange function BasicRange.Create(); begin {self.}Parent := nil; {self.}EndPage := nil; {self.}XOffset := 0.0; {self.}YOffset := 0.0; {self.}EndX := 0.0; {self.}EndY := 0.0; {self.}Width := 0.0; {self.}DynamicHeight := 0.0; {self.}FixedHeight := 0.0; // {self.}StartX := 0; // {self.}StartY := 0; end; function BasicRange.Offset(x: real; y: real; page: Page);virtual; begin {self.}EndX := {self.}XOffset + x; {self.}EndY := {self.}YOffset + y; {self.}EndPage := page; end; function BasicRange.AdjustOffset(x: real; y: real);virtual; begin {self.}XOffset += x; {self.}YOffset += y; end; // ImageRange function ImageRange.Create(); begin class(BasicRange).Create(); {self.}Image := nil; {self.}Type := ""; end; function ImageRange.Do();override; begin if {self.}RPr.Highlight.Val = "yellow" then begin {self.}EndPage.PdfPage.SetRGBFill(1, 1, 0); x := {self.}EndX; y := {self.}Parent.EndY; w := {self.}Width; h := {self.}Parent.DynamicHeight; {self.}EndPage.PdfPage.Rectangle(x, y, w, h); {self.}EndPage.PdfPage.Fill(); {self.}EndPage.PdfPage.SetRGBFill(0, 0, 0); end if {self.}Type = "emf" then {self.}EndPage.PdfPage.DrawEmf({self.}Image, {self.}EndX, {self.}EndY, {self.}Width, {self.}DynamicHeight); else if {self.}Type = "wmf" then {self.}EndPage.PdfPage.DrawWmf({self.}Image, {self.}EndX, {self.}EndY, {self.}Width, {self.}DynamicHeight); else {self.}EndPage.PdfPage.DrawImage({self.}Image, {self.}EndX, {self.}EndY, {self.}Width, {self.}DynamicHeight); if sysparams["_PDF_IMAGE_DEBUG_"] then begin {self.}EndPage.PdfPage.SetLineWidth(0.1); {self.}EndPage.PdfPage.SetRGBStroke(0.8, 0.8, 0); {self.}EndPage.PdfPage.Rectangle({self.}EndX, {self.}EndY, {self.}Width, {self.}DynamicHeight); {self.}EndPage.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.DoFill(); begin borders := {self.}TcPr.TcBorders; // println("TcPr.Shd.Val = {}", TcPr.Shd.Val); if {self.}TcPr.Shd.Val = "clear" and {self.}TcPr.Shd.Fill and {self.}TcPr.Shd.Fill <> "auto" then begin [r, g, b] := DTPColorToolKit.HexToRGB({self.}TcPr.Shd.Fill); {self.}EndPage.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.}EndPage.PdfPage.Rectangle(x, y, w, h); {self.}EndPage.PdfPage.Fill(); {self.}EndPage.PdfPage.SetRGBFill(0, 0, 0); // {self.}Left := true; end 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.}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.}EndPage.PdfPage.SetDash(array(), 0, 0); else if val = "dashed" then {self.}EndPage.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.}EndPage.PdfPage.SetRGBStroke(r/255, g/255, b/255); {self.}EndPage.PdfPage.SetLineWidth(line_width); {self.}EndPage.PdfPage.MoveTo(x1, y1); {self.}EndPage.PdfPage.LineTo(x2, y2); {self.}EndPage.PdfPage.Stroke(); {self.}EndPage.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 if {self.}RPr.Highlight.Val = "yellow" then begin {self.}EndPage.PdfPage.SetRGBFill(1, 1, 0); x := {self.}EndX; y := {self.}Parent.EndY; w := {self.}Width; h := {self.}Parent.DynamicHeight; {self.}EndPage.PdfPage.Rectangle(x, y, w, h); {self.}EndPage.PdfPage.Fill(); {self.}EndPage.PdfPage.SetRGBFill(0, 0, 0); end {self.}EndPage.PdfPage.SetRGBFill(r / 255, g / 255, b / 255); {self.}EndPage.PdfPage.SetFontAndSize({self.}Font, sz); {self.}EndPage.PdfPage.BeginText(); {self.}EndPage.PdfPage.TextOut({self.}EndX, y, {self.}Text); {self.}EndPage.PdfPage.EndText(); {self.}EndPage.PdfPage.SetRGBFill(0, 0, 0); if sysparams["_PDF_TEXT_DEBUG_"] then begin {self.}EndPage.PdfPage.SetLineWidth(0.1); {self.}EndPage.PdfPage.SetRGBStroke(1.0, 0.5, 0.0); {self.}EndPage.PdfPage.MoveTo(0, {self.}EndY); {self.}EndPage.PdfPage.LineTo(600, {self.}EndY); {self.}EndPage.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 = {}, line_width = {}", EndX, EndY, Width, LineWidth); {self.}EndPage.PdfPage.SetLineWidth({self.}LineWidth); {self.}EndPage.PdfPage.SetRGBStroke(0, 0, 0); {self.}EndPage.PdfPage.MoveTo({self.}EndX, {self.}EndY); {self.}EndPage.PdfPage.LineTo({self.}EndX + {self.}Width, {self.}EndY); {self.}EndPage.PdfPage.Stroke(); end; end.