protected IEnumerable<Tuple<string, bool, Func<FrameworkElement>, bool>> CheckLengths(ITextRenderAttributeState attributes, IEnumerable<string> words) { var wordsArr = GetRoughLengths(attributes, words).ToArray(); int idx0 = 0; string current = ""; double len = 0; for (int i = 0; i < wordsArr.Length; i++) { var word = wordsArr[i]; current += word.Item1; len = word.Item2; if ((len + LineWidth) > TextCanvas.ActualWidth) { idx0 = i; break; } } int idx1 = -1; for (int j = idx0; j >= 0; j--) { current = ""; for (int i = 0; i <= j; i++) { var word = wordsArr[i].Item1; current += word; } var com = new TextRenderCommand(attributes, new TextRenderTextContent(current)); var key = GetElementKey(com); var elWidth = GetElementWidth(key, com); if (!((elWidth + LineWidth) > TextCanvas.ActualWidth)) { idx1 = j; break; } } bool exceeded = false; current = ""; for (int i = 0; i < wordsArr.Length; i++) { var word = wordsArr[i].Item1; current += word; if (exceeded) { yield return new Tuple<string, bool, Func<FrameworkElement>, bool>(word, false, () => null, true); } else { var com = new TextRenderCommand(attributes, new TextRenderTextContent(current)); var key = GetElementKey(com); if (i > idx1) { var elWidth = GetElementWidth(key, com); if ((elWidth + LineWidth) > TextCanvas.ActualWidth) { exceeded = true; } yield return new Tuple<string, bool, Func<FrameworkElement>, bool>(word, !exceeded, ExtractElement(key, com), false); } else { yield return new Tuple<string, bool, Func<FrameworkElement>, bool>(word, true, ExtractElement(key, com), false); } } } }
protected IEnumerable<Tuple<string, bool, Action, bool>> CheckLengths(ITextRenderAttributeState attributes, IEnumerable<string> words) { var wordsArr = words.ToArray(); var testCom = new TextRenderCommand(attributes, new TextRenderTextContent("a")); var charWidth = GetElementWidth(testCom); int idx0 = 0; string current = ""; for (int i = 0; i < wordsArr.Length; i++) { var word = wordsArr[i]; current += word; var len = current.Length * charWidth; if ((len + LineWidth) > RenderWidth) { idx0 = i; break; } } int idx1 = -1; for (int j = idx0; j >= 0; j--) { current = ""; for (int i = 0; i <= j; i++) { var word = wordsArr[i]; current += word; } var com = new TextRenderCommand(attributes, new TextRenderTextContent(current)); var elWidth = GetElementWidth(com); if (!((elWidth + LineWidth) > RenderWidth)) { idx1 = j; break; } } bool exceeded = false; current = ""; for (int i = 0; i < wordsArr.Length; i++) { var word = wordsArr[i]; current += word; if (exceeded) { yield return new Tuple<string, bool, Action, bool>(word, false, null, true); } else { var com = new TextRenderCommand(attributes, new TextRenderTextContent(current)); if (i > idx1) { var elWidth = GetElementWidth(com); if ((elWidth + LineWidth) > RenderWidth) { exceeded = true; } yield return new Tuple<string, bool, Action, bool>(word, !exceeded, () => AddElementToCanvas(com), false); } else { yield return new Tuple<string, bool, Action, bool>(word, true, () => AddElementToCanvas(com), false); } } } }
protected IEnumerable<Tuple<string, double>> GetRoughLengths(ITextRenderAttributeState attributes, IEnumerable<string> words) { var wordsArr = words.ToArray(); var agg = wordsArr.Aggregate(new StringBuilder(), (sb, s) => sb.Append(s)).ToString(); var aggCom = new TextRenderCommand(attributes, new TextRenderTextContent(agg)); var aggKey = GetElementKey(aggCom); var totalWidth = GetElementWidth(aggKey, aggCom); var totalCount = agg.Length > 0 ? agg.Length : 1; int cnt = 0; foreach (var word in wordsArr) { cnt += word.Length; yield return new Tuple<string, double>(word, totalWidth * cnt / totalCount); } }