using System; using System.Collections.Generic; using System.IO; using System.Text; using FastReport.RichTextParser; using FastReport.Code; using FastReport.Utils; namespace FastReport { partial class RichObject { IList expression_list = null; int expressionIndex; private void GenerateExpressionList() { FindTextArgs args = new FindTextArgs(); string plain_text = string.Empty; using (RTF_DocumentParser parser = new RTF_DocumentParser()) { parser.Load(Text); using (RTF_ToTextSaver saver = new RTF_ToTextSaver(parser.Document)) args.Text = new FastString(saver.PlainText); } string[] brackets = Brackets.Split(','); args.OpenBracket = brackets[0]; args.CloseBracket = brackets[1]; args.StartIndex = ActualTextStart; expression_list = new List(); while (args.StartIndex < args.Text.Length - 2) { string expression = CodeUtils.GetExpression(args, false); if (expression == null) break; expression_list.Add(expression); args.StartIndex = args.EndIndex; } } /// /// Called from RichObject.CalcHeight() /// /// internal float SecondStageTranslation() { float height = 0; BandBase parentBand = this.Parent as BandBase; float bottom = 0; float current_top = this.Top; float shift = translated_height - this.Height; // shift vertical position of objects which below RichObject foreach (ReportComponentBase c in parentBand.Objects) { if (this.Top < c.Top) { if((this.Left < c.Left && this.Left + this.Width > c.Left) || (this.Left > c.Left && c.Left + c.Width > this.Left)) c.Top += shift; } } // assign translated objects to parent band foreach (ReportComponentBase c in TransltedObjects) { parentBand.AddChild(c); c.ShiftMode = this.ShiftMode; // 20220118 replaced from ShiftMode.Never; c.Top += current_top; bottom = c.Bottom; } height = bottom - this.Top; Visible = false; if (bottom != 0) shift = bottom - this.Height; return height; } enum States { Wait, Open }; private bool InsertText(StreamWriter rtf_writer, string formattedValue) { bool isRich = formattedValue.StartsWith(@"{\rtf"); if(isRich) { rtf_writer.Write(formattedValue); } else { bool lf = false; foreach (char chr in formattedValue) { if (chr == '\r') { rtf_writer.Write("\\line "); lf = true; } else { if (chr == '\n') { if (lf != true) rtf_writer.Write("\\line "); } else if ((int)chr <= 127) rtf_writer.Write(chr); else rtf_writer.Write("\\u{0}\\'3f", (uint)chr); lf = false; } } } return isRich; } private void CalculateExpressions() { char ch; expressionIndex = 0; int internal_brackets_count = 0; States state = States.Wait; bool need_repack = false; if (expression_list == null) GenerateExpressionList(); if (Text == null) return; using (MemoryStream rtf_stream = new MemoryStream()) { using (StreamWriter rtf_writer = new StreamWriter(rtf_stream, Encoding.UTF8)) { for (int i = 0; i < Text.Length; i++) { ch = Text[i]; switch (state) { case States.Wait: if (ch != '[') rtf_writer.Write(ch); else state = States.Open; break; case States.Open: if (ch == '[') internal_brackets_count++; if (ch != ']') break; if (internal_brackets_count > 0) { internal_brackets_count--; break; } string formattedValue = CalcAndFormatExpression(expression_list[expressionIndex], expressionIndex); ///// if (expression_list.Count == 1 && formattedValue.StartsWith(@"{\rtf")) { Text = formattedValue; return; } ///// need_repack |= InsertText(rtf_writer, formattedValue); expressionIndex++; state = States.Wait; break; } } rtf_writer.Flush(); rtf_stream.Seek(0, SeekOrigin.Begin); using (StreamReader rtf_reader = new StreamReader(rtf_stream, Encoding.UTF8)) { if (need_repack) { using (RTF_DocumentParser parser = new RTF_DocumentParser()) { string buffer = rtf_reader.ReadToEnd(); parser.Load(buffer); using (RTF_DocumentSaver saver = new RTF_DocumentSaver(parser.Document)) { base.Text = saver.RichText; } } } else { base.Text = rtf_reader.ReadToEnd(); } } } } } private void MergeRichText() { CalculateExpressions(); } } }