internal static int GetTextInRun(TextContainer textContainer, int symbolOffset, TextTreeTextNode textNode, int nodeOffset, LogicalDirection direction, char[] textBuffer, int startIndex, int count) { int skipCount; int finalCount; if (textBuffer == null) { throw new ArgumentNullException("textBuffer"); } if (startIndex < 0) { throw new ArgumentException(SR.Get(SRID.NegativeValue, "startIndex")); } if (startIndex > textBuffer.Length) { throw new ArgumentException(SR.Get(SRID.StartIndexExceedsBufferSize, startIndex, textBuffer.Length)); } if (count < 0) { throw new ArgumentException(SR.Get(SRID.NegativeValue, "count")); } if (count > textBuffer.Length - startIndex) { throw new ArgumentException(SR.Get(SRID.MaxLengthExceedsBufferSize, count, textBuffer.Length, startIndex)); } Invariant.Assert(textNode != null, "textNode is expected to be non-null"); textContainer.EmptyDeadPositionList(); if (nodeOffset < 0) { skipCount = 0; } else { skipCount = (direction == LogicalDirection.Forward) ? nodeOffset : textNode.SymbolCount - nodeOffset; symbolOffset += nodeOffset; } finalCount = 0; // Loop and combine adjacent text nodes into a single run. // This isn't just a perf optimization. Because text positions // split text nodes, if we just returned a single node's text // callers would see strange side effects where position.GetTextLength() != // position.GetText() if another position is moved between the calls. while (textNode != null) { // Never return more textBuffer than the text following this position in the current text node. finalCount += Math.Min(count - finalCount, textNode.SymbolCount - skipCount); skipCount = 0; if (finalCount == count) break; textNode = ((direction == LogicalDirection.Forward) ? textNode.GetNextNode() : textNode.GetPreviousNode()) as TextTreeTextNode; } // If we're reading backwards, need to fixup symbolOffset to point into the node. if (direction == LogicalDirection.Backward) { symbolOffset -= finalCount; } if (finalCount > 0) // We may not have allocated textContainer.RootTextBlock if no text was ever inserted. { TextTreeText.ReadText(textContainer.RootTextBlock, symbolOffset, finalCount, textBuffer, startIndex); } return finalCount; }