TextSpanModifier.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 / Text / TextSpanModifier.cs / 1305600 / TextSpanModifier.cs

                            //------------------------------------------------------------------------ 
//
//  Microsoft Windows Client Platform
//  Copyright (C) Microsoft Corporation, 2001
// 
//  File:      TextSpanModifier.cs
// 
//  Created:   12-5-2004 Niklas Borson (niklasb) 
//             8-4-2005 garyyang Make it an internal implemenation of framework
// 
//-----------------------------------------------------------------------

using System;
using System.Collections; 
using System.Globalization;
using System.Windows; 
using System.Windows.Media; 
using System.Windows.Media.TextFormatting;
 
namespace MS.Internal.Text
{

    ///  
    /// TextModifier that can modify properties of a text span.
    /// It supports modifying TextDecorations and bid embedding levels 
    /// over a span of runs. 
    /// 
    internal class TextSpanModifier : TextModifier 
    {
        private int                      _length;

        private TextDecorationCollection _modifierDecorations; 
        private Brush                    _modifierBrush;
        private FlowDirection            _flowDirection; 
        private bool                     _hasDirectionalEmbedding; 

        ///  
        /// Creates a TextSpanModifier with the specified length and
        /// properties to modify TextDecorations.
        /// Instance created will not affect bidi embedding level.
        ///  
        public TextSpanModifier(int length, TextDecorationCollection textDecorations, Brush foregroundBrush)
        { 
            _length = length; 
            _modifierDecorations = textDecorations;
            _modifierBrush = foregroundBrush; 
        }

        /// 
        /// Creates a TextSpanModifier with the specified length and 
        /// properties. Instance created will modify Bidi embedding level. It will also modify TextDecorations if the
        /// input TextDecorations is not null. 
        ///  
        public TextSpanModifier(int length, TextDecorationCollection textDecorations, Brush foregroundBrush, FlowDirection flowDirection)
            : this (length, textDecorations, foregroundBrush) 
        {
            _hasDirectionalEmbedding = true;
            _flowDirection = flowDirection;
        } 

        ///  
        /// Character length 
        /// 
        public sealed override int Length 
        {
            get { return _length; }
        }
 
        /// 
        /// A set of properties shared by every characters in the run 
        /// It is null for a TextModifier run. 
        /// 
        public sealed override TextRunProperties Properties 
        {
            get { return null; }
        }
 
        /// 
        /// Modifies the properties of a text run. 
        ///  
        /// Properties of a text run or the return value of
        /// ModifyProperties for a nested text modifier. 
        /// Returns the actual text run properties to be used for formatting,
        /// subject to further modification by text modifiers at outer scopes.
        public sealed override TextRunProperties ModifyProperties(TextRunProperties properties)
        { 
            // Get the text decorations applied to the text modifier run. If there are
            // none, we don't change anything. 
            if (properties == null || _modifierDecorations == null || _modifierDecorations.Count == 0) 
                return properties;
 
            // Let brush be the foreground brush for the text modifier run. Any text
            // decorations defined at the text modifier scope that have a null Pen
            // should be drawn using this brush, which means we may need to copy some
            // TextDecoration objects and set the Pen property on the copies. We can 
            // elide this if the same brush is used at both scopes. We shouldn't miss
            // too many optimization opportunities by using the (lower cost) reference 
            // comparison here because in most cases where the brushes are equal it's 
            // because it's an inherited property.
            Brush brush = _modifierBrush; 
            if (object.ReferenceEquals(brush, properties.ForegroundBrush))
            {
                // No need to set the pen property.
                brush = null; 
            }
 
            // We're going to create a merged set of text decorations. 
            TextDecorationCollection mergedDecorations;
 
            // Get the text decorations of the affected run, if any.
            TextDecorationCollection runDecorations = properties.TextDecorations;
            if (runDecorations == null || runDecorations.Count == 0)
            { 
                // Only the text modifier run defines text decorations so
                // we don't need to merge anything. 
                if (brush == null) 
                {
                    // Use the text decorations of the modifier run. 
                    mergedDecorations = _modifierDecorations;
                }
                else
                { 
                    // The foreground brushes differ so copy the text decorations to a
                    // new collection and make sure each has a non-null pen. 
                    mergedDecorations = CopyTextDecorations(_modifierDecorations, brush); 
                }
            } 
            else
            {
                // Add the modifier decorations first because we want text decorations
                // defined at the inner scope (e.g., by the run) to be drawn on top. 
                mergedDecorations = CopyTextDecorations(_modifierDecorations, brush);
 
                // Add the text decorations defined at the inner scope; we never need 
                // to set the pen for these because they should be drawn using the
                // foreground brush. 
                foreach (TextDecoration td in runDecorations)
                {
                    mergedDecorations.Add(td);
                } 
            }
 
            return new MergedTextRunProperties(properties, mergedDecorations); 
        }
 
