ParagraphResult.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Framework / MS / Internal / documents / ParagraphResult.cs / 1 / ParagraphResult.cs

                            //-------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// Description: The ParagraphResult class provides access to layout-calculated 
//              information for a paragraph. 
//
// History: 
//  05/20/2003 : grzegorz - Moving from Avalon branch.
//  06/25/2004 : grzegorz - Performance work.
//
//--------------------------------------------------------------------------- 

using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel;
using System.Diagnostics; 
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
using MS.Internal.PtsHost; 
using MS.Internal.Text;
 
namespace MS.Internal.Documents 
{
    ///  
    /// The ParagraphResult class provides access to layout-calculated
    /// information for a paragraph.
    /// 
    internal abstract class ParagraphResult 
    {
        //------------------------------------------------------------------- 
        // 
        //  Constructors
        // 
        //-------------------------------------------------------------------

        #region Constructors
 
        /// 
        /// Constructor. 
        ///  
        /// Object representing a paragraph.
        internal ParagraphResult(BaseParaClient paraClient) 
        {
            _paraClient = paraClient;
            _layoutBox = _paraClient.Rect.FromTextDpi();
            _element = paraClient.Paragraph.Element; 
        }
 
        ///  
        /// Constructor.
        ///  
        /// Object representing a paragraph.
        /// Layout box for paragraph.
        /// Element associated with this paragraph result.
        internal ParagraphResult(BaseParaClient paraClient, Rect layoutBox, DependencyObject element) : this(paraClient) 
        {
            _layoutBox = layoutBox; 
            _element = element; 
        }
 
        #endregion Constructors

        //--------------------------------------------------------------------
        // 
        //  Internal Methods
        // 
        //------------------------------------------------------------------- 

        #region Internal Methods 

        /// 
        /// Returns whether the position is contained in this paragraph.
        ///  
        /// A position to test.
        /// Apply strict validation rules. 
        ///  
        /// True if column contains specified text position.
        /// Otherwise returns false. 
        /// 
        internal virtual bool Contains(ITextPointer position, bool strict)
        {
            EnsureTextContentRange(); 
            return _contentRange.Contains(position, strict);
        } 
 
        #endregion Internal Methods
 
        //--------------------------------------------------------------------
        //
        //  Internal Properties
        // 
        //--------------------------------------------------------------------
 
        #region Internal Properties 

        ///  
        /// Represents the beginning of the paragraph’s contents.
        /// 
        internal ITextPointer StartPosition
        { 
            get
            { 
                EnsureTextContentRange(); 
                return _contentRange.StartPosition;
            } 
        }

        /// 
        /// Represents the end of the paragraph’s contents. 
        /// 
        internal ITextPointer EndPosition 
        { 
            get
            { 
                EnsureTextContentRange();
                return _contentRange.EndPosition;
            }
        } 

        ///  
        /// The bounding rectangle of the paragraph; this is relative 
        /// to the parent bounding box.
        ///  
        internal Rect LayoutBox { get { return _layoutBox;  } }

        /// 
        /// Element associated with the paragraph. 
        /// 
        internal DependencyObject Element { get { return _element;  } } 
 
        /// 
        /// In derived classes, will return the _hasTextContent member whose value is set if the paragraph 
        /// has text content.
        /// 
        internal virtual bool HasTextContent
        { 
            get
            { 
                return false; 
            }
        } 

        #endregion Internal Properties

        //------------------------------------------------------------------- 
        //
        //  Private Methods 
        // 
        //--------------------------------------------------------------------
 
        #region Private Methods

        /// 
        /// Retrive TextContentRange if necessary. 
        /// 
        private void EnsureTextContentRange() 
        { 
            if (_contentRange == null)
            { 
                _contentRange = _paraClient.GetTextContentRange();
                Invariant.Assert(_contentRange != null);
            }
        } 

        #endregion Private Methods 
 
        //-------------------------------------------------------------------
        // 
        //  Private Fields
        //
        //-------------------------------------------------------------------
 
        #region Private Fields
 
        ///  
        /// Object representing a paragraph.
        ///  
        protected readonly BaseParaClient _paraClient;

        /// 
        /// Layout rectangle of the paragraph. 
        /// 
        protected readonly Rect _layoutBox; 
 
        /// 
        /// Element paragraph is associated with 
        /// 
        protected readonly DependencyObject _element;

        ///  
        /// TextContentRanges representing the column's contents.
        ///  
        private TextContentRange _contentRange; 

        ///  
        /// True if the paragraph or any nested paragraphs has text content
        /// 
        protected bool _hasTextContent;
 
        #endregion Private Fields
    } 
 
    /// 
    /// The ParagraphResult for a paragraph which only contains other 
    /// paragraphs.
    /// 
    internal sealed class ContainerParagraphResult : ParagraphResult
    { 
        //-------------------------------------------------------------------
        // 
        //  Constructors 
        //
        //-------------------------------------------------------------------- 

        #region Constructors

        ///  
        /// Constructor.
        ///  
        /// Object representing a paragraph. 
        internal ContainerParagraphResult(ContainerParaClient paraClient)
            : base(paraClient) 
        {
        }

        #endregion Constructors 

 
        //------------------------------------------------------------------- 
        //
        //  Internal Methods 
        //
        //--------------------------------------------------------------------

        #region Internal Methods 

        ///  
        /// Returns tight bounding geometry for the given text range. 
        /// 
        /// Start position of the range. 
        /// End position of the range.
        /// Visible clipping area
        /// Geometry object containing tight bound.
        internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition, Rect visibleRect) 
        {
            return (((ContainerParaClient)_paraClient).GetTightBoundingGeometryFromTextPositions(startPosition, endPosition, visibleRect)); 
        } 

        #endregion Internal Methods 

        //--------------------------------------------------------------------
        //
        //  Internal Properties 
        //
        //------------------------------------------------------------------- 
 
        #region Internal Properties
 
        /// 
        /// Collection of paragraphs in this paragraph.
        /// 
        internal ReadOnlyCollection Paragraphs 
        {
            get 
            { 
                if (_paragraphs == null)
                { 
                    // While getting children paragraph results, each paragraph is queried for text content
                    _paragraphs = ((ContainerParaClient)_paraClient).GetChildrenParagraphResults(out _hasTextContent);
                }
                Invariant.Assert(_paragraphs != null, "Paragraph collection is empty"); 
                return _paragraphs;
            } 
        } 

        ///  
        /// True if the paragraph has text content, i.e. not just figures and floaters. For a container paragraph, this is
        /// true if any of its children paras has text content
        /// 
        internal override bool HasTextContent 
        {
            get 
            { 
                if (_paragraphs == null)
                { 
                    // Getting Paragraphs collection queries each paragraph for text content and sets the value
                    ReadOnlyCollection paragraphs = Paragraphs;
                }
                return _hasTextContent; 
            }
        } 
 
        #endregion Internal Properties
 
        //--------------------------------------------------------------------
        //
        //  Private Fields
        // 
        //-------------------------------------------------------------------
 
        #region Private Fields 

        ///  
        /// The collection of ParagraphResults for for nested paragraphs.
        /// 
        private ReadOnlyCollection _paragraphs;
 
