예제 #1
0
 /// <summary>
 /// Modifies the specified text run properties by invoking the modifier at
 /// the current scope and all containing scopes.
 /// </summary>
 /// <param name="properties">Properties to modify.</param>
 /// <returns>Returns the text run properties after modification.</returns>
 internal TextRunProperties ModifyProperties(TextRunProperties properties)
 {
     for (TextModifierScope scope = this; scope != null; scope = scope._parentScope)
     {
         properties = scope._modifier.ModifyProperties(properties);
     }
     return(properties);
 }
예제 #2
0
        /// <summary>
        /// Performs a deep copy of the stack of TextModifierScope objects.
        /// </summary>
        /// <returns>Returns the top of the new stack.</returns>
        internal TextModifierScope CloneStack()
        {
            TextModifierScope top   = new TextModifierScope(null, _modifier, _cp);
            TextModifierScope scope = top;

            for (TextModifierScope source = _parentScope; source != null; source = source._parentScope)
            {
                scope._parentScope = new TextModifierScope(null, source._modifier, source._cp);
                scope = scope._parentScope;
            }

            return(top);
        }
예제 #3
0
        /// <summary>
        /// Internallly construct the line break
        /// </summary>
        internal TextLineBreak(
            TextModifierScope                   currentScope,
            SecurityCriticalDataForSet<IntPtr>  breakRecord
            )
        {
            _currentScope = currentScope;
            _breakRecord = breakRecord;

            if (breakRecord.Value == IntPtr.Zero)
            {
                // this object does not hold unmanaged resource,
                // remove it from the finalizer queue.
                GC.SuppressFinalize(this);
            }
        }
예제 #4
0
        /// <summary>
        /// Internallly construct the line break
        /// </summary>
        internal TextLineBreak(
            TextModifierScope currentScope,
            SecurityCriticalDataForSet <IntPtr> breakRecord
            )
        {
            _currentScope = currentScope;
            _breakRecord  = breakRecord;

            if (breakRecord.Value == IntPtr.Zero)
            {
                // this object does not hold unmanaged resource,
                // remove it from the finalizer queue.
                GC.SuppressFinalize(this);
            }
        }
예제 #5
0
        /// <summary>
        /// Break a run of text into individually shape items.
        /// Shape items are delimited by
        ///     Change of writing system
        ///     Change of glyph typeface
        /// </summary>
        IList <TextShapeableSymbols> ITextSymbols.GetTextShapeableSymbols(
            GlyphingCache glyphingCache,
            CharacterBufferReference characterBufferReference,
            int length,
            bool rightToLeft,
            bool isRightToLeftParagraph,
            CultureInfo digitCulture,
            TextModifierScope textModifierScope,
            TextFormattingMode textFormattingMode,
            bool isSideways
            )
        {
            if (characterBufferReference.CharacterBuffer == null)
            {
                throw new ArgumentNullException("characterBufferReference.CharacterBuffer");
            }

            int offsetToFirstChar = characterBufferReference.OffsetToFirstChar - _characterBufferReference.OffsetToFirstChar;

            Debug.Assert(characterBufferReference.CharacterBuffer == _characterBufferReference.CharacterBuffer);
            Debug.Assert(offsetToFirstChar >= 0 && offsetToFirstChar < _length);

            if (length < 0 ||
                offsetToFirstChar + length > _length)
            {
                length = _length - offsetToFirstChar;
            }

            // Get the actual text run properties in effect, after invoking any
            // text modifiers that may be in scope.
            TextRunProperties textRunProperties = _textRunProperties;

            if (textModifierScope != null)
            {
                textRunProperties = textModifierScope.ModifyProperties(textRunProperties);
            }

            if (!rightToLeft)
            {
                // Fast loop early out for run with all non-complex characters
                // which can be optimized by not going thru shaping engine.

                int nominalLength;

                if (textRunProperties.Typeface.CheckFastPathNominalGlyphs(
                        new CharacterBufferRange(characterBufferReference, length),
                        textRunProperties.FontRenderingEmSize,
                        (float)textRunProperties.PixelsPerDip,
                        1.0,
                        double.MaxValue, // widthMax
                        true,            // keepAWord
                        digitCulture != null,
                        CultureMapper.GetSpecificCulture(textRunProperties.CultureInfo),
                        textFormattingMode,
                        isSideways,
                        false, //breakOnTabs
                        out nominalLength
                        ) && length == nominalLength)
                {
                    return(new TextShapeableCharacters[]
                    {
                        new TextShapeableCharacters(
                            new CharacterBufferRange(characterBufferReference, nominalLength),
                            textRunProperties,
                            textRunProperties.FontRenderingEmSize,
                            new MS.Internal.Text.TextInterface.ItemProps(),
                            null,   // shapeTypeface (no shaping required)
                            false,  // nullShape,
                            textFormattingMode,
                            isSideways
                            )
                    });
                }
            }

            IList <TextShapeableSymbols> shapeables = new List <TextShapeableSymbols>(2);

            glyphingCache.GetShapeableText(
                textRunProperties.Typeface,
                characterBufferReference,
                length,
                textRunProperties,
                digitCulture,
                isRightToLeftParagraph,
                shapeables,
                this as IShapeableTextCollector,
                textFormattingMode
                );

            return(shapeables);
        }
예제 #6
0
        /// <summary>
        /// Break a run of text into individually shape items.
        /// Shape items are delimited by 
        ///     Change of writing system
        ///     Change of glyph typeface
        /// </summary>
        IList<TextShapeableSymbols> ITextSymbols.GetTextShapeableSymbols(
            GlyphingCache               glyphingCache,
            CharacterBufferReference    characterBufferReference,
            int                         length,
            bool                        rightToLeft,
            bool                        isRightToLeftParagraph,
            CultureInfo                 digitCulture,
            TextModifierScope           textModifierScope,
            TextFormattingMode          textFormattingMode,
            bool                        isSideways
            )
        {
            if (characterBufferReference.CharacterBuffer == null)
            {
                throw new ArgumentNullException("characterBufferReference.CharacterBuffer");
            }
            
            int offsetToFirstChar = characterBufferReference.OffsetToFirstChar - _characterBufferReference.OffsetToFirstChar;

            Debug.Assert(characterBufferReference.CharacterBuffer == _characterBufferReference.CharacterBuffer);
            Debug.Assert(offsetToFirstChar >= 0 && offsetToFirstChar < _length);

            if (    length < 0 
                ||  offsetToFirstChar + length > _length)
            {
                length = _length - offsetToFirstChar;
            }

            // Get the actual text run properties in effect, after invoking any
            // text modifiers that may be in scope.
            TextRunProperties textRunProperties = _textRunProperties;
            if (textModifierScope != null)
            {
                textRunProperties = textModifierScope.ModifyProperties(textRunProperties);
            }

            if (!rightToLeft)
            {
                // Fast loop early out for run with all non-complex characters
                // which can be optimized by not going thru shaping engine.

                int nominalLength;

                if (textRunProperties.Typeface.CheckFastPathNominalGlyphs(
                    new CharacterBufferRange(characterBufferReference, length),
                    textRunProperties.FontRenderingEmSize,
                    1.0,
                    double.MaxValue,    // widthMax
                    true,               // keepAWord
                    digitCulture != null,
                    CultureMapper.GetSpecificCulture(textRunProperties.CultureInfo),
                    textFormattingMode,
                    isSideways,
                    false, //breakOnTabs
                    out nominalLength
                    ) && length == nominalLength)
                {
                    return new TextShapeableCharacters[]
                    {
                        new TextShapeableCharacters(
                            new CharacterBufferRange(characterBufferReference, nominalLength),
                            textRunProperties,
                            textRunProperties.FontRenderingEmSize,                        
                            new MS.Internal.Text.TextInterface.ItemProps(),
                            null,   // shapeTypeface (no shaping required)
                            false,   // nullShape,
                            textFormattingMode,
                            isSideways
                            )
                    };
                }
            }

            IList<TextShapeableSymbols> shapeables = new List<TextShapeableSymbols>(2);

            glyphingCache.GetShapeableText(
                textRunProperties.Typeface,
                characterBufferReference,
                length,
                textRunProperties,
                digitCulture,
                isRightToLeftParagraph,
                shapeables,
                this as IShapeableTextCollector,
                textFormattingMode
                );

            return shapeables;
        }
예제 #7
0
        /// <summary>
        /// Constructing a textrun info
        /// </summary> 
        /// <param name="charBufferRange">characte buffer range for the run</param>
        /// <param name="textRunLength">textrun length</param> 
        /// <param name="offsetToFirstCp">character offset to run first cp</param> 
        /// <param name="textRun">text run</param>
        /// <param name="lsRunType">the internal LS run type </param> 
        /// <param name="charFlags">character attribute flags</param>
        /// <param name="digitCulture">digit culture for the run</param>
        /// <param name="contextualSubstitution">contextual number substitution for the run</param>
        /// <param name="symbolTypeface">if true, indicates a text run in a symbol (i.e., non-Unicode) font</param> 
        /// <param name="modifierScope">The current TextModifier scope for this TextRunInfo</param>
        internal TextRunInfo( 
            CharacterBufferRange charBufferRange, 
            int                  textRunLength,
            int                  offsetToFirstCp, 
            TextRun              textRun,
            Plsrun               lsRunType,
            ushort               charFlags,
            CultureInfo          digitCulture, 
            bool                 contextualSubstitution,
            bool                 symbolTypeface, 
            TextModifierScope    modifierScope 
            )
        { 
            _charBufferRange = charBufferRange;
            _textRunLength = textRunLength;
            _offsetToFirstCp = offsetToFirstCp;
            _textRun = textRun; 
            _plsrun = lsRunType;
            _charFlags = charFlags; 
            _digitCulture = digitCulture; 
            _runFlags = 0;
            _modifierScope = modifierScope; 

            if (contextualSubstitution)
            {
                _runFlags |= (ushort)RunFlags.ContextualSubstitution; 
            }
 
            if (symbolTypeface) 
            {
                _runFlags |= (ushort)RunFlags.IsSymbol; 
            }
        }
예제 #8
0
 /// <summary>
 /// Constructs a new text modification state object.
 /// </summary>
 /// <param name="parentScope">Parent scope, i.e., the previous top of the stack.</param>
 /// <param name="modifier">Text modifier run fetched from the client.</param>
 /// <param name="cp">Text source character index of the run.</param>
 internal TextModifierScope(TextModifierScope parentScope, TextModifier modifier, int cp)
 {
     _parentScope = parentScope;
     _modifier    = modifier;
     _cp          = cp;
 }
예제 #9
0
        /// <summary>
        /// Performs a deep copy of the stack of TextModifierScope objects.
        /// </summary>
        /// <returns>Returns the top of the new stack.</returns>
        internal TextModifierScope CloneStack()
        {
            TextModifierScope top = new TextModifierScope(null, _modifier, _cp);
            TextModifierScope scope = top;

            for (TextModifierScope source = _parentScope; source != null; source = source._parentScope)
            {
                scope._parentScope = new TextModifierScope(null, source._modifier, source._cp);
                scope = scope._parentScope;
            }

            return top;
        }
예제 #10
0
 /// <summary>
 /// Constructs a new text modification state object.
 /// </summary>
 /// <param name="parentScope">Parent scope, i.e., the previous top of the stack.</param>
 /// <param name="modifier">Text modifier run fetched from the client.</param>
 /// <param name="cp">Text source character index of the run.</param>
 internal TextModifierScope(TextModifierScope parentScope, TextModifier modifier, int cp)
 {
     _parentScope = parentScope;
     _modifier = modifier;
     _cp = cp;
 }