/// <summary> /// Returns the text with correct line wrapping (used for Unity.UI.Text component only) /// </summary> /// <param name="text">UI text string</param> /// <param name="textComponent">Unity UI Text component</param> /// <param name="numsFormat"> /// 0 = Latin (default), /// 1 = Arabic, /// 2 = Persian /// </param> /// <returns></returns> public static string CorrectWithLineWrapping(string text, UnityEngine.UI.Text textComponent, int numsFormat = 0) { // arbitrary max line length. needs to be long enough for a start // the correct max will be calculated later int lineMax = 1000; List <string> linesStr = new List <string>(); // force updating the text graphic (performance cost and Garbage) because the text has not been rendered yet // this is needed when your are assigning new text and correcting it in the same frame textComponent.Rebuild(UnityEngine.UI.CanvasUpdate.PreRender); // set desired numbers format NumCase = (numCase)numsFormat; if ((int)NumCase < 0 || (int)NumCase > 2) { NumCase = numCase.LATIN; // wrong input, fallback to latin } // parse each line, correct it and add it to the final strings list for (int i = 0; i < textComponent.cachedTextGenerator.lines.Count; i++) { int startIndex = textComponent.cachedTextGenerator.lines[i].startCharIdx; int endIndex = -1; if (i == textComponent.cachedTextGenerator.lines.Count - 1) { endIndex = textComponent.text.Length; // one line } else { endIndex = textComponent.cachedTextGenerator.lines[i + 1].startCharIdx; // line ends where next one starts } // line length int length = endIndex - startIndex; // extract the line string string line = textComponent.text.Substring(startIndex, length); //Debug.Log(line); // correct the extracted line and add it to the list linesStr.Add(CorrectText(ExtractStrings(line))); } for (int j = 0; j < linesStr.Count; j++) { int currLen = linesStr[j].Length; //current line length //Debug.Log(currLen); if (linesStr.Count > 1) { if (j + 1 < linesStr.Count) { List <string> nextLineStrings = new List <string>(linesStr[j + 1].Split()); // splitted strings in next line nextLineStrings.Reverse(); foreach (var s in nextLineStrings) { int finalLen = s.Length + currLen; if (finalLen <= lineMax) { linesStr[j] = linesStr[j].Insert(0, s); // insert into previous line linesStr[j + 1] = linesStr[j + 1].Remove(linesStr[j + 1].IndexOf(s), s.Length).Trim(); // remove from next line lineMax = linesStr[j].Length; // now we are able to calculate the correct capacity of the line if (linesStr[j + 1].Length == 0) // all next line strings has been added to previous one, remove the empty line { // insert a space after last word. Note: remember the string is reversed linesStr[j] = linesStr[j].Insert(linesStr[j].LastIndexOf(s) + s.Length, " "); linesStr.Remove(linesStr[j + 1]); } currLen = finalLen; break; } else { break; } } // foreach end nextLineStrings.Clear(); } } // if end } // for end // join the strings into one final string string myStr = ""; for (int i = 0; i < linesStr.Count; i++) { myStr += linesStr[i].Trim(); // concatenate each line into the final string if (i != linesStr.Count - 1) { myStr += "\n"; // make sure it is not one line, then wrap it into new line } } linesStr.Clear(); return(myStr); }