Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2346,43 +2346,45 @@ private void IncrementalMeasureLinesAfterInsert(double constraintWidth, LineProp
}
}

// Walk back through soft-wrap predecessors (lines without a hard break:
// Length == ContentLength) so the whole wrapped paragraph is re-formatted.
int firstAffectedLineIndex = lineIndex;
if (firstAffectedLineIndex > 0)
{
firstAffectedLineIndex--;
while (firstAffectedLineIndex > 0 &&
_lineMetrics[firstAffectedLineIndex - 1].Length == _lineMetrics[firstAffectedLineIndex - 1].ContentLength)
{
firstAffectedLineIndex--;
}
}

TextBoxLine line = new TextBoxLine(this);
int lineOffset;
int lineOffset = _lineMetrics[firstAffectedLineIndex].Offset;
bool endOfParagraph = false;

// We need to re-format the previous line, because if someone inserted
// a hard break, the first directly affected line might now be shorter
// and mergeable with its predecessor.
if (lineIndex > 0) // we can skip this if line wrap is disabled.
// Re-format each line from firstAffectedLineIndex through lineIndex,
// absorbing any successor lines fully covered by the new line.
int idx = firstAffectedLineIndex;
while (idx <= lineIndex && !endOfParagraph)
{
FormatFirstIncrementalLine(lineIndex - 1, constraintWidth, lineProperties, line, out lineOffset, out endOfParagraph);
}
else
{
lineOffset = _lineMetrics[lineIndex].Offset;
}
FormatIncrementalLine(idx, constraintWidth, lineProperties, line, ref lineOffset, out endOfParagraph);

// Format the line directly affected by the change.
// If endOfParagraph == true, then the line was absorbed into its
// predessor (because its new content is thinner, or because the
// TextWrapping property changed).
if (!endOfParagraph)
{
using (line)
while (idx + 1 < _lineMetrics.Count && lineOffset >= _lineMetrics[idx + 1].EndOffset)
{
line.Format(lineOffset, constraintWidth, constraintWidth, lineProperties, _cache.TextRunCache, _cache.TextFormatter);

_lineMetrics[lineIndex] = new LineRecord(lineOffset, line);

lineOffset += line.Length;
endOfParagraph = line.EndOfParagraph;
_lineMetrics.RemoveAt(idx + 1);
RemoveLineVisualRange(idx + 1, 1);
if (idx + 1 <= lineIndex)
{
lineIndex--;
}
}
ClearLineVisual(lineIndex);
lineIndex++;

idx++;
}

// Recalc the following lines not directly affected as needed.
SyncLineMetrics(range, constraintWidth, lineProperties, line, endOfParagraph, lineIndex, lineOffset);
SyncLineMetrics(range, constraintWidth, lineProperties, line, endOfParagraph, idx, lineOffset);

desiredSize = BruteForceCalculateDesiredSize();
}
Expand Down Expand Up @@ -2429,7 +2431,8 @@ private void IncrementalMeasureLinesAfterDelete(double constraintWidth, LineProp
// and mergeable with its predecessor.
if (lineIndex > 0) // we can skip this if line wrap is disabled.
{
FormatFirstIncrementalLine(lineIndex - 1, constraintWidth, lineProperties, line, out lineOffset, out endOfParagraph);
lineOffset = _lineMetrics[lineIndex - 1].Offset;
FormatIncrementalLine(lineIndex - 1, constraintWidth, lineProperties, line, ref lineOffset, out endOfParagraph);
}
else
{
Expand Down Expand Up @@ -2470,15 +2473,10 @@ private void IncrementalMeasureLinesAfterDelete(double constraintWidth, LineProp
desiredSize = BruteForceCalculateDesiredSize();
}

// Helper for IncrementalMeasureLinesAfterInsert, IncrementalMeasureLinesAfterDelete.
// Formats the line preceding the first directly affected line after a TextContainer change.
// In general this line might grow as content in the following line is absorbed.
private void FormatFirstIncrementalLine(int lineIndex, double constraintWidth, LineProperties lineProperties, TextBoxLine line,
out int lineOffset, out bool endOfParagraph)
// Formats the line at lineIndex, updates metrics, and clears the cached visual.
private void FormatIncrementalLine(int lineIndex, double constraintWidth, LineProperties lineProperties, TextBoxLine line,
ref int lineOffset, out bool endOfParagraph)
{
int originalEndOffset = _lineMetrics[lineIndex].EndOffset;
lineOffset = _lineMetrics[lineIndex].Offset;

using (line)
{
line.Format(lineOffset, constraintWidth, constraintWidth, lineProperties, _cache.TextRunCache, _cache.TextFormatter);
Expand All @@ -2489,11 +2487,7 @@ private void FormatFirstIncrementalLine(int lineIndex, double constraintWidth, L
endOfParagraph = line.EndOfParagraph;
}

// Don't clear the cached Visual unless something changed.
if (originalEndOffset != _lineMetrics[lineIndex].EndOffset)
{
ClearLineVisual(lineIndex);
}
ClearLineVisual(lineIndex);
}

// Helper for IncrementalMeasureLinesAfterInsert, IncrementalMeasureLinesAfterDelete.
Expand Down