        #endregion Private Fields
    } 
 
    /// 
    /// The ParagraphResult for a paragraph which contains Text, Figures, 
    /// and Floaters (no nested paragraphs).
    /// 
    internal sealed class TextParagraphResult : ParagraphResult
    { 
        //-------------------------------------------------------------------
        // 
        //  Constructors 
        //
        //------------------------------------------------------------------- 

        #region Constructors

        ///  
        /// Constructor.
        ///  
        /// Object representing a paragraph. 
        internal TextParagraphResult(TextParaClient paraClient)
            : base(paraClient) 
        {
        }

        #endregion Constructors 

        //-------------------------------------------------------------------- 
        // 
        //  Internal Methods
        // 
        //-------------------------------------------------------------------

        #region Internal Methods
 
        /// 
        /// Retrieves the height and offset, in pixels, of the edge of 
        /// the object/character represented by position. 
        /// 
        /// Position of an object/character. 
        /// 
        /// The height, in pixels, of the edge of the object/character
        /// represented by position.
        ///  
        internal Rect GetRectangleFromTextPosition(ITextPointer position)
        { 
            return ((TextParaClient)_paraClient).GetRectangleFromTextPosition(position); 
        }
 
        /// 
        /// Returns tight bounding geometry for the given text range.
        /// 
        /// Start position of the range. 
        /// End position of the range.
        /// Paragraph's top space. 
        /// Visible clipping rectangle 
        /// Geometry object containing tight bound.
        internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition, double paragraphTopSpace, Rect visibleRect) 
        {
            return ((TextParaClient)_paraClient).GetTightBoundingGeometryFromTextPositions(startPosition, endPosition, paragraphTopSpace, visibleRect);
        }
 
        /// 
        /// Returns true if caret is at unit boundary 
        ///  
        /// Position of an object/character.
        internal bool IsAtCaretUnitBoundary(ITextPointer position) 
        {
            return ((TextParaClient)_paraClient).IsAtCaretUnitBoundary(position);
        }
 
        /// 
        /// Retrieves next caret unit position 
        ///  
        /// Position of an object/character.
        ///  
        /// LogicalDirection in which we seek the next caret unit position
        /// 
        internal ITextPointer GetNextCaretUnitPosition(ITextPointer position, LogicalDirection direction)
        { 
            return ((TextParaClient)_paraClient).GetNextCaretUnitPosition(position, direction);
        } 
 
        /// 
        /// Retrieves caret unit position after backspace 
        /// 
        /// Position of an object/character.
        internal ITextPointer GetBackspaceCaretUnitPosition(ITextPointer position)
        { 
            return ((TextParaClient)_paraClient).GetBackspaceCaretUnitPosition(position);
        } 
 
        /// 
        /// Retrieves collection of GlyphRuns from a range of text. 
        /// 
        /// 
        /// Preallocated collection of GlyphRuns.
        /// May already contain runs and new runs need to be appended. 
        /// 
        /// The beginning of the range. 
        /// The end of the range. 
        internal void GetGlyphRuns(List glyphRuns, ITextPointer start, ITextPointer end)
        { 
            ((TextParaClient)_paraClient).GetGlyphRuns(glyphRuns, start, end);
        }

        ///  
        /// Returns whether the position is contained in this paragraph.
        ///  
        /// A position to test. 
        /// Apply strict validation rules.
        ///  
        /// True if column contains specified text position.
        /// Otherwise returns false.
        /// 
        internal override bool Contains(ITextPointer position, bool strict) 
        {
            bool contains = base.Contains(position, strict); 
            // If the last line of text paragraph does not have content (example: some text), 
            // position after LineBreak with Forward direction belongs to this text paragraph and indicates
            // the last line of it. 
            // Because of that, always treat position after th last character of text paragraph as a valid
            // position for it. It is safe to do it because it is impossible to get 2 adjacent text paragraphs.
            if (!contains && strict)
            { 
                contains = (position.CompareTo(this.EndPosition) == 0);
            } 
            return contains; 
        }
 
        #endregion Internal Methods

        //--------------------------------------------------------------------
        // 
        //  Internal Properties
        // 
        //-------------------------------------------------------------------- 

        #region Internal Properties 

        /// 
        /// Collection of lines in this paragraph.
        ///  
        internal ReadOnlyCollection Lines
        { 
            get 
            {
                if (_lines == null) 
                {
                    _lines = ((TextParaClient)_paraClient).GetLineResults();
                }
                Invariant.Assert(_lines != null, "Lines collection is null"); 
                return _lines;
            } 
        } 

        ///  
        /// Collection of floating UIElements in this paragraph.
        /// 
        internal ReadOnlyCollection Floaters
        { 
            get
            { 
                if (_floaters == null) 
                {
                    _floaters = ((TextParaClient)_paraClient).GetFloaters(); 
                }
                return _floaters;
            }
        } 

        ///  
        /// Collection of figure UIElements in this paragraph. 
        /// 
        internal ReadOnlyCollection Figures 
        {
            get
            {
                if (_figures == null) 
                {
                    _figures = ((TextParaClient)_paraClient).GetFigures(); 
                } 
                return _figures;
            } 
        }

        /// 
        /// True if the paragraph has some text content, not only attached objects. A paragraph with no lines has no text content. 
        /// A paragraph with just one line containing figures and/or floaters does *not* have text content. We will ignore the end of paragraph character
        /// in this case and not hit test the lines in the paragraph. However, an empty paragraph with no figures and floaters does have text content. 
        /// We treat the EOP character as being on a line by itself. This is needed for editing. 
        /// 
        internal override bool HasTextContent 
        {
            get
            {
                return (Lines.Count > 0 && !ContainsOnlyFloatingElements); 
            }
        } 
 
        #endregion Internal Properties
 
        //-------------------------------------------------------------------
        //
        //  Private Properties
        // 
        //--------------------------------------------------------------------
 
        #region Private Properties 

        ///  
        /// True if the paragraph contains only figures or floaters with no text.
        /// 
        /// 
        /// An empty paragraph with no floating elements and just EOP character will return false. 
        /// 
        private bool ContainsOnlyFloatingElements 
        { 
            get
            { 
                bool floatingElementsOnly = false;
                TextParagraph textParagraph = _paraClient.Paragraph as TextParagraph;
                Invariant.Assert(textParagraph != null);
                if (textParagraph.HasFiguresOrFloaters()) 
                {
                    if (Lines.Count == 0) 
                    { 
                        // No lines, only attached objects
                        floatingElementsOnly = true; 
                    }
                    else if (Lines.Count == 1)
                    {
                        // If this line has no content, paragraph contains only attached objects 
                        int lastDcpAttachedObjectBeforeLine = textParagraph.GetLastDcpAttachedObjectBeforeLine(0);
                        if (lastDcpAttachedObjectBeforeLine + textParagraph.ParagraphStartCharacterPosition == textParagraph.ParagraphEndCharacterPosition) 
                        { 
                            floatingElementsOnly = true;
                        } 
                    }
                }
                return floatingElementsOnly;
            } 
        }
 
        #endregion Private Properties 

        //------------------------------------------------------------------- 
        //
        //  Private Fields
        //
        //------------------------------------------------------------------- 

        #region Private Fields 
 
        /// 
        /// The collection of LineResults for for the paragraph's lines. 
        /// 
        private ReadOnlyCollection _lines;

        ///  
        /// The collection of floating objects.
        ///  
        private ReadOnlyCollection _floaters; 

        ///  
        /// The collection of figures.
        /// 
        private ReadOnlyCollection _figures;
 
        #endregion Private Fields
    } 
 
    /// 
    /// The ParagraphResult for a table paragraph. 
    /// 
    internal sealed class TableParagraphResult : ParagraphResult
    {
        //------------------------------------------------------------------- 
        //
        //  Constructors 
        // 
        //--------------------------------------------------------------------
 
        #region Constructors

        /// 
        /// Constructor. 
        /// 
        /// Object representing a paragraph. 
        internal TableParagraphResult(BaseParaClient paraClient) 
            : base(paraClient)
        { 
        }

        #endregion Constructors
 
        //-------------------------------------------------------------------
        // 
        //  Internal Methods 
        //
        //-------------------------------------------------------------------- 

        #region Internal Methods

        ///  
        /// Returns the paragraphs for the appropriate cell, given a point
        ///  
        /// Point to check for cell. 
        /// Whether to snap to text
        ///  
        /// Array of paragraph results
        /// 
        internal ReadOnlyCollection GetParagraphsFromPoint(Point point, bool snapToText)
        { 
            return ((TableParaClient)_paraClient).GetParagraphsFromPoint(point, snapToText);
        } 
 
        /// 
        /// Returns the paragraphs for the appropriate cell, given a text position 
        /// 
        /// Position to check for cell.
        /// 
        /// Array of paragraph results 
        /// 
        internal ReadOnlyCollection GetParagraphsFromPosition(ITextPointer position) 
        { 
            return ((TableParaClient)_paraClient).GetParagraphsFromPosition(position);
        } 

        /// 
        /// Returns tight bounding geometry for the given text range.
        ///  
        /// Start position of the range.
        /// End position of the range. 
        /// Visible clipping rectangle. 
        /// Geometry object containing tight bound.
        internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition, Rect visibleRect) 
        {
            return ((TableParaClient)_paraClient).GetTightBoundingGeometryFromTextPositions(startPosition, endPosition, visibleRect);
        }
 
        /// 
        /// Returns the para client for a cell, given a position 
        ///  
        /// Position to check for cell.
        ///  
        /// Cell para client
        /// 
        internal CellParaClient GetCellParaClientFromPosition(ITextPointer position)
        { 
            return ((TableParaClient)_paraClient).GetCellParaClientFromPosition(position);
        } 
 
        /// 
        /// Returns an appropriate found cell 
        /// 
        /// Suggested X position for cell to find.
        /// RowGroupIndex to be above.
        /// RowIndex to be above. 
        /// 
        /// Cell Para Client of cell 
        ///  
        internal CellParaClient GetCellAbove(double suggestedX, int rowGroupIndex, int rowIndex)
        { 
            return ((TableParaClient)_paraClient).GetCellAbove(suggestedX, rowGroupIndex, rowIndex);
        }

        ///  
        /// Returns an appropriate found cell
        ///  
        /// Suggested X position for cell to find. 
        /// RowGroupIndex to be below.
        /// RowIndex to be below. 
        /// 
        /// Cell Para Client of cell
        /// 
        internal CellParaClient GetCellBelow(double suggestedX, int rowGroupIndex, int rowIndex) 
        {
            return ((TableParaClient)_paraClient).GetCellBelow(suggestedX, rowGroupIndex, rowIndex); 
        } 

        ///  
        /// Returns a cellinfo structure for a given point
        /// 
        /// Point to check for cell.
        ///  
        /// CellInfo class
        ///  
        internal CellInfo GetCellInfoFromPoint(Point point) 
        {
            return ((TableParaClient)_paraClient).GetCellInfoFromPoint(point); 
        }

        /// 
        /// Returns a rect corresponding to a row end position. 
        /// 
        /// Position to check against. 
        ///  
        /// Rect, area
        ///  
        internal Rect GetRectangleFromRowEndPosition(ITextPointer position)
        {
            return ((TableParaClient)_paraClient).GetRectangleFromRowEndPosition(position);
        } 

 
        ///  
        /// Collection of paragraphs in this paragraph.
        ///  
        internal ReadOnlyCollection Paragraphs
        {
            get
            { 
                if (_paragraphs == null)
                { 
                    // While getting children paras, query each one for text content and use the result to set _hasTextContent 
                    _paragraphs = ((TableParaClient)_paraClient).GetChildrenParagraphResults(out _hasTextContent);
                } 
                Invariant.Assert(_paragraphs != null, "Paragraph collection is empty");
                return _paragraphs;
            }
        } 

        ///  
        /// True if the paragraph has text content and not only figures/floaters. For Table paragraph this is true if any of its 
        /// children paras has text content
        ///  
        internal override bool HasTextContent
        {
            get
            { 
                if (_paragraphs == null)
                { 
                    // Getting Paragraphs collection sets the value of _hasTextContent by checking each child for text content 
                    ReadOnlyCollection paragraphs = Paragraphs;
                } 
                return _hasTextContent;
            }
        }
 
        #endregion Internal Methods
 
        //-------------------------------------------------------------------- 
        //
        //  Private Fields 
        //
        //-------------------------------------------------------------------

        #region Private Fields 

        ///  
        /// The collection of ParagraphResults for for nested paragraphs. 
        /// 
        private ReadOnlyCollection _paragraphs; 

        #endregion Private Fields

    } 

    ///  
    /// The ParagraphResult for a table row. 
    /// 
    internal sealed class RowParagraphResult : ParagraphResult 
    {
        //--------------------------------------------------------------------
        //
        //  Constructors 
        //
        //------------------------------------------------------------------- 
 
        #region Constructors
 
        /// 
        /// Constructor.
        /// 
        /// Object representing a paragraph. 
        /// Index of row in paragraph.
        /// Rectangle of row - as rendered. 
        /// Actual paragraph result is bound to. 
        internal RowParagraphResult(BaseParaClient paraClient, int index, Rect rowRect, RowParagraph rowParagraph)
            : base(paraClient, rowRect, rowParagraph.Element) 
        {
            _index = index;
        }
 
        #endregion Constructors
 
        //------------------------------------------------------------------- 
        //
        //  Internal Methods 
        //
        //-------------------------------------------------------------------

        #region Internal Properties 

        ///  
        /// Collection of paragraphs in this paragraph. 
        /// 
        internal ReadOnlyCollection CellParagraphs 
        {
            get
            {
                if (_cells == null) 
                {
                    // Check each cell for text content when getting cell paragraph results 
                    _cells = ((TableParaClient)_paraClient).GetChildrenParagraphResultsForRow(_index, out _hasTextContent); 
                }
                Invariant.Assert(_cells != null, "Paragraph collection is empty"); 
                return _cells;
            }
        }
 
        /// 
        /// True if the table row has text content, i.e. if any of the table cells in the row has text content 
        ///  
        internal override bool HasTextContent
        { 
            get
            {
                if (_cells == null)
                { 
                    // Getting cell paragraph results queries each one for text content
                    ReadOnlyCollection cells = CellParagraphs; 
                } 
                return _hasTextContent;
            } 
        }

        #endregion Internal Properties
 
        //--------------------------------------------------------------------
        // 
        //  Private Fields 
        //
        //------------------------------------------------------------------- 

        #region Private Fields

        ///  
        /// The collection of ParagraphResults for for nested paragraphs.
        ///  
        private ReadOnlyCollection _cells; 

        ///  
        /// Index of this row paragraph in tableparaclient's row array.
        /// 
        int _index;
 
        #endregion Private Fields
 
    } 

    ///  
    /// The ParagraphResult for a subpage paragraph.
    /// 
    internal sealed class SubpageParagraphResult : ParagraphResult
    { 
        //--------------------------------------------------------------------
        // 
        //  Constructors 
        //
        //-------------------------------------------------------------------- 

        #region Constructors

        ///  
        /// Constructor.
        ///  
        /// Object representing a paragraph. 
        internal SubpageParagraphResult(BaseParaClient paraClient)
            : base(paraClient) 
        {
        }

        #endregion Constructors 

        //------------------------------------------------------------------- 
        // 
        //  Internal Properties
        // 
        //--------------------------------------------------------------------

        #region Internal Properties
 
        /// 
        /// Collection of ColumnResults for each line in the paragraph. 
        ///  
        internal ReadOnlyCollection Columns
        { 
            get
            {
                if (_columns == null)
                { 
                    // Check subpage columns for text content
                    _columns = ((SubpageParaClient)_paraClient).GetColumnResults(out _hasTextContent); 
                    Invariant.Assert(_columns != null, "Columns collection is null"); 
                }
                return _columns; 
            }
        }

        ///  
        /// True if subpage has text content, i.e. if any of its columns has text content. Checking columns for text content will
        /// recursively check each column's paragraph collections 
        ///  
        internal override bool HasTextContent
        { 
            get
            {
                if (_columns == null)
                { 
                    ReadOnlyCollection columns = Columns;
                } 
                return _hasTextContent; 
            }
        } 

        /// 
        /// Collection of ParagraphResults for floating elements
        ///  
        internal ReadOnlyCollection FloatingElements
        { 
            get 
            {
                if (_floatingElements == null) 
                {
                    _floatingElements = ((SubpageParaClient)_paraClient).FloatingElementResults;
                    Invariant.Assert(_floatingElements != null, "Floating elements collection is null");
                } 
                return _floatingElements;
            } 
        } 

        ///  
        /// Offset for contained content - New PTS coordinate system (0, 0)
        /// 
        internal Vector ContentOffset
        { 
            get
            { 
                MbpInfo mbp = MbpInfo.FromElement(_paraClient.Paragraph.Element); 
                return new Vector(LayoutBox.X + TextDpi.FromTextDpi(mbp.BPLeft), LayoutBox.Y + TextDpi.FromTextDpi(mbp.BPTop));
            } 
        }

        #endregion Internal Properties
 
        //-------------------------------------------------------------------
        // 
        //  Private Fields 
        //
        //------------------------------------------------------------------- 

        #region Private Fields

        ///  
        /// The collection of ParagraphResults for for nested paragraphs.
        ///  
        private ReadOnlyCollection _columns; 

        ///  
        /// The collection of ParagraphResults for floating elements.
        /// 
        private ReadOnlyCollection _floatingElements;
 
        #endregion Private Fields
    } 
 
    /// 
    /// The ParagraphResult for a figure paragraph. 
    /// 
    internal sealed class FigureParagraphResult : ParagraphResult
    {
        //------------------------------------------------------------------- 
        //
        //  Constructors 
        // 
        //--------------------------------------------------------------------
 
        #region Constructors

        /// 
        /// Constructor. 
        /// 
        /// Object representing a paragraph. 
        internal FigureParagraphResult(BaseParaClient paraClient) 
            : base(paraClient)
        { 
        }

        #endregion Constructors
 
        //-------------------------------------------------------------------
        // 
        //  Internal Properties 
        //
        //-------------------------------------------------------------------- 

        #region Internal Properties

        ///  
        /// Collection of ColumnResults for each line in the paragraph.
        ///  
        internal ReadOnlyCollection Columns 
        {
            get 
            {
                if (_columns == null)
                {
                    // Check figure's columns for text content 
                    _columns = ((FigureParaClient)_paraClient).GetColumnResults(out _hasTextContent);
                    Invariant.Assert(_columns != null, "Columns collection is null"); 
                } 
                return _columns;
            } 
        }

        /// 
        /// True if the figure has text content, i.e. if its columns collection has text content. 
        /// 
        internal override bool HasTextContent 
        { 
            get
            { 
                if (_columns == null)
                {
                    ReadOnlyCollection columns = Columns;
                } 
                return _hasTextContent;
            } 
        } 

        ///  
        /// Collection of ParagraphResults for floating elements
        /// 
        internal ReadOnlyCollection FloatingElements
        { 
            get
            { 
                if (_floatingElements == null) 
                {
                    _floatingElements = ((FigureParaClient)_paraClient).FloatingElementResults; 
                    Invariant.Assert(_floatingElements != null, "Floating elements collection is null");
                }
                return _floatingElements;
            } 
        }
 
        ///  
        /// Offset for contained content - New PTS coordinate system (0, 0)
        ///  
        internal Vector ContentOffset
        {
            get
            { 
                MbpInfo mbp = MbpInfo.FromElement(_paraClient.Paragraph.Element);
                return new Vector(LayoutBox.X + TextDpi.FromTextDpi(mbp.BPLeft), LayoutBox.Y + TextDpi.FromTextDpi(mbp.BPTop)); 
            } 
        }
 
        #endregion Internal Properties

        //--------------------------------------------------------------------
        // 
        //  Internal Methods
        // 
        //------------------------------------------------------------------- 

        #region Internal Methods 

        /// 
        /// Returns tight bounding geometry for the given text range.
        ///  
        /// Start position of the range.
        /// End position of the range. 
        /// Visible clipping area 
        ///  True if range starts in this [ara
        /// Geometry object containing tight bound. 
        internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition, Rect visibleRect, out bool success)
        {
            success = false;
            if (this.Contains(startPosition, true)) 
            {
                // Selection starts inside this floater and must end inside it 
                success = true; 
                ITextPointer endPositionInThisPara = endPosition.CompareTo(this.EndPosition) < 0 ? endPosition : this.EndPosition;
                // Pass paragraph results and floating elements to para client so it doesn't have to generate them 
                return (((FigureParaClient)_paraClient).GetTightBoundingGeometryFromTextPositions(Columns, FloatingElements, startPosition, endPositionInThisPara, visibleRect));
            }
            return null;
        } 

        #endregion Internal Methods 
 
        //--------------------------------------------------------------------
        // 
        //  Private Fields
        //
        //-------------------------------------------------------------------
 
        #region Private Fields
 
        ///  
        /// The collection of ColumnResults for nested columns.
        ///  
        private ReadOnlyCollection _columns;

        /// 
        /// The collection of ParagraphResults for floating elements. 
        /// 
        private ReadOnlyCollection _floatingElements; 
 

        #endregion Private Fields 
    }

    /// 
    /// The ParagraphResult for a floater base paragraph. 
    /// 
    internal abstract class FloaterBaseParagraphResult : ParagraphResult 
    { 
        //-------------------------------------------------------------------
        // 
        //  Constructors
        //
        //-------------------------------------------------------------------
 
        #region Constructors
 
        ///  
        /// Constructor.
        ///  
        /// Object representing a paragraph.
        internal FloaterBaseParagraphResult(BaseParaClient paraClient)
            : base(paraClient)
        { 
        }
 
        #endregion Constructors 
    }
 
    /// 
    /// The ParagraphResult for a floater paragraph.
    /// 
    internal sealed class FloaterParagraphResult : FloaterBaseParagraphResult 
    {
        //-------------------------------------------------------------------- 
        // 
        //  Constructors
        // 
        //-------------------------------------------------------------------

        #region Constructors
 
        /// 
        /// Constructor. 
        ///  
        /// Object representing a paragraph.
        internal FloaterParagraphResult(BaseParaClient paraClient) 
            : base(paraClient)
        {
        }
 
        #endregion Constructors
 
        //-------------------------------------------------------------------- 
        //
        //  Internal Properties 
        //
        //--------------------------------------------------------------------

        #region Internal Properties 

        ///  
        /// Collection of ColumnResults for each line in the paragraph. 
        /// 
        internal ReadOnlyCollection Columns 
        {
            get
            {
                if (_columns == null) 
                {
                    // Query floater's columns for text content 
                    _columns = ((FloaterParaClient)_paraClient).GetColumnResults(out _hasTextContent); 
                    Invariant.Assert(_columns != null, "Columns collection is null");
                } 
                return _columns;
            }
        }
 
        /// 
        /// True if the floater has text content, i.e. if its columns collection has text content. 
        ///  
        internal override bool HasTextContent
        { 
            get
            {
                if (_columns == null)
                { 
                    ReadOnlyCollection columns = Columns;
                } 
                return _hasTextContent; 
            }
        } 

        /// 
        /// Collection of ParagraphResults for floating elements
        ///  
        internal ReadOnlyCollection FloatingElements
        { 
            get 
            {
                if (_floatingElements == null) 
                {
                    _floatingElements = ((FloaterParaClient)_paraClient).FloatingElementResults;
                    Invariant.Assert(_floatingElements != null, "Floating elements collection is null");
                } 
                return _floatingElements;
            } 
        } 

        ///  
        /// Offset for contained content - New PTS coordinate system (0, 0)
        /// 
        internal Vector ContentOffset
        { 
            get
            { 
                MbpInfo mbp = MbpInfo.FromElement(_paraClient.Paragraph.Element); 
                return new Vector(LayoutBox.X + TextDpi.FromTextDpi(mbp.BPLeft), LayoutBox.Y + TextDpi.FromTextDpi(mbp.BPTop));
            } 
        }

        #endregion Internal Properties
 
        //-------------------------------------------------------------------
        // 
        //  Internal Methods 
        //
        //-------------------------------------------------------------------- 

        #region Internal Methods

        ///  
        /// Returns tight bounding geometry for the given text range.
        ///  
        /// Start position of the range. 
        /// End position of the range.
        /// Visible clipping area 
        /// True if the range starts in this floater paragraph
        /// Geometry object containing tight bound.
        internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition, Rect visibleRect, out bool success)
        { 
            success = false;
            if (this.Contains(startPosition, true)) 
            { 
                // Selection starts inside this floater and must end inside it
                success = true; 
                ITextPointer endPositionInThisPara = endPosition.CompareTo(this.EndPosition) < 0 ? endPosition : this.EndPosition;
                return (((FloaterParaClient)_paraClient).GetTightBoundingGeometryFromTextPositions(Columns, FloatingElements, startPosition, endPositionInThisPara, visibleRect));
            }
            return null; 
        }
 
        #endregion Internal Methods 

 
        //-------------------------------------------------------------------
        //
        //  Private Fields
        // 
        //-------------------------------------------------------------------
 
        #region Private Fields 

        ///  
        /// The collection of ColumnResults for nested columns.
        /// 
        private ReadOnlyCollection _columns;
 
        /// 
        /// The collection of ParagraphResults for floating elements. 
        ///  
        private ReadOnlyCollection _floatingElements;
 
        #endregion Private Fields
    }

    ///  
    /// The ParagraphResult for a UIElement paragraph.
    ///  
    internal sealed class UIElementParagraphResult : FloaterBaseParagraphResult 
    {
        //------------------------------------------------------------------- 
        //
        //  Constructors
        //
        //-------------------------------------------------------------------- 

        #region Constructors 
 
        /// 
        /// Constructor. 
        /// 
        /// Object representing a paragraph.
        internal UIElementParagraphResult(BaseParaClient paraClient)
            : base(paraClient) 
        {
        } 
 
        #endregion Constructors
 
        //-------------------------------------------------------------------
        //
        //  Internal Properties
        // 
        //--------------------------------------------------------------------
 
        #region Internal Properties 

        ///  
        /// True if the BUIC has text content
        /// 
        internal override bool HasTextContent
        { 
            get
            { 
                // We always treat BlockUIContainer as a 'line' from ContentStart to ContentEnd. So HasTextContent is always true 
                return true;
            } 
        }

        /// 
        /// Returns tight bounding geometry for the given text range. 
        /// 
        internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition) 
        { 
            return (((UIElementParaClient)_paraClient).GetTightBoundingGeometryFromTextPositions(startPosition, endPosition));
        } 


        #endregion Internal Properties
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//-------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// Description: The ParagraphResult class provides access to layout-calculated 
//              information for a paragraph. 
//
// History: 
//  05/20/2003 : grzegorz - Moving from Avalon branch.
//  06/25/2004 : grzegorz - Performance work.
//
//--------------------------------------------------------------------------- 

