Recipe 9.20. Getting the Height and Width of a Graphic String


Problem

You want to know how many pixels a text string will require in both the horizontal and vertical directions.

Solution

Sample code folder: Chapter 09\MeasuringText

GDI+ includes several features that let you examine the width and height of a string. Graphics.MeasureString() is a general-purpose text-measurement method that bases its measurements on a font you pass to it:

 Dim result As SizeF = _    e.  Graphics.MeasureString("How big am I?", Me.Font, _    Me.ClientRectangle.Width) MsgBox("Width = " & result.Width & vbCrLf & _    "Height = " & result.Height) 

On our system, using the default form font of Microsoft Sans Serif 8.25 Regular, the message box displays the following response:

 Width = 75.71989Height = 13.8252 

Discussion

Font measurement is tricky. Fonts are more than just the width and height of their letters. The height is a combination of the core height, plus the height of ascenders (the part of the letter "d" that sticks up) and descenders (the part of the letter "p" that sticks down). The width of a character string is impacted by kerning, the adjustment of two letters that fit together better than others. To get a flavor of some of these measurements, consider the following code:

 Public Class Form1    Private Sub PictureBox1_Paint(ByVal sender As Object, _          ByVal e As System.Windows.Forms.PaintEventArgs) _          Handles PictureBox1.Paint       ' ----- Show vertical font measures.       Dim textArea As SizeF       Dim linePen As Pen       Dim largeFont As Font       Dim fontRatio As Single       Dim ascentSize As Single       Dim descentSize As Single       Dim emSize As Single       Dim cellHeight As Single       Dim internalLeading As Single       Dim externalLeading As Single       ' ----- Create the font to use for drawing.       '       Using "AntiAlias" to enable text smoothing       '       will result in more precise output.       e.Graphics.TextRenderingHint = _          Drawing.Text.TextRenderingHint.AntiAlias       largeFont = New Font("Times New Roman", 96, _          FontStyle.Regular)       ' ----- Fonts are measured in design units. We need to       '       convert to pixels to mix measurement systems.       '       Determine the ratio between the display line       '       height and the font design's line height.       fontRatio = largeFont.Height / _          largeFont.FontFamily.GetLineSpacing( _          FontStyle.Regular)       ' ----- Get the measurements.       textArea = e.  Graphics.MeasureString("Ag", largeFont)       ' ----- Offset everything for simplicity.       e.Graphics.TranslateTransform(20, 20)       ' ----- Draw the text.       e.Graphics.DrawString("Ag", largeFont, _       Brushes.Black, 0, 0)       ' ----- Create a line-drawing pen.       linePen = New Pen(Color.Gray, 1)       linePen.DashStyle = Drawing2D.DashStyle.Dash       ' ----- Calculate all of the various font measurements.       ascentSize = largeFont.FontFamily.GetCellAscent( _          FontStyle.Regular) * fontRatio       descentSize = largeFont.FontFamily.GetCellDescent( _          FontStyle.Regular) * fontRatio       emSize = largeFont.FontFamily.GetEmHeight( _          FontStyle.Regular) * fontRatio       cellHeight = ascentSize + descentSize       internalLeading = cellHeight - emSize       externalLeading = _          (largeFont.FontFamily.GetLineSpacing( _          FontStyle.Regular) * fontRatio) - cellHeight       ' ----- Draw the top and bottom lines.       e.Graphics.DrawLine(linePen, 0, 0, textArea.Width, 0)       e.Graphics.DrawLine(linePen, 0, textArea.Height, _          textArea.Width, textArea.Height)       ' ----- Draw the ascender and descender areas.       e.Graphics.DrawLine(linePen, 0, _          ascentSize, textArea.Width, ascentSize)       e.Graphics.DrawLine(linePen, 0, _          ascentSize + descentSize, textArea.Width, _          ascentSize + descentSize)       ' ----- Clean up.       linePen.Dispose()       largeFont.Dispose()       e.Graphics.ResetTransform()    End Sub End Class 

We added this code to a form with a single PictureBox control. The results appear in Figure 9-30.

The four lines from top to bottom are as follows:

  • The top of the "line height" box

  • The baseline, based on the ascender height

    Figure 9-30. Measuring elements of a font

  • The bottom of the descender

  • The bottom of the "line height" box

The code also includes calculations for other measurements, although they are not used in the output.




Visual Basic 2005 Cookbook(c) Solutions for VB 2005 Programmers
Visual Basic 2005 Cookbook: Solutions for VB 2005 Programmers (Cookbooks (OReilly))
ISBN: 0596101775
EAN: 2147483647
Year: 2006
Pages: 400

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net