RichObject.Ext.cs 7.1 KB

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