示例#1
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);
            }
示例#2
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;
            }
        }