ContainerParaClient.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 / PtsHost / ContainerParaClient.cs / 1 / ContainerParaClient.cs

                            //---------------------------------------------------------------------------- 
//
// Copyright (C) Microsoft Corporation.  All rights reserved.
//
// File: ContainerParaClient.cs 
//
// Description: ContainerParaClient is responsible for handling display 
//              related data of paragraph containers. 
//
// History: 
//  05/05/2003 : grzegorz - moving from Avalon branch.
//
//---------------------------------------------------------------------------
 
using System;
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.Collections;
using System.Diagnostics; 
using System.Security;
using System.Windows;
using System.Windows.Media;
using System.Windows.Documents; 
using MS.Internal.Documents;
using MS.Internal.Text; 
 
using MS.Internal.PtsHost.UnsafeNativeMethods;
 
namespace MS.Internal.PtsHost
{
    /// 
    /// ContainerParaClient is responsible for handling display related data 
    /// of paragraph containers.
    ///  
    internal class ContainerParaClient : BaseParaClient 
    {
        ///  
        /// Constructor.
        /// 
        /// 
        /// Paragraph associated with this object. 
        /// 
        internal ContainerParaClient(ContainerParagraph paragraph) : base(paragraph) 
        { 
        }
 
        /// 
        /// Arrange paragraph.
        /// 
        ///  
        /// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails,
        ///            and some PtsHelper functions 
        /// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet 
        ///        which ensures that partial trust code won't be able to set it to a random value.
        ///        The subtrackDetails parameter passed to other methods is generated securely in this function. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        protected override void OnArrange()
        { 
            base.OnArrange();
 
            // Query paragraph details 
            PTS.FSSUBTRACKDETAILS subtrackDetails;
            PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails)); 

            // Adjust rectangle and offset to take into account MBPs
            MbpInfo mbp = MbpInfo.FromElement(Paragraph.Element);
 
            if(ParentFlowDirection != PageFlowDirection)
            { 
                mbp.MirrorMargin(); 
            }
 
            _rect.u += mbp.MarginLeft;
            _rect.du -= mbp.MarginLeft + mbp.MarginRight;

            _rect.du = Math.Max(TextDpi.ToTextDpi(TextDpi.MinWidth), _rect.du); 
            _rect.dv = Math.Max(TextDpi.ToTextDpi(TextDpi.MinWidth), _rect.dv);
 
            uint fswdirSubtrack = PTS.FlowDirectionToFswdir(_flowDirection); 

            // There is possibility to get empty track. 
            if (subtrackDetails.cParas != 0)
            {

                // Get list of paragraphs 
                PTS.FSPARADESCRIPTION [] arrayParaDesc;
                PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc); 
 
