123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323 |
- using FastReport.SVG;
- using FastReport.Utils;
- using Svg;
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.Drawing.Drawing2D;
- using System.Text;
- namespace FastReport.Export.Pdf
- {
- partial class PDFExport
- {
- private bool PDFExportV4(ReportComponentBase obj)
- {
- if (obj != null && obj is SVG.SVGObject && !svgAsPicture)
- {
- AddPDFSvgVector(obj as SVG.SVGObject, contentBuilder);
- obj.Dispose();
- obj = null;
- return true;
- }
- return false;
- }
- #region Private Methods
- private void AddPDFSvgVector(SVGObject obj, StringBuilder sb)
- {
- RectangleF rect = new RectangleF(obj.AbsLeft + obj.Padding.Left, obj.AbsTop + obj.Padding.Top, obj.Width - obj.Padding.Horizontal, obj.Height - obj.Padding.Vertical);
- PointF upperLeft;
- PointF upperRight;
- PointF lowerLeft;
- SvgDocument document = obj.Grayscale ? obj.SVGGrayscale : obj.SvgDocument;
- SizeF imageBounds = SizeF.Empty;
- try
- {
- imageBounds = document.GetDimensions();
- }
- catch (NullReferenceException)
- {
- DrawPDFBorder(obj.Border, obj.AbsLeft, obj.AbsTop, obj.Width, obj.Height, sb);
- return;
- }
- obj.GetImageAngleTransform(rect, imageBounds.Width, imageBounds.Height, 1, 1, 0, 0, out upperLeft, out upperRight, out lowerLeft);
- upperLeft = new PointF(GetLeft(upperLeft.X), GetTop(upperLeft.Y));
- upperRight = new PointF(GetLeft(upperRight.X), GetTop(upperRight.Y));
- lowerLeft = new PointF(GetLeft(lowerLeft.X), GetTop(lowerLeft.Y));
- //int imgWidth = (int)Math.Sqrt((upperLeft.X - upperRight.X) * (upperLeft.X - upperRight.X) + (upperLeft.Y - upperRight.Y) * (upperLeft.Y - upperRight.Y));
- //int imgHeight = (int)Math.Sqrt((upperLeft.X - lowerLeft.X) * (upperLeft.X - lowerLeft.X) + (upperLeft.Y - lowerLeft.Y) * (upperLeft.Y - lowerLeft.Y));
- if (!isPdfX())
- AddAnnot(obj);
- PDFSVGRenderer renderer = new PDFSVGRenderer(this, imageBounds);
- PointF vector1 = PointF.Subtract(upperRight, new SizeF(upperLeft));
- PointF vector2 = PointF.Subtract(lowerLeft, new SizeF(upperLeft));
- float[] m = new float[] {
- vector1.X / imageBounds.Width,
- vector1.Y / imageBounds.Height,
- vector2.X / imageBounds.Width,
- vector2.Y / imageBounds.Height,
- upperLeft.X,
- upperLeft.Y
- };
- document.Draw(renderer);
- sb.AppendLine("q");
- sb.Append(FloatToString(GetLeft(obj.AbsLeft))).Append(" ");
- sb.Append(FloatToString(GetTop(obj.AbsTop + obj.Height))).Append(" ");
- sb.Append(FloatToString((obj.Width) * PDF_DIVIDER)).Append(" ");
- sb.Append(FloatToString((obj.Height) * PDF_DIVIDER)).AppendLine(" re");
- sb.AppendLine("W");
- sb.AppendLine("n");
- sb.Append(FloatToStringSmart(m[0])).Append(" ")
- .Append(FloatToStringSmart(m[1])).Append(" ")
- .Append(FloatToStringSmart(m[2])).Append(" ")
- .Append(FloatToStringSmart(m[3])).Append(" ")
- .Append(FloatToStringSmart(m[4])).Append(" ")
- .Append(FloatToStringSmart(m[5])).AppendLine(" cm");
- sb.Append(renderer.GetString());
- sb.AppendLine("Q");
- }
- #endregion Private Methods
- #region Private Classes
- private class PDFSVGRenderer : ISvgRenderer
- {
- #region Private Fields
- private Stack<ISvgBoundable> _boundables = new Stack<ISvgBoundable>();
- private float dpiY = Utils.DrawUtils.ScreenDpi;
- private PDFExport export;
- private Region region;
- private SmoothingMode smoothingMode = SmoothingMode.Default;
- private System.Drawing.Drawing2D.Matrix transform = new System.Drawing.Drawing2D.Matrix();
- private StringBuilder sb = new StringBuilder();
- #endregion Private Fields
- #region Public Properties
- public float DpiY
- {
- get
- {
- return DrawUtils.ScreenDpi;
- }
- }
- public SmoothingMode SmoothingMode
- {
- get
- {
- return smoothingMode;
- }
- set
- {
- smoothingMode = value;
- }
- }
- public System.Drawing.Drawing2D.Matrix Transform
- {
- get
- {
- return transform.Clone() as System.Drawing.Drawing2D.Matrix;
- }
- set
- {
- transform = value;
- }
- }
- #endregion Public Properties
- #region Public Constructors
- /// <summary>
- ///
- /// </summary>
- /// <param name="export">The pdf export</param>
- /// <param name="size">size of place for svg</param>
- public PDFSVGRenderer(PDFExport export, SizeF size)
- {
- this.export = export;
- region = new Region(new RectangleF(0, 0, size.Width, size.Height));
- }
- #endregion Public Constructors
- #region Public Methods
- public void Dispose()
- {
- region.Dispose();
- }
- public void DrawImage(System.Drawing.Image image, RectangleF destRect, RectangleF srcRect, GraphicsUnit graphicsUnit)
- {
- using (Bitmap bmp = new Bitmap((int)srcRect.Width, (int)srcRect.Height))
- {
- using (Graphics g = Graphics.FromImage(bmp))
- {
- g.DrawImage(image, new RectangleF(0, 0, bmp.Width, bmp.Height), srcRect, graphicsUnit);
- g.Flush();
- }
- long imageIndex = export.AppendPDFImage(bmp, export.jpegQuality);
- if (imageIndex < 0) return;
- export.AddImageToList(imageIndex);
- PointF[] points = TransformPoints(Transform,
- PointF.Add(destRect.Location, new SizeF(0, destRect.Size.Height)),
- PointF.Add(destRect.Location, new SizeF(destRect.Size.Width, destRect.Size.Height)),
- destRect.Location
- );
- PointF offset = points[0];
- PointF vector1 = PointF.Subtract(points[1], new SizeF(offset));
- PointF vector2 = PointF.Subtract(points[2], new SizeF(offset));
- sb.AppendLine("q");
- // m00
- sb.Append(export.FloatToString(vector1.X)).Append(" ");
- // m01
- sb.Append(export.FloatToString(vector1.Y)).Append(" ");
- // m10
- sb.Append(export.FloatToString(vector2.X)).Append(" ");
- // m11
- sb.Append(export.FloatToString(vector2.Y)).Append(" ");
- // m02
- sb.Append(export.FloatToString(offset.X)).Append(" ");
- // m12
- sb.Append(export.FloatToString(offset.Y)).Append(" ");
- //clip
- sb.AppendLine(" cm");
- sb.AppendLine(ExportUtils.StringFormat("/Im{0} Do", imageIndex));
- sb.AppendLine("Q");
- }
- }
- public void DrawImageUnscaled(System.Drawing.Image image, Point location)
- {
- DrawImage(image, new RectangleF(location, image.Size), new RectangleF(PointF.Empty, image.Size), GraphicsUnit.Pixel);
- }
- public void DrawPath(Pen pen, GraphicsPath path)
- {
- SetPdfClip();
- export.StrokePDFGraphicsPath(path, pen, path.PointCount > 0 && ((path.PathTypes[path.PointCount - 1] & 0x80) == 0x80), sb, export.curvesInterpolation, transform);
- ResetPdfClip();
- }
- public void FillPath(Brush brush, GraphicsPath path)
- {
- SetPdfClip();
- export.FillPDFGraphicsPath(GetBoundable().Size, path, brush, sb, export.curvesInterpolation, transform);
- ResetPdfClip();
- }
- private void SetPdfClip()
- {
- using (var path = new GraphicsPath())
- {
- foreach (var r in region.GetRegionScans(new System.Drawing.Drawing2D.Matrix()))
- {
- path.AddRectangle(r);
- }
- export.ClipPDFGraphicsPath(path, sb);
- }
- }
- private void ResetPdfClip()
- {
- sb.AppendLine("Q");
- }
- public ISvgBoundable GetBoundable()
- {
- return _boundables.Peek();
- }
- public Region GetClip()
- {
- return region.Clone();
- }
- public ISvgBoundable PopBoundable()
- {
- return _boundables.Pop();
- }
- public void RotateTransform(float fAngle, MatrixOrder order = MatrixOrder.Append)
- {
- transform.Rotate(fAngle, order);
- }
- public void ScaleTransform(float sx, float sy, MatrixOrder order = MatrixOrder.Append)
- {
- transform.Scale(sx, sy, order);
- }
- public void SetBoundable(ISvgBoundable boundable)
- {
- _boundables.Push(boundable);
- }
- public void SetClip(Region region, CombineMode combineMode = CombineMode.Replace)
- {
- // two ops used here, Replace and Intersect
- if (combineMode == CombineMode.Replace)
- {
- this.region.Dispose();
- this.region = region;
- }
- else
- {
- this.region.Intersect(region);
- }
- }
- public void TranslateTransform(float dx, float dy, MatrixOrder order = MatrixOrder.Append)
- {
- transform.Translate(dx, dy, order);
- }
- #endregion Public Methods
- #region Internal Methods
- internal string GetString()
- {
- return sb.ToString();
- }
- #endregion Internal Methods
- #region Private Methods
- private PointF[] TransformPoints(System.Drawing.Drawing2D.Matrix matrix, params PointF[] points)
- {
- matrix.TransformPoints(points);
- return points;
- }
- #endregion Private Methods
- }
- #endregion Private Classes
- }
- }
|