HtmlObject.cs 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Drawing.Text;
  5. using System.ComponentModel;
  6. using FastReport.Utils;
  7. using FastReport.Code;
  8. namespace FastReport
  9. {
  10. /// <summary>
  11. /// Represents the Text object that may display one or several text lines.
  12. /// </summary>
  13. /// <remarks>
  14. /// Specify the object's text in the <see cref="TextObjectBase.Text">Text</see> property.
  15. /// Text may contain expressions and data items, for example: "Today is [Date]". When report
  16. /// is running, all expressions are calculated and replaced with actual values, so the text
  17. /// would be "Today is 01.01.2008".
  18. /// <para/>The symbols used to find expressions in a text are set in the
  19. /// <see cref="TextObjectBase.Brackets">Brackets</see> property. You also may disable expressions
  20. /// using the <see cref="TextObjectBase.AllowExpressions">AllowExpressions</see> property.
  21. /// <para/>To format an expression value, use the <see cref="Format"/> property.
  22. /// </remarks>
  23. public partial class HtmlObject : TextObjectBase
  24. {
  25. #region Fields
  26. private bool rightToLeft;
  27. private string savedText;
  28. #endregion
  29. #region Properties
  30. /// <summary>
  31. /// Gets or sets a value that indicates whether the component should draw right-to-left for RTL languages.
  32. /// </summary>
  33. [DefaultValue(false)]
  34. [Category("Behavior")]
  35. public bool RightToLeft
  36. {
  37. get { return rightToLeft; }
  38. set { rightToLeft = value; }
  39. }
  40. #endregion
  41. #region Private Methods
  42. private float InternalCalcWidth()
  43. {
  44. return this.Width;
  45. }
  46. private float InternalCalcHeight()
  47. {
  48. return this.Height;
  49. }
  50. private string BreakText()
  51. {
  52. return null;
  53. }
  54. #endregion
  55. #region Public Methods
  56. internal StringFormat GetStringFormat(GraphicCache cache, StringFormatFlags flags)
  57. {
  58. return GetStringFormat(cache, flags, 1);
  59. }
  60. internal StringFormat GetStringFormat(GraphicCache cache, StringFormatFlags flags, float scale)
  61. {
  62. if (RightToLeft)
  63. flags |= StringFormatFlags.DirectionRightToLeft;
  64. return cache.GetStringFormat(StringAlignment.Near, StringAlignment.Near, StringTrimming.None, flags, 0 * scale, 0 * scale);
  65. }
  66. /// <inheritdoc/>
  67. public override void Assign(Base source)
  68. {
  69. base.Assign(source);
  70. HtmlObject src = source as HtmlObject;
  71. RightToLeft = src.RightToLeft;
  72. }
  73. /// <summary>
  74. /// Draws a text.
  75. /// </summary>
  76. /// <param name="e">Paint event data.</param>
  77. public void DrawText(FRPaintEventArgs e)
  78. {
  79. string text = Text;
  80. if (!String.IsNullOrEmpty(text))
  81. {
  82. IGraphics g = e.Graphics;
  83. RectangleF textRect = new RectangleF(
  84. (AbsLeft + Padding.Left) * e.ScaleX,
  85. (AbsTop + Padding.Top) * e.ScaleY,
  86. (Width - Padding.Horizontal) * e.ScaleX,
  87. (Height - Padding.Vertical) * e.ScaleY);
  88. StringFormat format = GetStringFormat(e.Cache, 0, e.ScaleX);
  89. Font font = DrawUtils.DefaultTextObjectFont;
  90. Brush textBrush = e.Cache.GetBrush(Color.Black);
  91. Report report = Report;
  92. if (report != null)
  93. g.TextRenderingHint = report.GetTextQuality();
  94. if (textRect.Width > 0 && textRect.Height > 0)
  95. {
  96. // use simple rendering
  97. g.DrawString(text, font, textBrush, textRect, format);
  98. }
  99. }
  100. }
  101. /// <inheritdoc/>
  102. public override void Draw(FRPaintEventArgs e)
  103. {
  104. base.Draw(e);
  105. DrawText(e);
  106. DrawMarkers(e);
  107. Border.Draw(e, new RectangleF(AbsLeft, AbsTop, Width, Height));
  108. DrawDesign(e);
  109. }
  110. /// <inheritdoc/>
  111. public override void Serialize(FRWriter writer)
  112. {
  113. HtmlObject c = writer.DiffObject as HtmlObject;
  114. base.Serialize(writer);
  115. if (writer.SerializeTo != SerializeTo.Preview)
  116. {
  117. if (Style != c.Style)
  118. writer.WriteStr("Style", Style);
  119. }
  120. }
  121. internal void ApplyCondition(HighlightCondition c)
  122. {
  123. if (c.ApplyBorder)
  124. Border = c.Border.Clone();
  125. if (c.ApplyFill)
  126. Fill = c.Fill.Clone();
  127. if (!c.Visible)
  128. Visible = false;
  129. }
  130. #endregion
  131. #region Report Engine
  132. /// <inheritdoc/>
  133. public override string[] GetExpressions()
  134. {
  135. List<string> expressions = new List<string>();
  136. expressions.AddRange(base.GetExpressions());
  137. if (AllowExpressions && !String.IsNullOrEmpty(Brackets))
  138. {
  139. string[] brackets = Brackets.Split(',');
  140. // collect expressions found in the text
  141. expressions.AddRange(CodeUtils.GetExpressions(Text, brackets[0], brackets[1]));
  142. }
  143. return expressions.ToArray();
  144. }
  145. /// <inheritdoc/>
  146. public override void SaveState()
  147. {
  148. base.SaveState();
  149. savedText = Text;
  150. }
  151. /// <inheritdoc/>
  152. public override void RestoreState()
  153. {
  154. base.RestoreState();
  155. Text = savedText;
  156. }
  157. /// <summary>
  158. /// Calculates the object's width.
  159. /// </summary>
  160. /// <returns>The width, in pixels.</returns>
  161. public float CalcWidth()
  162. {
  163. return InternalCalcWidth();
  164. }
  165. /// <inheritdoc/>
  166. public override float CalcHeight()
  167. {
  168. return InternalCalcHeight();
  169. }
  170. /// <inheritdoc/>
  171. public override void GetData()
  172. {
  173. base.GetData();
  174. // process expressions
  175. if (AllowExpressions)
  176. {
  177. if (!String.IsNullOrEmpty(Brackets))
  178. {
  179. string[] brackets = Brackets.Split(',');
  180. FindTextArgs args = new FindTextArgs();
  181. args.Text = new FastString(Text);
  182. args.OpenBracket = brackets[0];
  183. args.CloseBracket = brackets[1];
  184. int expressionIndex = 0;
  185. while (args.StartIndex < args.Text.Length)
  186. {
  187. string expression = CodeUtils.GetExpression(args, false);
  188. if (expression == null)
  189. break;
  190. string formattedValue = CalcAndFormatExpression(expression, expressionIndex);
  191. args.Text = args.Text.Remove(args.StartIndex, args.EndIndex - args.StartIndex);
  192. args.Text = args.Text.Insert(args.StartIndex, formattedValue);
  193. args.StartIndex += formattedValue.Length;
  194. expressionIndex++;
  195. }
  196. Text = args.Text.ToString();
  197. }
  198. }
  199. // process highlight
  200. Variant varValue = new Variant(Value);
  201. }
  202. /// <inheritdoc/>
  203. public override bool Break(BreakableComponent breakTo)
  204. {
  205. string breakText = BreakText();
  206. if (breakText != null && breakTo != null)
  207. (breakTo as TextObject).Text = breakText;
  208. return breakText != null;
  209. }
  210. #endregion
  211. /// <summary>
  212. /// Initializes a new instance of the <see cref="HtmlObject"/> class with default settings.
  213. /// </summary>
  214. public HtmlObject()
  215. {
  216. FlagSerializeStyle = false;
  217. SetFlags(Flags.HasSmartTag, true);
  218. }
  219. }
  220. }