        public override bool HasDirectionalEmbedding
        {
            get { return _hasDirectionalEmbedding; }
        } 

        public override FlowDirection FlowDirection 
        { 
            get { return _flowDirection; }
        } 

        private TextDecorationCollection CopyTextDecorations(TextDecorationCollection textDecorations, Brush brush)
        {
            TextDecorationCollection result = new TextDecorationCollection(); 
            Pen pen = null;
 
            foreach (TextDecoration td in textDecorations) 
            {
                if (td.Pen == null && brush != null) 
                {
                    if (pen == null)
                        pen = new Pen(brush, 1);
 
                    TextDecoration copy = td.Clone();
                    copy.Pen = pen; 
                    result.Add(copy); 
                }
                else 
                {
                    result.Add(td);
                }
            } 

            return result; 
        } 

        private class MergedTextRunProperties : TextRunProperties 
        {
            TextRunProperties _runProperties;
            TextDecorationCollection _textDecorations;
 
            internal MergedTextRunProperties(
                TextRunProperties runProperties, 
                TextDecorationCollection textDecorations) 
            {
                _runProperties = runProperties; 
                _textDecorations = textDecorations;
            }

            public override Typeface Typeface 
            {
                get { return _runProperties.Typeface; } 
            } 

            public override double FontRenderingEmSize 
            {
                get { return _runProperties.FontRenderingEmSize; }
            }
 
            public override double FontHintingEmSize
            { 
                get { return _runProperties.FontHintingEmSize; } 
            }
 
            public override TextDecorationCollection TextDecorations
            {
                get { return _textDecorations; }
            } 

            public override Brush ForegroundBrush 
            { 
                get { return _runProperties.ForegroundBrush; }
            } 

            public override Brush BackgroundBrush
            {
                get { return _runProperties.BackgroundBrush; } 
            }
 
            public override CultureInfo CultureInfo 
            {
                get { return _runProperties.CultureInfo; } 
            }

            public override TextEffectCollection TextEffects
            { 
                get { return _runProperties.TextEffects; }
            } 
 
            public override BaselineAlignment BaselineAlignment
            { 
                get { return _runProperties.BaselineAlignment; }
            }

            public override TextRunTypographyProperties TypographyProperties 
            {
                get { return _runProperties.TypographyProperties; } 
            } 

            public override NumberSubstitution NumberSubstitution 
            {
                get { return _runProperties.NumberSubstitution; }
            }
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------ 
//
//  Microsoft Windows Client Platform
//  Copyright (C) Microsoft Corporation, 2001
// 
//  File:      TextSpanModifier.cs
// 
//  Created:   12-5-2004 Niklas Borson (niklasb) 
//             8-4-2005 garyyang Make it an internal implemenation of framework
// 
//-----------------------------------------------------------------------

using System;
using System.Collections; 
using System.Globalization;
using System.Windows; 
using System.Windows.Media; 
using System.Windows.Media.TextFormatting;
 
namespace MS.Internal.Text
{

    ///  
    /// TextModifier that can modify properties of a text span.
    /// It supports modifying TextDecorations and bid embedding levels 
    /// over a span of runs. 
    /// 
    internal class TextSpanModifier : TextModifier 
    {
        private int                      _length;

        private TextDecorationCollection _modifierDecorations; 
        private Brush                    _modifierBrush;
        private FlowDirection            _flowDirection; 
        private bool                     _hasDirectionalEmbedding; 

        ///  
        /// Creates a TextSpanModifier with the specified length and
        /// properties to modify TextDecorations.
        /// Instance created will not affect bidi embedding level.
        ///  
        public TextSpanModifier(int length, TextDecorationCollection textDecorations, Brush foregroundBrush)
        { 
            _length = length; 
            _modifierDecorations = textDecorations;
            _modifierBrush = foregroundBrush; 
        }

        /// 
        /// Creates a TextSpanModifier with the specified length and 
        /// properties. Instance created will modify Bidi embedding level. It will also modify TextDecorations if the
        /// input TextDecorations is not null. 
        ///  
        public TextSpanModifier(int length, TextDecorationCollection textDecorations, Brush foregroundBrush, FlowDirection flowDirection)
            : this (length, textDecorations, foregroundBrush) 
        {
            _hasDirectionalEmbedding = true;
            _flowDirection = flowDirection;
        } 

        ///  
        /// Character length 
        /// 
        public sealed override int Length 
        {
            get { return _length; }
        }
 
        /// 
        /// A set of properties shared by every characters in the run 
        /// It is null for a TextModifier run. 
        /// 
        public sealed override TextRunProperties Properties 
        {
            get { return null; }
        }
 
