ProblemYou want to know how many pixels a text string will require in both the horizontal and vertical directions. SolutionSample 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 DiscussionFont 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 code also includes calculations for other measurements, although they are not used in the output. |