| netlib.narod.ru | < Назад | Оглавление | Далее > |
FontFamily имеет еще одно статическое свойство и еще один статический метод. Они схожи и очень важны. Оба возвращают набор объектов FontFamily, соответствующий установленным в системе шрифтам TrueType и OpenType:
Статические свойства FontFamily (выборочно)
| Тип | Свойство | Доступ |
| FontFamily[] | Families | Чтение |
Если выполнить инструкцию
FontFamily[] aff = FontFamily.Families;
каждый элемент массива aff будет объектом FontFamily. Если вам доводилось сталкиваться с перечислением шрифтов в программах Win32 API, вы оцените простоту такого подхода.
Этот массив позволяет легко получить список доступных шрифтов и вывести на внешнее устройство образцы текста с этими шрифтами:
NaiveFamiliesList.cs
//--------------------------------------------------
// NaiveFamiliesList.cs (C) 2001 by Charles Petzold
//--------------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;
class NaiveFamiliesList: PrintableForm
{
public new static void Main()
{
Application.Run(new NaiveFamiliesList());
}
public NaiveFamiliesList()
{
Text = "Naive Font Families List";
}
protected override void DoPage(Graphics grfx, Color clr, int cx, int cy)
{
Brush brush = new SolidBrush(clr);
float y = 0;
FontFamily[] aff = FontFamily.Families;
foreach (FontFamily ff in aff)
{
Font font = new Font(ff, 12);
grfx.DrawString(ff.Name, font, brush, 0, y);
y += font.GetHeight(grfx);
}
}
}
Инструкция foreach перебирает все элементы FontFamily. Для каждого элемента конструктор Font создает 12-пунктный шрифт, DrawString использует его для вывода на монитор названия гарнитуры, a GetHeight готовит вертикальные координаты для вывода следующей строки.
Эта программа может не работать на некоторых компьютерах. На моем конструктор Font генерирует исключение для самой первой гарнитуры массива.
К ошибке приводит файл шрифта Ahronbd.ttf, который устанавливается с дистрибутивного диска Windows 2000 для поддержки гарнитуры Hebrew. Он содержит шрифт Aharoni Bold, единственный шрифт гарнитуры Aharoni (по крайней мере в Windows 2000). Это значит, что следующая инструкция будет работать
font = new Font("Aharoni", 12, FontStyle.Bold)
А эта
font = new Font("Aharoni", 12)
не будет, так как она равносильна
font = new Font("Aharoni", 12, FontStyle.Regular)
а шрифт Aharoni с нормальным начертанием не реализован. (Вот лентяи!)
Эту проблему можно решить двумя способами. Первый — использовать конструкции try и catch. Поместите код из предыдущего цикла foreach в блок try. В блоке catch выведите название гарнитуры, из-за которой возникают проблемы, со знаком «звездочка», используя свойство формы Font:
foreach (FontFamily ff in aff)
{
try
{
Font font = new Font(ff, 12);
grfx.DrawString(ff.Name, font, brush, 0, y);
y += font.GetHeight(grfx);
}
catch
{
grfx.DrawString("* " + ff.Name, Font, brush, 0, y);
у += Font.GetHeight(grfx);
}
}
Вместе с тем лучше не использовать блоки try и catch, если есть другие способы. В нашем случае альтернативный подход состоит в применении метода IsStyleAvailable класса FontFamily. Вот лучшее решение задачи, которое работает независимо от того, установлен ли шрифт Aharoni Bold.
BetterFamiliesList.cs
//---------------------------------------------------
// BetterFamiliesList.cs (C) 2001 by Charles Petzold
//---------------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;
class BetterFamiliesList: PrintableForm
{
public new static void Main()
{
Application.Run(new BetterFamiliesList());
}
public BetterFamiliesList()
{
Text = "Better Font Families List";
}
protected override void DoPage(Graphics grfx, Color clr, int cx, int cy)
{
Brush brush = new SolidBrush(clr);
float y = 0;
FontFamily[] aff = FontFamily.Families;
foreach (FontFamily ff in aff)
{
if (ff.IsStyleAvailable(FontStyle.Regular))
{
Font font = new Font(ff, 12);
grfx.DrawString(ff.Name, font, brush, 0, y);
y += font.GetHeight(grfx);
}
else
{
grfx.DrawString("* " + ff.Name, Font, brush, 0, y);
y += Font.GetHeight(grfx);
}
}
}
}
Если у вас установлено большое количество шрифтов, этот подход не позволит вам увидеть все шрифты, даже на большом мониторе или на распечатке.
Если не рассматривать полосы прокрутки, правильнее сформатировать список в колонки. Следующая программа так и работает. А если и этого не хватит для вывода всех шрифтов, попробуйте изменить поле iPointSize на 10, 8 или 6.
FamiliesList.cs
//---------------------------------------------
// FamiliesList.cs (C) 2001 by Charles Petzold
//---------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;
class FamiliesList: PrintableForm
{
const int iPointSize = 12;
public new static void Main()
{
Application.Run(new FamiliesList());
}
public FamiliesList()
{
Text = "Font Families List";
}
protected override void DoPage(Graphics grfx, Color clr, int cx, int cy)
{
Brush brush = new SolidBrush(clr);
float x = 0, y = 0, fMaxWidth = 0;
FontFamily[] aff = GetFontFamilyArray(grfx);
foreach (FontFamily ff in aff)
{
Font font = CreateSampleFont(ff, iPointSize);
SizeF sizef = grfx.MeasureString(ff.Name, font);
fMaxWidth = Math.Max(fMaxWidth, sizef.Width);
}
foreach (FontFamily ff in aff)
{
Font font = CreateSampleFont(ff, iPointSize);
float fHeight = font.GetHeight(grfx);
if (y > 0 && y + fHeight > cy)
{
x += fMaxWidth;
y = 0;
}
grfx.DrawString(ff.Name, font, brush, x, y);
y += fHeight;
}
}
protected virtual FontFamily[] GetFontFamilyArray(Graphics grfx)
{
return FontFamily.Families;
}
Font CreateSampleFont(FontFamily ff, float fPointSize)
{
if (ff.IsStyleAvailable(FontStyle.Regular))
return new Font(ff, fPointSize);
else if (ff.IsStyleAvailable(FontStyle.Bold))
return new Font(ff, fPointSize, FontStyle.Bold);
else if (ff.IsStyleAvailable(FontStyle.Italic))
return new Font(ff, fPointSize, FontStyle.Italic);
else
return Font;
}
}
В методе DoPage два цикла foreach. В первом определяется ширина названия каждой гарнитуры с соответствующим шрифтом и запоминается максимальная ширина. Второй цикл использует эту величину для построения колонок.
Обратите внимание на метод CreateSampleFont в конце тела класса. Я применяю его в методе DoPage вместо конструктора Font. CreateSampleFont с помощью метода IsStyleAvailable определяет, какое использовать начертание — нормальное, курсивное или полужирное. Это позволяет вывести на экран образец текста со шрифтом Aharoni, тогда как предыдущая программа не могла этого сделать. Вот результат работы программы на моем компьютере:

Если у вас установлены некоторые восточные шрифты, то вы заметите, что межстрочный интервал слишком большой для отображаемого текста. Это вызвано тем, что такие шрифты разработаны для вывода алфавитов, отличных от латинского.
В программе FamiliesList инструкция, получающая массив объектов FontFamily изолирована в небольшом методе, который я назвал GetFontFamilyArray. Это сделано для того, чтобы в следующей программе мне было проще продемонстрировать использование единственного статического метода, реализованного в FontFamily. Этот метод очень похож на свойство Families, за исключением наличия аргумента типа Graphics.
Статический метод FontFamily
| FontFamily[] GetFamilies(Graphics grfx) |
Идея здесь в том, что для различных графических устройств вывода могут быть установлены различные шрифты; в частности, у некоторых принтеров есть встроенные шрифты, которые не могут быть отображены на экране. Следующая программа переопределяет метод GetFontFamilyArray, чтобы получать массив гарнитур из GetFamilies, а не из Families.
GetFamiliesList.cs
//------------------------------------------------
// GetFamiliesList.cs (C) 2001 by Charles Petzold
//------------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;
class GetFamiliesList: FamiliesList
{
public new static void Main()
{
Application.Run(new GetFamiliesList());
}
public GetFamiliesList()
{
Text = "Font GetFamilies List";
}
protected override FontFamily[] GetFontFamilyArray(Graphics grfx)
{
return FontFamily.GetFamilies(grfx);
}
}
Для моего принтера GetFamilies возвращает тот же самый массив, что и Families. Возможно, в будущих версиях Windows Forms мы увидим более развернутую поддержку принтерных шрифтов.
| netlib.narod.ru | < Назад | Оглавление | Далее > |