using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel;
using System.Diagnostics; 
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
using MS.Internal.PtsHost; 
using MS.Internal.Text;
 
namespace MS.Internal.Documents 
{
    ///  
    /// The ParagraphResult class provides access to layout-calculated
    /// information for a paragraph.
    /// 
    internal abstract class ParagraphResult 
    {
        //------------------------------------------------------------------- 
        // 
        //  Constructors
        // 
        //-------------------------------------------------------------------

        #region Constructors
 
        /// 
        /// Constructor. 
        ///  
        /// Object representing a paragraph.
        internal ParagraphResult(BaseParaClient paraClient) 
        {
            _paraClient = paraClient;
            _layoutBox = _paraClient.Rect.FromTextDpi();
            _element = paraClient.Paragraph.Element; 
        }
 
        ///  
        /// Constructor.
        ///  
        /// Object representing a paragraph.
        /// Layout box for paragraph.
        /// Element associated with this paragraph result.
        internal ParagraphResult(BaseParaClient paraClient, Rect layoutBox, DependencyObject element) : this(paraClient) 
        {
            _layoutBox = layoutBox; 
            _element = element; 
        }
 
        #endregion Constructors

        //--------------------------------------------------------------------
        // 
        //  Internal Methods
        // 
        //------------------------------------------------------------------- 

