RichObject.Ext.cs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Text;
  5. using FastReport.RichTextParser;
  6. using FastReport.Code;
  7. using FastReport.Utils;
  8. using System.Linq.Expressions;
  9. using System.Diagnostics;
  10. namespace FastReport
  11. {
  12. partial class RichObject
  13. {
  14. IList<string> expression_list = null;
  15. int expressionIndex;
  16. private void GenerateExpressionList()
  17. {
  18. FindTextArgs args = new FindTextArgs();
  19. string plain_text = string.Empty;
  20. using (RTF_DocumentParser parser = new RTF_DocumentParser())
  21. {
  22. parser.Load(Text);
  23. using (RTF_ToTextSaver saver = new RTF_ToTextSaver(parser.Document))
  24. args.Text = new FastString(saver.PlainText);
  25. }
  26. string[] brackets = Brackets.Split(',');
  27. args.OpenBracket = brackets[0];
  28. args.CloseBracket = brackets[1];
  29. args.StartIndex = ActualTextStart;
  30. expression_list = new List<string>();
  31. while (args.StartIndex < args.Text.Length - 2)
  32. {
  33. string expression = CodeUtils.GetExpression(args, false);
  34. if (expression == null)
  35. break;
  36. expression_list.Add(expression);
  37. args.StartIndex = args.EndIndex;
  38. }
  39. }
  40. /// <summary>
  41. /// Called from RichObject.CalcHeight()
  42. /// </summary>
  43. /// <returns></returns>
  44. internal float SecondStageTranslation()
  45. {
  46. float height = 0;
  47. BandBase parentBand = this.Parent as BandBase;
  48. float bottom = 0;
  49. float current_top = this.Top;
  50. float shift = translated_height - this.Height;
  51. // shift vertical position of objects which below RichObject
  52. foreach (ReportComponentBase c in parentBand.Objects)
  53. {
  54. if (c.ShiftMode != ShiftMode.Never && this.Top < c.Top && !TransltedObjects.Contains(c))
  55. {
  56. if ((Math.Round(this.Left, 2) <= Math.Round(c.Left, 2) && Math.Round(this.Right, 2) >= Math.Round(c.Left, 2)) ||
  57. (Math.Round(this.Left, 2) >= Math.Round(c.Left, 2) && Math.Round(c.Right, 2) >= Math.Round(this.Left, 2)))
  58. c.Top += shift;
  59. }
  60. }
  61. // assign translated objects to parent band
  62. foreach (ReportComponentBase c in TransltedObjects)
  63. {
  64. parentBand.AddChild(c);
  65. c.ShiftMode = this.ShiftMode; // 20220118 replaced from ShiftMode.Never;
  66. c.Top += current_top;
  67. bottom = c.Bottom;
  68. }
  69. height = bottom - this.Top;
  70. Visible = false;
  71. if (bottom != 0)
  72. shift = bottom - this.Height;
  73. return height;
  74. }
  75. enum States { Wait, Open };
  76. private bool InsertText(StreamWriter rtf_writer, string formattedValue)
  77. {
  78. bool isRich = formattedValue.StartsWith(@"{\rtf");
  79. if (isRich)
  80. {
  81. rtf_writer.Write(formattedValue);
  82. }
  83. else
  84. {
  85. bool lf = false;
  86. foreach (char chr in formattedValue)
  87. {
  88. if (chr == '\r')
  89. {
  90. rtf_writer.Write("\\line ");
  91. lf = true;
  92. }
  93. else
  94. {
  95. if (chr == '\n')
  96. {
  97. if (lf != true)
  98. rtf_writer.Write("\\line ");
  99. }
  100. else if ((int)chr <= 127)
  101. rtf_writer.Write(chr);
  102. else
  103. rtf_writer.Write("\\u{0}\\'3f", (uint)chr);
  104. lf = false;
  105. }
  106. }
  107. }
  108. return isRich;
  109. }
  110. private void CalculateExpressions()
  111. {
  112. char ch;
  113. expressionIndex = 0;
  114. int internal_brackets_count = 0;
  115. States state = States.Wait;
  116. bool need_repack = false;
  117. if (expression_list == null)
  118. GenerateExpressionList();
  119. if (Text == null)
  120. return;
  121. using (MemoryStream rtf_stream = new MemoryStream())
  122. {
  123. using (StreamWriter rtf_writer = new StreamWriter(rtf_stream, Encoding.UTF8))
  124. {
  125. for (int i = 0; i < Text.Length; i++)
  126. {
  127. ch = Text[i];
  128. switch (state)
  129. {
  130. case States.Wait:
  131. if (ch != '[')
  132. rtf_writer.Write(ch);
  133. else
  134. state = States.Open;
  135. break;
  136. case States.Open:
  137. if (ch == '[')
  138. internal_brackets_count++;
  139. if (ch != ']')
  140. break;
  141. if (internal_brackets_count > 0)
  142. {
  143. internal_brackets_count--;
  144. break;
  145. }
  146. string formattedValue = String.Empty;
  147. if (expression_list.Count > expressionIndex)
  148. formattedValue = CalcAndFormatExpression(expression_list[expressionIndex], expressionIndex);
  149. else
  150. Debug.WriteLine("RTF document structure error");
  151. /////
  152. if (expression_list.Count == 1 && formattedValue.StartsWith(@"{\rtf"))
  153. {
  154. Text = formattedValue;
  155. return;
  156. }
  157. /////
  158. need_repack |= InsertText(rtf_writer, formattedValue);
  159. expressionIndex++;
  160. state = States.Wait;
  161. break;
  162. }
  163. }
  164. rtf_writer.Flush();
  165. rtf_stream.Seek(0, SeekOrigin.Begin);
  166. using (StreamReader rtf_reader = new StreamReader(rtf_stream, Encoding.UTF8))
  167. {
  168. if (need_repack)
  169. {
  170. using (RTF_DocumentParser parser = new RTF_DocumentParser())
  171. {
  172. string buffer = rtf_reader.ReadToEnd();
  173. parser.Load(buffer);
  174. using (RTF_DocumentSaver saver = new RTF_DocumentSaver(parser.Document))
  175. {
  176. base.Text = saver.RichText;
  177. }
  178. }
  179. }
  180. else
  181. {
  182. base.Text = rtf_reader.ReadToEnd();
  183. }
  184. }
  185. }
  186. }
  187. }
  188. private void MergeRichText()
  189. {
  190. CalculateExpressions();
  191. }
  192. }
  193. }