OptimalTextSource.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / MS / Internal / PtsHost / OptimalTextSource.cs / 1305600 / OptimalTextSource.cs

                             
//----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation.  All rights reserved.
// 
// File: ContainerParagraph.cs
// 
// Description: Text line formatter. 
//
// History: 
//  05/05/2003 : [....] - moving from Avalon branch.
//
//---------------------------------------------------------------------------
#pragma warning disable 1634, 1691  // avoid generating warnings about unknown 
                                    // message numbers and unknown pragmas for PRESharp contol
 
using System; 
using System.Diagnostics;
using System.Collections; 
using System.Collections.Generic;
using System.Globalization;
using System.Security;                  // SecurityCritical
using System.Windows; 
using System.Windows.Controls;
using System.Windows.Documents; 
using System.Windows.Media; 
using System.Windows.Media.TextFormatting;
using MS.Internal.Text; 
using MS.Internal.Documents;

using MS.Internal.PtsHost.UnsafeNativeMethods;
 
namespace MS.Internal.PtsHost
{ 
    ///  
    /// Text line formatter.
    ///  
    /// 
    /// NOTE: All DCPs used during line formatting are related to cpPara.
    /// To get abosolute CP, add cpPara to a dcp value.
    ///  
    internal sealed class OptimalTextSource : LineBase
    { 
        //------------------------------------------------------------------- 
        //
        //  Constructors 
        //
        //-------------------------------------------------------------------

        #region Constructors 

        ///  
        /// Constructor. 
        /// 
        ///  
        /// TextFormatter host
        /// 
        /// 
        /// Character position of paragraph 
        /// 
        ///  
        /// Track width 
        /// 
        ///  
        /// Owner of the line
        /// 
        /// 
        /// Text run cache 
        /// 
        internal OptimalTextSource(TextFormatterHost host, int cpPara, int durTrack, TextParaClient paraClient, TextRunCache runCache) : base(paraClient) 
        { 
            _host = host;
            _durTrack = durTrack; 
            _runCache = runCache;
            _cpPara = cpPara;
        }
 

        ///  
        /// Free all resources associated with the line. Prepare it for reuse. 
        /// 
        public override void Dispose() 
        {
            base.Dispose();
        }
 
        #endregion Constructors
 
 
        // ------------------------------------------------------------------
        // 
        //  TextSource Implementation
        //
        // -----------------------------------------------------------------
 
        #region TextSource Implementation
 
        ///  
        /// Get a text run at specified text source position and return it.
        ///  
        /// 
        /// dcp of position relative to start of line
        /// 
        internal override TextRun GetTextRun(int dcp) 
        {
            TextRun run = null; 
            ITextContainer textContainer = _paraClient.Paragraph.StructuralCache.TextContainer; 
            StaticTextPointer position = textContainer.CreateStaticPointerAtOffset(_cpPara + dcp);
 
            switch (position.GetPointerContext(LogicalDirection.Forward))
            {
                case TextPointerContext.Text:
                    run = HandleText(position); 
                    break;
 
                case TextPointerContext.ElementStart: 
                    run = HandleElementStartEdge(position);
                    break; 

                case TextPointerContext.ElementEnd:
                    run = HandleElementEndEdge(position);
                    break; 

                case TextPointerContext.EmbeddedElement: 
                    run = HandleEmbeddedObject(dcp, position); 
                    break;
 
                case TextPointerContext.None:
                    run = new ParagraphBreakRun(_syntheticCharacterLength, PTS.FSFLRES.fsflrEndOfParagraph);
                    break;
            } 
            Invariant.Assert(run != null, "TextRun has not been created.");
            Invariant.Assert(run.Length > 0, "TextRun has to have positive length."); 
 
            return run;
        } 