        #region Internal Methods 

        /// 
        /// Returns whether the position is contained in this paragraph.
        ///  
        /// A position to test.
        /// Apply strict validation rules. 
        ///  
        /// True if column contains specified text position.
        /// Otherwise returns false. 
        /// 
        internal virtual bool Contains(ITextPointer position, bool strict)
        {
            EnsureTextContentRange(); 
            return _contentRange.Contains(position, strict);
        } 
 
        #endregion Internal Methods
 
        //--------------------------------------------------------------------
        //
        //  Internal Properties
        // 
        //--------------------------------------------------------------------
 
        #region Internal Properties 

        ///  
        /// Represents the beginning of the paragraph’s contents.
        /// 
        internal ITextPointer StartPosition
        { 
            get
            { 
                EnsureTextContentRange(); 
                return _contentRange.StartPosition;
            } 
        }

        /// 
        /// Represents the end of the paragraph’s contents. 
        /// 
        internal ITextPointer EndPosition 
        { 
            get
            { 
                EnsureTextContentRange();
                return _contentRange.EndPosition;
            }
        } 

        ///  
        /// The bounding rectangle of the paragraph; this is relative 
        /// to the parent bounding box.
        ///  
        internal Rect LayoutBox { get { return _layoutBox;  } }

        /// 
        /// Element associated with the paragraph. 
        /// 
        internal DependencyObject Element { get { return _element;  } } 
 
