/// <summary> /// Computes drawing commands to layout a block of text within /// certain constraints /// </summary> /// <returns></returns> public static TextRendererResult ComputeText(string text, TextRendererOptions options, UIElement target) { var TextStyle = options.TextStyle; var _Scale = options.Scale; var txtScale = TextStyle.Scale * _Scale; var m_LineHeight = TextStyle.MeasureString("W").Y - (2 * txtScale.Y); var spaceWidth = TextStyle.MeasureString(" ").X; var words = text.Split(' ').ToList(); var newWordsArray = TextRenderer.ExtractLineBreaks(words); var m_Lines = new List <UITextEditLine>(); TextRenderer.CalculateLines(m_Lines, newWordsArray, TextStyle, options.MaxWidth, spaceWidth, options.TopLeftIconSpace, m_LineHeight); var topLeft = options.Position; var position = topLeft; var result = new TextRendererResult(); var drawCommands = new List <ITextDrawCmd>(); result.DrawingCommands = drawCommands; var yPosition = topLeft.Y; var numLinesAdded = 0; var realMaxWidth = 0; for (var i = 0; i < m_Lines.Count; i++) { var lineOffset = (i * m_LineHeight < options.TopLeftIconSpace.Y) ? options.TopLeftIconSpace.X : 0; var line = m_Lines[i]; var xPosition = topLeft.X + lineOffset; if (line.LineWidth > realMaxWidth) { realMaxWidth = (int)line.LineWidth; } /** Alignment **/ if (options.Alignment == TextAlignment.Center) { xPosition += (int)Math.Round(((options.MaxWidth - lineOffset) - line.LineWidth) / 2); } var segmentPosition = target.LocalPoint(new Vector2(xPosition, yPosition)); drawCommands.Add(new TextDrawCmd_Text { Selected = false, Text = line.Text, Style = TextStyle, Position = segmentPosition, Scale = txtScale }); numLinesAdded++; yPosition += m_LineHeight; position.Y += m_LineHeight; } result.BoundingBox = new Rectangle((int)topLeft.X, (int)topLeft.Y, (int)options.MaxWidth, (int)(yPosition - m_LineHeight)); result.MaxWidth = realMaxWidth; foreach (var cmd in drawCommands) { cmd.Init(); } return(result); }
/// <summary> /// Computes drawing commands to layout a block of text within /// certain constraints /// </summary> /// <returns></returns> public static TextRendererResult ComputeText(string text, TextRendererOptions options, UIElement target) { var TextStyle = options.TextStyle; var _Scale = options.Scale; var txtScale = TextStyle.Scale * _Scale; var m_LineHeight = TextStyle.MeasureString("W").Y - (2 * txtScale.Y); var spaceWidth = TextStyle.MeasureString(" ").X; text = text.Replace("\r", ""); var bbCommands = new List <BBCodeCommand>(); if (options.BBCode) { var parsed = new BBCodeParser(text); text = parsed.Stripped; bbCommands = parsed.Commands; } var words = text.Split(' ').ToList(); var newWordsArray = TextRenderer.ExtractLineBreaks(words); var m_Lines = new List <UITextEditLine>(); TextRenderer.CalculateLines(m_Lines, newWordsArray, TextStyle, options.MaxWidth, spaceWidth, options.TopLeftIconSpace, m_LineHeight); var topLeft = options.Position; var position = topLeft; var result = new TextRendererResult(); var drawCommands = new List <ITextDrawCmd>(); result.DrawingCommands = drawCommands; var yPosition = topLeft.Y; var numLinesAdded = 0; var realMaxWidth = 0; var bbIndex = 0; var bbColorStack = new Stack <Color>(); var lastColor = TextStyle.Color; var shadowApplied = false; for (var i = 0; i < m_Lines.Count; i++) { var lineOffset = (i * m_LineHeight < options.TopLeftIconSpace.Y) ? options.TopLeftIconSpace.X : 0; var line = m_Lines[i]; var segments = CalculateSegments(line, bbCommands, ref bbIndex); var xPosition = topLeft.X + lineOffset; segments.ForEach(x => x.Size = TextStyle.MeasureString(x.Text)); var thisLineWidth = segments.Sum(x => x.Size.X); if (thisLineWidth > realMaxWidth) { realMaxWidth = (int)thisLineWidth; } /** Alignment **/ if (options.Alignment == TextAlignment.Center) { xPosition += (int)Math.Round(((options.MaxWidth - lineOffset) - thisLineWidth) / 2); } foreach (var segment in segments) { var segmentSize = segment.Size; var segmentPosition = target.LocalPoint(new Vector2(xPosition, yPosition)); if (segment.Text.Length > 0) { drawCommands.Add(new TextDrawCmd_Text { Selected = segment.Selected, Text = segment.Text, Style = TextStyle, Position = segmentPosition, Scale = txtScale }); xPosition += segmentSize.X; } if (segment.StartCommand != null) { var cmd = segment.StartCommand; switch (cmd.Type) { case BBCodeCommandType.color: if (cmd.Close) { //pop a color off our stack if (bbColorStack.Count > 0) { lastColor = bbColorStack.Pop(); drawCommands.Add(new TextDrawCmd_Color(TextStyle, lastColor)); } } else { bbColorStack.Push(lastColor); lastColor = cmd.ParseColor(); drawCommands.Add(new TextDrawCmd_Color(TextStyle, lastColor)); } break; case BBCodeCommandType.s: if (cmd.Close) { drawCommands.Add(new TextDrawCmd_Shadow(TextStyle, false)); shadowApplied = false; } else { drawCommands.Add(new TextDrawCmd_Shadow(TextStyle, true)); shadowApplied = true; } break; case BBCodeCommandType.emoji: if (segment.BBCatchup) { break; } drawCommands.Add(new TextDrawCmd_Emoji(TextStyle, cmd.Parameter, target.LocalPoint(new Vector2(xPosition, yPosition)), _Scale)); break; } } } /* * var segmentPosition = target.LocalPoint(new Vector2(xPosition, yPosition)); * drawCommands.Add(new TextDrawCmd_Text * { * Selected = false, * Text = line.Text, * Style = TextStyle, * Position = segmentPosition, * Scale = txtScale * }); */ numLinesAdded++; yPosition += m_LineHeight; position.Y += m_LineHeight; } if (shadowApplied) { drawCommands.Add(new TextDrawCmd_Shadow(TextStyle, false)); } while (bbColorStack.Count > 0) { lastColor = bbColorStack.Pop(); drawCommands.Add(new TextDrawCmd_Color(TextStyle, lastColor)); } result.BoundingBox = new Rectangle((int)topLeft.X, (int)topLeft.Y, (int)options.MaxWidth, (int)(yPosition - (m_LineHeight + topLeft.Y))); result.MaxWidth = realMaxWidth; foreach (var cmd in drawCommands) { cmd.Init(); } return(result); }