        /// 
        /// Get text immediately before specified text source position. Return CharacterBufferRange
        /// containing this text. 
        /// 
        ///  
        /// dcp of position relative to start of line 
        /// 
        internal override TextSpan GetPrecedingText(int dcp) 
        {
            // Parameter validation
            Invariant.Assert(dcp >= 0);
 
            int nonTextLength = 0;
            CharacterBufferRange precedingText = CharacterBufferRange.Empty; 
            CultureInfo culture = null; 

            if (dcp > 0) 
            {
                // Create TextPointer at dcp, and pointer at paragraph start to compare
                ITextPointer startPosition = TextContainerHelper.GetTextPointerFromCP(_paraClient.Paragraph.StructuralCache.TextContainer, _cpPara, LogicalDirection.Forward);
                ITextPointer position = TextContainerHelper.GetTextPointerFromCP(_paraClient.Paragraph.StructuralCache.TextContainer, _cpPara + dcp, LogicalDirection.Forward); 

                // Move backward until we find a position at the end of a text run, or reach start of TextContainer 
                while (position.GetPointerContext(LogicalDirection.Backward) != TextPointerContext.Text && 
                       position.CompareTo(startPosition) != 0)
                { 
                    position.MoveByOffset(-1);
                    nonTextLength++;
                }
 

                // Return text in run. If it is at start of TextContainer this will return an empty string 
                string precedingTextString = position.GetTextInRun(LogicalDirection.Backward); 
                precedingText = new CharacterBufferRange(precedingTextString, 0, precedingTextString.Length);
 

                StaticTextPointer pointer = position.CreateStaticPointer();
                DependencyObject element = (pointer.Parent != null) ? pointer.Parent : _paraClient.Paragraph.Element;
                culture = DynamicPropertyReader.GetCultureInfo(element); 
            }
 
            return new TextSpan( 
                nonTextLength + precedingText.Length,
                new CultureSpecificCharacterBufferRange(culture, precedingText) 
                );
        }

        ///  
        /// Get Text effect index from text source character index. Return int value of Text effect index.
        ///  
        ///  
        /// dcp of CharacterHit relative to start of line
        ///  
        internal override int GetTextEffectCharacterIndexFromTextSourceCharacterIndex(int dcp)
        {
            // Text effect index is an index relative to the start of the Text Container.
            // To convert a text source index to text effect index, we first convert the dcp into text pointer 
            // and call GetDistance() from the start of the text container.
            ITextPointer position = TextContainerHelper.GetTextPointerFromCP(_paraClient.Paragraph.StructuralCache.TextContainer, _cpPara + dcp, LogicalDirection.Forward); 
            return position.TextContainer.Start.GetOffsetToPosition(position); 
        }
 
        #endregion TextSource Implementation


        internal PTS.FSFLRES GetFormatResultForBreakpoint(int dcp, TextBreakpoint textBreakpoint) 
        {
            int dcpRun = 0; 
            PTS.FSFLRES formatResult = PTS.FSFLRES.fsflrOutOfSpace; 

            foreach (TextSpan textSpan in _runCache.GetTextRunSpans()) 
            {
                TextRun run = textSpan.Value;

 
                if (run != null && ((dcpRun + run.Length) >= (dcp + textBreakpoint.Length)))
                { 
                    if (run is ParagraphBreakRun) 
                    {
                        formatResult = ((ParagraphBreakRun)run).BreakReason; 
                    }
                    else if (run is LineBreakRun)
                    {
                        formatResult = ((LineBreakRun)run).BreakReason; 
                    }
                    break; 
                } 

                dcpRun += textSpan.Length; 
            }

            return formatResult;
        } 

        ///  
        /// Measure child UIElement. 
        /// 
        ///  
        /// Element whose size we are measuring
        /// 
        /// 
        /// Size of the child UIElement 
        /// 
        internal Size MeasureChild(InlineObjectRun inlineObject) 
        { 
            // Always measure at infinity for bottomless, consistent constraint.
            double pageHeight = _paraClient.Paragraph.StructuralCache.CurrentFormatContext.DocumentPageSize.Height; 
            if (!_paraClient.Paragraph.StructuralCache.CurrentFormatContext.FinitePage)
            {
                pageHeight = Double.PositiveInfinity;
            } 

            return inlineObject.UIElementIsland.DoLayout(new Size(TextDpi.FromTextDpi(_durTrack), pageHeight), true, true); 
        } 

 
        /// 
        /// TextFormatter host
        /// 
        private readonly TextFormatterHost _host; 

        private TextRunCache _runCache; 
 