                PtsHelper.ArrangeParaList(PtsContext, subtrackDetails.fsrc, arrayParaDesc, fswdirSubtrack);
            } 
        }

        /// 
        /// Hit tests to the correct IInputElement within the paragraph 
        /// that the mouse is over.
        ///  
        ///  
        /// Point which gives location of Hit test
        ///  
        /// 
        /// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails,
        /// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet
        ///        which ensures that partial trust code won't be able to set it to a random value. 
        ///        The subtrackDetails parameter passed to other methods is generated securely in this function.
        ///  
        [SecurityCritical, SecurityTreatAsSafe] 
        internal override IInputElement InputHitTest(PTS.FSPOINT pt)
        { 
            IInputElement ie = null;

            // Query paragraph details
            PTS.FSSUBTRACKDETAILS subtrackDetails; 
            PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails));
 
            // Hittest subtrack content. 

            // There might be possibility to get empty sub-track, skip the sub-track 
            // in such case.
            if (subtrackDetails.cParas != 0)
            {
                // Get list of paragraphs 
                PTS.FSPARADESCRIPTION [] arrayParaDesc;
                PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc); 
 
                // Render list of paragraphs
                ie = PtsHelper.InputHitTestParaList(PtsContext, pt, ref subtrackDetails.fsrc, arrayParaDesc); 
            }

            // If nothing is hit, return the owner of the paragraph.
            if (ie == null && _rect.Contains(pt)) 
            {
                ie = Paragraph.Element as IInputElement; 
            } 

            return ie; 
        }

        /// 
        /// Returns ArrayList of rectangles for the given ContentElement e if 
        /// e lies in this client. Otherwise returns empty list.
        ///  
        ///  
        /// ContentElement for which rectangles are needed
        ///  
        /// 
        /// Int representing start offset of e.
        /// 
        ///  
        /// int representing number of positions occupied by e.
        ///  
        ///  
        /// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails,
        /// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet 
        ///        which ensures that partial trust code won't be able to set it to a random value.
        ///        The subtrackDetails parameter passed to other methods is generated securely in this function.
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal override List GetRectangles(ContentElement e, int start, int length)
        { 
            List rectangles = new List(); 

            if (this.Paragraph.Element as ContentElement == e) 
            {
                // We have found the element. Return rectangles for this paragraph.
                GetRectanglesForParagraphElement(out rectangles);
            } 
            else
            { 
                // Element not found as Paragraph.Element. Look inside 

                // Query paragraph details 
                PTS.FSSUBTRACKDETAILS subtrackDetails;
                PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails));

                // There might be possibility to get empty sub-track, skip the sub-track 
                // in such case.
                if (subtrackDetails.cParas != 0) 
                { 
                    // Get list of paragraphs
                    // No changes to offset, since there are no subpages generated, only lists of paragraphs 
                    PTS.FSPARADESCRIPTION[] arrayParaDesc;
                    PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc);

                    // Render list of paragraphs 
                    rectangles = PtsHelper.GetRectanglesInParaList(PtsContext, e, start, length, arrayParaDesc);
                } 
                else 
                {
                    rectangles = new List(); 
                }
            }

            // Rectangles must be non-null 
            Invariant.Assert(rectangles != null);
            return rectangles; 
        } 

        ///  
        /// Validate visual node associated with paragraph.
        /// 
        /// 
        /// Inherited update info 
        /// 
        ///  
        /// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails, 
        /// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet
        ///        which ensures that partial trust code won't be able to set it to a random value. 
        ///        The subtrackDetails parameter passed to other methods is generated securely in this function.
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        internal override void ValidateVisual(PTS.FSKUPDATE fskupdInherited) 
        {
            // Query paragraph details 
            PTS.FSSUBTRACKDETAILS subtrackDetails; 
            PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails));
 
            // Draw border and background info.

            // Adjust rectangle and offset to take into account MBPs
            MbpInfo mbp = MbpInfo.FromElement(Paragraph.Element); 

            if(ThisFlowDirection != PageFlowDirection) 
            { 
                mbp.MirrorBP();
            } 

            Brush backgroundBrush = (Brush)Paragraph.Element.GetValue(TextElement.BackgroundProperty);
            _visual.DrawBackgroundAndBorder(backgroundBrush, mbp.BorderBrush, mbp.Border, _rect.FromTextDpi(), IsFirstChunk, IsLastChunk);
 
            // There might be possibility to get empty sub-track, skip the sub-track in such case.
            if (subtrackDetails.cParas != 0) 
            { 
                // Get list of paragraphs
                PTS.FSPARADESCRIPTION [] arrayParaDesc; 
                PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc);

                // Render list of paragraphs
                PtsHelper.UpdateParaListVisuals(PtsContext, _visual.Children, fskupdInherited, arrayParaDesc); 
            }
            else 
            { 
                _visual.Children.Clear();
            } 
        }

        /// 
        /// Updates the viewport for this para 
        /// 
        ///  
        /// Fsrect with viewport info 
        /// 
        ///  
        /// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails,
        ///            and PtsHelper.ParaListFromSubtrack.
        /// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet
        ///        which ensures that partial trust code won't be able to set it to a random value. 
        ///        The subtrackDetails parameter passed to other methods is generated securely in this function.
        ///  
        [SecurityCritical, SecurityTreatAsSafe] 
        internal override void UpdateViewport(ref PTS.FSRECT viewport)
        { 
            // Query paragraph details
            PTS.FSSUBTRACKDETAILS subtrackDetails;
            PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails));
 
            // There might be possibility to get empty sub-track, skip the sub-track in such case.
            if (subtrackDetails.cParas != 0) 
            { 
                // Get list of paragraphs
                PTS.FSPARADESCRIPTION [] arrayParaDesc; 
                PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc);

                // Render list of paragraphs
                PtsHelper.UpdateViewportParaList(PtsContext, arrayParaDesc, ref viewport); 
            }
        } 
 
        /// 
        /// Create and return paragraph result representing this paragraph. 
        /// 
        internal override ParagraphResult CreateParagraphResult()
        {
            /* 
            // Query paragraph details
            PTS.FSSUBTRACKDETAILS subtrackDetails; 
            PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails)); 

            // If there is just one paragraph, do not create container. Return just this paragraph. 
            if (subtrackDetails.cParas == 1)
            {
                // Get list of paragraphs
                PTS.FSPARADESCRIPTION [] arrayParaDesc; 
                PtsHelper.ParaListFromSubtrack(_paraHandle.Value, ref subtrackDetails, out arrayParaDesc);
 
                BaseParaClient paraClient = PtsContext.HandleToObject(arrayParaDesc[0].pfsparaclient) as BaseParaClient; 
                PTS.ValidateHandle(paraClient);
                return paraClient.CreateParagraphResult(); 
            }
            */
            return new ContainerParagraphResult(this);
        } 

        ///  
        /// Return TextContentRange for the content of the paragraph. 
        /// 
        ///  
        /// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails
        /// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet
        ///        which ensures that partial trust code won't be able to set it to a random value.
        ///        The subtrackDetails parameter passed to other methods is generated securely in this function. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal override TextContentRange GetTextContentRange() 
        {
            TextElement elementOwner = this.Paragraph.Element as TextElement; 
            TextContentRange textContentRange;
            BaseParaClient paraClient;
            PTS.FSSUBTRACKDETAILS subtrackDetails;
            PTS.FSPARADESCRIPTION[] arrayParaDesc; 

            Invariant.Assert(elementOwner != null, "Expecting TextElement as owner of ContainerParagraph."); 
 
            // Query paragraph details
            PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails)); 

            // If container is empty, return range for the entire element.
            // If the beginning and the end of content of the paragraph is
            // part of this ParaClient, return range for the entire element. 
            // Otherwise combine ranges from all nested paragraphs.
            if (subtrackDetails.cParas == 0 || (_isFirstChunk && _isLastChunk)) 
            { 
                textContentRange = TextContainerHelper.GetTextContentRangeForTextElement(elementOwner);
            } 
            else
            {
                PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc);
 
                // Merge TextContentRanges for all paragraphs
                textContentRange = new TextContentRange(); 
                for (int i = 0; i < arrayParaDesc.Length; i++) 
                {
                    paraClient = Paragraph.StructuralCache.PtsContext.HandleToObject(arrayParaDesc[i].pfsparaclient) as BaseParaClient; 
                    PTS.ValidateHandle(paraClient);
                    textContentRange.Merge(paraClient.GetTextContentRange());
                }
 
                // If the first paragraph is the first paragraph in the container and it is the first chunk,
                // include start position of this element. 
                if (_isFirstChunk) 
                {
                    textContentRange.Merge(TextContainerHelper.GetTextContentRangeForTextElementEdge( 
                        elementOwner, ElementEdge.BeforeStart));
                }

                // If the last paragraph is the last paragraph in the container and it is the last chunk, 
                // include end position of this element.
                if (_isLastChunk) 
                { 
                    textContentRange.Merge(TextContainerHelper.GetTextContentRangeForTextElementEdge(
                        elementOwner, ElementEdge.AfterEnd)); 
                }
            }

            Invariant.Assert(textContentRange != null); 
            return textContentRange;
        } 
 
        /// 
        /// Returns a new colleciton of ParagraphResults for the contained paragraphs. 
        /// 
        /// 
        /// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails
        /// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet 
        ///        which ensures that partial trust code won't be able to set it to a random value.
        ///        The subtrackDetails parameter passed to other methods is generated securely in this function. 
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        internal ReadOnlyCollection GetChildrenParagraphResults(out bool hasTextContent) 
        {
#if TEXTPANELLAYOUTDEBUG
            TextPanelDebug.IncrementCounter("ContainerPara.GetParagraphs", TextPanelDebug.Category.TextView);
#endif 
            // Query paragraph details
            PTS.FSSUBTRACKDETAILS subtrackDetails; 
            PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails)); 

            // hasTextContent is set to true if any of the children paragraphs has text content, not just attached objects 
            hasTextContent = false;

            if (subtrackDetails.cParas == 0)
            { 
                return new ReadOnlyCollection(new List(0));
            } 
 
            // Get list of paragraphs
            PTS.FSPARADESCRIPTION [] arrayParaDesc; 
            PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc);

            List paragraphResults = new List(arrayParaDesc.Length);
            for (int i = 0; i < arrayParaDesc.Length; i++) 
            {
                BaseParaClient paraClient = PtsContext.HandleToObject(arrayParaDesc[i].pfsparaclient) as BaseParaClient; 
                PTS.ValidateHandle(paraClient); 
                ParagraphResult paragraphResult = paraClient.CreateParagraphResult();
                if (paragraphResult.HasTextContent) 
                {
                    hasTextContent = true;
                }
                paragraphResults.Add(paragraphResult); 
            }
            return new ReadOnlyCollection(paragraphResults); 
        } 

        ///  
        /// Update information about first/last chunk.
        /// 
        /// 
        /// True if para is first chunk of paginated content 
        /// 
        ///  
        /// True if para is last chunk of paginated content 
        /// 
        internal void SetChunkInfo(bool isFirstChunk, bool isLastChunk) 
        {
            _isFirstChunk = isFirstChunk;
            _isLastChunk = isLastChunk;
        } 

        ///  
        /// Returns baseline for first text line 
        /// 
        ///  
        /// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails
        /// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet
        ///        which ensures that partial trust code won't be able to set it to a random value.
        ///        The subtrackDetails parameter passed to other methods is generated securely in this function. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal override int GetFirstTextLineBaseline() 
        {
            PTS.FSSUBTRACKDETAILS subtrackDetails; 
            PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails));

            if (subtrackDetails.cParas == 0)
            { 
                return _rect.v;
            } 
 
            // Get list of paragraphs
            PTS.FSPARADESCRIPTION [] arrayParaDesc; 
            PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc);

            BaseParaClient paraClient = PtsContext.HandleToObject(arrayParaDesc[0].pfsparaclient) as BaseParaClient;
            PTS.ValidateHandle(paraClient); 

            return paraClient.GetFirstTextLineBaseline(); 
        } 

        ///  
        /// Returns tight bounding path geometry.
        /// 
        internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition, Rect visibleRect)
        { 
            bool hasTextContent;
            ReadOnlyCollection paragraphs = GetChildrenParagraphResults(out hasTextContent); 
            Invariant.Assert(paragraphs != null, "Paragraph collection is null."); 

            if (paragraphs.Count > 0) 
            {
                return (TextDocumentView.GetTightBoundingGeometryFromTextPositionsHelper(paragraphs, startPosition, endPosition, TextDpi.FromTextDpi(_dvrTopSpace), visibleRect));
            }
 
            return null;
        } 
 
        /// 
        /// Is this the first chunk of paginated content. 
        /// 
        internal override bool IsFirstChunk
        {
            get 
            {
                return _isFirstChunk; 
            } 
        }
        private bool _isFirstChunk; 

        /// 
        /// Is this the last chunk of paginated content.
        ///  
        internal override bool IsLastChunk
        { 
            get 
            {
                return _isLastChunk; 
            }
        }
        private bool _isLastChunk;
    } 
}