        /// 
        /// In derived classes, will return the _hasTextContent member whose value is set if the paragraph 
        /// has text content.
        /// 
        internal virtual bool HasTextContent
        { 
            get
            { 
                return false; 
            }
        } 

        #endregion Internal Properties

        //------------------------------------------------------------------- 
        //
        //  Private Methods 
        // 
        //--------------------------------------------------------------------
 
        #region Private Methods

        /// 
        /// Retrive TextContentRange if necessary. 
        /// 
        private void EnsureTextContentRange() 
        { 
            if (_contentRange == null)
            { 
                _contentRange = _paraClient.GetTextContentRange();
                Invariant.Assert(_contentRange != null);
            }
        } 

        #endregion Private Methods 
 
        //-------------------------------------------------------------------
        // 
        //  Private Fields
        //
        //-------------------------------------------------------------------
 
        #region Private Fields
 
        ///  
        /// Object representing a paragraph.
        ///  
        protected readonly BaseParaClient _paraClient;

        /// 
        /// Layout rectangle of the paragraph. 
        /// 
        protected readonly Rect _layoutBox; 
 
        /// 
        /// Element paragraph is associated with 
        /// 
        protected readonly DependencyObject _element;

        ///  
        /// TextContentRanges representing the column's contents.
        ///  
        private TextContentRange _contentRange; 

        ///  
        /// True if the paragraph or any nested paragraphs has text content
        /// 
        protected bool _hasTextContent;
 
        #endregion Private Fields
    } 
 
    /// 
    /// The ParagraphResult for a paragraph which only contains other 
    /// paragraphs.
    /// 
    internal sealed class ContainerParagraphResult : ParagraphResult
    { 
        //-------------------------------------------------------------------
        // 
        //  Constructors 
        //
        //-------------------------------------------------------------------- 

        #region Constructors

        ///  
        /// Constructor.
        ///  
        /// Object representing a paragraph. 
        internal ContainerParagraphResult(ContainerParaClient paraClient)
            : base(paraClient) 
        {
        }

        #endregion Constructors 

 
        //------------------------------------------------------------------- 
        //
        //  Internal Methods 
        //
        //--------------------------------------------------------------------

        #region Internal Methods 

        ///  
        /// Returns tight bounding geometry for the given text range. 
        /// 
        /// Start position of the range. 
        /// End position of the range.
        /// Visible clipping area
        /// Geometry object containing tight bound.
        internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition, Rect visibleRect) 
        {
            return (((ContainerParaClient)_paraClient).GetTightBoundingGeometryFromTextPositions(startPosition, endPosition, visibleRect)); 
        } 

        #endregion Internal Methods 

        //--------------------------------------------------------------------
        //
        //  Internal Properties 
        //
        //------------------------------------------------------------------- 
 
        #region Internal Properties
 
        /// 
        /// Collection of paragraphs in this paragraph.
        /// 
        internal ReadOnlyCollection Paragraphs 
        {
            get 
            { 
                if (_paragraphs == null)
                { 
                    // While getting children paragraph results, each paragraph is queried for text content
                    _paragraphs = ((ContainerParaClient)_paraClient).GetChildrenParagraphResults(out _hasTextContent);
                }
                Invariant.Assert(_paragraphs != null, "Paragraph collection is empty"); 
                return _paragraphs;
            } 
        } 

        ///  
        /// True if the paragraph has text content, i.e. not just figures and floaters. For a container paragraph, this is
        /// true if any of its children paras has text content
        /// 
        internal override bool HasTextContent 
        {
            get 
            { 
                if (_paragraphs == null)
                { 
                    // Getting Paragraphs collection queries each paragraph for text content and sets the value
                    ReadOnlyCollection paragraphs = Paragraphs;
                }
                return _hasTextContent; 
            }
        } 
 
        #endregion Internal Properties
 
        //--------------------------------------------------------------------
        //
        //  Private Fields
        // 
        //-------------------------------------------------------------------
 
        #region Private Fields 

        ///  
        /// The collection of ParagraphResults for for nested paragraphs.
        /// 
        private ReadOnlyCollection _paragraphs;
 