        private int _durTrack;
        private int _cpPara; 
    }
}

#pragma warning enable 1634, 1691 


// 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: ContainerParagraph.cs
// 
// Description: Text line formatter. 
//
// History: 
//  05/05/2003 : [....] - moving from Avalon branch.
//
//---------------------------------------------------------------------------
#pragma warning disable 1634, 1691  // avoid generating warnings about unknown 
                                    // message numbers and unknown pragmas for PRESharp contol
 
using System; 
using System.Diagnostics;
using System.Collections; 
using System.Collections.Generic;
using System.Globalization;
using System.Security;                  // SecurityCritical
using System.Windows; 
using System.Windows.Controls;
using System.Windows.Documents; 
using System.Windows.Media; 
using System.Windows.Media.TextFormatting;
using MS.Internal.Text; 
using MS.Internal.Documents;

using MS.Internal.PtsHost.UnsafeNativeMethods;
 
namespace MS.Internal.PtsHost
{ 
    ///  
    /// Text line formatter.
    ///  
    /// 
    /// NOTE: All DCPs used during line formatting are related to cpPara.
    /// To get abosolute CP, add cpPara to a dcp value.
    ///  
    internal sealed class OptimalTextSource : LineBase
    { 
        //------------------------------------------------------------------- 
        //
        //  Constructors 
        //
        //-------------------------------------------------------------------

        #region Constructors 

        ///  
        /// Constructor. 
        /// 
        ///  
        /// TextFormatter host
        /// 
        /// 
        /// Character position of paragraph 
        /// 
        ///  
        /// Track width 
        /// 
        ///  
        /// Owner of the line
        /// 
        /// 
        /// Text run cache 
        /// 
        internal OptimalTextSource(TextFormatterHost host, int cpPara, int durTrack, TextParaClient paraClient, TextRunCache runCache) : base(paraClient) 
        { 
            _host = host;
            _durTrack = durTrack; 
            _runCache = runCache;
            _cpPara = cpPara;
        }
 

        ///  
        /// Free all resources associated with the line. Prepare it for reuse. 
        /// 
        public override void Dispose() 
        {
            base.Dispose();
        }
 
        #endregion Constructors
 
 
        // ------------------------------------------------------------------
        // 
        //  TextSource Implementation
        //
        // -----------------------------------------------------------------
 
        #region TextSource Implementation
 
        ///  
        /// Get a text run at specified text source position and return it.
        ///  
        /// 
        /// dcp of position relative to start of line
        /// 
        internal override TextRun GetTextRun(int dcp) 
        {
            TextRun run = null; 
            ITextContainer textContainer = _paraClient.Paragraph.StructuralCache.TextContainer; 
            StaticTextPointer position = textContainer.CreateStaticPointerAtOffset(_cpPara + dcp);
 
            switch (position.GetPointerContext(LogicalDirection.Forward))
            {
                case TextPointerContext.Text:
                    run = HandleText(position); 
                    break;
 
                case TextPointerContext.ElementStart: 
                    run = HandleElementStartEdge(position);
                    break; 

                case TextPointerContext.ElementEnd:
                    run = HandleElementEndEdge(position);
                    break; 

                case TextPointerContext.EmbeddedElement: 
                    run = HandleEmbeddedObject(dcp, position); 
                    break;
 
                case TextPointerContext.None:
                    run = new ParagraphBreakRun(_syntheticCharacterLength, PTS.FSFLRES.fsflrEndOfParagraph);
                    break;
            } 
            Invariant.Assert(run != null, "TextRun has not been created.");
            Invariant.Assert(run.Length > 0, "TextRun has to have positive length."); 
 
            return run;
        } 

