TextExport.cs 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.IO;
  5. using System.Text;
  6. using FastReport.Preview;
  7. using FastReport.Table;
  8. using FastReport.Utils;
  9. namespace FastReport.Export.Text
  10. {
  11. /// <summary>
  12. /// Represents the text export.
  13. /// </summary>
  14. public partial class TextExport : ExportBase
  15. {
  16. #region Constants
  17. private const float XDiv = 7.5f;
  18. private const float YDiv = 4f;
  19. private const float XDivAdv = 0.1015f;
  20. private const float YDivAdv = 0.06f;
  21. private const float CalculateStep = 0.1f;
  22. private const float CalculateStepBack = 0.01f;
  23. private const float divPaperX = 4.8f;
  24. private const float divPaperY = 3.6f;
  25. private const int CalcIterations = 10;
  26. byte[] u_HEADER = { 239, 187, 191 };
  27. string[] ref_frames = {
  28. // 0 left, 1 top, 2 left-up, 3 right-top, 4 right-down, 5 left-down, 6 left-t,
  29. // 7 right-t, 8 up-t, 9 down-t, 10 cross
  30. "|-+++++++++",
  31. "\u2502\u2500\u250c\u2510\u2518\u2514\u251c\u2524\u252c\u2534\u253c" };
  32. #endregion
  33. #region Private fields
  34. private bool pageBreaks;
  35. private MyRes res;
  36. private bool frames;
  37. private bool textFrames;
  38. private bool emptyLines;
  39. private int screenWidth;
  40. private int screenHeight;
  41. private StringBuilder screen;
  42. private float scaleX;
  43. private float scaleY;
  44. private float scaleXStart;
  45. private float scaleYStart;
  46. private Encoding encoding;
  47. private bool dataOnly;
  48. private bool previewMode;
  49. private int pageWidth;
  50. private int pageHeight;
  51. private bool dataSaved;
  52. private bool dataLossBreak;
  53. private string frameChars;
  54. private List<TextExportPrinterType> printerTypes;
  55. private int printerType;
  56. private bool printAfterExport;
  57. private string printerName;
  58. private int copies;
  59. private bool avoidDataLoss;
  60. #endregion
  61. #region Properties
  62. /// <summary>
  63. /// Enable or disable the Data loss avoiding.
  64. /// Auto calculation of ScaleX and ScaleY will be launched when dialogue window will be off.
  65. /// </summary>
  66. public bool AvoidDataLoss
  67. {
  68. get { return avoidDataLoss; }
  69. set { avoidDataLoss = value; }
  70. }
  71. /// <summary>
  72. /// Gets or sets the count of copies for printing of results.
  73. /// </summary>
  74. public int Copies
  75. {
  76. get { return copies; }
  77. set { copies = value; }
  78. }
  79. /// <summary>
  80. /// Gets or sets the printer name for printing of results.
  81. /// </summary>
  82. public string PrinterName
  83. {
  84. get { return printerName; }
  85. set { printerName = value; }
  86. }
  87. /// <summary>
  88. /// Enable or disable the printing results after export.
  89. /// </summary>
  90. public bool PrintAfterExport
  91. {
  92. get { return printAfterExport; }
  93. set { printAfterExport = value; }
  94. }
  95. /// <summary>
  96. /// Gets or sets the active index of registered printer type.
  97. /// </summary>
  98. public int PrinterType
  99. {
  100. get { return printerType; }
  101. set { printerType = value; }
  102. }
  103. /// <summary>
  104. /// Gets or sets the list of printer types. <see cref="TextExportPrinterType"/>
  105. /// </summary>
  106. public List<TextExportPrinterType> PrinterTypes
  107. {
  108. get { return printerTypes; }
  109. set { printerTypes = value; }
  110. }
  111. /// <summary>
  112. /// Gets or sets the scale by X axis for correct text objects placement.
  113. /// </summary>
  114. public float ScaleX
  115. {
  116. get { return scaleX; }
  117. set
  118. {
  119. scaleX = value;
  120. scaleXStart = value;
  121. }
  122. }
  123. /// <summary>
  124. /// Gets or sets the scale by Y axis for correct text objects placement.
  125. /// </summary>
  126. public float ScaleY
  127. {
  128. get { return scaleY; }
  129. set
  130. {
  131. scaleY = value;
  132. scaleYStart = value;
  133. }
  134. }
  135. /// <summary>
  136. /// Gets or sets the encoding of resulting document.
  137. /// </summary>
  138. /// <example>
  139. /// Windows ANSI encoding
  140. /// <code>TextExport.Encoding = Encoding.Default;</code>
  141. /// Unicode UTF-8 encoding
  142. /// <code>TextExport.Encoding = Encoding.UTF8;</code>
  143. /// OEM encoding for current system locale sessings
  144. /// <code>TextExport.Encoding = Encoding.GetEncoding(CultureInfo.CurrentCulture.TextInfo.OEMCodePage);</code>
  145. /// </example>
  146. public Encoding Encoding
  147. {
  148. get { return encoding; }
  149. set { encoding = value; }
  150. }
  151. /// <summary>
  152. /// Enable or disable the data only output without any headers. Default value is false.
  153. /// </summary>
  154. public bool DataOnly
  155. {
  156. get { return dataOnly; }
  157. set { dataOnly = value; }
  158. }
  159. /// <summary>
  160. /// Enable or disable the breaks of pages in resulting document. Default value is true.
  161. /// </summary>
  162. public bool PageBreaks
  163. {
  164. get { return pageBreaks; }
  165. set { pageBreaks = value; }
  166. }
  167. /// <summary>
  168. /// Enable or disable frames in resulting document. Default value is true.
  169. /// </summary>
  170. public bool Frames
  171. {
  172. get { return frames; }
  173. set { frames = value; }
  174. }
  175. /// <summary>
  176. /// Enable or disable the text (non graphic) frames in resulting document. Default value is false.
  177. /// </summary>
  178. public bool TextFrames
  179. {
  180. get { return textFrames; }
  181. set { textFrames = value; }
  182. }
  183. /// <summary>
  184. /// Enable or disable the output of empty lines in resulting document. Default value is false.
  185. /// </summary>
  186. public bool EmptyLines
  187. {
  188. get { return emptyLines; }
  189. set { emptyLines = value; }
  190. }
  191. /// <summary>
  192. ///
  193. /// </summary>
  194. public bool DataSaved
  195. {
  196. get { return dataSaved; }
  197. }
  198. /// <summary>
  199. ///
  200. /// </summary>
  201. public bool DataLossBreak
  202. {
  203. get { return dataLossBreak; }
  204. set { dataLossBreak = value; }
  205. }
  206. /// <summary>
  207. ///
  208. /// </summary>
  209. public int PageHeight
  210. {
  211. get { return pageHeight; }
  212. }
  213. /// <summary>
  214. ///
  215. /// </summary>
  216. public int PageWidth
  217. {
  218. get { return pageWidth; }
  219. }
  220. /// <summary>
  221. ///
  222. /// </summary>
  223. public bool PreviewMode
  224. {
  225. get { return previewMode; }
  226. set { previewMode = value; }
  227. }
  228. #endregion
  229. #region Private Methods
  230. private char ScreenGet(int x, int y)
  231. {
  232. if ((x < screenWidth) && (y < screenHeight) &&
  233. (x >= 0) && (y >= 0))
  234. return screen[screenWidth * y + x];
  235. else
  236. return ' ';
  237. }
  238. private void ScreenType(int x, int y, char c)
  239. {
  240. if ((x < screenWidth) && (y < screenHeight) &&
  241. (x >= 0) && (y >= 0))
  242. {
  243. if (c != ' ')
  244. {
  245. char current = screen[screenWidth * y + x];
  246. if (current != ' ' && !(frames && IsFrame(current) && IsFrame(c)))
  247. dataSaved = false;
  248. screen[screenWidth * y + x] = c;
  249. }
  250. }
  251. else
  252. if (c != ' ')
  253. dataSaved = false;
  254. }
  255. private bool IsFrame(char c)
  256. {
  257. return c == ' ' ? false : (frameChars.IndexOf(c) != -1);
  258. }
  259. private StringBuilder AlignStr(string s, HorzAlign align, int width)
  260. {
  261. if (align == HorzAlign.Right)
  262. return RightStr(s, width - 1);
  263. else if (align == HorzAlign.Center)
  264. return CenterStr(s, width - 1);
  265. else
  266. return LeftStr(s, width - 1);
  267. }
  268. private StringBuilder LeftStr(string s, int width)
  269. {
  270. return AddCharR(' ', s, width);
  271. }
  272. private StringBuilder AddCharR(char p, string s, int width)
  273. {
  274. width = width > 0 ? width : 0;
  275. StringBuilder result = new StringBuilder(width);
  276. if (s.Length < width)
  277. return result.Append(s).Append(new String(p, width - s.Length));
  278. else
  279. return result.Append(s);
  280. }
  281. private StringBuilder CenterStr(string s, int width)
  282. {
  283. if (width < s.Length)
  284. width = s.Length;
  285. StringBuilder result = new StringBuilder(width);
  286. if (s.Length < width)
  287. {
  288. result.Append(new String(' ', (int)(width / 2) - (int)(s.Length / 2))).Append(s);
  289. result.Append(new String(' ', width - result.Length));
  290. }
  291. else
  292. result.Append(s);
  293. return result;
  294. }
  295. private StringBuilder RightStr(string s, int width)
  296. {
  297. return AddChar(' ', s, width);
  298. }
  299. private StringBuilder AddChar(char p, string s, int width)
  300. {
  301. width = width > 0 ? width : 0;
  302. StringBuilder result = new StringBuilder(width);
  303. if (s.Length < width)
  304. result.Append(new String(p, width - s.Length)).Append(s);
  305. else
  306. result.Append(s);
  307. return result;
  308. }
  309. private void ScreenString(int x, int y, string s)
  310. {
  311. for (int i = 0; i < s.Length; i++)
  312. ScreenType(x + i, y, s[i]);
  313. }
  314. private void InitScreen()
  315. {
  316. screen = new StringBuilder(screenWidth * screenHeight);
  317. screen.Append(' ', screenWidth * screenHeight);
  318. }
  319. private void DrawLineObject(LineObject lineObject)
  320. {
  321. if (lineObject.Width == 0 || lineObject.Height == 0)
  322. {
  323. int d = frames ? 1 : 0;
  324. int curx = (int)Math.Round(lineObject.AbsLeft * scaleX * XDivAdv) + d;
  325. int cury = (int)Math.Round(lineObject.AbsTop * YDivAdv * scaleY) + d;
  326. int cury2 = (int)Math.Floor((lineObject.AbsTop + lineObject.Height) * scaleY * YDivAdv) + d;
  327. int curx2 = (int)Math.Floor((lineObject.AbsLeft + lineObject.Width) * scaleX * XDivAdv) + d;
  328. int height = cury2 - cury;
  329. int width = curx2 - curx;
  330. if (lineObject.Width == 0)
  331. for (int i = 0; i < height; i++)
  332. ScreenType(curx, cury + i, frameChars[0]);
  333. else if (lineObject.Height == 0)
  334. for (int i = 0; i < width; i++)
  335. ScreenType(curx + i, cury, frameChars[1]);
  336. }
  337. }
  338. private void DrawTextObject(TextObject textObject)
  339. {
  340. int linesBefore = 0;
  341. int d = frames ? 1 : 0;
  342. int curx = (int)(textObject.AbsLeft * scaleX * XDivAdv) + d;
  343. int cury = (int)(textObject.AbsTop * YDivAdv * scaleY) + d;
  344. int cury2 = (int)Math.Floor((textObject.AbsTop + textObject.Height) * scaleY * YDivAdv) + d;
  345. int curx2 = (int)Math.Floor((textObject.AbsLeft + textObject.Width) * scaleX * XDivAdv) + d;
  346. int height = cury2 - cury;
  347. int width = curx2 - curx;
  348. List<string> lines = WrapTextObject(textObject);
  349. if (textObject.VertAlign == VertAlign.Bottom)
  350. linesBefore = height - lines.Count;
  351. else if (textObject.VertAlign == VertAlign.Center)
  352. linesBefore = (int)((height - lines.Count) / 2);
  353. for (int i = 0; i < lines.Count; i++)
  354. {
  355. string s = AlignStr(lines[i], textObject.HorzAlign, width).ToString();
  356. ScreenString(curx, cury + i + linesBefore, s);
  357. if (dataLossBreak && !dataSaved)
  358. return;
  359. }
  360. if (frames)
  361. {
  362. if ((textObject.Border.Lines & BorderLines.Left) > 0)
  363. for (int i = 0; i < height; i++)
  364. ScreenType(curx - 1, cury + i, frameChars[0]);
  365. if ((textObject.Border.Lines & BorderLines.Right) > 0)
  366. for (int i = 0; i < height; i++)
  367. ScreenType(curx + width - 1, cury + i, frameChars[0]);
  368. if ((textObject.Border.Lines & BorderLines.Top) > 0)
  369. for (int i = 0; i < width; i++)
  370. ScreenType(curx + i, cury - 1, frameChars[1]);
  371. if ((textObject.Border.Lines & BorderLines.Bottom) > 0)
  372. for (int i = 0; i < width; i++)
  373. ScreenType(curx + i, cury + height - 1, frameChars[1]);
  374. }
  375. }
  376. private List<string> WrapTextObject(TextObject obj)
  377. {
  378. float FDpiFX = 96f / DrawUtils.ScreenDpi;
  379. List<string> result = new List<string>();
  380. DrawText drawer = new DrawText();
  381. using (Bitmap b = new Bitmap(1, 1))
  382. using (Graphics g = Graphics.FromImage(b))
  383. using (Font f = new Font(obj.Font.FontFamily, obj.Font.Size * FDpiFX, obj.Font.Style))
  384. {
  385. float h = f.Height - f.Height / 4;
  386. float memoWidth = obj.Width - obj.Padding.Horizontal;
  387. string text = obj.Text;
  388. float memoHeight = drawer.CalcHeight(text, g, f,
  389. memoWidth, obj.Height - obj.Padding.Vertical,
  390. obj.HorzAlign, obj.LineHeight, obj.ForceJustify, obj.RightToLeft, obj.WordWrap, obj.Trimming);
  391. float y, prevy = 0;
  392. StringBuilder line = new StringBuilder(256);
  393. foreach (Paragraph par in drawer.Paragraphs)
  394. {
  395. foreach (Word word in par.Words)
  396. {
  397. if (!word.visible)
  398. break;
  399. y = word.top + 1;
  400. if (prevy == 0)
  401. prevy = y;
  402. if (y != prevy)
  403. {
  404. result.Add(line.ToString());
  405. line.Length = 0;
  406. prevy = y;
  407. }
  408. line.Append(word.text).Append(' ');
  409. }
  410. }
  411. result.Add(line.ToString());
  412. }
  413. return result;
  414. }
  415. #endregion
  416. #region Protected Methods
  417. /// <inheritdoc/>
  418. protected override void Start()
  419. {
  420. base.Start();
  421. if (avoidDataLoss)
  422. CalculateScale(null);
  423. if (printerType >= 0 && printerType < printerTypes.Count)
  424. foreach (TextExportPrinterCommand command in printerTypes[printerType].Commands)
  425. if (command.Active)
  426. foreach (byte esc in command.SequenceOn)
  427. Stream.WriteByte(esc);
  428. if (Encoding == Encoding.UTF8)
  429. Stream.Write(u_HEADER, 0, 3);
  430. }
  431. /// <inheritdoc/>
  432. protected override void Finish()
  433. {
  434. if (printerType >= 0 && printerType < printerTypes.Count)
  435. foreach (TextExportPrinterCommand command in printerTypes[printerType].Commands)
  436. if (command.Active)
  437. foreach (byte esc in command.SequenceOff)
  438. Stream.WriteByte(esc);
  439. FinishInternal();
  440. scaleX = scaleXStart;
  441. scaleY = scaleYStart;
  442. }
  443. /// <inheritdoc/>
  444. protected override string GetFileFilter()
  445. {
  446. return new MyRes("FileFilters").Get("TxtFile");
  447. }
  448. #endregion
  449. /// <inheritdoc/>
  450. protected override void ExportPageBegin(ReportPage page)
  451. {
  452. base.ExportPageBegin(page);
  453. if (frames)
  454. frameChars = textFrames ? ref_frames[0] : ref_frames[1];
  455. pageWidth = pageHeight = 0;
  456. dataSaved = true;
  457. screenWidth = (int)Math.Floor(ExportUtils.GetPageWidth(page) * divPaperX * XDivAdv * scaleX);
  458. screenHeight = (int)Math.Floor(ExportUtils.GetPageHeight(page) * divPaperY * YDivAdv * scaleY);
  459. InitScreen();
  460. }
  461. private void ExportObject(Base c)
  462. {
  463. if (c is ReportComponentBase && (c as ReportComponentBase).Exportable)
  464. {
  465. ReportComponentBase obj = c as ReportComponentBase;
  466. if (dataOnly && (obj.Parent == null || !(obj.Parent is DataBand)))
  467. return;
  468. if (obj is TableCell)
  469. return;
  470. else
  471. if (obj is TableBase)
  472. {
  473. TableBase table = obj as TableBase;
  474. using (TextObject tableback = new TextObject())
  475. {
  476. tableback.Border = table.Border;
  477. tableback.Fill = table.Fill;
  478. tableback.FillColor = table.FillColor;
  479. tableback.Left = table.AbsLeft;
  480. tableback.Top = table.AbsTop;
  481. float tableWidth = 0;
  482. for (int i = 0; i < table.ColumnCount; i++)
  483. {
  484. if (table.RowCount > 0)
  485. tableWidth += table[i, 0].Width;
  486. }
  487. tableback.Width = (tableWidth < table.Width) ? tableWidth : table.Width;
  488. tableback.Height = table.Height;
  489. DrawTextObject(tableback);
  490. }
  491. float y = 0;
  492. for (int i = 0; i < table.RowCount; i++)
  493. {
  494. float x = 0;
  495. for (int j = 0; j < table.ColumnCount; j++)
  496. {
  497. if (!table.IsInsideSpan(table[j, i]))
  498. {
  499. TableCell textcell = table[j, i];
  500. textcell.Left = x;
  501. textcell.Top = y;
  502. DrawTextObject(textcell);
  503. }
  504. x += (table.Columns[j]).Width;
  505. }
  506. y += (table.Rows[i]).Height;
  507. }
  508. }
  509. else if (obj is TextObject)
  510. DrawTextObject(obj as TextObject);
  511. else if (obj is LineObject && frames)
  512. DrawLineObject(obj as LineObject);
  513. //if (FDataLossBreak && !FDataSaved)
  514. // return;
  515. }
  516. }
  517. /// <inheritdoc/>
  518. protected override void ExportBand(BandBase band)
  519. {
  520. base.ExportBand(band);
  521. ExportObject(band);
  522. foreach (Base c in band.ForEachAllConvectedObjects(this))
  523. {
  524. ExportObject(c);
  525. }
  526. }
  527. private StringBuilder builder;
  528. /// <inheritdoc/>
  529. protected override void ExportPageEnd(ReportPage page)
  530. {
  531. builder = new StringBuilder(screenHeight * screenWidth);
  532. for (int y = 0; y < screenHeight; y++)
  533. {
  534. bool empty = true;
  535. StringBuilder buf = new StringBuilder(screenWidth);
  536. for (int x = 0; x < screenWidth; x++)
  537. {
  538. char c = ScreenGet(x, y);
  539. if (frames && (c == ' ' || IsFrame(c))) // && c != ' ' && IsFrame(c)
  540. {
  541. bool up = ScreenGet(x, y - 1) == frameChars[0];
  542. bool down = ScreenGet(x, y + 1) == frameChars[0];
  543. bool left = ScreenGet(x - 1, y) == frameChars[1];
  544. bool right = ScreenGet(x + 1, y) == frameChars[1];
  545. if (down && right && !left && !up)
  546. c = frameChars[2];
  547. else if (down && !right && left && !up)
  548. c = frameChars[3];
  549. else if (!down && !right && left && up)
  550. c = frameChars[4];
  551. else if (!down && right && !left && up)
  552. c = frameChars[5];
  553. else if (down && right && !left && up)
  554. c = frameChars[6];
  555. else if (down && !right && left && up)
  556. c = frameChars[7];
  557. else if (down && right && left && !up)
  558. c = frameChars[8];
  559. else if (!down && right && left && up)
  560. c = frameChars[9];
  561. else if (up && down && left && right)
  562. c = frameChars[10];
  563. else if (up && down && !left && !right)
  564. c = frameChars[0];
  565. else if (!up && !down && left && right)
  566. c = frameChars[1];
  567. }
  568. buf.Append(c);
  569. if (c != ' ' && (!frames || c != frameChars[0]))
  570. empty = false;
  571. }
  572. if (!empty || emptyLines)
  573. {
  574. string s = buf.ToString().TrimEnd((char)32);
  575. builder.AppendLine(s);
  576. if (s.Length > pageWidth)
  577. pageWidth = s.Length;
  578. pageHeight++;
  579. }
  580. }
  581. if (pageBreaks)
  582. builder.AppendLine("\u000c");
  583. if (!previewMode)
  584. {
  585. byte[] bytes = encoding.GetBytes(builder.ToString());
  586. Stream.Write(bytes, 0, bytes.Length);
  587. }
  588. }
  589. #region Internal methods
  590. /// <summary>
  591. /// Exports the page.
  592. /// </summary>
  593. /// <param name="pageNo"></param>
  594. /// <returns></returns>
  595. public string ExportPage(int pageNo)
  596. {
  597. PreparedPage ppage = Report.PreparedPages.GetPreparedPage(pageNo);
  598. ReportPage page = null;
  599. try
  600. {
  601. page = ppage.StartGetPage(pageNo);
  602. ExportPageBegin(page);
  603. foreach (Base obj in ppage.GetPageItems(page, false))
  604. ExportBand(obj as BandBase);
  605. ExportPageEnd(page);
  606. }
  607. finally
  608. {
  609. ppage.EndGetPage(page);
  610. }
  611. if (previewMode)
  612. return builder.ToString();
  613. else
  614. return String.Empty;
  615. }
  616. /// <summary>
  617. /// Calculates scale.
  618. /// </summary>
  619. /// <param name="progress"></param>
  620. public void CalculateScale(object progress)
  621. {
  622. bool oldPreviewMode = previewMode;
  623. dataLossBreak = true;
  624. previewMode = true;
  625. float initX = CalculateStep;
  626. float initY = CalculateStep;
  627. for (int p = 0; p < Report.PreparedPages.Count; p++)
  628. {
  629. if (IsAborted(progress))
  630. break;
  631. ExportPage(p);
  632. int j = CalcIterations;
  633. while (!dataSaved && --j > 0)
  634. {
  635. if (IsAborted(progress))
  636. break;
  637. int i = CalcIterations;
  638. float oldX = ScaleX;
  639. while (!dataSaved && --i > 0)
  640. {
  641. if (IsAborted(progress))
  642. break;
  643. scaleX += CalculateStep;
  644. ExportPage(p);
  645. }
  646. i = CalcIterations;
  647. while (!dataSaved && --i > 0)
  648. {
  649. if (IsAborted(progress))
  650. break;
  651. scaleY += CalculateStep;
  652. ExportPage(p);
  653. }
  654. if (dataSaved && i < CalcIterations)
  655. {
  656. i = CalcIterations;
  657. scaleX = oldX;
  658. ExportPage(p);
  659. while (!dataSaved && --i > 0)
  660. {
  661. if (IsAborted(progress))
  662. break;
  663. scaleX += CalculateStep;
  664. ExportPage(p);
  665. }
  666. }
  667. }
  668. if (dataSaved && frames)
  669. {
  670. int i = CalcIterations;
  671. float oldY = scaleY;
  672. while (dataSaved && --i > 0)
  673. {
  674. if (IsAborted(progress))
  675. break;
  676. oldY = scaleY;
  677. scaleY -= CalculateStepBack;
  678. if (scaleY < initY)
  679. break;
  680. ExportPage(p);
  681. }
  682. scaleY = oldY;
  683. dataSaved = true;
  684. i = CalcIterations;
  685. float oldX = scaleX;
  686. while (dataSaved && --i > 0)
  687. {
  688. if (IsAborted(progress))
  689. break;
  690. oldX = scaleX;
  691. scaleX -= CalculateStepBack;
  692. if (scaleX < initX)
  693. break;
  694. ExportPage(p);
  695. }
  696. scaleX = oldX;
  697. dataSaved = true;
  698. }
  699. initX = scaleX;
  700. initY = scaleY;
  701. if (j == 0)
  702. break;
  703. }
  704. dataLossBreak = false;
  705. previewMode = oldPreviewMode;
  706. }
  707. #endregion
  708. /// <summary>
  709. /// Initializes a new instance of the <see cref="TextExport"/> class.
  710. /// </summary>
  711. public TextExport()
  712. {
  713. pageBreaks = true;
  714. emptyLines = false;
  715. frames = true;
  716. textFrames = false;
  717. encoding = Encoding.UTF8;
  718. dataOnly = false;
  719. scaleX = 1.0f;
  720. scaleXStart = 1.0f;
  721. scaleY = 1.0f;
  722. scaleYStart = 1.0f;
  723. previewMode = false;
  724. dataLossBreak = false;
  725. avoidDataLoss = true;
  726. printerTypes = new List<TextExportPrinterType>();
  727. TextExportPrinterType printer = new TextExportPrinterType();
  728. printer.Name = "Epson ESC/P2";
  729. printerTypes.Add(printer);
  730. TextExportPrinterCommand command = new TextExportPrinterCommand();
  731. command.Name = "Reset";
  732. command.SequenceOn.Add(27);
  733. command.SequenceOn.Add(64);
  734. printer.Commands.Add(command);
  735. command = new TextExportPrinterCommand();
  736. command.Name = "Normal";
  737. command.SequenceOn.Add(27);
  738. command.SequenceOn.Add(120);
  739. command.SequenceOn.Add(0);
  740. printer.Commands.Add(command);
  741. command = new TextExportPrinterCommand();
  742. command.Name = "Pica";
  743. command.SequenceOn.Add(27);
  744. command.SequenceOn.Add(120);
  745. command.SequenceOn.Add(1);
  746. command.SequenceOn.Add(27);
  747. command.SequenceOn.Add(107);
  748. command.SequenceOn.Add(0);
  749. printer.Commands.Add(command);
  750. command = new TextExportPrinterCommand();
  751. command.Name = "Elite";
  752. command.SequenceOn.Add(27);
  753. command.SequenceOn.Add(120);
  754. command.SequenceOn.Add(1);
  755. command.SequenceOn.Add(27);
  756. command.SequenceOn.Add(107);
  757. command.SequenceOn.Add(1);
  758. printer.Commands.Add(command);
  759. command = new TextExportPrinterCommand();
  760. command.Name = "Condenced";
  761. command.SequenceOn.Add(15);
  762. command.SequenceOff.Add(18);
  763. printer.Commands.Add(command);
  764. command = new TextExportPrinterCommand();
  765. command.Name = "Bold";
  766. command.SequenceOn.Add(27);
  767. command.SequenceOn.Add(71);
  768. command.SequenceOff.Add(27);
  769. command.SequenceOff.Add(72);
  770. printer.Commands.Add(command);
  771. command = new TextExportPrinterCommand();
  772. command.Name = "Italic";
  773. command.SequenceOn.Add(27);
  774. command.SequenceOn.Add(52);
  775. command.SequenceOff.Add(27);
  776. command.SequenceOff.Add(53);
  777. printer.Commands.Add(command);
  778. command = new TextExportPrinterCommand();
  779. command.Name = "Wide";
  780. command.SequenceOn.Add(27);
  781. command.SequenceOn.Add(87);
  782. command.SequenceOn.Add(1);
  783. command.SequenceOff.Add(27);
  784. command.SequenceOff.Add(87);
  785. command.SequenceOff.Add(0);
  786. printer.Commands.Add(command);
  787. command = new TextExportPrinterCommand();
  788. command.Name = "12cpi";
  789. command.SequenceOn.Add(27);
  790. command.SequenceOn.Add(77);
  791. command.SequenceOff.Add(27);
  792. command.SequenceOff.Add(80);
  793. printer.Commands.Add(command);
  794. command = new TextExportPrinterCommand();
  795. command.Name = "Linefeed 1/8\"";
  796. command.SequenceOn.Add(27);
  797. command.SequenceOn.Add(48);
  798. printer.Commands.Add(command);
  799. command = new TextExportPrinterCommand();
  800. command.Name = "Linefeed 7/72\"";
  801. command.SequenceOn.Add(27);
  802. command.SequenceOn.Add(49);
  803. printer.Commands.Add(command);
  804. command = new TextExportPrinterCommand();
  805. command.Name = "Linefeed 1/6\"";
  806. command.SequenceOn.Add(27);
  807. command.SequenceOn.Add(50);
  808. printer.Commands.Add(command);
  809. printer = new TextExportPrinterType();
  810. printer.Name = "HP PCL";
  811. printerTypes.Add(printer);
  812. command = new TextExportPrinterCommand();
  813. command.Name = "Reset";
  814. command.SequenceOn.Add(27);
  815. command.SequenceOn.Add(69);
  816. printer.Commands.Add(command);
  817. command = new TextExportPrinterCommand();
  818. command.Name = "Landscape";
  819. command.SequenceOn.Add(27);
  820. command.SequenceOn.Add(38);
  821. command.SequenceOn.Add(108);
  822. command.SequenceOn.Add(49);
  823. command.SequenceOn.Add(79);
  824. command.SequenceOff.Add(27);
  825. command.SequenceOff.Add(38);
  826. command.SequenceOff.Add(108);
  827. command.SequenceOff.Add(48);
  828. command.SequenceOff.Add(79);
  829. printer.Commands.Add(command);
  830. command = new TextExportPrinterCommand();
  831. command.Name = "Italic";
  832. command.SequenceOn.Add(27);
  833. command.SequenceOn.Add(40);
  834. command.SequenceOn.Add(115);
  835. command.SequenceOn.Add(49);
  836. command.SequenceOn.Add(83);
  837. command.SequenceOff.Add(27);
  838. command.SequenceOff.Add(40);
  839. command.SequenceOff.Add(115);
  840. command.SequenceOff.Add(48);
  841. command.SequenceOff.Add(83);
  842. printer.Commands.Add(command);
  843. command = new TextExportPrinterCommand();
  844. command.Name = "Bold";
  845. command.SequenceOn.Add(27);
  846. command.SequenceOn.Add(40);
  847. command.SequenceOn.Add(115);
  848. command.SequenceOn.Add(51);
  849. command.SequenceOn.Add(66);
  850. command.SequenceOff.Add(27);
  851. command.SequenceOff.Add(40);
  852. command.SequenceOff.Add(115);
  853. command.SequenceOff.Add(48);
  854. command.SequenceOff.Add(66);
  855. printer.Commands.Add(command);
  856. command = new TextExportPrinterCommand();
  857. command.Name = "Draft EconoMode";
  858. command.SequenceOn.Add(27);
  859. command.SequenceOn.Add(40);
  860. command.SequenceOn.Add(115);
  861. command.SequenceOn.Add(49);
  862. command.SequenceOn.Add(81);
  863. command.SequenceOff.Add(27);
  864. command.SequenceOff.Add(40);
  865. command.SequenceOff.Add(115);
  866. command.SequenceOff.Add(50);
  867. command.SequenceOff.Add(81);
  868. printer.Commands.Add(command);
  869. command = new TextExportPrinterCommand();
  870. command.Name = "Condenced";
  871. command.SequenceOn.Add(27);
  872. command.SequenceOn.Add(40);
  873. command.SequenceOn.Add(115);
  874. command.SequenceOn.Add(49);
  875. command.SequenceOn.Add(50);
  876. command.SequenceOn.Add(72);
  877. command.SequenceOn.Add(27);
  878. command.SequenceOn.Add(38);
  879. command.SequenceOn.Add(108);
  880. command.SequenceOn.Add(56);
  881. command.SequenceOn.Add(68);
  882. command.SequenceOff.Add(27);
  883. command.SequenceOff.Add(40);
  884. command.SequenceOff.Add(115);
  885. command.SequenceOff.Add(49);
  886. command.SequenceOff.Add(48);
  887. command.SequenceOff.Add(72);
  888. printer.Commands.Add(command);
  889. printer = new TextExportPrinterType();
  890. printer.Name = "Canon/IBM";
  891. printerTypes.Add(printer);
  892. command = new TextExportPrinterCommand();
  893. command.Name = "Reset";
  894. command.SequenceOn.Add(27);
  895. command.SequenceOn.Add(64);
  896. printer.Commands.Add(command);
  897. command = new TextExportPrinterCommand();
  898. command.Name = "Normal";
  899. command.SequenceOn.Add(27);
  900. command.SequenceOn.Add(120);
  901. command.SequenceOn.Add(0);
  902. printer.Commands.Add(command);
  903. command = new TextExportPrinterCommand();
  904. command.Name = "Pica";
  905. command.SequenceOn.Add(27);
  906. command.SequenceOn.Add(48);
  907. command.SequenceOn.Add(73);
  908. printer.Commands.Add(command);
  909. command = new TextExportPrinterCommand();
  910. command.Name = "Elite";
  911. command.SequenceOn.Add(27);
  912. command.SequenceOn.Add(56);
  913. command.SequenceOn.Add(73);
  914. printer.Commands.Add(command);
  915. command = new TextExportPrinterCommand();
  916. command.Name = "Condenced";
  917. command.SequenceOn.Add(15);
  918. command.SequenceOff.Add(18);
  919. printer.Commands.Add(command);
  920. command = new TextExportPrinterCommand();
  921. command.Name = "Bold";
  922. command.SequenceOn.Add(27);
  923. command.SequenceOn.Add(71);
  924. command.SequenceOff.Add(27);
  925. command.SequenceOff.Add(72);
  926. printer.Commands.Add(command);
  927. command = new TextExportPrinterCommand();
  928. command.Name = "Italic";
  929. command.SequenceOn.Add(27);
  930. command.SequenceOn.Add(52);
  931. command.SequenceOff.Add(27);
  932. command.SequenceOff.Add(53);
  933. printer.Commands.Add(command);
  934. command = new TextExportPrinterCommand();
  935. command.Name = "12cpi";
  936. command.SequenceOn.Add(27);
  937. command.SequenceOn.Add(77);
  938. command.SequenceOff.Add(27);
  939. command.SequenceOff.Add(80);
  940. printer.Commands.Add(command);
  941. printerType = 0;
  942. copies = 1;
  943. OpenAfterExport = false;
  944. printAfterExport = false;
  945. res = new MyRes("Export,Misc");
  946. }
  947. }
  948. /// <summary>
  949. /// Represents the printer command class
  950. /// </summary>
  951. public class TextExportPrinterCommand
  952. {
  953. private List<byte> sequenceOn;
  954. private List<byte> sequenceOff;
  955. private string name;
  956. private bool active;
  957. /// <summary>
  958. /// Gets or sets the active state of command. Default value is false.
  959. /// </summary>
  960. public bool Active
  961. {
  962. get { return active; }
  963. set { active = value; }
  964. }
  965. /// <summary>
  966. /// Gets or sets the command name.
  967. /// </summary>
  968. public string Name
  969. {
  970. get { return name; }
  971. set { name = value; }
  972. }
  973. /// <summary>
  974. /// Gets or sets the list of "on sequence".
  975. /// </summary>
  976. public List<byte> SequenceOn
  977. {
  978. get { return sequenceOn; }
  979. set { sequenceOn = value; }
  980. }
  981. /// <summary>
  982. /// Gets or sets the list of "off sequence".
  983. /// </summary>
  984. public List<byte> SequenceOff
  985. {
  986. get { return sequenceOff; }
  987. set { sequenceOff = value; }
  988. }
  989. /// <summary>
  990. /// Initializes a new instance of the <see cref="TextExportPrinterCommand"/> class.
  991. /// </summary>
  992. public TextExportPrinterCommand()
  993. {
  994. sequenceOn = new List<byte>();
  995. sequenceOff = new List<byte>();
  996. active = false;
  997. }
  998. }
  999. /// <summary>
  1000. /// Represents of the printer type class.
  1001. /// </summary>
  1002. public class TextExportPrinterType
  1003. {
  1004. private List<TextExportPrinterCommand> commands;
  1005. private string name;
  1006. /// <summary>
  1007. /// Gets or sets the printer name.
  1008. /// </summary>
  1009. public string Name
  1010. {
  1011. get { return name; }
  1012. set { name = value; }
  1013. }
  1014. /// <summary>
  1015. /// Gets or sets the list of printer commands. <see cref="TextExportPrinterCommand"/>
  1016. /// </summary>
  1017. public List<TextExportPrinterCommand> Commands
  1018. {
  1019. get { return commands; }
  1020. set { commands = value; }
  1021. }
  1022. /// <summary>
  1023. /// Initializes a new instance of the <see cref="TextExportPrinterType"/> class.
  1024. /// </summary>
  1025. public TextExportPrinterType()
  1026. {
  1027. commands = new List<TextExportPrinterCommand>();
  1028. }
  1029. }
  1030. }