File: src\Framework\System\Windows\Documents\TextTreeTextElementNode.cs
Project: wpf\PresentationFramework.csproj (PresentationFramework)
//---------------------------------------------------------------------------
//
// <copyright file=TextTreeTextElementNode.cs company=Microsoft>
//    Copyright (C) Microsoft Corporation.  All rights reserved.
// </copyright>
// 
//
// Description: A TextContainer node representing a TextElement.
//
// History:  
//  02/18/2004 : Microsoft - Created
//
//---------------------------------------------------------------------------
 
using System;
using MS.Internal;
 
namespace System.Windows.Documents
{
    // Each TextElement inserted though a public API is represented internally
    // by a TextTreeTextElementNode.
    //
    // TextTreeTextElementNodes may contain trees of child nodes, nodes in
    // a contained tree are scoped by the element node.
    internal class TextTreeTextElementNode : TextTreeNode
    {
        //------------------------------------------------------
        //
        //  Constructors
        //
        //------------------------------------------------------
 
        #region Constructors
 
        // Creates a new instance.
        internal TextTreeTextElementNode()
        {
            _symbolOffsetCache = -1;
        }
 
        #endregion Constructors
 
        //------------------------------------------------------
        //
        //  Public Methods
        //
        //------------------------------------------------------
 
        #region Public Methods
 
#if DEBUG
        // Debug-only ToString override.
        public override string ToString()
        {
            return ("TextElementNode Id=" + this.DebugId + " SymbolCount=" + _symbolCount);
        }
#endif // DEBUG
 
        #endregion Public Methods
 
        //------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------
 
        #region Internal Methods
 
        // Returns a shallow copy of this node.
        internal override TextTreeNode Clone()
        {
            TextTreeTextElementNode clone;
 
            clone = new TextTreeTextElementNode();
            clone._symbolCount = _symbolCount;
            clone._imeCharCount = _imeCharCount;
            clone._textElement = _textElement;
 
            return clone;
        }
 
        // Returns the TextPointerContext of the node.
        // Returns ElementStart if direction == Forward, otherwise ElementEnd
        // if direction == Backward.
        internal override TextPointerContext GetPointerContext(LogicalDirection direction)
        {
            return (direction == LogicalDirection.Forward) ? TextPointerContext.ElementStart : TextPointerContext.ElementEnd;
        }
 
        #endregion Internal methods
 
        //------------------------------------------------------
        //
        //  Internal Properties
        //
        //------------------------------------------------------
 
        #region Internal Properties
 
        // If this node is a local root, then ParentNode contains it.
        // Otherwise, this is the node parenting this node within its tree.
        internal override SplayTreeNode ParentNode
        {
            get
            {
                return _parentNode;
            }
            
            set
            {
                _parentNode = (TextTreeNode)value;
            }
        }
 
        // Root node of a contained tree, if any.
        internal override SplayTreeNode ContainedNode
        {
            get
            {
                return _containedNode;
            }
            
            set
            {
                _containedNode = (TextTreeNode)value;
            }
        }
 
        // Count of symbols of all siblings preceding this node.
        internal override int LeftSymbolCount
        {
            get
            {
                return _leftSymbolCount;
            }
 
            set
            {
                _leftSymbolCount = value;
            }
        }
 
        // Count of chars of all siblings preceding this node.
        internal override int LeftCharCount
        {
            get
            {
                return _leftCharCount;
            }
 
            set
            {
                _leftCharCount = value;
            }
        }
 
        // Left child node in a sibling tree.
        internal override SplayTreeNode LeftChildNode
        {
            get
            {
                return _leftChildNode;
            }
            
            set
            {
                _leftChildNode = (TextTreeNode)value;
            }
        }
 
        // Right child node in a sibling tree.
        internal override SplayTreeNode RightChildNode
        {
            get
            {
                return _rightChildNode;
            }
            
            set
            {
                _rightChildNode = (TextTreeNode)value;
            }
        }
 
        // The TextContainer's generation when SymbolOffsetCache was last updated.
        // If the current generation doesn't match TextContainer.Generation, then
        // SymbolOffsetCache is invalid.
        internal override uint Generation
        {
            get
            {
                return _generation;
            }
            
            set
            {
                _generation = value;
            }
        }
 
        // Cached symbol offset.
        internal override int SymbolOffsetCache
        {
            get
            {
                return _symbolOffsetCache;
            }
            
            set
            {
                _symbolOffsetCache = value;
            }
        }
 
