public bool UpdateTrailingInfo(TrailingInfo trailing) { if (IsEnd) { return(true); } if (IsTab) { return(false); } var index = Length; if (index > 0 && IsSpace(StringRange[index - 1])) { while (index > 0 && IsSpace(StringRange[index - 1])) { trailing.SpaceWidth += _glyphWidths[index - 1]; index--; trailing.Count++; } return(index == 0); } return(false); }
internal static TextLineImpl Create(TextParagraphProperties paragraphProperties, int firstIndex, double availableWidth, TextSource textSource) { var index = firstIndex; var visibleLength = 0; var widthLeft = paragraphProperties.TextWrapping == TextWrapping.Wrap && availableWidth > 0 ? availableWidth : double.MaxValue; widthLeft -= paragraphProperties.Margin.Left + paragraphProperties.Margin.Right; if (widthLeft < paragraphProperties.DefaultTextRunProperties.FontSize) { widthLeft = paragraphProperties.DefaultTextRunProperties.FontSize; } TextLineRun prevRun = null; var run = TextLineRun.Create(textSource, index, firstIndex, widthLeft); if (!run.IsEnd && run.Width <= widthLeft) { index += run.Length; widthLeft -= run.Width; prevRun = run; run = TextLineRun.Create(textSource, index, firstIndex, widthLeft); } var trailing = new TrailingInfo(); var runs = new List <TextLineRun>(2); if (prevRun != null) { visibleLength += AddRunReturnVisibleLength(runs, prevRun); } if (visibleLength >= MaxCharactersPerLine) { throw new NotSupportedException("Too many characters per line"); } while (true) { visibleLength += AddRunReturnVisibleLength(runs, run); index += run.Length; widthLeft -= run.Width; if (run.IsEnd || widthLeft <= 0) { if (!run.IsEnd && widthLeft <= 0) { //The text needs to be wrapped CalculateLineBreak(runs); } trailing.SpaceWidth = 0; UpdateTrailingInfo(runs, trailing); return(new TextLineImpl(paragraphProperties, firstIndex, runs, trailing)); } run = TextLineRun.Create(textSource, index, firstIndex, widthLeft); } }
private static void UpdateTrailingInfo(List <TextLineRun> runs, TrailingInfo trailing) { for (var index = (runs?.Count ?? 0) - 1; index >= 0; index--) { // ReSharper disable once PossibleNullReferenceException if (!runs[index].UpdateTrailingInfo(trailing)) { return; } } }
internal static TextLineImpl Create(TextParagraphProperties paragraphProperties, int firstIndex, int paragraphLength, TextSource textSource) { var index = firstIndex; var visibleLength = 0; var widthLeft = paragraphLength > 0 ? paragraphLength : int.MaxValue; TextLineRun prevRun = null; var run = TextLineRun.Create(textSource, index, firstIndex, widthLeft); if (!run.IsEnd && run.Width <= widthLeft) { index += run.Length; widthLeft -= run.Width; prevRun = run; run = TextLineRun.Create(textSource, index, firstIndex, widthLeft); } var trailing = new TrailingInfo(); var runs = new List <TextLineRun>(2); if (prevRun != null) { visibleLength += AddRunReturnVisibleLength(runs, prevRun); } if (visibleLength >= MaxCharactersPerLine) { throw new NotSupportedException("Too many characters per line"); } while (run.IsEnd || run.Width <= widthLeft) { visibleLength += AddRunReturnVisibleLength(runs, run); index += run.Length; widthLeft -= run.Width; if (run.IsEnd) { trailing.SpaceWidth = 0; UpdateTrailingInfo(runs, trailing); return(new TextLineImpl(paragraphProperties, firstIndex, runs, trailing)); } run = TextLineRun.Create(textSource, index, firstIndex, widthLeft); } return(null); }
internal static TextLineImpl Create(TextParagraphProperties paragraphProperties, int firstIndex, int paragraphLength, TextSource textSource) { var index = firstIndex; var visibleLength = 0; var widthLeft = paragraphProperties.TextWrapping == TextWrapping.Wrap && paragraphLength > 0 ? paragraphLength : double.MaxValue; TextLineRun prevRun = null; var run = TextLineRun.Create(textSource, index, firstIndex, widthLeft, paragraphProperties); if (!run.IsEnd && run.Width <= widthLeft) { index += run.Length; widthLeft -= run.Width; prevRun = run; run = TextLineRun.Create(textSource, index, firstIndex, widthLeft, paragraphProperties); } var trailing = new TrailingInfo(); var runs = new List <TextLineRun>(2); if (prevRun != null) { visibleLength += AddRunReturnVisibleLength(runs, prevRun); } while (true) { visibleLength += AddRunReturnVisibleLength(runs, run); index += run.Length; widthLeft -= run.Width; if (run.IsEnd || widthLeft <= 0) { trailing.SpaceWidth = 0; UpdateTrailingInfo(runs, trailing); return(new TextLineImpl(paragraphProperties, firstIndex, runs, trailing)); } run = TextLineRun.Create(textSource, index, firstIndex, widthLeft, paragraphProperties); if (run.Width > widthLeft) { return(new TextLineImpl(paragraphProperties, firstIndex, runs, trailing)); } } }
private TextLineImpl(TextParagraphProperties paragraphProperties, int firstIndex, List <TextLineRun> runs, TrailingInfo trailing) { var top = 0.0; var height = 0.0; var index = 0; _runs = new TextLineRun[runs.Count]; foreach (var run in runs) { _runs[index++] = run; if (run.Length <= 0) { continue; } if (run.IsEnd) { trailing.Count += run.Length; } else { top = Math.Max(top, run.Height - run.Baseline); height = Math.Max(height, run.Height); Baseline = Math.Max(Baseline, run.Baseline); } Length += run.Length; WidthIncludingTrailingWhitespace += run.Width; } if (height <= 0) { var fontSize = paragraphProperties.DefaultTextRunProperties.FontSize; Height = fontSize * TextLineRun.HeightFactor + paragraphProperties.Margin.Top + paragraphProperties.LineSpacing; Baseline = fontSize * TextLineRun.BaselineFactor + paragraphProperties.Margin.Top + paragraphProperties.LineSpacing; } else { Baseline += paragraphProperties.Margin.Top + paragraphProperties.LineSpacing; Height = Math.Max(height, Baseline + top); } if (runs[^ 1].IsEnd)
private TextLineImpl(TextParagraphProperties paragraphProperties, int firstIndex, List <TextLineRun> runs, TrailingInfo trailing) { var top = 0.0; var height = 0.0; var index = 0; _runs = new TextLineRun[runs.Count]; foreach (var run in runs) { _runs[index++] = run; if (run.Length <= 0) { continue; } if (run.IsEnd) { trailing.Count += run.Length; } else { top = Math.Max(top, run.Height - run.Baseline); height = Math.Max(height, run.Height); Baseline = Math.Max(Baseline, run.Baseline); } Length += run.Length; WidthIncludingTrailingWhitespace += run.Width; } Height = Math.Max(height, Baseline + top); if (Height <= 0) { Height = TextLineRun.GetDefaultLineHeight(paragraphProperties.DefaultTextRunProperties.FontMetrics); Baseline = TextLineRun.GetDefaultBaseline(paragraphProperties.DefaultTextRunProperties.FontMetrics); } FirstIndex = firstIndex; TrailingWhitespaceLength = trailing.Count; Width = WidthIncludingTrailingWhitespace - trailing.SpaceWidth; }