// 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.
//
// File: ContainerParaClient.cs 
//
// Description: ContainerParaClient is responsible for handling display 
//              related data of paragraph containers. 
//
// History: 
//  05/05/2003 : grzegorz - moving from Avalon branch.
//
//---------------------------------------------------------------------------
 
using System;
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.Collections;
using System.Diagnostics; 
using System.Security;
using System.Windows;
using System.Windows.Media;
using System.Windows.Documents; 
using MS.Internal.Documents;
using MS.Internal.Text; 
 
using MS.Internal.PtsHost.UnsafeNativeMethods;
 
namespace MS.Internal.PtsHost
{
    /// 
    /// ContainerParaClient is responsible for handling display related data 
    /// of paragraph containers.
    ///  
    internal class ContainerParaClient : BaseParaClient 
    {
        ///  
        /// Constructor.
        /// 
        /// 
        /// Paragraph associated with this object. 
        /// 
        internal ContainerParaClient(ContainerParagraph paragraph) : base(paragraph) 
        { 
        }
 
        /// 
        /// Arrange paragraph.
        /// 
        ///  
        /// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails,
        ///            and some PtsHelper functions 
        /// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet 
        ///        which ensures that partial trust code won't be able to set it to a random value.
        ///        The subtrackDetails parameter passed to other methods is generated securely in this function. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        protected override void OnArrange()
        { 
            base.OnArrange();
 
            // Query paragraph details 
            PTS.FSSUBTRACKDETAILS subtrackDetails;
            PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails)); 