        // Count of symbols covered by this node and any contained nodes.
        // Includes two symbols for this node's start/end edges.
        internal override int SymbolCount
        {
            get
            {
                return _symbolCount;
            }
            
            set
            {
                _symbolCount = value;
            }
        }
 
        // Count of chars covered by this node and any contained nodes.
        internal override int IMECharCount
        {
            get
            {
                return _imeCharCount;
            }
 
            set
            {
                _imeCharCount = value;
            }
        }
 
        // Count of TextPositions referencing the node's BeforeStart edge.
        // Since nodes don't usually have any references, we demand allocate
        // storage when needed.
        internal override bool BeforeStartReferenceCount
        {
            get
            {
                return (_edgeReferenceCounts & ElementEdge.BeforeStart) != 0;
            }
 
            set
            {
                Invariant.Assert(value); // Illegal to clear a set ref count.
                _edgeReferenceCounts |= ElementEdge.BeforeStart;
            }
        }
 
        // Count of TextPositions referencing the node's AfterStart edge.
        // Since nodes don't usually have any references, we demand allocate
        // storage when needed.
        internal override bool AfterStartReferenceCount
        {
            get
            {
                return (_edgeReferenceCounts & ElementEdge.AfterStart) != 0;
            }
 
            set
            {
                Invariant.Assert(value); // Illegal to clear a set ref count.
                _edgeReferenceCounts |= ElementEdge.AfterStart;
            }
        }
 
        // Count of TextPositions referencing the node's BeforeEnd edge.
        // Since nodes don't usually have any references, we demand allocate
        // storage when needed.
        internal override bool BeforeEndReferenceCount
        {
            get
            {
                return (_edgeReferenceCounts & ElementEdge.BeforeEnd) != 0;
            }
 
            set
            {
                Invariant.Assert(value); // Illegal to clear a set ref count.
                _edgeReferenceCounts |= ElementEdge.BeforeEnd;
            }
        }
 
        // Count of TextPositions referencing the node's AfterEnd edge.
        // Since nodes don't usually have any references, we demand allocate
        // storage when needed.
        internal override bool AfterEndReferenceCount
        {
            get
            {
                return (_edgeReferenceCounts & ElementEdge.AfterEnd) != 0;
            }
 
            set
            {
                Invariant.Assert(value); // Illegal to clear a set ref count.
                _edgeReferenceCounts |= ElementEdge.AfterEnd;
            }
        }
 
        // The TextElement associated with this node.
        internal TextElement TextElement
        {
            get
            {
                return _textElement;
            }
            
            set
            {
                _textElement = value;
            }
        }
 
        // Plain text character count of this element's start edge.
        // This property depends on the current location of the node!
        internal int IMELeftEdgeCharCount
        {
            get
            {
                return (_textElement == null) ? -1 : _textElement.IMELeftEdgeCharCount;
            }
        }
 
        // Returns true if this node is the leftmost sibling of its parent.
        internal bool IsFirstSibling
        {
            get
            {
                Splay();
                return (_leftChildNode == null);
            }
        }
 
        #endregion Internal Properties
 
        //------------------------------------------------------
        //
        //  Private Fields
        //
        //------------------------------------------------------
 
        #region Private Fields
 
        // Count of symbols of all siblings preceding this node.
        private int _leftSymbolCount;
 
        // Count of chars of all siblings preceding this node.
        private int _leftCharCount;
 
        // If this node is a local root, then ParentNode contains it.
        // Otherwise, this is the node parenting this node within its tree.
        private TextTreeNode _parentNode;
 
        // Left child node in a sibling tree.
        private TextTreeNode _leftChildNode;
 
        // Right child node in a sibling tree.
        private TextTreeNode _rightChildNode;
 
        // Root node of a contained tree, if any.
        private TextTreeNode _containedNode;
 
        // The TextContainer's generation when SymbolOffsetCache was last updated.
        // If the current generation doesn't match TextContainer.Generation, then
        // SymbolOffsetCache is invalid.
        private uint _generation;
 
        // Cached symbol offset.
        private int _symbolOffsetCache;
 
        // Count of symbols covered by this node and any contained nodes.
        // Includes two symbols for this node's start/end edges.
        private int _symbolCount;
 
        // Count of chars covered by this node and any contained nodes.
        private int _imeCharCount;
 
        // The TextElement associated with this node.
        private TextElement _textElement;
 
        // Reference counts of TextPositions referencing this node.
        // Lazy allocated -- null means no references.
        private ElementEdge _edgeReferenceCounts;
 
        #endregion Private Fields
    }
}