        /// 
        /// Get text immediately before specified text source position. Return CharacterBufferRange
        /// containing this text. 
        /// 
        ///  
        /// dcp of position relative to start of line 
        /// 
        internal override TextSpan GetPrecedingText(int dcp) 
        {
            // Parameter validation
            Invariant.Assert(dcp >= 0);
 
            int nonTextLength = 0;
            CharacterBufferRange precedingText = CharacterBufferRange.Empty; 
            CultureInfo culture = null; 

            if (dcp > 0) 
            {
                // Create TextPointer at dcp, and pointer at paragraph start to compare
                ITextPointer startPosition = TextContainerHelper.GetTextPointerFromCP(_paraClient.Paragraph.StructuralCache.TextContainer, _cpPara, LogicalDirection.Forward);
                ITextPointer position = TextContainerHelper.GetTextPointerFromCP(_paraClient.Paragraph.StructuralCache.TextContainer, _cpPara + dcp, LogicalDirection.Forward); 

                // Move backward until we find a position at the end of a text run, or reach start of TextContainer 
                while (position.GetPointerContext(LogicalDirection.Backward) != TextPointerContext.Text && 
                       position.CompareTo(startPosition) != 0)
                { 
                    position.MoveByOffset(-1);
                    nonTextLength++;
                }
 

                // Return text in run. If it is at start of TextContainer this will return an empty string 
                string precedingTextString = position.GetTextInRun(LogicalDirection.Backward); 
                precedingText = new CharacterBufferRange(precedingTextString, 0, precedingTextString.Length);
 

                StaticTextPointer pointer = position.CreateStaticPointer();
                DependencyObject element = (pointer.Parent != null) ? pointer.Parent : _paraClient.Paragraph.Element;
                culture = DynamicPropertyReader.GetCultureInfo(element); 
            }
 
            return new TextSpan( 
                nonTextLength + precedingText.Length,
                new CultureSpecificCharacterBufferRange(culture, precedingText) 
                );
        }

        ///  
        /// Get Text effect index from text source character index. Return int value of Text effect index.
        ///  
        ///  
        /// dcp of CharacterHit relative to start of line
        ///  
        internal override int GetTextEffectCharacterIndexFromTextSourceCharacterIndex(int dcp)
        {
            // Text effect index is an index relative to the start of the Text Container.
            // To convert a text source index to text effect index, we first convert the dcp into text pointer 
            // and call GetDistance() from the start of the text container.
            ITextPointer position = TextContainerHelper.GetTextPointerFromCP(_paraClient.Paragraph.StructuralCache.TextContainer, _cpPara + dcp, LogicalDirection.Forward); 
            return position.TextContainer.Start.GetOffsetToPosition(position); 
        }
 
        #endregion TextSource Implementation


        internal PTS.FSFLRES GetFormatResultForBreakpoint(int dcp, TextBreakpoint textBreakpoint) 
        {
            int dcpRun = 0; 
            PTS.FSFLRES formatResult = PTS.FSFLRES.fsflrOutOfSpace; 

            foreach (TextSpan textSpan in _runCache.GetTextRunSpans()) 
            {
                TextRun run = textSpan.Value;

 
                if (run != null && ((dcpRun + run.Length) >= (dcp + textBreakpoint.Length)))
                { 
                    if (run is ParagraphBreakRun) 
                    {
                        formatResult = ((ParagraphBreakRun)run).BreakReason; 
                    }
                    else if (run is LineBreakRun)
                    {
                        formatResult = ((LineBreakRun)run).BreakReason; 
                    }
                    break; 
                } 

                dcpRun += textSpan.Length; 
            }

            return formatResult;
        } 

        ///  
        /// Measure child UIElement. 
        /// 
        ///  
        /// Element whose size we are measuring
        /// 
        /// 
        /// Size of the child UIElement 
        /// 
        internal Size MeasureChild(InlineObjectRun inlineObject) 
        { 
            // Always measure at infinity for bottomless, consistent constraint.
            double pageHeight = _paraClient.Paragraph.StructuralCache.CurrentFormatContext.DocumentPageSize.Height; 
            if (!_paraClient.Paragraph.StructuralCache.CurrentFormatContext.FinitePage)
            {
                pageHeight = Double.PositiveInfinity;
            } 

            return inlineObject.UIElementIsland.DoLayout(new Size(TextDpi.FromTextDpi(_durTrack), pageHeight), true, true); 
        } 

 
        /// 
        /// TextFormatter host
        /// 
        private readonly TextFormatterHost _host; 

        private TextRunCache _runCache; 
 
        private int _durTrack;
        private int _cpPara; 
    }
}

#pragma warning enable 1634, 1691 


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