Практическое руководство. Получение метрик шрифтов

Обновлен: Ноябрь 2007

Класс FontFamily предоставляет следующие методы для получения различных метрик для некоторой комбинации "семейство шрифтов — начертание".

Численные значения, возвращаемые этими методами, приводятся в специальных единицах, применяемых при разработке шрифта, поэтому они не зависят от размера и единиц измерения конкретного объекта Font.

Различные метрики шрифтов показаны на следующем рисунке.

Текст шрифтов

Пример

В следующем примере отображаются метрики обычного начертания шрифтов семейства Arial. Кодом также создается объект Font (на основе семейства шрифтов Arial) с размером в 16 точек и отображаются метрики (в точках) для этого объекта Font.

На следующем рисунке показан результат выполнения примера кода.

Текст шрифтов

Обратите внимание на две первые строки текста из приведенного выше рисунка. Объект Font возвращает в качестве размера 16, а объект FontFamily возвращает размер максимального пробела, равный 2048. Указанные два числа (16 и 2048) являются основой для преобразования между единицами измерения, применяемыми при проектировании шрифта, и единицами измерения объекта Font (в данном случае это точки).

Например, можно преобразовать проектные единицы измерения верхнего выносного элемента в точки следующим образом.

Текст шрифтов

Приведенный выше код располагает текст по вертикали, устанавливая значение члена Y объекта PointF. Координата y увеличивается на значение font.Height для каждой новой строки текста. Свойство Height объекта Font возвращает межстрочный интервал (в точках) для рассматриваемого объекта Font. В данном примере возвращаемое значение Height равно 19. Обратите внимание, что оно равно численному значению (округленному до большего целого), получаемому при преобразовании метрики межстрочного интервала в точки.

Обратите также внимание, что размер максимального пробела (называемый также эм-размером) не равен сумме размеров верхнего и нижнего выносных элементов. Сумма размеров верхнего и нижнего выносных элементов называется высотой клетки. Размер максимального пробела вычисляется как разность между высотой клетки и внутренним интерлиньяжем. Сумма высоты клетки и внешнего интерлиньяжа равна междустрочному интервалу.

Dim infoString As String = "" ' enough space for one line of output
Dim ascent As Integer ' font family ascent in design units
Dim ascentPixel As Single ' ascent converted to pixels
Dim descent As Integer ' font family descent in design units
Dim descentPixel As Single ' descent converted to pixels
Dim lineSpacing As Integer ' font family line spacing in design units
Dim lineSpacingPixel As Single ' line spacing converted to pixels
Dim fontFamily As New FontFamily("Arial")
Dim font As New Font( _
   fontFamily, _
   16, _
   FontStyle.Regular, _
   GraphicsUnit.Pixel)
Dim pointF As New PointF(10, 10)
Dim solidBrush As New SolidBrush(Color.Black)

' Display the font size in pixels.
infoString = "font.Size returns " & font.Size.ToString() & "."
e.Graphics.DrawString(infoString, font, solidBrush, pointF)

' Move down one line.
pointF.Y += font.Height

' Display the font family em height in design units.
infoString = "fontFamily.GetEmHeight() returns " & _
   fontFamily.GetEmHeight(FontStyle.Regular) & "."
e.Graphics.DrawString(infoString, font, solidBrush, pointF)

' Move down two lines.
pointF.Y += 2 * font.Height

' Display the ascent in design units and pixels.
ascent = fontFamily.GetCellAscent(FontStyle.Regular)

' 14.484375 = 16.0 * 1854 / 2048
ascentPixel = _
   font.Size * ascent / fontFamily.GetEmHeight(FontStyle.Regular)
infoString = "The ascent is " & ascent & " design units, " & ascentPixel _
   & " pixels."
e.Graphics.DrawString(infoString, font, solidBrush, pointF)

' Move down one line.
pointF.Y += font.Height

' Display the descent in design units and pixels.
descent = fontFamily.GetCellDescent(FontStyle.Regular)

' 3.390625 = 16.0 * 434 / 2048
descentPixel = _
   font.Size * descent / fontFamily.GetEmHeight(FontStyle.Regular)
infoString = "The descent is " & descent & " design units, " & _
   descentPixel & " pixels."
e.Graphics.DrawString(infoString, font, solidBrush, pointF)

' Move down one line.
pointF.Y += font.Height

' Display the line spacing in design units and pixels.
lineSpacing = fontFamily.GetLineSpacing(FontStyle.Regular)

' 18.398438 = 16.0 * 2355 / 2048
lineSpacingPixel = _
   font.Size * lineSpacing / fontFamily.GetEmHeight(FontStyle.Regular)
infoString = "The line spacing is " & lineSpacing & " design units, " & _
   lineSpacingPixel & " pixels."
e.Graphics.DrawString(infoString, font, solidBrush, pointF)

string infoString = "";  // enough space for one line of output
int ascent;             // font family ascent in design units
float ascentPixel;      // ascent converted to pixels
int descent;            // font family descent in design units
float descentPixel;     // descent converted to pixels
int lineSpacing;        // font family line spacing in design units
float lineSpacingPixel; // line spacing converted to pixels

FontFamily fontFamily = new FontFamily("Arial");
Font font = new Font(
   fontFamily,
   16, FontStyle.Regular,
   GraphicsUnit.Pixel);
PointF pointF = new PointF(10, 10);
SolidBrush solidBrush = new SolidBrush(Color.Black);

// Display the font size in pixels.
infoString = "font.Size returns " + font.Size + ".";
e.Graphics.DrawString(infoString, font, solidBrush, pointF);

// Move down one line.
pointF.Y += font.Height;

// Display the font family em height in design units.
infoString = "fontFamily.GetEmHeight() returns " +
   fontFamily.GetEmHeight(FontStyle.Regular) + ".";
e.Graphics.DrawString(infoString, font, solidBrush, pointF);

// Move down two lines.
pointF.Y += 2 * font.Height;

// Display the ascent in design units and pixels.
ascent = fontFamily.GetCellAscent(FontStyle.Regular);

// 14.484375 = 16.0 * 1854 / 2048
ascentPixel =
   font.Size * ascent / fontFamily.GetEmHeight(FontStyle.Regular);
infoString = "The ascent is " + ascent + " design units, " + ascentPixel +
   " pixels.";
e.Graphics.DrawString(infoString, font, solidBrush, pointF);

// Move down one line.
pointF.Y += font.Height;

// Display the descent in design units and pixels.
descent = fontFamily.GetCellDescent(FontStyle.Regular);

// 3.390625 = 16.0 * 434 / 2048
descentPixel =
   font.Size * descent / fontFamily.GetEmHeight(FontStyle.Regular);
infoString = "The descent is " + descent + " design units, " +
   descentPixel + " pixels.";
e.Graphics.DrawString(infoString, font, solidBrush, pointF);

// Move down one line.
pointF.Y += font.Height;

// Display the line spacing in design units and pixels.
lineSpacing = fontFamily.GetLineSpacing(FontStyle.Regular);

// 18.398438 = 16.0 * 2355 / 2048
lineSpacingPixel =
font.Size * lineSpacing / fontFamily.GetEmHeight(FontStyle.Regular);
infoString = "The line spacing is " + lineSpacing + " design units, " +
   lineSpacingPixel + " pixels.";
e.Graphics.DrawString(infoString, font, solidBrush, pointF);

Компиляция кода

Предыдущий пример предназначен для работы с Windows Forms, для него необходим объект PaintEventArgs e, передаваемый в качестве параметра обработчику событий PaintEventHandler.

См. также

Другие ресурсы

Объекты Graphics и Drawing в Windows Forms

Шрифты и текст