15

I have used TextRenderer to Measure the length of a string and therefore size a control appropriately. Is there an equivalent in WPF or can I simply use TextRendered.MeasureString?

Lipis
  • 21,388
  • 20
  • 94
  • 121
James
  • 3,597
  • 11
  • 47
  • 57

2 Answers2

21

Thanks Gishu,

Reading your links I came up with the following both of which do the job for me:

    /// <summary>
    /// Get the required height and width of the specified text. Uses FortammedText
    /// </summary>
    public static Size MeasureTextSize(string text, FontFamily fontFamily, FontStyle fontStyle, FontWeight fontWeight, FontStretch fontStretch, double fontSize)
    {
        FormattedText ft = new FormattedText(text,
                                             CultureInfo.CurrentCulture,
                                             FlowDirection.LeftToRight,
                                             new Typeface(fontFamily, fontStyle, fontWeight, fontStretch),
                                             fontSize,
                                             Brushes.Black);
        return new Size(ft.Width, ft.Height);
    }

    /// <summary>
    /// Get the required height and width of the specified text. Uses Glyph's
    /// </summary>
    public static Size MeasureText(string text, FontFamily fontFamily, FontStyle fontStyle, FontWeight fontWeight, FontStretch fontStretch, double fontSize)
    {
        Typeface typeface = new Typeface(fontFamily, fontStyle, fontWeight, fontStretch);
        GlyphTypeface glyphTypeface;

        if(!typeface.TryGetGlyphTypeface(out glyphTypeface))
        {
            return MeasureTextSize(text, fontFamily, fontStyle, fontWeight, fontStretch, fontSize);
        }

        double totalWidth = 0;
        double height = 0;

        for (int n = 0; n < text.Length; n++)
        {
            ushort glyphIndex = glyphTypeface.CharacterToGlyphMap[text[n]];

            double width = glyphTypeface.AdvanceWidths[glyphIndex] * fontSize;

            double glyphHeight = glyphTypeface.AdvanceHeights[glyphIndex]*fontSize;

            if(glyphHeight > height)
            {
                height = glyphHeight;
            }

            totalWidth += width;
        }

        return new Size(totalWidth, height);
    }
James
  • 3,597
  • 11
  • 47
  • 57
5

Take a look at the FormattedText class

If you need more granular control, then you'd need to descend to the GlyphTypeface type's AdvanceWidths member. Found a similar discussion here with a code snippet that looks like it might work.

Update: Looks like this may be a duplicate of Measuring text in WPF .. OP please confirm.

Community
  • 1
  • 1
Gishu
  • 134,492
  • 47
  • 225
  • 308