PSExport.cs 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801
  1. using System;
  2. using System.Collections.Generic;
  3. using FastReport.Utils;
  4. using System.IO;
  5. using System.Drawing;
  6. using FastReport.Table;
  7. using System.Drawing.Imaging;
  8. using System.Windows.Forms;
  9. namespace FastReport.Export.PS
  10. {
  11. /// <summary>
  12. /// Represents the ps export filter.
  13. /// </summary>
  14. public partial class PSExport : ExportBase
  15. {
  16. #region Private Fields
  17. private string path;
  18. private string fileNameWOext;
  19. private string extension;
  20. private string pageFileName;
  21. private int quality;
  22. private int currentPage;
  23. private int img_nbr;
  24. private bool pictures;
  25. private bool textInCurves;
  26. private bool pagesInDiffFiles;
  27. private bool saveImagesSeparately;
  28. private float pageLeftMargin;
  29. private float pageTopMargin;
  30. private Dictionary<string, string> hashtable;
  31. private ImageFormat format;
  32. private Dictionary<string, MemoryStream> images;
  33. private Dictionary<string, string> imageVariablesNames;
  34. private PSDocument ps;
  35. #endregion
  36. #region Properties
  37. /// <summary>
  38. /// Enable or disable the pictures in PS export
  39. /// </summary>
  40. public bool Pictures
  41. {
  42. get { return pictures; }
  43. set { pictures = value; }
  44. }
  45. /// <summary>
  46. /// Enable or disable export text in curves
  47. /// </summary>
  48. public bool TextInCurves
  49. {
  50. get { return textInCurves; }
  51. set { textInCurves = value; }
  52. }
  53. /// <summary>
  54. /// Enable or disable export every page in separate file
  55. /// </summary>
  56. public bool PagesInDiffFiles
  57. {
  58. get { return pagesInDiffFiles; }
  59. set { pagesInDiffFiles = value; }
  60. }
  61. /// <summary>
  62. /// Enable or disable saving every image in separate file
  63. /// </summary>
  64. public bool SaveImagesSeparately
  65. {
  66. get { return saveImagesSeparately; }
  67. set { saveImagesSeparately = value; }
  68. }
  69. /// <summary>
  70. /// Gets or sets quality of JPEG images
  71. /// </summary>
  72. public int Quality
  73. {
  74. get { return quality; }
  75. set { quality = value; }
  76. }
  77. #endregion
  78. #region Private Methods
  79. private void ExportObj(Base c)
  80. {
  81. if (c is ReportComponentBase && (c as ReportComponentBase).Exportable)
  82. {
  83. ReportComponentBase obj = c as ReportComponentBase;
  84. if (obj is CellularTextObject)
  85. obj = (obj as CellularTextObject).GetTable();
  86. else if (obj is TableBase)
  87. {
  88. TableBase table = obj as TableBase;
  89. if (table.ColumnCount > 0 && table.RowCount > 0)
  90. {
  91. using (TextObject tableback = new TextObject())
  92. {
  93. tableback.Border = table.Border;
  94. tableback.Fill = table.Fill;
  95. tableback.FillColor = table.FillColor;
  96. tableback.Left = table.AbsLeft;
  97. tableback.Top = table.AbsTop;
  98. float tableWidth = 0;
  99. float tableHeight = 0;
  100. for (int i = 0; i < table.ColumnCount; i++)
  101. tableWidth += table[i, 0].Width;
  102. for (int i = 0; i < table.RowCount; i++)
  103. tableHeight += table.Rows[i].Height;
  104. tableback.Width = (tableWidth < table.Width) ? tableWidth : table.Width;
  105. tableback.Height = tableHeight;
  106. AddTextObject(ps, tableback as TextObject, false);
  107. // draw cells
  108. AddTable(ps, table, true);
  109. // draw cells border
  110. AddTable(ps, table, false);
  111. // draw table border
  112. AddBorder(ps, tableback.Border, tableback.AbsLeft, tableback.AbsTop, tableback.Width, tableback.Height);
  113. }
  114. }
  115. }
  116. else if (obj is TextObject)
  117. AddTextObject(ps, obj as TextObject, false);
  118. else if (obj is BandBase)
  119. AddBandObject(ps, obj as BandBase);
  120. else if (obj is LineObject)
  121. AddLine(ps, obj as LineObject);
  122. else if (obj is ShapeObject)
  123. AddShape(ps, obj as ShapeObject);
  124. else if (saveImagesSeparately)
  125. AddPictureObject(ps, obj);
  126. else AddHexImage(ps, obj);
  127. }
  128. }
  129. private void AddHexImage(PSDocument ps, ReportComponentBase obj)
  130. {
  131. if (obj.Height <= 0 || obj.Width <= 0)
  132. return;
  133. byte[] imageBytes;
  134. string hex;
  135. using (MemoryStream imageStream = new MemoryStream())
  136. {
  137. using (System.Drawing.Image image = new Bitmap((int)obj.Width, (int)obj.Height))
  138. {
  139. using (Graphics g = Graphics.FromImage(image))
  140. {
  141. using (GraphicCache cache = new GraphicCache())
  142. {
  143. g.Clear(Color.White);
  144. float Left = obj.Width >= 0 ? obj.AbsLeft : obj.AbsLeft + obj.Width;
  145. float Top = obj.Height >= 0 ? obj.AbsTop : obj.AbsTop + obj.Height;
  146. g.TranslateTransform(-Left, -Top);
  147. obj.Draw(new FRPaintEventArgs(g, 1, 1, cache));
  148. }
  149. }
  150. int[] rawBitmap = GetRawBitmap((Bitmap)image);
  151. string hash = CalculateHash(rawBitmap);
  152. if (!hashtable.ContainsKey(hash))
  153. {
  154. ExportUtils.SaveJpeg(image, imageStream, quality);
  155. imageBytes = imageStream.ToArray();
  156. hashtable.Add(hash, ByteArrayToHexString(imageBytes));
  157. hex = hashtable[hash] as string;
  158. imageVariablesNames.Add(hash, "PIC" + img_nbr);
  159. ps.DeclareImage(imageVariablesNames[hash], hex);
  160. }
  161. ps.AddImage(imageVariablesNames[hash], (obj.AbsLeft + pageLeftMargin) * 0.75f, (obj.AbsTop + pageTopMargin) * 0.75f, obj.Width, obj.Height);
  162. }
  163. }
  164. img_nbr++;
  165. }
  166. private string CalculateHash(int[] raw_picture)
  167. {
  168. byte[] raw_picture_byte = new byte[raw_picture.Length * sizeof(int)];
  169. Buffer.BlockCopy(raw_picture, 0, raw_picture_byte, 0, raw_picture_byte.Length);
  170. byte[] hash = new Murmur3().ComputeHash(raw_picture_byte);
  171. return Convert.ToBase64String(hash);
  172. }
  173. private int[] GetRawBitmap(Bitmap image)
  174. {
  175. int raw_size = image.Width * image.Height;
  176. int[] raw_picture = new int[raw_size];
  177. BitmapData bmpdata = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadOnly, image.PixelFormat);
  178. IntPtr ptr = bmpdata.Scan0;
  179. System.Runtime.InteropServices.Marshal.Copy(ptr, raw_picture, 0, raw_size);
  180. image.UnlockBits(bmpdata);
  181. return raw_picture;
  182. }
  183. internal static string ByteArrayToHexString(byte[] byteArray)
  184. {
  185. System.Text.StringBuilder hex = new System.Text.StringBuilder(byteArray.Length * 2);
  186. foreach (byte b in byteArray)
  187. hex.AppendFormat("{0:x2}", b);
  188. return hex.ToString();
  189. }
  190. private void AddBitmapWatermark(ReportPage page)
  191. {
  192. if (page.Watermark.Image != null)
  193. {
  194. using (PictureObject pictureWatermark = new PictureObject())
  195. {
  196. pictureWatermark.Left = page.LeftMargin;
  197. pictureWatermark.Top = page.TopMargin;
  198. pictureWatermark.Width = ExportUtils.GetPageWidth(page) * Units.Millimeters;
  199. pictureWatermark.Height = ExportUtils.GetPageHeight(page) * Units.Millimeters;
  200. pictureWatermark.SizeMode = PictureBoxSizeMode.Normal;
  201. pictureWatermark.Image = new Bitmap((int)pictureWatermark.Width, (int)pictureWatermark.Height);
  202. using (Graphics g = Graphics.FromImage(pictureWatermark.Image))
  203. {
  204. g.Clear(Color.Transparent);
  205. page.Watermark.DrawImage(new FRPaintEventArgs(g, 1, 1, Report.GraphicCache),
  206. new RectangleF(0, 0, pictureWatermark.Width, pictureWatermark.Height), Report, true);
  207. }
  208. pictureWatermark.Transparency = page.Watermark.ImageTransparency;
  209. pictureWatermark.Fill = new SolidFill(Color.Transparent);
  210. pictureWatermark.FillColor = Color.Transparent;
  211. AddPictureObject(ps, pictureWatermark);
  212. }
  213. }
  214. }
  215. private void AddTextWatermark(ReportPage page)
  216. {
  217. if (!String.IsNullOrEmpty(page.Watermark.Text))
  218. using (TextObject textWatermark = new TextObject())
  219. {
  220. textWatermark.HorzAlign = HorzAlign.Center;
  221. textWatermark.VertAlign = VertAlign.Center;
  222. textWatermark.Left = page.LeftMargin;
  223. textWatermark.Top = page.TopMargin;
  224. textWatermark.Width = ExportUtils.GetPageWidth(page) * Units.Millimeters;
  225. textWatermark.Height = ExportUtils.GetPageHeight(page) * Units.Millimeters;
  226. textWatermark.Text = page.Watermark.Text;
  227. textWatermark.TextFill = page.Watermark.TextFill;
  228. if (page.Watermark.TextRotation == WatermarkTextRotation.Vertical)
  229. textWatermark.Angle = 270;
  230. else if (page.Watermark.TextRotation == WatermarkTextRotation.ForwardDiagonal)
  231. textWatermark.Angle = 360 - (int)(Math.Atan(textWatermark.Height / textWatermark.Width) * (180 / Math.PI));
  232. else if (page.Watermark.TextRotation == WatermarkTextRotation.BackwardDiagonal)
  233. textWatermark.Angle = (int)(Math.Atan(textWatermark.Height / textWatermark.Width) * (180 / Math.PI));
  234. textWatermark.Font = page.Watermark.Font;
  235. if (page.Watermark.TextFill is SolidFill)
  236. textWatermark.TextColor = (page.Watermark.TextFill as SolidFill).Color;
  237. textWatermark.Fill = new SolidFill(Color.Transparent);
  238. textWatermark.FillColor = Color.Transparent;
  239. AddTextObject(ps, textWatermark, false, true);
  240. }
  241. }
  242. private void SaveImgsToFiles()
  243. {
  244. foreach (KeyValuePair<string, string> fl_nm_e in hashtable)
  245. {
  246. foreach (KeyValuePair<string, MemoryStream> img_e in images)
  247. {
  248. if (fl_nm_e.Key == img_e.Key)
  249. {
  250. string fullImagePath = Path.Combine(path, fl_nm_e.Value) + "." + format.ToString().ToLower();
  251. using (FileStream file = new FileStream(fullImagePath, FileMode.Create))
  252. img_e.Value.WriteTo(file);
  253. }
  254. }
  255. }
  256. }
  257. private void AddTable(PSDocument ps, TableBase table, bool drawCells)
  258. {
  259. float y = 0;
  260. for (int i = 0; i < table.RowCount; i++)
  261. {
  262. float x = 0;
  263. for (int j = 0; j < table.ColumnCount; j++)
  264. {
  265. if (!table.IsInsideSpan(table[j, i]))
  266. {
  267. TableCell textcell = table[j, i];
  268. textcell.Left = x;
  269. textcell.Top = y;
  270. if (drawCells)
  271. {
  272. Border oldBorder = textcell.Border.Clone();
  273. textcell.Border.Lines = BorderLines.None;
  274. if ((textcell as TextObject) is TextObject)
  275. AddTextObject(ps, textcell as TextObject, false);
  276. else
  277. AddPictureObject(ps, textcell as ReportComponentBase);
  278. textcell.Border = oldBorder;
  279. }
  280. else
  281. AddBorder(ps, textcell.Border, textcell.AbsLeft, textcell.AbsTop, textcell.Width, textcell.Height);
  282. }
  283. x += (table.Columns[j]).Width;
  284. }
  285. y += (table.Rows[i]).Height;
  286. }
  287. }
  288. private void AddPictureObject(PSDocument ps, ReportComponentBase obj)
  289. {
  290. int[] rawBitmap;
  291. string hash;
  292. if (pictures)
  293. {
  294. MemoryStream imageStream = new MemoryStream();
  295. using (System.Drawing.Image image = new Bitmap((int)obj.Width, (int)obj.Height))
  296. {
  297. using (Graphics g = Graphics.FromImage(image))
  298. {
  299. using (GraphicCache cache = new GraphicCache())
  300. {
  301. g.Clear(Color.White);
  302. float Left = obj.Width >= 0 ? obj.AbsLeft : obj.AbsLeft + obj.Width;
  303. float Top = obj.Height >= 0 ? obj.AbsTop : obj.AbsTop + obj.Height;
  304. g.TranslateTransform(-Left, -Top);
  305. obj.Draw(new FRPaintEventArgs(g, 1, 1, cache));
  306. }
  307. }
  308. ExportUtils.SaveJpeg(image, imageStream, quality);
  309. rawBitmap = GetRawBitmap((Bitmap)image);
  310. hash = CalculateHash(rawBitmap);
  311. }
  312. imageStream.Position = 0;
  313. string imageFileName = fileNameWOext.Replace(" ", "") + hashtable.Count.ToString();
  314. if (!hashtable.ContainsKey(hash))
  315. {
  316. hashtable.Add(hash, imageFileName);
  317. if (path != null && path != "")
  318. GeneratedFiles.Add(imageFileName);
  319. images.Add(hash, imageStream);
  320. }
  321. else
  322. imageFileName = hashtable[hash] as string;
  323. // add image
  324. ps.AddImage(imageFileName, format.ToString().ToLower(), (obj.AbsLeft + pageLeftMargin) * 0.75f, (obj.AbsTop + pageTopMargin) * 0.75f, obj.Width, obj.Height);
  325. img_nbr++;
  326. }
  327. }
  328. private void AddBorder(PSDocument ps, Border border, float Left, float Top, float Width, float Height)
  329. {
  330. if (border.Lines != BorderLines.None)
  331. {
  332. using (TextObject emptyText = new TextObject())
  333. {
  334. emptyText.Left = Left;
  335. emptyText.Top = Top;
  336. emptyText.Width = Width;
  337. emptyText.Height = Height;
  338. emptyText.Border = border;
  339. emptyText.Text = String.Empty;
  340. emptyText.FillColor = Color.Transparent;
  341. AddTextObject(ps, emptyText, true);
  342. }
  343. }
  344. }
  345. /// <summary>
  346. /// Add TextObject.
  347. /// </summary>
  348. private void AddTextObject(PSDocument ps, TextObject text, bool Band, bool isWatermark = false)
  349. {
  350. Font font = text.Font;
  351. float AbsLeft = text.AbsLeft + pageLeftMargin;
  352. float AbsTop = text.AbsTop + pageTopMargin;
  353. float Width = text.Width;
  354. float Height = text.Height;
  355. string HorzAlign = Convert.ToString(text.HorzAlign);
  356. string VertAlign = Convert.ToString(text.VertAlign);
  357. float BorderWidth = text.Border.Width;
  358. string BorderLines = Convert.ToString(text.Border.Lines);
  359. string Text = text.Text;
  360. float FontSize = text.Font.Size;
  361. string FontName = Convert.ToString(text.Font.Name);
  362. bool Bold = text.Font.Bold;
  363. bool Italic = text.Font.Italic;
  364. bool Underline = text.Font.Underline;
  365. float PaddingLeft = text.Padding.Left;
  366. float PaddingTop = text.Padding.Top;
  367. float PaddingRight = text.Padding.Right;
  368. float PaddingBottom = text.Padding.Bottom;
  369. bool WordWrap = text.WordWrap;
  370. string BorderBrush;
  371. string Background;
  372. string Foreground;
  373. float Angle = text.Angle;
  374. float LeftLine = text.Border.LeftLine.Width;
  375. float TopLine = text.Border.TopLine.Width;
  376. float RightLine = text.Border.RightLine.Width;
  377. float BottomLine = text.Border.BottomLine.Width;
  378. //Dash------------------------------------------------
  379. string LeftLineDashStile = Convert.ToString(text.Border.LeftLine.Style);
  380. string TopLineDashStile = Convert.ToString(text.Border.TopLine.Style);
  381. string RightLineDashStile = Convert.ToString(text.Border.RightLine.Style);
  382. string BottomLineDashStile = Convert.ToString(text.Border.BottomLine.Style);
  383. string colorLeftLine = ExportUtils.HTMLColor(text.Border.LeftLine.Color);
  384. string colorTopLine = ExportUtils.HTMLColor(text.Border.TopLine.Color);
  385. string colorRightLine = ExportUtils.HTMLColor(text.Border.RightLine.Color);
  386. string colorBottomLine = ExportUtils.HTMLColor(text.Border.BottomLine.Color);
  387. //GlassFill
  388. bool Glass = false;
  389. string colorTop = null;
  390. if (text.Fill is GlassFill)
  391. {
  392. Glass = true;
  393. Color color = GetBlendColor((text.Fill as GlassFill).Color, (text.Fill as GlassFill).Blend);
  394. colorTop = ExportUtils.HTMLColor(color);
  395. }
  396. NormalizeBorderBrushColor(text, out BorderBrush);
  397. NormalizeForegroundColor(text, out Foreground);
  398. NormalizeBackgroundColor(text, out Background);
  399. //Shadow----
  400. float ShadowWidth = text.Border.ShadowWidth;
  401. string ShadowColor = ExportUtils.HTMLColor(text.Border.ShadowColor);
  402. if (Band)
  403. {
  404. HorzAlign = null;
  405. VertAlign = null;
  406. Text = null;
  407. FontSize = 0;
  408. Foreground = null;
  409. FontName = null;
  410. Bold = false;
  411. Italic = false;
  412. Underline = false;
  413. PaddingLeft = 0;
  414. PaddingTop = 0;
  415. PaddingRight = 0;
  416. PaddingBottom = 0;
  417. WordWrap = false;
  418. }
  419. {
  420. ps.AddTextObject(AbsLeft * 0.75f, AbsTop * 0.75f, Width * 0.75f, Height * 0.75f, HorzAlign, VertAlign, BorderBrush,
  421. BorderWidth * 0.75f, LeftLine * 0.75f, TopLine * 0.75f, RightLine * 0.75f, BottomLine * 0.75f, LeftLineDashStile, TopLineDashStile,
  422. RightLineDashStile, BottomLineDashStile, colorLeftLine, colorTopLine, colorRightLine, colorBottomLine,
  423. text.Border.Shadow, ShadowColor, ShadowWidth * 0.75f, Background, BorderLines, Text, Foreground, PaddingLeft * 0.75f, PaddingTop * 0.75f, PaddingRight * 0.75f, PaddingBottom * 0.75f, WordWrap, Angle, Glass, colorTop, font, isWatermark);
  424. }
  425. }
  426. /// <summary>
  427. /// Add BandObject.
  428. /// </summary>
  429. private void AddBandObject(PSDocument ps, BandBase band)
  430. {
  431. using (TextObject newObj = new TextObject())
  432. {
  433. newObj.Left = band.AbsLeft;
  434. newObj.Top = band.AbsTop;
  435. newObj.Width = band.Width;
  436. newObj.Height = band.Height;
  437. newObj.Fill = band.Fill;
  438. newObj.Border = band.Border;
  439. AddTextObject(ps, newObj, true);
  440. }
  441. }
  442. /// <summary>
  443. /// Add Line.
  444. /// </summary>
  445. private void AddLine(PSDocument ps, LineObject line)
  446. {
  447. float AbsLeft = line.AbsLeft + pageLeftMargin;
  448. float AbsTop = line.AbsTop + pageTopMargin;
  449. float Width = line.Width;
  450. float Height = line.Height;
  451. string Fill = Convert.ToString(ExportUtils.GetColorFromFill(line.Fill));
  452. float Border = line.Border.Width;
  453. string LineStyle = line.Style;
  454. string BorderBrush = ExportUtils.HTMLColor(line.Border.Color);
  455. if (line.StartCap.Style == CapStyle.Arrow)
  456. {
  457. float x3, y3, x4, y4;
  458. DrawArrow(line.StartCap, Border, Width + AbsLeft, Height + AbsTop, AbsLeft, AbsTop, out x3, out y3, out x4, out y4);
  459. ps.AddLine(AbsLeft * 0.75f, AbsTop * 0.75f, x3 * 0.75f, y3 * 0.75f, BorderBrush, Border * 0.75f);
  460. ps.AddLine(AbsLeft * 0.75f, AbsTop * 0.75f, x4 * 0.75f, y4 * 0.75f, BorderBrush, Border * 0.75f);
  461. }
  462. if (line.EndCap.Style == CapStyle.Arrow)
  463. {
  464. float x3, y3, x4, y4;
  465. DrawArrow(line.EndCap, Border, AbsLeft, AbsTop, Width + AbsLeft, Height + AbsTop, out x3, out y3, out x4, out y4);
  466. ps.AddLine((Width + AbsLeft) * 0.75f, (AbsTop + Height) * 0.75f, x3 * 0.75f, y3 * 0.75f, BorderBrush, Border * 0.75f);
  467. ps.AddLine((Width + AbsLeft) * 0.75f, (AbsTop + Height) * 0.75f, x4 * 0.75f, y4 * 0.75f, BorderBrush, Border * 0.75f);
  468. }
  469. ps.AddLine(AbsLeft * 0.75f, AbsTop * 0.75f, (AbsLeft + Width) * 0.75f, (AbsTop + Height) * 0.75f, BorderBrush, Border * 0.75f);
  470. }
  471. private void DrawArrow(CapSettings Arrow, float lineWidth, float x1, float y1, float x2, float y2, out float x3, out float y3, out float x4, out float y4)
  472. {
  473. float k1, a, b, c, d;
  474. float xp, yp;
  475. float wd = Arrow.Width * lineWidth;
  476. float ld = Arrow.Height * lineWidth;
  477. if (Math.Abs(x2 - x1) > 0)
  478. {
  479. k1 = (y2 - y1) / (x2 - x1);
  480. a = (float)(Math.Pow(k1, 2) + 1);
  481. b = 2 * (k1 * ((x2 * y1 - x1 * y2) / (x2 - x1) - y2) - x2);
  482. c = (float)(Math.Pow(x2, 2) + Math.Pow(y2, 2) - Math.Pow(ld, 2) +
  483. Math.Pow((x2 * y1 - x1 * y2) / (x2 - x1), 2) -
  484. 2 * y2 * (x2 * y1 - x1 * y2) / (x2 - x1));
  485. d = (float)(Math.Pow(b, 2) - 4 * a * c);
  486. xp = (float)((-b + Math.Sqrt(d)) / (2 * a));
  487. if ((xp > x1) && (xp > x2) || (xp < x1) && (xp < x2))
  488. xp = (float)((-b - Math.Sqrt(d)) / (2 * a));
  489. yp = xp * k1 + (x2 * y1 - x1 * y2) / (x2 - x1);
  490. if (y2 != y1)
  491. {
  492. x3 = (float)(xp + wd * Math.Sin(Math.Atan(k1)));
  493. y3 = (float)(yp - wd * Math.Cos(Math.Atan(k1)));
  494. x4 = (float)(xp - wd * Math.Sin(Math.Atan(k1)));
  495. y4 = (float)(yp + wd * Math.Cos(Math.Atan(k1)));
  496. }
  497. else
  498. {
  499. x3 = xp; y3 = yp - wd;
  500. x4 = xp; y4 = yp + wd;
  501. }
  502. }
  503. else
  504. {
  505. xp = x2; yp = y2 - ld;
  506. if ((yp > y1) && (yp > y2) || (yp < y1) && (yp < y2))
  507. yp = y2 + ld;
  508. x3 = xp - wd; y3 = yp;
  509. x4 = xp + wd; y4 = yp;
  510. }
  511. }
  512. /// <summary>
  513. /// Add Shape.
  514. /// </summary>
  515. private void AddShape(PSDocument ps, ShapeObject shape)
  516. {
  517. float AbsLeft = shape.AbsLeft + pageLeftMargin;
  518. float AbsTop = shape.AbsTop + pageTopMargin;
  519. float Width = shape.Width;
  520. float Height = shape.Height;
  521. float BorderWidth = shape.Border.Width;
  522. string BorderLines = Convert.ToString(shape.Border.Lines);
  523. string BorderBrush;
  524. string Background;
  525. NormalizeColor(shape, out BorderBrush, out Background);
  526. if (shape.Shape == ShapeKind.Rectangle)
  527. ps.AddRectangle(AbsLeft * 0.75f, AbsTop * 0.75f, Width * 0.75f, Height * 0.75f, BorderBrush, BorderWidth * 0.75f, Background, false);
  528. if (shape.Shape == ShapeKind.RoundRectangle)
  529. ps.AddRectangle(AbsLeft * 0.75f, AbsTop * 0.75f, Width * 0.75f, Height * 0.75f, BorderBrush, BorderWidth * 0.75f, Background, true);
  530. if (shape.Shape == ShapeKind.Ellipse)
  531. ps.AddEllipse(AbsLeft * 0.75f, AbsTop * 0.75f, Width * 0.75f, Height * 0.75f, BorderBrush, BorderWidth * 0.75f, Background);
  532. if (shape.Shape == ShapeKind.Triangle)
  533. ps.AddTriangle(AbsLeft * 0.75f, AbsTop * 0.75f, Width * 0.75f, Height * 0.75f, BorderBrush, BorderWidth * 0.75f, Background);
  534. if (shape.Shape == ShapeKind.Diamond)
  535. ps.AddDiamond(AbsLeft * 0.75f, AbsTop * 0.75f, Width * 0.75f, Height * 0.75f, BorderBrush, BorderWidth * 0.75f, Background);
  536. }
  537. private Color GetBlendColor(Color c, float Blend)
  538. {
  539. return Color.FromArgb(255, (int)Math.Round(c.R + (255 - c.R) * Blend),
  540. (int)Math.Round(c.G + (255 - c.G) * Blend),
  541. (int)Math.Round(c.B + (255 - c.B) * Blend));
  542. }
  543. private void NormalizeBorderBrushColor(TextObject obj, out string BorderBrush)
  544. {
  545. obj.FillColor = ExportUtils.GetColorFromFill(obj.Fill);
  546. BorderBrush = ExportUtils.HTMLColor(obj.Border.Color);
  547. }
  548. private void NormalizeBackgroundColor(TextObject obj, out string Background)
  549. {
  550. obj.FillColor = ExportUtils.GetColorFromFill(obj.Fill);
  551. if (obj.FillColor.Name == "Transparent")
  552. {
  553. Background = "none";
  554. }
  555. else Background = ExportUtils.HTMLColor(obj.FillColor);
  556. }
  557. private void NormalizeForegroundColor(TextObject obj, out string Foreground)
  558. {
  559. obj.FillColor = ExportUtils.GetColorFromFill(obj.Fill);
  560. Foreground = ExportUtils.HTMLColor(obj.TextColor);
  561. }
  562. private void NormalizeColor(ShapeObject obj, out string BorderBrush, out string Background)
  563. {
  564. obj.FillColor = ExportUtils.GetColorFromFill(obj.Fill);
  565. BorderBrush = ExportUtils.HTMLColor(obj.Border.Color);
  566. if (obj.FillColor.Name == "Transparent")
  567. {
  568. Background = "none";
  569. }
  570. else Background = ExportUtils.HTMLColor(obj.FillColor);
  571. }
  572. #endregion
  573. #region Protected Methods
  574. /// <inheritdoc/>
  575. protected override void Start()
  576. {
  577. //init
  578. hashtable = new Dictionary<string, string>();
  579. img_nbr = 0;
  580. images = new Dictionary<string, MemoryStream>();
  581. imageVariablesNames = new Dictionary<string, string>();
  582. if (!pagesInDiffFiles)
  583. {
  584. ps = new PSDocument();
  585. ps.TextInCurves = textInCurves;
  586. }
  587. currentPage = 0;
  588. if (FileName != "" && FileName != null)
  589. {
  590. path = Path.GetDirectoryName(FileName);
  591. fileNameWOext = Path.GetFileNameWithoutExtension(FileName);
  592. extension = Path.GetExtension(FileName);
  593. }
  594. else
  595. fileNameWOext = "xamlreport";
  596. GeneratedFiles.Clear();
  597. hashtable.Clear();
  598. }
  599. /// <summary>
  600. /// Begin exporting of page
  601. /// </summary>
  602. /// <param name="page"></param>
  603. protected override void ExportPageBegin(ReportPage page)
  604. {
  605. base.ExportPageBegin(page);
  606. if (pagesInDiffFiles)
  607. {
  608. ps = new PSDocument(ExportUtils.GetPageWidth(page) * Units.Millimeters * 0.75f,
  609. ExportUtils.GetPageHeight(page) * Units.Millimeters * 0.75f);
  610. ps.TextInCurves = textInCurves;
  611. }
  612. else ps.CreateWindow();
  613. pageLeftMargin = page.LeftMargin * Units.Millimeters;
  614. pageTopMargin = page.TopMargin * Units.Millimeters;
  615. // bitmap watermark on bottom
  616. if (page.Watermark.Enabled && !page.Watermark.ShowImageOnTop)
  617. AddBitmapWatermark(page);
  618. // text watermark on bottom
  619. if (page.Watermark.Enabled && !page.Watermark.ShowTextOnTop)
  620. AddTextWatermark(page);
  621. // page borders
  622. if (page.Border.Lines != BorderLines.None)
  623. {
  624. using (TextObject pageBorder = new TextObject())
  625. {
  626. pageBorder.Border = page.Border;
  627. pageBorder.Left = 0;
  628. pageBorder.Top = 0;
  629. pageBorder.Width = (ExportUtils.GetPageWidth(page) - page.LeftMargin - page.RightMargin);
  630. pageBorder.Height = (ExportUtils.GetPageHeight(page) - page.TopMargin - page.BottomMargin);
  631. AddTextObject(ps, pageBorder, true);
  632. }
  633. }
  634. if (path != null && path != "")
  635. pageFileName = Path.Combine(path, fileNameWOext + currentPage.ToString() + extension);
  636. else
  637. pageFileName = null;
  638. }
  639. /// <summary>
  640. /// Export of Band
  641. /// </summary>
  642. /// <param name="band"></param>
  643. protected override void ExportBand(BandBase band)
  644. {
  645. base.ExportBand(band);
  646. ExportObj(band);
  647. foreach (Base c in band.ForEachAllConvectedObjects(this))
  648. {
  649. ExportObj(c);
  650. }
  651. }
  652. /// <summary>
  653. /// End exporting
  654. /// </summary>
  655. /// <param name="page"></param>
  656. protected override void ExportPageEnd(ReportPage page)
  657. {
  658. base.ExportPageEnd(page);
  659. // bitmap watermark on top
  660. if (page.Watermark.Enabled && page.Watermark.ShowImageOnTop)
  661. AddBitmapWatermark(page);
  662. // text watermark on top
  663. if (page.Watermark.Enabled && page.Watermark.ShowTextOnTop)
  664. AddTextWatermark(page);
  665. ps.Finish();
  666. if (PagesInDiffFiles)
  667. {
  668. if (Directory.Exists(path) && !string.IsNullOrEmpty(FileName))
  669. {
  670. // desktop mode
  671. if (currentPage == 0)
  672. {
  673. // save first page in parent Stream
  674. ps.Save(Stream);
  675. Stream.Position = 0;
  676. GeneratedFiles.Add(FileName);
  677. }
  678. else
  679. {
  680. // save all page after first in files
  681. ps.Save(pageFileName);
  682. GeneratedFiles.Add(pageFileName);
  683. }
  684. }
  685. else if (string.IsNullOrEmpty(path))
  686. {
  687. if (currentPage == 0)
  688. {
  689. // save first page in parent Stream
  690. ps.Save(Stream);
  691. Stream.Position = 0;
  692. GeneratedFiles.Add(FileName);
  693. }
  694. else
  695. {
  696. // server mode, save in internal stream collection
  697. using (MemoryStream pageStream = new MemoryStream())
  698. {
  699. ps.Save(pageStream);
  700. pageStream.Position = 0;
  701. GeneratedFiles.Add(pageFileName);
  702. }
  703. }
  704. }
  705. }
  706. // increment page number
  707. currentPage++;
  708. }
  709. /// <inheritdoc/>
  710. protected override void Finish()
  711. {
  712. if (Directory.Exists(path) && !string.IsNullOrEmpty(FileName) && SaveImagesSeparately)
  713. SaveImgsToFiles();
  714. if (!pagesInDiffFiles) ps.Save(Stream);
  715. ps = null;
  716. }
  717. /// <inheritdoc/>
  718. protected override string GetFileFilter()
  719. {
  720. return new MyRes("FileFilters").Get("PSFile");
  721. }
  722. #endregion
  723. /// <inheritdoc/>
  724. public override void Serialize(FRWriter writer)
  725. {
  726. base.Serialize(writer);
  727. writer.WriteBool("TextInCurves", TextInCurves);
  728. writer.WriteBool("PagesInDiffFiles", PagesInDiffFiles);
  729. writer.WriteBool("SaveImagesSeparately", SaveImagesSeparately);
  730. writer.WriteInt("JpegQuality", quality);
  731. }
  732. /// <summary>
  733. /// Initializes a new instance of the <see cref="PSExport"/> class.
  734. /// </summary>
  735. public PSExport()
  736. {
  737. saveImagesSeparately = false;
  738. HasMultipleFiles = true;
  739. PagesInDiffFiles = false;
  740. pictures = true;
  741. quality = 100;
  742. format = System.Drawing.Imaging.ImageFormat.Jpeg;
  743. }
  744. }
  745. }