        #endregion Private Fields
    } 
 
    /// 
    /// The ParagraphResult for a paragraph which contains Text, Figures, 
    /// and Floaters (no nested paragraphs).
    /// 
    internal sealed class TextParagraphResult : ParagraphResult
    { 
        //-------------------------------------------------------------------
        // 
        //  Constructors 
        //
        //------------------------------------------------------------------- 

        #region Constructors

        ///  
        /// Constructor.
        ///  
        /// Object representing a paragraph. 
        internal TextParagraphResult(TextParaClient paraClient)
            : base(paraClient) 
        {
        }

        #endregion Constructors 

        //-------------------------------------------------------------------- 
        // 
        //  Internal Methods
        // 
        //-------------------------------------------------------------------

        #region Internal Methods
 
        /// 
        /// Retrieves the height and offset, in pixels, of the edge of 
        /// the object/character represented by position. 
        /// 
        /// Position of an object/character. 
        /// 
        /// The height, in pixels, of the edge of the object/character
        /// represented by position.
        ///  
        internal Rect GetRectangleFromTextPosition(ITextPointer position)
        { 
            return ((TextParaClient)_paraClient).GetRectangleFromTextPosition(position); 
        }
 
        /// 
        /// Returns tight bounding geometry for the given text range.
        /// 
        /// Start position of the range. 
        /// End position of the range.
        /// Paragraph's top space. 
        /// Visible clipping rectangle 
        /// Geometry object containing tight bound.
        internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition, double paragraphTopSpace, Rect visibleRect) 
        {
            return ((TextParaClient)_paraClient).GetTightBoundingGeometryFromTextPositions(startPosition, endPosition, paragraphTopSpace, visibleRect);
        }
 
        /// 
        /// Returns true if caret is at unit boundary 
        ///  
        /// Position of an object/character.
        internal bool IsAtCaretUnitBoundary(ITextPointer position) 
        {
            return ((TextParaClient)_paraClient).IsAtCaretUnitBoundary(position);
        }
 
        /// 
        /// Retrieves next caret unit position 
        ///  
        /// Position of an object/character.
        ///  
        /// LogicalDirection in which we seek the next caret unit position
        /// 
        internal ITextPointer GetNextCaretUnitPosition(ITextPointer position, LogicalDirection direction)
        { 
            return ((TextParaClient)_paraClient).GetNextCaretUnitPosition(position, direction);
        } 
 
        /// 
        /// Retrieves caret unit position after backspace 
        /// 
        /// Position of an object/character.
        internal ITextPointer GetBackspaceCaretUnitPosition(ITextPointer position)
        { 
            return ((TextParaClient)_paraClient).GetBackspaceCaretUnitPosition(position);
        } 
 
        /// 
        /// Retrieves collection of GlyphRuns from a range of text. 
        /// 
        /// 
        /// Preallocated collection of GlyphRuns.
        /// May already contain runs and new runs need to be appended. 
        /// 
        /// The beginning of the range. 
        /// The end of the range. 
        internal void GetGlyphRuns(List glyphRuns, ITextPointer start, ITextPointer end)
        { 
            ((TextParaClient)_paraClient).GetGlyphRuns(glyphRuns, start, end);
        }

        ///  
        /// Returns whether the position is contained in this paragraph.
        ///  
        /// A position to test. 
        /// Apply strict validation rules.
        ///  
        /// True if column contains specified text position.
        /// Otherwise returns false.
        /// 
        internal override bool Contains(ITextPointer position, bool strict) 
        {
            bool contains = base.Contains(position, strict); 
            // If the last line of text paragraph does not have content (example: some text), 
            // position after LineBreak with Forward direction belongs to this text paragraph and indicates
            // the last line of it. 
            // Because of that, always treat position after th last character of text paragraph as a valid
            // position for it. It is safe to do it because it is impossible to get 2 adjacent text paragraphs.
            if (!contains && strict)
            { 
                contains = (position.CompareTo(this.EndPosition) == 0);
            } 
            return contains; 
        }
 
        #endregion Internal Methods

        //--------------------------------------------------------------------
        // 
        //  Internal Properties
        // 
        //-------------------------------------------------------------------- 

        #region Internal Properties 

        /// 
        /// Collection of lines in this paragraph.
        ///  
        internal ReadOnlyCollection Lines
        { 
            get 
            {
                if (_lines == null) 
                {
                    _lines = ((TextParaClient)_paraClient).GetLineResults();
                }
                Invariant.Assert(_lines != null, "Lines collection is null"); 
                return _lines;
            } 
        } 

        ///  
        /// Collection of floating UIElements in this paragraph.
        /// 
        internal ReadOnlyCollection Floaters
        { 
            get
            { 
                if (_floaters == null) 
                {
                    _floaters = ((TextParaClient)_paraClient).GetFloaters(); 
                }
                return _floaters;
            }
        } 

        ///  
        /// Collection of figure UIElements in this paragraph. 
        /// 
        internal ReadOnlyCollection Figures 
        {
            get
            {
                if (_figures == null) 
                {
                    _figures = ((TextParaClient)_paraClient).GetFigures(); 
                } 
                return _figures;
            } 
        }

        /// 
        /// True if the paragraph has some text content, not only attached objects. A paragraph with no lines has no text content. 
        /// A paragraph with just one line containing figures and/or floaters does *not* have text content. We will ignore the end of paragraph character
        /// in this case and not hit test the lines in the paragraph. However, an empty paragraph with no figures and floaters does have text content. 
        /// We treat the EOP character as being on a line by itself. This is needed for editing. 
        /// 
        internal override bool HasTextContent 
        {
            get
            {
                return (Lines.Count > 0 && !ContainsOnlyFloatingElements); 
            }
        } 
 
        #endregion Internal Properties
 
        //-------------------------------------------------------------------
        //
        //  Private Properties
        // 
        //--------------------------------------------------------------------
 
        #region Private Properties 

        ///  
        /// True if the paragraph contains only figures or floaters with no text.
        /// 
        /// 
        /// An empty paragraph with no floating elements and just EOP character will return false. 
        /// 
        private bool ContainsOnlyFloatingElements 
        { 
            get
            { 
                bool floatingElementsOnly = false;
                TextParagraph textParagraph = _paraClient.Paragraph as TextParagraph;
                Invariant.Assert(textParagraph != null);
                if (textParagraph.HasFiguresOrFloaters()) 
                {
                    if (Lines.Count == 0) 
                    { 
                        // No lines, only attached objects
                        floatingElementsOnly = true; 
                    }
                    else if (Lines.Count == 1)
                    {
                        // If this line has no content, paragraph contains only attached objects 
                        int lastDcpAttachedObjectBeforeLine = textParagraph.GetLastDcpAttachedObjectBeforeLine(0);
                        if (lastDcpAttachedObjectBeforeLine + textParagraph.ParagraphStartCharacterPosition == textParagraph.ParagraphEndCharacterPosition) 
                        { 
                            floatingElementsOnly = true;
                        } 
                    }
                }
                return floatingElementsOnly;
            } 
        }
 
        #endregion Private Properties 

        //------------------------------------------------------------------- 
        //
        //  Private Fields
        //
        //------------------------------------------------------------------- 

        #region Private Fields 
 
        /// 
        /// The collection of LineResults for for the paragraph's lines. 
        /// 
        private ReadOnlyCollection _lines;

        ///  
        /// The collection of floating objects.
        ///  
        private ReadOnlyCollection _floaters; 

        ///  
        /// The collection of figures.
        /// 
        private ReadOnlyCollection _figures;
 
        #endregion Private Fields
    } 
 
    /// 
    /// The ParagraphResult for a table paragraph. 
    /// 
    internal sealed class TableParagraphResult : ParagraphResult
    {
        //------------------------------------------------------------------- 
        //
        //  Constructors 
        // 
        //--------------------------------------------------------------------
 
        #region Constructors

        /// 
        /// Constructor. 
        /// 
        /// Object representing a paragraph. 
        internal TableParagraphResult(BaseParaClient paraClient) 
            : base(paraClient)
        { 
        }

        #endregion Constructors
 
        //-------------------------------------------------------------------
        // 
        //  Internal Methods 
        //
        //-------------------------------------------------------------------- 

        #region Internal Methods

        ///  
        /// Returns the paragraphs for the appropriate cell, given a point
        ///  
        /// Point to check for cell. 
        /// Whether to snap to text
        ///  
        /// Array of paragraph results
        /// 
        internal ReadOnlyCollection GetParagraphsFromPoint(Point point, bool snapToText)
        { 
            return ((TableParaClient)_paraClient).GetParagraphsFromPoint(point, snapToText);
        } 
 
        /// 
        /// Returns the paragraphs for the appropriate cell, given a text position 
        /// 
        /// Position to check for cell.
        /// 
        /// Array of paragraph results 
        /// 
        internal ReadOnlyCollection GetParagraphsFromPosition(ITextPointer position) 
        { 
            return ((TableParaClient)_paraClient).GetParagraphsFromPosition(position);
        } 

        /// 
        /// Returns tight bounding geometry for the given text range.
        ///  
        /// Start position of the range.
        /// End position of the range. 
        /// Visible clipping rectangle. 
        /// Geometry object containing tight bound.
        internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition, Rect visibleRect) 
        {
            return ((TableParaClient)_paraClient).GetTightBoundingGeometryFromTextPositions(startPosition, endPosition, visibleRect);
        }
 
        /// 
        /// Returns the para client for a cell, given a position 
        ///  
        /// Position to check for cell.
        ///  
        /// Cell para client
        /// 
        internal CellParaClient GetCellParaClientFromPosition(ITextPointer position)
        { 
            return ((TableParaClient)_paraClient).GetCellParaClientFromPosition(position);
        } 
 
        /// 
        /// Returns an appropriate found cell 
        /// 
        /// Suggested X position for cell to find.
        /// RowGroupIndex to be above.
        /// RowIndex to be above. 
        /// 
        /// Cell Para Client of cell 
        ///  
        internal CellParaClient GetCellAbove(double suggestedX, int rowGroupIndex, int rowIndex)
        { 
            return ((TableParaClient)_paraClient).GetCellAbove(suggestedX, rowGroupIndex, rowIndex);
        }

        ///  
        /// Returns an appropriate found cell
        ///  
        /// Suggested X position for cell to find. 
        /// RowGroupIndex to be below.
        /// RowIndex to be below. 
        /// 
        /// Cell Para Client of cell
        /// 
        internal CellParaClient GetCellBelow(double suggestedX, int rowGroupIndex, int rowIndex) 
        {
            return ((TableParaClient)_paraClient).GetCellBelow(suggestedX, rowGroupIndex, rowIndex); 
        } 

        ///  
        /// Returns a cellinfo structure for a given point
        /// 
        /// Point to check for cell.
        ///  
        /// CellInfo class
        ///  
        internal CellInfo GetCellInfoFromPoint(Point point) 
        {
            return ((TableParaClient)_paraClient).GetCellInfoFromPoint(point); 
        }

        /// 
        /// Returns a rect corresponding to a row end position. 
        /// 
        /// Position to check against. 
        ///  
        /// Rect, area
        ///  
        internal Rect GetRectangleFromRowEndPosition(ITextPointer position)
        {
            return ((TableParaClient)_paraClient).GetRectangleFromRowEndPosition(position);
        } 

 
        ///  
        /// Collection of paragraphs in this paragraph.
        ///  
        internal ReadOnlyCollection Paragraphs
        {
            get
            { 
                if (_paragraphs == null)
                { 
                    // While getting children paras, query each one for text content and use the result to set _hasTextContent 
                    _paragraphs = ((TableParaClient)_paraClient).GetChildrenParagraphResults(out _hasTextContent);
                } 
                Invariant.Assert(_paragraphs != null, "Paragraph collection is empty");
                return _paragraphs;
            }
        } 

        ///  
        /// True if the paragraph has text content and not only figures/floaters. For Table paragraph this is true if any of its 
        /// children paras has text content
        ///  
        internal override bool HasTextContent
        {
            get
            { 
                if (_paragraphs == null)
                { 
                    // Getting Paragraphs collection sets the value of _hasTextContent by checking each child for text content 
                    ReadOnlyCollection paragraphs = Paragraphs;
                } 
                return _hasTextContent;
            }
        }
 
        #endregion Internal Methods
 
        //-------------------------------------------------------------------- 
        //
        //  Private Fields 
        //
        //-------------------------------------------------------------------

        #region Private Fields 

        ///  
        /// The collection of ParagraphResults for for nested paragraphs. 
        /// 
        private ReadOnlyCollection _paragraphs; 

        #endregion Private Fields

    } 

    ///  
    /// The ParagraphResult for a table row. 
    /// 
    internal sealed class RowParagraphResult : ParagraphResult 
    {
        //--------------------------------------------------------------------
        //
        //  Constructors 
        //
        //------------------------------------------------------------------- 
 
        #region Constructors
 
        /// 
        /// Constructor.
        /// 
        /// Object representing a paragraph. 
        /// Index of row in paragraph.
        /// Rectangle of row - as rendered. 
        /// Actual paragraph result is bound to. 
        internal RowParagraphResult(BaseParaClient paraClient, int index, Rect rowRect, RowParagraph rowParagraph)
            : base(paraClient, rowRect, rowParagraph.Element) 
        {
            _index = index;
        }
 
        #endregion Constructors
 
        //------------------------------------------------------------------- 
        //
        //  Internal Methods 
        //
        //-------------------------------------------------------------------

        #region Internal Properties 

        ///  
        /// Collection of paragraphs in this paragraph. 
        /// 
        internal ReadOnlyCollection CellParagraphs 
        {
            get
            {
                if (_cells == null) 
                {
                    // Check each cell for text content when getting cell paragraph results 
                    _cells = ((TableParaClient)_paraClient).GetChildrenParagraphResultsForRow(_index, out _hasTextContent); 
                }
                Invariant.Assert(_cells != null, "Paragraph collection is empty"); 
                return _cells;
            }
        }
 
        /// 
        /// True if the table row has text content, i.e. if any of the table cells in the row has text content 
        ///  
        internal override bool HasTextContent
        { 
            get
            {
                if (_cells == null)
                { 
                    // Getting cell paragraph results queries each one for text content
                    ReadOnlyCollection cells = CellParagraphs; 
                } 
                return _hasTextContent;
            } 
        }

        #endregion Internal Properties
 
        //--------------------------------------------------------------------
        // 
        //  Private Fields 
        //
        //------------------------------------------------------------------- 

        #region Private Fields

        ///  
        /// The collection of ParagraphResults for for nested paragraphs.
        ///  
        private ReadOnlyCollection _cells; 

        ///  
        /// Index of this row paragraph in tableparaclient's row array.
        /// 
        int _index;
 
        #endregion Private Fields
 
    } 

    ///  
    /// The ParagraphResult for a subpage paragraph.
    /// 
    internal sealed class SubpageParagraphResult : ParagraphResult
    { 
        //--------------------------------------------------------------------
        // 
        //  Constructors 
        //
        //-------------------------------------------------------------------- 

        #region Constructors

        ///  
        /// Constructor.
        ///  
        /// Object representing a paragraph. 
        internal SubpageParagraphResult(BaseParaClient paraClient)
            : base(paraClient) 
        {
        }

        #endregion Constructors 

        //------------------------------------------------------------------- 
        // 
        //  Internal Properties
        // 
        //--------------------------------------------------------------------

        #region Internal Properties
 
        /// 
        /// Collection of ColumnResults for each line in the paragraph. 
        ///  
        internal ReadOnlyCollection Columns
        { 
            get
            {
                if (_columns == null)
                { 
                    // Check subpage columns for text content
                    _columns = ((SubpageParaClient)_paraClient).GetColumnResults(out _hasTextContent); 
                    Invariant.Assert(_columns != null, "Columns collection is null"); 
                }
                return _columns; 
            }
        }

        ///  
        /// True if subpage has text content, i.e. if any of its columns has text content. Checking columns for text content will
        /// recursively check each column's paragraph collections 
        ///  
        internal override bool HasTextContent
        { 
            get
            {
                if (_columns == null)
                { 
                    ReadOnlyCollection columns = Columns;
                } 
                return _hasTextContent; 
            }
        } 

        /// 
        /// Collection of ParagraphResults for floating elements
        ///  
        internal ReadOnlyCollection FloatingElements
        { 
            get 
            {
                if (_floatingElements == null) 
                {
                    _floatingElements = ((SubpageParaClient)_paraClient).FloatingElementResults;
                    Invariant.Assert(_floatingElements != null, "Floating elements collection is null");
                } 
                return _floatingElements;
            } 
        } 

        ///  
        /// Offset for contained content - New PTS coordinate system (0, 0)
        /// 
        internal Vector ContentOffset
        { 
            get
            { 
                MbpInfo mbp = MbpInfo.FromElement(_paraClient.Paragraph.Element); 
                return new Vector(LayoutBox.X + TextDpi.FromTextDpi(mbp.BPLeft), LayoutBox.Y + TextDpi.FromTextDpi(mbp.BPTop));
            } 
        }

        #endregion Internal Properties
 
        //-------------------------------------------------------------------
        // 
        //  Private Fields 
        //
        //------------------------------------------------------------------- 

        #region Private Fields

        ///  
        /// The collection of ParagraphResults for for nested paragraphs.
        ///  
        private ReadOnlyCollection _columns; 

        ///  
        /// The collection of ParagraphResults for floating elements.
        /// 
        private ReadOnlyCollection _floatingElements;
 
        #endregion Private Fields
    } 
 
    /// 
    /// The ParagraphResult for a figure paragraph. 
    /// 
    internal sealed class FigureParagraphResult : ParagraphResult
    {
        //------------------------------------------------------------------- 
        //
        //  Constructors 
        // 
        //--------------------------------------------------------------------
 
        #region Constructors

        /// 
        /// Constructor. 
        /// 
        /// Object representing a paragraph. 
        internal FigureParagraphResult(BaseParaClient paraClient) 
            : base(paraClient)
        { 
        }

        #endregion Constructors
 
        //-------------------------------------------------------------------
        // 
        //  Internal Properties 
        //
        //-------------------------------------------------------------------- 

        #region Internal Properties

        ///  
        /// Collection of ColumnResults for each line in the paragraph.
        ///  
        internal ReadOnlyCollection Columns 
        {
            get 
            {
                if (_columns == null)
                {
                    // Check figure's columns for text content 
                    _columns = ((FigureParaClient)_paraClient).GetColumnResults(out _hasTextContent);
                    Invariant.Assert(_columns != null, "Columns collection is null"); 
                } 
                return _columns;
            } 
        }

        /// 
        /// True if the figure has text content, i.e. if its columns collection has text content. 
        /// 
        internal override bool HasTextContent 
        { 
            get
            { 
                if (_columns == null)
                {
                    ReadOnlyCollection columns = Columns;
                } 
                return _hasTextContent;
            } 
        } 

        ///  
        /// Collection of ParagraphResults for floating elements
        /// 
        internal ReadOnlyCollection FloatingElements
        { 
            get
            { 
                if (_floatingElements == null) 
                {
                    _floatingElements = ((FigureParaClient)_paraClient).FloatingElementResults; 
                    Invariant.Assert(_floatingElements != null, "Floating elements collection is null");
                }
                return _floatingElements;
            } 
        }
 
        ///  
        /// Offset for contained content - New PTS coordinate system (0, 0)
        ///  
        internal Vector ContentOffset
        {
            get
            { 
                MbpInfo mbp = MbpInfo.FromElement(_paraClient.Paragraph.Element);
                return new Vector(LayoutBox.X + TextDpi.FromTextDpi(mbp.BPLeft), LayoutBox.Y + TextDpi.FromTextDpi(mbp.BPTop)); 
            } 
        }
 
        #endregion Internal Properties

        //--------------------------------------------------------------------
        // 
        //  Internal Methods
        // 
        //------------------------------------------------------------------- 

        #region Internal Methods 

        /// 
        /// Returns tight bounding geometry for the given text range.
        ///  
        /// Start position of the range.
        /// End position of the range. 
        /// Visible clipping area 
        ///  True if range starts in this [ara
        /// Geometry object containing tight bound. 
        internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition, Rect visibleRect, out bool success)
        {
            success = false;
            if (this.Contains(startPosition, true)) 
            {
                // Selection starts inside this floater and must end inside it 
                success = true; 
                ITextPointer endPositionInThisPara = endPosition.CompareTo(this.EndPosition) < 0 ? endPosition : this.EndPosition;
                // Pass paragraph results and floating elements to para client so it doesn't have to generate them 
                return (((FigureParaClient)_paraClient).GetTightBoundingGeometryFromTextPositions(Columns, FloatingElements, startPosition, endPositionInThisPara, visibleRect));
            }
            return null;
        } 

        #endregion Internal Methods 
 
        //--------------------------------------------------------------------
        // 
        //  Private Fields
        //
        //-------------------------------------------------------------------
 
        #region Private Fields
 
        ///  
        /// The collection of ColumnResults for nested columns.
        ///  
        private ReadOnlyCollection _columns;

        /// 
        /// The collection of ParagraphResults for floating elements. 
        /// 
        private ReadOnlyCollection _floatingElements; 
 

        #endregion Private Fields 
    }

    /// 
    /// The ParagraphResult for a floater base paragraph. 
    /// 
    internal abstract class FloaterBaseParagraphResult : ParagraphResult 
    { 
        //-------------------------------------------------------------------
        // 
        //  Constructors
        //
        //-------------------------------------------------------------------
 
        #region Constructors
 
        ///  
        /// Constructor.
        ///  
        /// Object representing a paragraph.
        internal FloaterBaseParagraphResult(BaseParaClient paraClient)
            : base(paraClient)
        { 
        }
 
        #endregion Constructors 
    }
 
    /// 
    /// The ParagraphResult for a floater paragraph.
    /// 
    internal sealed class FloaterParagraphResult : FloaterBaseParagraphResult 
    {
        //-------------------------------------------------------------------- 
        // 
        //  Constructors
        // 
        //-------------------------------------------------------------------

        #region Constructors
 
        /// 
        /// Constructor. 
        ///  
        /// Object representing a paragraph.
        internal FloaterParagraphResult(BaseParaClient paraClient) 
            : base(paraClient)
        {
        }
 
        #endregion Constructors
 
        //-------------------------------------------------------------------- 
        //
        //  Internal Properties 
        //
        //--------------------------------------------------------------------

        #region Internal Properties 

        ///  
        /// Collection of ColumnResults for each line in the paragraph. 
        /// 
        internal ReadOnlyCollection Columns 
        {
            get
            {
                if (_columns == null) 
                {
                    // Query floater's columns for text content 
                    _columns = ((FloaterParaClient)_paraClient).GetColumnResults(out _hasTextContent); 
                    Invariant.Assert(_columns != null, "Columns collection is null");
                } 
                return _columns;
            }
        }
 
        /// 
        /// True if the floater has text content, i.e. if its columns collection has text content. 
        ///  
        internal override bool HasTextContent
        { 
            get
            {
                if (_columns == null)
                { 
                    ReadOnlyCollection columns = Columns;
                } 
                return _hasTextContent; 
            }
        } 

        /// 
        /// Collection of ParagraphResults for floating elements
        ///  
        internal ReadOnlyCollection FloatingElements
        { 
            get 
            {
                if (_floatingElements == null) 
                {
                    _floatingElements = ((FloaterParaClient)_paraClient).FloatingElementResults;
                    Invariant.Assert(_floatingElements != null, "Floating elements collection is null");
                } 
                return _floatingElements;
            } 
        } 

        ///  
        /// Offset for contained content - New PTS coordinate system (0, 0)
        /// 
        internal Vector ContentOffset
        { 
            get
            { 
                MbpInfo mbp = MbpInfo.FromElement(_paraClient.Paragraph.Element); 
                return new Vector(LayoutBox.X + TextDpi.FromTextDpi(mbp.BPLeft), LayoutBox.Y + TextDpi.FromTextDpi(mbp.BPTop));
            } 
        }

        #endregion Internal Properties
 
        //-------------------------------------------------------------------
        // 
        //  Internal Methods 
        //
        //-------------------------------------------------------------------- 

        #region Internal Methods

        ///  
        /// Returns tight bounding geometry for the given text range.
        ///  
        /// Start position of the range. 
        /// End position of the range.
        /// Visible clipping area 
        /// True if the range starts in this floater paragraph
        /// Geometry object containing tight bound.
        internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition, Rect visibleRect, out bool success)
        { 
            success = false;
            if (this.Contains(startPosition, true)) 
            { 
                // Selection starts inside this floater and must end inside it
                success = true; 
                ITextPointer endPositionInThisPara = endPosition.CompareTo(this.EndPosition) < 0 ? endPosition : this.EndPosition;
                return (((FloaterParaClient)_paraClient).GetTightBoundingGeometryFromTextPositions(Columns, FloatingElements, startPosition, endPositionInThisPara, visibleRect));
            }
            return null; 
        }
 
        #endregion Internal Methods 

 
        //-------------------------------------------------------------------
        //
        //  Private Fields
        // 
        //-------------------------------------------------------------------
 
        #region Private Fields 

        ///  
        /// The collection of ColumnResults for nested columns.
        /// 
        private ReadOnlyCollection _columns;
 
        /// 
        /// The collection of ParagraphResults for floating elements. 
        ///  
        private ReadOnlyCollection _floatingElements;
 
        #endregion Private Fields
    }

    ///  
    /// The ParagraphResult for a UIElement paragraph.
    ///  
    internal sealed class UIElementParagraphResult : FloaterBaseParagraphResult 
    {
        //------------------------------------------------------------------- 
        //
        //  Constructors
        //
        //-------------------------------------------------------------------- 

        #region Constructors 
 
        /// 
        /// Constructor. 
        /// 
        /// Object representing a paragraph.
        internal UIElementParagraphResult(BaseParaClient paraClient)
            : base(paraClient) 
        {
        } 
 
        #endregion Constructors
 
        //-------------------------------------------------------------------
        //
        //  Internal Properties
        // 
        //--------------------------------------------------------------------
 
        #region Internal Properties 

        ///  
        /// True if the BUIC has text content
        /// 
        internal override bool HasTextContent
        { 
            get
            { 
                // We always treat BlockUIContainer as a 'line' from ContentStart to ContentEnd. So HasTextContent is always true 
                return true;
            } 
        }

        /// 
        /// Returns tight bounding geometry for the given text range. 
        /// 
        internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition) 
        { 
            return (((UIElementParaClient)_paraClient).GetTightBoundingGeometryFromTextPositions(startPosition, endPosition));
        } 


        #endregion Internal Properties
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK