示例#1
0
        private IList<TextEffect>       _textEffects;               // TextEffects that should be applied for this run
 

        /// <summary>
        /// Construct an lsrun
        /// </summary> 
        internal LSRun(
            TextRunInfo             runInfo, 
            IList<TextEffect>       textEffects, 
            Plsrun                  type,
            int                     offsetToFirstCp, 
            int                     textRunLength,
            int                     emSize,
            ushort                  charFlags,
            CharacterBufferRange    charBufferRange, 
            TextShapeableSymbols    shapeable,
            double                  realToIdeal, 
            byte                    bidiLevel 
            ) :
            this( 
                runInfo,
                textEffects,
                type,
                offsetToFirstCp, 
                textRunLength,
                emSize, 
                charFlags, 
                charBufferRange,
                (shapeable != null ? (int)Math.Round(shapeable.Baseline * realToIdeal) : 0), 
                (shapeable != null ? (int)Math.Round(shapeable.Height * realToIdeal) : 0),
                shapeable,
                bidiLevel
                ) 
        {}
示例#2
0
            private int GetShapeableSymbolsWidth(TextShapeableSymbols textRun)
            {
                int result      = 0;
                int text_length = textRun.Length;

                int[]           advance_widths = new int[text_length];
                GCHandle        pin_handle;
                CharacterBuffer char_buf = textRun.CharacterBufferReference.CharacterBuffer;

                unsafe
                {
                    IntPtr run_characters = char_buf.PinAndGetCharacterPointer(textRun.CharacterBufferReference.OffsetToFirstChar, out pin_handle);
                    try
                    {
                        fixed(int *widths_ptr = advance_widths)
                        {
                            textRun.GetAdvanceWidthsUnshaped((char *)run_characters.ToPointer(), text_length, TextFormatterImp.ToIdeal, widths_ptr);
                        }
                    }
                    finally
                    {
                        char_buf.UnpinCharacterPointer(pin_handle);
                    }
                }

                for (int i = 0; i < text_length; i++)
                {
                    result += advance_widths[i];
                }

                return(result);
            }
示例#3
0
            /// <summary>
            /// Construct a full description of glyph data
            /// </summary>
            internal Glyphs(
                TextShapeableSymbols shapeable,
                char[]                   charArray,
                int[]                   glyphAdvances,
                ushort[]                 clusterMap,
                ushort[]                 glyphIndices,
                GlyphOffset[]            glyphOffsets,
                double scalingFactor
                )
            {
                _shapeable = shapeable;
                _charArray = charArray;

                _glyphAdvances = new double[glyphAdvances.Length];

                double ToReal = 1.0 / scalingFactor;

                for (int i = 0; i < glyphAdvances.Length; i++)
                {
                    _unscaledWidth   += glyphAdvances[i];
                    _glyphAdvances[i] = glyphAdvances[i] * ToReal;
                    _width           += _glyphAdvances[i];
                }

                if (glyphIndices != null)
                {
                    _clusterMap = clusterMap;

                    if (glyphOffsets != null)
                    {
                        _glyphOffsets = new PartialArray <Point>(new Point[glyphOffsets.Length]);

                        for (int i = 0; i < glyphOffsets.Length; i++)
                        {
                            _glyphOffsets[i] = new Point(
                                glyphOffsets[i].du * ToReal,
                                glyphOffsets[i].dv * ToReal
                                );
                        }
                    }

                    Debug.Assert(glyphAdvances.Length <= glyphIndices.Length);

                    if (glyphAdvances.Length != glyphIndices.Length)
                    {
                        _glyphIndices = new ushort[glyphAdvances.Length];

                        for (int i = 0; i < glyphAdvances.Length; i++)
                        {
                            _glyphIndices[i] = glyphIndices[i];
                        }
                    }
                    else
                    {
                        _glyphIndices = glyphIndices;
                    }
                }
            }
示例#4
0
 /// <summary>
 /// Construct a nominal description of glyph data
 /// </summary>
 internal Glyphs(
     TextShapeableSymbols shapeable,
     char[]                  charArray,
     int[]                  nominalAdvances,
     double scalingFactor
     ) :
     this(
         shapeable,
         charArray,
         nominalAdvances,
         null,   // clusterMap
         null,   // glyphIndices
         null,   // glyphOffsets
         scalingFactor
         )
 {
 }
        /// <summary>
        /// Return value indicates whether two runs can shape together
        /// </summary>
        internal sealed override bool CanShapeTogether(
            TextShapeableSymbols shapeable
            )
        {
            TextShapeableCharacters charShape = shapeable as TextShapeableCharacters;

            if (charShape == null)
            {
                return(false);
            }

            return
                (_shapeTypeface.Equals(charShape._shapeTypeface)
                 // Extended characters need to be shaped by surrogate shaper. They cannot be shaped together with non-exteneded characters.
                 && (_textItem.HasExtendedCharacter) == (charShape._textItem.HasExtendedCharacter) &&
                 _emSize == charShape._emSize &&
                 (
                     _properties.CultureInfo == null ?
                     charShape._properties.CultureInfo == null
                      : _properties.CultureInfo.Equals(charShape._properties.CultureInfo)
                 ) &&
                 _nullShape == charShape._nullShape &&
                 (_textItem.CanShapeTogether(charShape._textItem)));
        }
        /// <summary>
        /// Return value indicates whether two runs can shape together
        /// </summary>
        internal sealed override bool CanShapeTogether(
            TextShapeableSymbols   shapeable
            )
        {
            TextShapeableCharacters charShape = shapeable as TextShapeableCharacters;

            if (charShape == null)
                return false;

            return
                    _shapeTypeface.Equals(charShape._shapeTypeface)
                // Extended characters need to be shaped by surrogate shaper. They cannot be shaped together with non-exteneded characters. 
                && (_textItem.HasExtendedCharacter) == (charShape._textItem.HasExtendedCharacter)
                && _emSize == charShape._emSize
                && (
                    _properties.CultureInfo == null ?
                        charShape._properties.CultureInfo == null
                      : _properties.CultureInfo.Equals(charShape._properties.CultureInfo)
                    )
                && _nullShape == charShape._nullShape
                && (_textItem.CanShapeTogether(charShape._textItem));
        }
示例#7
0
            /// <summary>
            /// Construct a full description of glyph data
            /// </summary>
            internal Glyphs(
                TextShapeableSymbols     shapeable,
                char[]                   charArray,
                int[]                   glyphAdvances,
                ushort[]                 clusterMap,
                ushort[]                 glyphIndices,
                GlyphOffset[]            glyphOffsets,
                double                   scalingFactor
                )
            {
                _shapeable = shapeable;
                _charArray = charArray;

                // create double array for glyph run creation, because Shaping is all done in 
                // ideal units. FormattedTextSymbol is used to draw text collapsing symbols 
                // which usually contains very few glyphs. Using double[] and Point[] directly
                // is more efficient. 
                _glyphAdvances = new double[glyphAdvances.Length];

                double ToReal = 1.0 / scalingFactor;
                
                for (int i = 0; i < glyphAdvances.Length; i++)
                {
                    _glyphAdvances[i] = glyphAdvances[i] * ToReal;
                    _width += _glyphAdvances[i];                
                    
                }

                if (glyphIndices != null)
                {
                    _clusterMap = clusterMap;

                    if (glyphOffsets != null)
                    {
                        _glyphOffsets  = new PartialArray<Point>(new Point[glyphOffsets.Length]);                    
                    
                        for (int i = 0; i < glyphOffsets.Length; i++)
                        {
                            _glyphOffsets[i] = new Point(
                                glyphOffsets[i].du * ToReal,
                                glyphOffsets[i].dv * ToReal
                                );
                        }
                    }

                    Debug.Assert(glyphAdvances.Length <= glyphIndices.Length);

                    if (glyphAdvances.Length != glyphIndices.Length)
                    {
                        _glyphIndices = new ushort[glyphAdvances.Length];

                        for (int i = 0; i < glyphAdvances.Length; i++)
                        {
                            _glyphIndices[i] = glyphIndices[i];
                        }
                    }
                    else
                    {
                        _glyphIndices = glyphIndices;
                    }
                }
            }
示例#8
0
 /// <summary>
 /// Construct a nominal description of glyph data
 /// </summary>
 internal Glyphs(
     TextShapeableSymbols    shapeable,
     char[]                  charArray,
     int[]                  nominalAdvances,
     double                  scalingFactor
     ) :
     this(
         shapeable,
         charArray,
         nominalAdvances,
         null,   // clusterMap
         null,   // glyphIndices                
         null,   // glyphOffsets
         scalingFactor
         )
 {}
示例#9
0
 /// <summary>
 /// Construct an lsrun 
 /// </summary>
 private LSRun(
     TextRunInfo             runInfo,
     IList<TextEffect>       textEffects, 
     Plsrun                  type,
     int                     offsetToFirstCp, 
     int                     textRunLength, 
     int                     emSize,
     ushort                  charFlags, 
     CharacterBufferRange    charBufferRange,
     int                     baselineOffset,
     int                     height,
     TextShapeableSymbols    shapeable, 
     byte                    bidiLevel
     ) 
 { 
     _runInfo = runInfo;
     _type = type; 
     _offsetToFirstCp = offsetToFirstCp;
     _textRunLength = textRunLength;
     _emSize = emSize;
     _charFlags = charFlags; 
     _charBufferRange = charBufferRange;
     _baselineOffset = baselineOffset; 
     _height = height; 
     _bidiLevel = bidiLevel;
     _shapeable = shapeable; 
     _textEffects = textEffects;
 }
示例#10
0
        /// <summary>
        /// Construct a formatted run
        /// </summary>
        public FormattedTextSymbols(
            GlyphingCache glyphingCache,
            TextRun textSymbols,
            CharacterBufferRange chars,
            bool rightToLeft,
            double scalingFactor,
            float pixelsPerDip,
            TextFormattingMode textFormattingMode,
            bool isSideways
            )
        {
            _textFormattingMode = textFormattingMode;
            _isSideways         = isSideways;
            ITextSymbols symbols = textSymbols as ITextSymbols;

            Debug.Assert(symbols != null);

            // break down a single text run into pieces
            IList <TextShapeableSymbols> shapeables = symbols.GetTextShapeableSymbols(
                glyphingCache,
                chars.CharacterBufferReference,
                chars.Length,
                rightToLeft, // This is a bool indicating the RTL
                             // based on the bidi level of text (if applicable).
                             // For FormattedTextSymbols it is equal to paragraph flow direction.

                rightToLeft, // This is the flow direction of the paragraph as
                             // specified by the user. DWrite needs the paragraph
                             // flow direction of the paragraph
                             // while WPF algorithms need the RTL of the text based on
                             // Bidi if possible.

                null,        // cultureInfo
                null,        // textModifierScope
                _textFormattingMode,
                _isSideways
                );

            Debug.Assert(shapeables != null && shapeables.Count > 0);

            _rightToLeft = rightToLeft;
            _glyphs      = new Glyphs[shapeables.Count];

            CharacterBuffer charBuffer        = chars.CharacterBuffer;
            int             offsetToFirstChar = chars.OffsetToFirstChar;

            int i   = 0;
            int ich = 0;

            while (i < shapeables.Count)
            {
                TextShapeableSymbols current = shapeables[i] as TextShapeableSymbols;
                Debug.Assert(current != null);

                int cch = current.Length;
                int j;

                // make a separate character buffer for glyphrun persistence
                char[] charArray = new char[cch];
                for (j = 0; j < cch; j++)
                {
                    charArray[j] = charBuffer[offsetToFirstChar + ich + j];
                }

                if (current.IsShapingRequired)
                {
                    ushort[]      clusterMap;
                    ushort[]      glyphIndices;
                    int[]         glyphAdvances;
                    GlyphOffset[] glyphOffsets;


                    // Note that we dont check for the chance of having multiple
                    // shapeables shaped together here since we're dealing with
                    // single-style text. There is virtually no chance to require
                    // for adjacent runs to shape together. We rely on TextSymbols
                    // to reduce duplication of the itemized shapeables for performance.
                    unsafe
                    {
                        fixed(char *fixedCharArray = &charArray[0])
                        {
                            MS.Internal.Text.TextInterface.TextAnalyzer textAnalyzer = MS.Internal.FontCache.DWriteFactory.Instance.CreateTextAnalyzer();

                            GlyphTypeface glyphTypeface = current.GlyphTypeFace;

                            DWriteFontFeature[][] fontFeatures;
                            uint[] fontFeatureRanges;
                            uint   unsignedCch = checked ((uint)cch);

                            //LSRun.CompileFeatureSet(current.Properties.TypographyProperties, unsignedCch, out fontFeatures, out fontFeatureRanges);
                            fontFeatures      = new DWriteFontFeature[0][];
                            fontFeatureRanges = new uint[0];

                            textAnalyzer.GetGlyphsAndTheirPlacements(
                                new IntPtr(fixedCharArray),
                                unsignedCch,
                                glyphTypeface.FontDWrite,
                                glyphTypeface.BlankGlyphIndex,
                                false,   // no sideway support yet
                                         /************************************************************************************************/
                                         // Should we break down the runs to know whats the Bidi for every range of characters?
                                rightToLeft,
                                current.Properties.CultureInfo,
                                /************************************************************************************************/
                                fontFeatures,
                                fontFeatureRanges,
                                current.Properties.FontRenderingEmSize,
                                scalingFactor,
                                pixelsPerDip,
                                _textFormattingMode,
                                current.ItemProps,
                                out clusterMap,
                                out glyphIndices,
                                out glyphAdvances,
                                out glyphOffsets
                                );
                        }

                        _glyphs[i] = new Glyphs(
                            current,
                            charArray,
                            glyphAdvances,
                            clusterMap,
                            glyphIndices,
                            glyphOffsets,
                            scalingFactor
                            );
                    }
                }
                else
                {
                    // shaping not required,
                    // bypass glyphing process altogether
                    int[] nominalAdvances = new int[charArray.Length];

                    unsafe
                    {
                        fixed(char *fixedCharArray = &charArray[0])
                        fixed(int *fixedNominalAdvances = &nominalAdvances[0])
                        {
                            current.GetAdvanceWidthsUnshaped(
                                fixedCharArray,
                                cch,
                                scalingFactor, // format resolution specified per em,
                                fixedNominalAdvances
                                );
                        }
                    }

                    _glyphs[i] = new Glyphs(
                        current,
                        charArray,
                        nominalAdvances,
                        scalingFactor
                        );
                }

                i++;
                ich += cch;
            }
        }