XAMLExport.cs 32 KB

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