        /// 
        /// Modifies the properties of a text run. 
        ///  
        /// Properties of a text run or the return value of
        /// ModifyProperties for a nested text modifier. 
        /// Returns the actual text run properties to be used for formatting,
        /// subject to further modification by text modifiers at outer scopes.
        public sealed override TextRunProperties ModifyProperties(TextRunProperties properties)
        { 
            // Get the text decorations applied to the text modifier run. If there are
            // none, we don't change anything. 
            if (properties == null || _modifierDecorations == null || _modifierDecorations.Count == 0) 
                return properties;
 
            // Let brush be the foreground brush for the text modifier run. Any text
            // decorations defined at the text modifier scope that have a null Pen
            // should be drawn using this brush, which means we may need to copy some
            // TextDecoration objects and set the Pen property on the copies. We can 
            // elide this if the same brush is used at both scopes. We shouldn't miss
            // too many optimization opportunities by using the (lower cost) reference 
            // comparison here because in most cases where the brushes are equal it's 
            // because it's an inherited property.
            Brush brush = _modifierBrush; 
            if (object.ReferenceEquals(brush, properties.ForegroundBrush))
            {
                // No need to set the pen property.
                brush = null; 
            }
 
            // We're going to create a merged set of text decorations. 
            TextDecorationCollection mergedDecorations;
 
            // Get the text decorations of the affected run, if any.
            TextDecorationCollection runDecorations = properties.TextDecorations;
            if (runDecorations == null || runDecorations.Count == 0)
            { 
                // Only the text modifier run defines text decorations so
                // we don't need to merge anything. 
                if (brush == null) 
                {
                    // Use the text decorations of the modifier run. 
                    mergedDecorations = _modifierDecorations;
                }
                else
                { 
                    // The foreground brushes differ so copy the text decorations to a
                    // new collection and make sure each has a non-null pen. 
                    mergedDecorations = CopyTextDecorations(_modifierDecorations, brush); 
                }
            } 
            else
            {
                // Add the modifier decorations first because we want text decorations
                // defined at the inner scope (e.g., by the run) to be drawn on top. 
                mergedDecorations = CopyTextDecorations(_modifierDecorations, brush);
 
                // Add the text decorations defined at the inner scope; we never need 
                // to set the pen for these because they should be drawn using the
                // foreground brush. 
                foreach (TextDecoration td in runDecorations)
                {
                    mergedDecorations.Add(td);
                } 
            }
 
            return new MergedTextRunProperties(properties, mergedDecorations); 
        }
 
        public override bool HasDirectionalEmbedding
        {
            get { return _hasDirectionalEmbedding; }
        } 

        public override FlowDirection FlowDirection 
        { 
            get { return _flowDirection; }
        } 

        private TextDecorationCollection CopyTextDecorations(TextDecorationCollection textDecorations, Brush brush)
        {
            TextDecorationCollection result = new TextDecorationCollection(); 
            Pen pen = null;
 
            foreach (TextDecoration td in textDecorations) 
            {
                if (td.Pen == null && brush != null) 
                {
                    if (pen == null)
                        pen = new Pen(brush, 1);
 
                    TextDecoration copy = td.Clone();
                    copy.Pen = pen; 
                    result.Add(copy); 
                }
                else 
                {
                    result.Add(td);
                }
            } 

            return result; 
        } 

        private class MergedTextRunProperties : TextRunProperties 
        {
            TextRunProperties _runProperties;
            TextDecorationCollection _textDecorations;
 
            internal MergedTextRunProperties(
                TextRunProperties runProperties, 
                TextDecorationCollection textDecorations) 
            {
                _runProperties = runProperties; 
                _textDecorations = textDecorations;
            }

            public override Typeface Typeface 
            {
                get { return _runProperties.Typeface; } 
            } 

            public override double FontRenderingEmSize 
            {
                get { return _runProperties.FontRenderingEmSize; }
            }
 
            public override double FontHintingEmSize
            { 
                get { return _runProperties.FontHintingEmSize; } 
            }
 
            public override TextDecorationCollection TextDecorations
            {
                get { return _textDecorations; }
            } 

            public override Brush ForegroundBrush 
            { 
                get { return _runProperties.ForegroundBrush; }
            } 

            public override Brush BackgroundBrush
            {
                get { return _runProperties.BackgroundBrush; } 
            }
 
            public override CultureInfo CultureInfo 
            {
                get { return _runProperties.CultureInfo; } 
            }

            public override TextEffectCollection TextEffects
            { 
                get { return _runProperties.TextEffects; }
            } 
 
            public override BaselineAlignment BaselineAlignment
            { 
                get { return _runProperties.BaselineAlignment; }
            }

            public override TextRunTypographyProperties TypographyProperties 
            {
                get { return _runProperties.TypographyProperties; } 
            } 

            public override NumberSubstitution NumberSubstitution 
            {
                get { return _runProperties.NumberSubstitution; }
            }
        } 
    }
} 

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