            // Adjust rectangle and offset to take into account MBPs
            MbpInfo mbp = MbpInfo.FromElement(Paragraph.Element);
 
            if(ParentFlowDirection != PageFlowDirection)
            { 
                mbp.MirrorMargin(); 
            }
 
            _rect.u += mbp.MarginLeft;
            _rect.du -= mbp.MarginLeft + mbp.MarginRight;

            _rect.du = Math.Max(TextDpi.ToTextDpi(TextDpi.MinWidth), _rect.du); 
            _rect.dv = Math.Max(TextDpi.ToTextDpi(TextDpi.MinWidth), _rect.dv);
 
            uint fswdirSubtrack = PTS.FlowDirectionToFswdir(_flowDirection); 

            // There is possibility to get empty track. 
            if (subtrackDetails.cParas != 0)
            {

                // Get list of paragraphs 
                PTS.FSPARADESCRIPTION [] arrayParaDesc;
                PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc); 
 
                PtsHelper.ArrangeParaList(PtsContext, subtrackDetails.fsrc, arrayParaDesc, fswdirSubtrack);
            } 
        }

        /// 
        /// Hit tests to the correct IInputElement within the paragraph 
        /// that the mouse is over.
        ///  
        ///  
        /// Point which gives location of Hit test
        ///  
        /// 
        /// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails,
        /// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet
        ///        which ensures that partial trust code won't be able to set it to a random value. 
        ///        The subtrackDetails parameter passed to other methods is generated securely in this function.
        ///  
        [SecurityCritical, SecurityTreatAsSafe] 
        internal override IInputElement InputHitTest(PTS.FSPOINT pt)
        { 
            IInputElement ie = null;

            // Query paragraph details
            PTS.FSSUBTRACKDETAILS subtrackDetails; 
            PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails));
 
            // Hittest subtrack content. 

            // There might be possibility to get empty sub-track, skip the sub-track 
            // in such case.
            if (subtrackDetails.cParas != 0)
            {
                // Get list of paragraphs 
                PTS.FSPARADESCRIPTION [] arrayParaDesc;
                PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc); 
 
                // Render list of paragraphs
                ie = PtsHelper.InputHitTestParaList(PtsContext, pt, ref subtrackDetails.fsrc, arrayParaDesc); 
            }

            // If nothing is hit, return the owner of the paragraph.
            if (ie == null && _rect.Contains(pt)) 
            {
                ie = Paragraph.Element as IInputElement; 
            } 

            return ie; 
        }

        /// 
        /// Returns ArrayList of rectangles for the given ContentElement e if 
        /// e lies in this client. Otherwise returns empty list.
        ///  
        ///  
        /// ContentElement for which rectangles are needed
        ///  
        /// 
        /// Int representing start offset of e.
        /// 
        ///  
        /// int representing number of positions occupied by e.
        ///  
        ///  
        /// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails,
        /// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet 
        ///        which ensures that partial trust code won't be able to set it to a random value.
        ///        The subtrackDetails parameter passed to other methods is generated securely in this function.
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal override List GetRectangles(ContentElement e, int start, int length)
        { 
            List rectangles = new List(); 

            if (this.Paragraph.Element as ContentElement == e) 
            {
                // We have found the element. Return rectangles for this paragraph.
                GetRectanglesForParagraphElement(out rectangles);
            } 
            else
            { 
                // Element not found as Paragraph.Element. Look inside 

                // Query paragraph details 
                PTS.FSSUBTRACKDETAILS subtrackDetails;
                PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails));

                // There might be possibility to get empty sub-track, skip the sub-track 
                // in such case.
                if (subtrackDetails.cParas != 0) 
                { 
                    // Get list of paragraphs
                    // No changes to offset, since there are no subpages generated, only lists of paragraphs 
                    PTS.FSPARADESCRIPTION[] arrayParaDesc;
                    PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc);

                    // Render list of paragraphs 
                    rectangles = PtsHelper.GetRectanglesInParaList(PtsContext, e, start, length, arrayParaDesc);
                } 
                else 
                {
                    rectangles = new List(); 
                }
            }

            // Rectangles must be non-null 
            Invariant.Assert(rectangles != null);
            return rectangles; 
        } 

        ///  
        /// Validate visual node associated with paragraph.
        /// 
        /// 
        /// Inherited update info 
        /// 
        ///  
        /// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails, 
        /// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet
        ///        which ensures that partial trust code won't be able to set it to a random value. 
        ///        The subtrackDetails parameter passed to other methods is generated securely in this function.
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        internal override void ValidateVisual(PTS.FSKUPDATE fskupdInherited) 
        {
            // Query paragraph details 
            PTS.FSSUBTRACKDETAILS subtrackDetails; 
            PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails));
 
            // Draw border and background info.

            // Adjust rectangle and offset to take into account MBPs
            MbpInfo mbp = MbpInfo.FromElement(Paragraph.Element); 

            if(ThisFlowDirection != PageFlowDirection) 
            { 
                mbp.MirrorBP();
            } 

            Brush backgroundBrush = (Brush)Paragraph.Element.GetValue(TextElement.BackgroundProperty);
            _visual.DrawBackgroundAndBorder(backgroundBrush, mbp.BorderBrush, mbp.Border, _rect.FromTextDpi(), IsFirstChunk, IsLastChunk);
 
            // There might be possibility to get empty sub-track, skip the sub-track in such case.
            if (subtrackDetails.cParas != 0) 
            { 
                // Get list of paragraphs
                PTS.FSPARADESCRIPTION [] arrayParaDesc; 
                PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc);

                // Render list of paragraphs
                PtsHelper.UpdateParaListVisuals(PtsContext, _visual.Children, fskupdInherited, arrayParaDesc); 
            }
            else 
            { 
                _visual.Children.Clear();
            } 
        }

        /// 
        /// Updates the viewport for this para 
        /// 
        ///  
        /// Fsrect with viewport info 
        /// 
        ///  
        /// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails,
        ///            and PtsHelper.ParaListFromSubtrack.
        /// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet
        ///        which ensures that partial trust code won't be able to set it to a random value. 
        ///        The subtrackDetails parameter passed to other methods is generated securely in this function.
        ///  
        [SecurityCritical, SecurityTreatAsSafe] 
        internal override void UpdateViewport(ref PTS.FSRECT viewport)
        { 
            // Query paragraph details
            PTS.FSSUBTRACKDETAILS subtrackDetails;
            PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails));
 
            // There might be possibility to get empty sub-track, skip the sub-track in such case.
            if (subtrackDetails.cParas != 0) 
            { 
                // Get list of paragraphs
                PTS.FSPARADESCRIPTION [] arrayParaDesc; 
                PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc);

                // Render list of paragraphs
                PtsHelper.UpdateViewportParaList(PtsContext, arrayParaDesc, ref viewport); 
            }
        } 
 
        /// 
        /// Create and return paragraph result representing this paragraph. 
        /// 
        internal override ParagraphResult CreateParagraphResult()
        {
            /* 
            // Query paragraph details
            PTS.FSSUBTRACKDETAILS subtrackDetails; 
            PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails)); 

            // If there is just one paragraph, do not create container. Return just this paragraph. 
            if (subtrackDetails.cParas == 1)
            {
                // Get list of paragraphs
                PTS.FSPARADESCRIPTION [] arrayParaDesc; 
                PtsHelper.ParaListFromSubtrack(_paraHandle.Value, ref subtrackDetails, out arrayParaDesc);
 
                BaseParaClient paraClient = PtsContext.HandleToObject(arrayParaDesc[0].pfsparaclient) as BaseParaClient; 
                PTS.ValidateHandle(paraClient);
                return paraClient.CreateParagraphResult(); 
            }
            */
            return new ContainerParagraphResult(this);
        } 

        ///  
        /// Return TextContentRange for the content of the paragraph. 
        /// 
        ///  
        /// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails
        /// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet
        ///        which ensures that partial trust code won't be able to set it to a random value.
        ///        The subtrackDetails parameter passed to other methods is generated securely in this function. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal override TextContentRange GetTextContentRange() 
        {
            TextElement elementOwner = this.Paragraph.Element as TextElement; 
            TextContentRange textContentRange;
            BaseParaClient paraClient;
            PTS.FSSUBTRACKDETAILS subtrackDetails;
            PTS.FSPARADESCRIPTION[] arrayParaDesc; 

            Invariant.Assert(elementOwner != null, "Expecting TextElement as owner of ContainerParagraph."); 
 
            // Query paragraph details
            PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails)); 

            // If container is empty, return range for the entire element.
            // If the beginning and the end of content of the paragraph is
            // part of this ParaClient, return range for the entire element. 
            // Otherwise combine ranges from all nested paragraphs.
            if (subtrackDetails.cParas == 0 || (_isFirstChunk && _isLastChunk)) 
            { 
                textContentRange = TextContainerHelper.GetTextContentRangeForTextElement(elementOwner);
            } 
            else
            {
                PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc);
 
                // Merge TextContentRanges for all paragraphs
                textContentRange = new TextContentRange(); 
                for (int i = 0; i < arrayParaDesc.Length; i++) 
                {
                    paraClient = Paragraph.StructuralCache.PtsContext.HandleToObject(arrayParaDesc[i].pfsparaclient) as BaseParaClient; 
                    PTS.ValidateHandle(paraClient);
                    textContentRange.Merge(paraClient.GetTextContentRange());
                }
 
                // If the first paragraph is the first paragraph in the container and it is the first chunk,
                // include start position of this element. 
                if (_isFirstChunk) 
                {
                    textContentRange.Merge(TextContainerHelper.GetTextContentRangeForTextElementEdge( 
                        elementOwner, ElementEdge.BeforeStart));
                }

                // If the last paragraph is the last paragraph in the container and it is the last chunk, 
                // include end position of this element.
                if (_isLastChunk) 
                { 
                    textContentRange.Merge(TextContainerHelper.GetTextContentRangeForTextElementEdge(
                        elementOwner, ElementEdge.AfterEnd)); 
                }
            }

            Invariant.Assert(textContentRange != null); 
            return textContentRange;
        } 
 
        /// 
        /// Returns a new colleciton of ParagraphResults for the contained paragraphs. 
        /// 
        /// 
        /// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails
        /// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet 
        ///        which ensures that partial trust code won't be able to set it to a random value.
        ///        The subtrackDetails parameter passed to other methods is generated securely in this function. 
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        internal ReadOnlyCollection GetChildrenParagraphResults(out bool hasTextContent) 
        {
#if TEXTPANELLAYOUTDEBUG
            TextPanelDebug.IncrementCounter("ContainerPara.GetParagraphs", TextPanelDebug.Category.TextView);
#endif 
            // Query paragraph details
            PTS.FSSUBTRACKDETAILS subtrackDetails; 
            PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails)); 

            // hasTextContent is set to true if any of the children paragraphs has text content, not just attached objects 
            hasTextContent = false;

            if (subtrackDetails.cParas == 0)
            { 
                return new ReadOnlyCollection(new List(0));
            } 
 
            // Get list of paragraphs
            PTS.FSPARADESCRIPTION [] arrayParaDesc; 
            PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc);

            List paragraphResults = new List(arrayParaDesc.Length);
            for (int i = 0; i < arrayParaDesc.Length; i++) 
            {
                BaseParaClient paraClient = PtsContext.HandleToObject(arrayParaDesc[i].pfsparaclient) as BaseParaClient; 
                PTS.ValidateHandle(paraClient); 
                ParagraphResult paragraphResult = paraClient.CreateParagraphResult();
                if (paragraphResult.HasTextContent) 
                {
                    hasTextContent = true;
                }
                paragraphResults.Add(paragraphResult); 
            }
            return new ReadOnlyCollection(paragraphResults); 
        } 

        ///  
        /// Update information about first/last chunk.
        /// 
        /// 
        /// True if para is first chunk of paginated content 
        /// 
        ///  
        /// True if para is last chunk of paginated content 
        /// 
        internal void SetChunkInfo(bool isFirstChunk, bool isLastChunk) 
        {
            _isFirstChunk = isFirstChunk;
            _isLastChunk = isLastChunk;
        } 

        ///  
        /// Returns baseline for first text line 
        /// 
        ///  
        /// Critical - as this calls Critical functions PTS.FsQuerySubtrackDetails
        /// Safe - The IntPtr parameters passed to PTS.FsQuerySubtrackDetails are SecurityCriticalDataForSet
        ///        which ensures that partial trust code won't be able to set it to a random value.
        ///        The subtrackDetails parameter passed to other methods is generated securely in this function. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal override int GetFirstTextLineBaseline() 
        {
            PTS.FSSUBTRACKDETAILS subtrackDetails; 
            PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails));

            if (subtrackDetails.cParas == 0)
            { 
                return _rect.v;
            } 
 
            // Get list of paragraphs
            PTS.FSPARADESCRIPTION [] arrayParaDesc; 
            PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc);

            BaseParaClient paraClient = PtsContext.HandleToObject(arrayParaDesc[0].pfsparaclient) as BaseParaClient;
            PTS.ValidateHandle(paraClient); 

            return paraClient.GetFirstTextLineBaseline(); 
        } 

        ///  
        /// Returns tight bounding path geometry.
        /// 
        internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition, Rect visibleRect)
        { 
            bool hasTextContent;
            ReadOnlyCollection paragraphs = GetChildrenParagraphResults(out hasTextContent); 
            Invariant.Assert(paragraphs != null, "Paragraph collection is null."); 

            if (paragraphs.Count > 0) 
            {
                return (TextDocumentView.GetTightBoundingGeometryFromTextPositionsHelper(paragraphs, startPosition, endPosition, TextDpi.FromTextDpi(_dvrTopSpace), visibleRect));
            }
 
            return null;
        } 
 
        /// 
        /// Is this the first chunk of paginated content. 
        /// 
        internal override bool IsFirstChunk
        {
            get 
            {
                return _isFirstChunk; 
            } 
        }
        private bool _isFirstChunk; 

        /// 
        /// Is this the last chunk of paginated content.
        ///  
        internal override bool IsLastChunk
        { 
            get 
            {
                return _isLastChunk; 
            }
        }
        private bool _isLastChunk;
    } 
}

// 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