private void AppendTextSegmentCharWrap([NotNull] InlineSegment sourceSeg) { _curSeg = InlineSegment.CreateWithBuilder(AvailableWidth); for (int i = 0; i < sourceSeg.Text.Length; i++) { CharInfo c = CharInfo.From(sourceSeg.Text[i]); Debug.Assert(_curLineLength == GetLineLength(_curLine) + _curSeg.TextLength); if (!c.IsZeroWidth && _curLineLength >= AvailableWidth) { // Proceed as if the current char is '\n', repeat with current char on the next iteration // (unless current char is actually '\n', then it is consumed on wrap). if (!c.IsNewLine) { i--; _curLineLength--; } c = CharInfo.From('\n'); } if (c.IsNewLine) { StartNewLine(); } else if (!c.IsZeroWidth) { _curSeg.TextBuilder.Append(c); _curLineLength++; } } AppendCurrentSegment(); }
public InlineSequence([NotNull] InlineContainer container) { var initSegment = InlineSegment.CreateFromColors(container.EffectiveColor, container.EffectiveBackground); _formattingStack.Push(initSegment); Segments = new List <InlineSegment>(); AddFormattingSegment(); }
private void AddFormattingSegment() { InlineSegment lastSegment = Segments.LastOrDefault(); if (lastSegment == null || lastSegment.Text != null) { lastSegment = InlineSegment.CreateEmpty(); Segments.Add(lastSegment); } lastSegment.Color = _formattingStack.First(s => s.Color != null).Color.Value; lastSegment.Background = _formattingStack.First(s => s.Background != null).Background.Value; }
private void StartNewLine() { if (_curSeg != null && _curSeg.TextLength > 0) { _curLine.Add(_curSeg); _curSeg = InlineSegment.CreateWithBuilder(AvailableWidth); } _curLine = new List <InlineSegment>(); _lines.Add(_curLine); _curLineLength = 0; _wrapPos = -1; _segPos = 0; }
private void AppendTextSegmentWordWrap([NotNull] InlineSegment sourceSeg, bool isSpaceOnly) { _curSeg = InlineSegment.CreateWithBuilder(AvailableWidth); _segPos = 0; for (int i = 0; i < sourceSeg.Text.Length; i++) { CharInfo c = CharInfo.From(sourceSeg.Text[i]); Debug.Assert(_curLineLength == GetLineLength(_curLine) + _curSeg.TextLength); bool canAddChar = _curLineLength < AvailableWidth; if (!canAddChar && !c.IsZeroWidth) { if (c.IsConsumedOnWrap) { c = CharInfo.From('\n'); } else if (_wrapPos == -1) { c = CharInfo.From('\n'); // Repeat with current char on the next iteration i--; _curLineLength--; _segPos--; } else if (!c.IsNewLine) { _curLine.Add(_curSeg); WrapLine(); } } bool canWrap = isSpaceOnly ? c.IsWrappableSpace && (canAddChar || c.IsZeroWidth) : c.IsWrappable && (canAddChar || c.IsZeroWidth && !c.IsSoftHyphen); if (canWrap) { _wrapPos = _segPos; _wrapChar = c; _wrapSegmentIndex = _curLine.Count; } if (c.IsNewLine) { StartNewLine(); } else if (!c.IsZeroWidth) { _curSeg.TextBuilder.Append(c); _curLineLength++; _segPos++; } } AppendCurrentSegment(); }
private void AppendTextSegmentNoWrap([NotNull] InlineSegment sourceSeg) { _curSeg = InlineSegment.CreateWithBuilder(AvailableWidth); for (int i = 0; i < sourceSeg.Text.Length; i++) { CharInfo c = CharInfo.From(sourceSeg.Text[i]); if (c.IsNewLine) { StartNewLine(); } else if (!c.IsZeroWidth && _curLineLength < AvailableWidth) { _curSeg.TextBuilder.Append(c); _curLineLength++; } } AppendCurrentSegment(); }
private void WrapLine() { // TODO MemPerf: Avoid calling StringBuilder.ToString (pass string builder instead of string to SplitWrappedText, remove text from it). string wrappedText = _curLine[_wrapSegmentIndex].ToString(); SplitWrappedText(wrappedText, out string textBeforeWrap, out string textAfterWrap); // Put textBeforeWrap into wrappedSeg. if (wrappedText != textBeforeWrap) { InlineSegment wrappedSeg = _curLine[_wrapSegmentIndex]; wrappedSeg.TextBuilder.Clear(); wrappedSeg.TextBuilder.Append(textBeforeWrap); } // Remember extra segments after the wrapped segment to add to the last line later. Total length guaranteed to be short enough. List <InlineSegment> segmentsAfterWrap = _curLine.Skip(_wrapSegmentIndex + 1).ToList(); _curLine.RemoveRange(_wrapSegmentIndex + 1, segmentsAfterWrap.Count); // Start new line, ignoring current segment (it is being wrapped). _curSeg = null; StartNewLine(); // Put textAfterWrap on new line. if (textAfterWrap.Length > 0) { Debug.Assert(textAfterWrap.Length <= AvailableWidth); InlineSegment nextSeg = InlineSegment.CreateWithBuilder(textAfterWrap.Length); nextSeg.TextBuilder.Append(textAfterWrap); _curLine.Add(nextSeg); _curLineLength += textAfterWrap.Length; } _curLine.AddRange(segmentsAfterWrap); _curLineLength += GetLineLength(segmentsAfterWrap); _curSeg = InlineSegment.CreateWithBuilder(AvailableWidth); }
public void PushBackground(ConsoleColor background) { _formattingStack.Push(InlineSegment.CreateFromColors(null, background)); AddFormattingSegment(); }
public void PushColor(ConsoleColor color) { _formattingStack.Push(InlineSegment.CreateFromColors(color, null)); AddFormattingSegment(); }
public void AppendText(string text) { Segments.Add(InlineSegment.CreateFromText(text)); }