PDFExportV4.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. using FastReport.SVG;
  2. using FastReport.Utils;
  3. using Svg;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Drawing;
  7. using System.Drawing.Drawing2D;
  8. using System.Text;
  9. namespace FastReport.Export.Pdf
  10. {
  11. partial class PDFExport
  12. {
  13. private bool PDFExportV4(ReportComponentBase obj)
  14. {
  15. if (obj != null && obj is SVG.SVGObject && !svgAsPicture)
  16. {
  17. AddPDFSvgVector(obj as SVG.SVGObject, contentBuilder);
  18. obj.Dispose();
  19. obj = null;
  20. return true;
  21. }
  22. return false;
  23. }
  24. #region Private Methods
  25. private void AddPDFSvgVector(SVGObject obj, StringBuilder sb)
  26. {
  27. RectangleF rect = new RectangleF(obj.AbsLeft + obj.Padding.Left, obj.AbsTop + obj.Padding.Top, obj.Width - obj.Padding.Horizontal, obj.Height - obj.Padding.Vertical);
  28. PointF upperLeft;
  29. PointF upperRight;
  30. PointF lowerLeft;
  31. SvgDocument document = obj.Grayscale ? obj.SVGGrayscale : obj.SvgDocument;
  32. SizeF imageBounds = SizeF.Empty;
  33. try
  34. {
  35. imageBounds = document.GetDimensions();
  36. }
  37. catch (NullReferenceException)
  38. {
  39. DrawPDFBorder(obj.Border, obj.AbsLeft, obj.AbsTop, obj.Width, obj.Height, sb);
  40. return;
  41. }
  42. obj.GetImageAngleTransform(rect, imageBounds.Width, imageBounds.Height, 1, 1, 0, 0, out upperLeft, out upperRight, out lowerLeft);
  43. upperLeft = new PointF(GetLeft(upperLeft.X), GetTop(upperLeft.Y));
  44. upperRight = new PointF(GetLeft(upperRight.X), GetTop(upperRight.Y));
  45. lowerLeft = new PointF(GetLeft(lowerLeft.X), GetTop(lowerLeft.Y));
  46. //int imgWidth = (int)Math.Sqrt((upperLeft.X - upperRight.X) * (upperLeft.X - upperRight.X) + (upperLeft.Y - upperRight.Y) * (upperLeft.Y - upperRight.Y));
  47. //int imgHeight = (int)Math.Sqrt((upperLeft.X - lowerLeft.X) * (upperLeft.X - lowerLeft.X) + (upperLeft.Y - lowerLeft.Y) * (upperLeft.Y - lowerLeft.Y));
  48. if (!isPdfX())
  49. AddAnnot(obj);
  50. PDFSVGRenderer renderer = new PDFSVGRenderer(this, imageBounds);
  51. PointF vector1 = PointF.Subtract(upperRight, new SizeF(upperLeft));
  52. PointF vector2 = PointF.Subtract(lowerLeft, new SizeF(upperLeft));
  53. float[] m = new float[] {
  54. vector1.X / imageBounds.Width,
  55. vector1.Y / imageBounds.Height,
  56. vector2.X / imageBounds.Width,
  57. vector2.Y / imageBounds.Height,
  58. upperLeft.X,
  59. upperLeft.Y
  60. };
  61. document.Draw(renderer);
  62. sb.AppendLine("q");
  63. sb.Append(FloatToString(GetLeft(obj.AbsLeft))).Append(" ");
  64. sb.Append(FloatToString(GetTop(obj.AbsTop + obj.Height))).Append(" ");
  65. sb.Append(FloatToString((obj.Width) * PDF_DIVIDER)).Append(" ");
  66. sb.Append(FloatToString((obj.Height) * PDF_DIVIDER)).AppendLine(" re");
  67. sb.AppendLine("W");
  68. sb.AppendLine("n");
  69. sb.Append(FloatToStringSmart(m[0])).Append(" ")
  70. .Append(FloatToStringSmart(m[1])).Append(" ")
  71. .Append(FloatToStringSmart(m[2])).Append(" ")
  72. .Append(FloatToStringSmart(m[3])).Append(" ")
  73. .Append(FloatToStringSmart(m[4])).Append(" ")
  74. .Append(FloatToStringSmart(m[5])).AppendLine(" cm");
  75. sb.Append(renderer.GetString());
  76. sb.AppendLine("Q");
  77. }
  78. #endregion Private Methods
  79. #region Private Classes
  80. private class PDFSVGRenderer : ISvgRenderer
  81. {
  82. #region Private Fields
  83. private Stack<ISvgBoundable> _boundables = new Stack<ISvgBoundable>();
  84. private float dpiY = Utils.DrawUtils.ScreenDpi;
  85. private PDFExport export;
  86. private Region region;
  87. private SmoothingMode smoothingMode = SmoothingMode.Default;
  88. private System.Drawing.Drawing2D.Matrix transform = new System.Drawing.Drawing2D.Matrix();
  89. private StringBuilder sb = new StringBuilder();
  90. #endregion Private Fields
  91. #region Public Properties
  92. public float DpiY
  93. {
  94. get
  95. {
  96. return DrawUtils.ScreenDpi;
  97. }
  98. }
  99. public SmoothingMode SmoothingMode
  100. {
  101. get
  102. {
  103. return smoothingMode;
  104. }
  105. set
  106. {
  107. smoothingMode = value;
  108. }
  109. }
  110. public System.Drawing.Drawing2D.Matrix Transform
  111. {
  112. get
  113. {
  114. return transform.Clone() as System.Drawing.Drawing2D.Matrix;
  115. }
  116. set
  117. {
  118. transform = value;
  119. }
  120. }
  121. #endregion Public Properties
  122. #region Public Constructors
  123. /// <summary>
  124. ///
  125. /// </summary>
  126. /// <param name="export">The pdf export</param>
  127. /// <param name="size">size of place for svg</param>
  128. public PDFSVGRenderer(PDFExport export, SizeF size)
  129. {
  130. this.export = export;
  131. region = new Region(new RectangleF(0, 0, size.Width, size.Height));
  132. }
  133. #endregion Public Constructors
  134. #region Public Methods
  135. public void Dispose()
  136. {
  137. region.Dispose();
  138. }
  139. public void DrawImage(System.Drawing.Image image, RectangleF destRect, RectangleF srcRect, GraphicsUnit graphicsUnit)
  140. {
  141. using (Bitmap bmp = new Bitmap((int)srcRect.Width, (int)srcRect.Height))
  142. {
  143. using (Graphics g = Graphics.FromImage(bmp))
  144. {
  145. g.DrawImage(image, new RectangleF(0, 0, bmp.Width, bmp.Height), srcRect, graphicsUnit);
  146. g.Flush();
  147. }
  148. long imageIndex = export.AppendPDFImage(bmp, export.jpegQuality);
  149. if (imageIndex < 0) return;
  150. export.AddImageToList(imageIndex);
  151. PointF[] points = TransformPoints(Transform,
  152. PointF.Add(destRect.Location, new SizeF(0, destRect.Size.Height)),
  153. PointF.Add(destRect.Location, new SizeF(destRect.Size.Width, destRect.Size.Height)),
  154. destRect.Location
  155. );
  156. PointF offset = points[0];
  157. PointF vector1 = PointF.Subtract(points[1], new SizeF(offset));
  158. PointF vector2 = PointF.Subtract(points[2], new SizeF(offset));
  159. sb.AppendLine("q");
  160. // m00
  161. sb.Append(export.FloatToString(vector1.X)).Append(" ");
  162. // m01
  163. sb.Append(export.FloatToString(vector1.Y)).Append(" ");
  164. // m10
  165. sb.Append(export.FloatToString(vector2.X)).Append(" ");
  166. // m11
  167. sb.Append(export.FloatToString(vector2.Y)).Append(" ");
  168. // m02
  169. sb.Append(export.FloatToString(offset.X)).Append(" ");
  170. // m12
  171. sb.Append(export.FloatToString(offset.Y)).Append(" ");
  172. //clip
  173. sb.AppendLine(" cm");
  174. sb.AppendLine(ExportUtils.StringFormat("/Im{0} Do", imageIndex));
  175. sb.AppendLine("Q");
  176. }
  177. }
  178. public void DrawImageUnscaled(System.Drawing.Image image, Point location)
  179. {
  180. DrawImage(image, new RectangleF(location, image.Size), new RectangleF(PointF.Empty, image.Size), GraphicsUnit.Pixel);
  181. }
  182. public void DrawPath(Pen pen, GraphicsPath path)
  183. {
  184. SetPdfClip();
  185. export.StrokePDFGraphicsPath(path, pen, path.PointCount > 0 && ((path.PathTypes[path.PointCount - 1] & 0x80) == 0x80), sb, export.curvesInterpolation, transform);
  186. ResetPdfClip();
  187. }
  188. public void FillPath(Brush brush, GraphicsPath path)
  189. {
  190. SetPdfClip();
  191. export.FillPDFGraphicsPath(GetBoundable().Size, path, brush, sb, export.curvesInterpolation, transform);
  192. ResetPdfClip();
  193. }
  194. private void SetPdfClip()
  195. {
  196. using (var path = new GraphicsPath())
  197. {
  198. foreach (var r in region.GetRegionScans(new System.Drawing.Drawing2D.Matrix()))
  199. {
  200. path.AddRectangle(r);
  201. }
  202. export.ClipPDFGraphicsPath(path, sb);
  203. }
  204. }
  205. private void ResetPdfClip()
  206. {
  207. sb.AppendLine("Q");
  208. }
  209. public ISvgBoundable GetBoundable()
  210. {
  211. return _boundables.Peek();
  212. }
  213. public Region GetClip()
  214. {
  215. return region.Clone();
  216. }
  217. public ISvgBoundable PopBoundable()
  218. {
  219. return _boundables.Pop();
  220. }
  221. public void RotateTransform(float fAngle, MatrixOrder order = MatrixOrder.Append)
  222. {
  223. transform.Rotate(fAngle, order);
  224. }
  225. public void ScaleTransform(float sx, float sy, MatrixOrder order = MatrixOrder.Append)
  226. {
  227. transform.Scale(sx, sy, order);
  228. }
  229. public void SetBoundable(ISvgBoundable boundable)
  230. {
  231. _boundables.Push(boundable);
  232. }
  233. public void SetClip(Region region, CombineMode combineMode = CombineMode.Replace)
  234. {
  235. // two ops used here, Replace and Intersect
  236. if (combineMode == CombineMode.Replace)
  237. {
  238. this.region.Dispose();
  239. this.region = region;
  240. }
  241. else
  242. {
  243. this.region.Intersect(region);
  244. }
  245. }
  246. public void TranslateTransform(float dx, float dy, MatrixOrder order = MatrixOrder.Append)
  247. {
  248. transform.Translate(dx, dy, order);
  249. }
  250. #endregion Public Methods
  251. #region Internal Methods
  252. internal string GetString()
  253. {
  254. return sb.ToString();
  255. }
  256. #endregion Internal Methods
  257. #region Private Methods
  258. private PointF[] TransformPoints(System.Drawing.Drawing2D.Matrix matrix, params PointF[] points)
  259. {
  260. matrix.TransformPoints(points);
  261. return points;
  262. }
  263. #endregion Private Methods
  264. }
  265. #endregion Private Classes
  266. }
  267. }