コード例 #1
0
ファイル: TextPointer.cs プロジェクト: mind0n/hive
        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;
        }