internal sealed override unsafe void GetAdvanceWidthsUnshaped(
            char *characterString,
            int characterLength,
            double scalingFactor,
            int *advanceWidthsUnshaped
            )
        {
            if (!IsShapingRequired)
            {
                if ((_shapeTypeface != null) &&
                    (_shapeTypeface.DeviceFont != null))
                {
                    // Use device font to compute advance widths
                    _shapeTypeface.DeviceFont.GetAdvanceWidths(
                        characterString,
                        characterLength,
                        _emSize * scalingFactor,
                        advanceWidthsUnshaped
                        );
                }
                else
                {
                    bool          nullFont;
                    GlyphTypeface glyphTypeface = GetGlyphTypeface(out nullFont);
                    Invariant.Assert(glyphTypeface != null);

                    glyphTypeface.GetAdvanceWidthsUnshaped(
                        characterString,
                        characterLength,
                        _emSize,
                        (float)_properties.PixelsPerDip,
                        scalingFactor,
                        advanceWidthsUnshaped,
                        nullFont,
                        _textFormattingMode,
                        _isSideways
                        );
                }
            }
            else
            {
                GlyphTypeface glyphTypeface = _shapeTypeface.GlyphTypeface;

                Invariant.Assert(glyphTypeface != null);
                Invariant.Assert(characterLength > 0);

                CharacterBufferRange newBuffer = new CharacterBufferRange(characterString, characterLength);
                MS.Internal.Text.TextInterface.GlyphMetrics[] glyphMetrics = BufferCache.GetGlyphMetrics(characterLength);

                glyphTypeface.GetGlyphMetricsOptimized(newBuffer,
                                                       _emSize,
                                                       (float)_properties.PixelsPerDip,
                                                       _textFormattingMode,
                                                       _isSideways,
                                                       glyphMetrics
                                                       );

                if (_textFormattingMode == TextFormattingMode.Display &&
                    TextFormatterContext.IsSpecialCharacter(*characterString))
                {
                    // (DDVSO 92892) If the run starts with a special character (in
                    // the LineServices sense), we apply display-mode rounding now,
                    // as we won't get another chance.   This assumes that the characters
                    // in a run are either all special or all non-special;  that assumption
                    // is valid in the current LS implementation.
                    double designToEm   = _emSize / glyphTypeface.DesignEmHeight;
                    double pixelsPerDip = _properties.PixelsPerDip;

                    for (int i = 0; i < characterLength; i++)
                    {
                        advanceWidthsUnshaped[i] = (int)Math.Round(TextFormatterImp.RoundDipForDisplayMode(glyphMetrics[i].AdvanceWidth * designToEm, pixelsPerDip) * scalingFactor);
                    }
                }
                else
                {
                    // For the normal case, rounding is applied later on when LS
                    // invokes the callback GetGlyphPositions, so that adjustments
                    // due to justification and shaping are taken into account.
                    double designToEm = _emSize * scalingFactor / glyphTypeface.DesignEmHeight;

                    for (int i = 0; i < characterLength; i++)
                    {
                        advanceWidthsUnshaped[i] = (int)Math.Round(glyphMetrics[i].AdvanceWidth * designToEm);
                    }
                }


                BufferCache.ReleaseGlyphMetrics(glyphMetrics);
            }
        }
        internal sealed override unsafe void GetAdvanceWidthsUnshaped(
            char *characterString,
            int characterLength,
            double scalingFactor,
            int *advanceWidthsUnshaped
            )
        {
            if (!IsShapingRequired)
            {
                if ((_shapeTypeface != null) &&
                    (_shapeTypeface.DeviceFont != null))
                {
                    // Use device font to compute advance widths
                    _shapeTypeface.DeviceFont.GetAdvanceWidths(
                        characterString,
                        characterLength,
                        _emSize * scalingFactor,
                        advanceWidthsUnshaped
                        );
                }
                else
                {
                    bool          nullFont;
                    GlyphTypeface glyphTypeface = GetGlyphTypeface(out nullFont);
                    Invariant.Assert(glyphTypeface != null);

                    glyphTypeface.GetAdvanceWidthsUnshaped(
                        characterString,
                        characterLength,
                        _emSize,
                        scalingFactor,
                        advanceWidthsUnshaped,
                        nullFont,
                        _textFormattingMode,
                        _isSideways
                        );
                }
            }
            else
            {
                GlyphTypeface glyphTypeface = _shapeTypeface.GlyphTypeface;

                Invariant.Assert(glyphTypeface != null);
                Invariant.Assert(characterLength > 0);

                CharacterBufferRange newBuffer = new CharacterBufferRange(characterString, characterLength);
                MS.Internal.Text.TextInterface.GlyphMetrics[] glyphMetrics = BufferCache.GetGlyphMetrics(characterLength);

                glyphTypeface.GetGlyphMetricsOptimized(newBuffer,
                                                       _emSize,
                                                       _textFormattingMode,
                                                       _isSideways,
                                                       glyphMetrics
                                                       );

                double designToEm = _emSize * scalingFactor / glyphTypeface.DesignEmHeight;

                for (int i = 0; i < characterLength; i++)
                {
                    advanceWidthsUnshaped[i] = (int)Math.Round(glyphMetrics[i].AdvanceWidth * designToEm);
                }

                BufferCache.ReleaseGlyphMetrics(glyphMetrics);
            }
        }