Практическое руководство. Получение метрик шрифтов
Обновлен: Ноябрь 2007
Класс FontFamily предоставляет следующие методы для получения различных метрик для некоторой комбинации "семейство шрифтов — начертание".
GetEmHeight(FontStyle)
GetCellAscent(FontStyle)
GetCellDescent(FontStyle)
GetLineSpacing(FontStyle)
Численные значения, возвращаемые этими методами, приводятся в специальных единицах, применяемых при разработке шрифта, поэтому они не зависят от размера и единиц измерения конкретного объекта 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.