Поделиться через


Создание частной коллекции шрифтов

Класс PrivateFontCollection наследуется от абстрактного базового класса FontCollection . Объект PrivateFontCollection можно использовать для поддержки набора шрифтов специально для вашего приложения.

Частная коллекция шрифтов может включать в себя как установленные системные шрифты, так и шрифты, которые не были установлены на компьютере. Чтобы добавить файл шрифта в частную коллекцию шрифтов, вызовите метод PrivateFontCollection::AddFontFile объекта PrivateFontCollection .

Примечание

При использовании API GDI+ никогда не следует разрешать приложению скачивать произвольные шрифты из ненадежных источников. Операционной системе требуются повышенные привилегии, чтобы гарантировать, что все установленные шрифты являются доверенными.

 

Метод FontCollection::GetFamilies объекта PrivateFontCollection возвращает массив объектов FontFamily . Перед вызовом FontCollection::GetFamilies необходимо выделить буфер, достаточно большой для хранения этого массива. Чтобы определить размер требуемого буфера, вызовите метод FontCollection::GetFamilyCount и умножьте возвращаемое значение на sizeof(FontFamily).

Количество семейств шрифтов в частной коллекции шрифтов не обязательно должно совпадать с количеством файлов шрифтов, добавленных в коллекцию. Например, предположим, что в коллекцию были добавлены файлы ArialBd.tff, Times.tff и TimesBd.tff. В коллекции будет три файла, но только два семейства, так как Times.tff и TimesBd.tff принадлежат одному семейству.

В следующем примере к объекту PrivateFontCollection добавляются следующие три файла шрифтов:

  • C:\WINNT\Fonts\Arial.tff (Arial, regular)
  • C:\WINNT\Fonts\CourBI.tff (Courier New, курсив полужирным шрифтом)
  • C:\WINNT\Fonts\TimesBd.tff (Times New Roman, полужирный)

Код вызывает метод FontCollection::GetFamilyCount объекта PrivateFontCollection для определения количества семейств в частной коллекции, а затем вызывает FontCollection::GetFamilies для получения массива объектов FontFamily .

Для каждого объекта FontFamily в коллекции код вызывает метод FontFamily::IsStyleAvailable , чтобы определить, доступны ли различные стили (обычный, полужирный, курсив, курсив, подчеркивание и зачеркивка). Аргументы, передаваемые методу FontFamily::IsStyleAvailable , являются членами перечисления FontStyle , которое объявляется в Gdiplusenums.h.

Если доступно определенное сочетание семейства и стиля, объект Font создается с использованием этого семейства и стиля. Первым аргументом, переданным конструктору Font , является имя семейства шрифтов (а не объект FontFamily , как в случае с другими вариантами конструктора шрифта ), а последним аргументом является адрес объекта PrivateFontCollection . После создания объекта Font его адрес передается методу DrawString класса Graphics , чтобы отобразить имя семейства вместе с именем стиля.

#define MAX_STYLE_SIZE 20
#define MAX_FACEANDSTYLE_SIZE (LF_FACESIZE + MAX_STYLE_SIZE + 2)

PointF      pointF(10.0f, 0.0f);
SolidBrush  solidBrush(Color(255, 0, 0, 0));
INT                   count = 0;
INT                   found = 0;
WCHAR                 familyName[LF_FACESIZE];
WCHAR                 familyNameAndStyle[MAX_FACEANDSTYLE_SIZE]; 
FontFamily*           pFontFamily;
PrivateFontCollection privateFontCollection;

// Add three font files to the private collection.
privateFontCollection.AddFontFile(L"c:\\Winnt\\Fonts\\Arial.ttf");
privateFontCollection.AddFontFile(L"c:\\Winnt\\Fonts\\CourBI.ttf");
privateFontCollection.AddFontFile(L"c:\\Winnt\\Fonts\\TimesBd.ttf");

// How many font families are in the private collection?
count = privateFontCollection.GetFamilyCount();

// Allocate a buffer to hold the array of FontFamily
// objects returned by GetFamilies.
pFontFamily = new FontFamily[count];

// Get the array of FontFamily objects.
privateFontCollection.GetFamilies(count, pFontFamily, &found);

// Display the name of each font family in the private collection
// along with the available styles for that font family.
for(INT j = 0; j < count; ++j)
{
   // Get the font family name.
   pFontFamily[j].GetFamilyName(familyName);
   
   // Is the regular style available?
   if(pFontFamily[j].IsStyleAvailable(FontStyleRegular))
   {
      StringCchCopyW(familyNameAndStyle, LF_FACESIZE, familyName);
      StringCchCatW(familyNameAndStyle, MAX_FACEANDSTYLE_SIZE, L" Regular");

      Font* pFont = new Font(
         familyName, 16, FontStyleRegular, UnitPixel, &privateFontCollection);

      graphics.DrawString(familyNameAndStyle, -1, pFont, pointF, &solidBrush);

      pointF.Y += pFont->GetHeight(0.0f);
      delete(pFont);      
   }

   // Is the bold style available?
   if(pFontFamily[j].IsStyleAvailable(FontStyleBold))
   {
      StringCchCopyW(familyNameAndStyle, LF_FACESIZE, familyName);
      StringCchCatW(familyNameAndStyle, MAX_FACEANDSTYLE_SIZE, L" Bold");

      Font* pFont = new Font(
         familyName, 16, FontStyleBold, UnitPixel, &privateFontCollection);

      graphics.DrawString(familyNameAndStyle, -1, pFont, pointF, &solidBrush);

      pointF.Y += pFont->GetHeight(0.0f);
      delete(pFont);
   }

   // Is the italic style available?
   if(pFontFamily[j].IsStyleAvailable(FontStyleItalic))
   {
      StringCchCopyW(familyNameAndStyle, LF_FACESIZE, familyName);
      StringCchCatW(familyNameAndStyle, MAX_FACEANDSTYLE_SIZE, L" Italic");

      Font* pFont = new Font(
         familyName, 16, FontStyleItalic, UnitPixel, &privateFontCollection);

      graphics.DrawString(familyNameAndStyle, -1, pFont, pointF, &solidBrush);

      pointF.Y += pFont->GetHeight(0.0f);
      delete(pFont);
   }

   // Is the bold italic style available?
   if(pFontFamily[j].IsStyleAvailable(FontStyleBoldItalic))
   {
      StringCchCopyW(familyNameAndStyle, LF_FACESIZE, familyName);
      StringCchCatW(familyNameAndStyle, MAX_FACEANDSTYLE_SIZE, L" BoldItalic");

      Font* pFont = new Font(familyName, 16, 
         FontStyleBoldItalic, UnitPixel, &privateFontCollection);

      graphics.DrawString(familyNameAndStyle, -1, pFont, pointF, &solidBrush);

      pointF.Y += pFont->GetHeight(0.0f);
      delete(pFont);
    }

   // Is the underline style available?
   if(pFontFamily[j].IsStyleAvailable(FontStyleUnderline))
   {
      StringCchCopyW(familyNameAndStyle, LF_FACESIZE, familyName);
      StringCchCatW(familyNameAndStyle, MAX_FACEANDSTYLE_SIZE, L" Underline");

      Font* pFont = new Font(familyName, 16, 
         FontStyleUnderline, UnitPixel, &privateFontCollection);

      graphics.DrawString(familyNameAndStyle, -1, pFont, pointF, &solidBrush);

      pointF.Y += pFont->GetHeight(0.0);
      delete(pFont);
   }
 
   // Is the strikeout style available?
   if(pFontFamily[j].IsStyleAvailable(FontStyleStrikeout))
   {
      StringCchCopyW(familyNameAndStyle, LF_FACESIZE, familyName);
      StringCchCatW(familyNameAndStyle, MAX_FACEANDSTYLE_SIZE, L" Strikeout");

      Font* pFont = new Font(familyName, 16, 
         FontStyleStrikeout, UnitPixel, &privateFontCollection);

      graphics.DrawString(familyNameAndStyle, -1, pFont, pointF, &solidBrush);

      pointF.Y += pFont->GetHeight(0.0f);
      delete(pFont);
   }

   // Separate the families with white space.
   pointF.Y += 10.0f;

} // for

delete pFontFamily;
            

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

Снимок экрана: окно со списком девяти названий шрифтов, каждое из которых демонстрирует именованный шрифт

Arial.tff (который был добавлен в коллекцию частных шрифтов в предыдущем примере кода) — это файл шрифта для обычного стиля Arial. Обратите внимание, что в выходных данных программы отображаются несколько доступных стилей для семейства шрифтов Arial, помимо обычного. Это связано с тем, что Windows GDI+ может имитировать полужирный, курсив и полужирный курсив из обычного стиля. GDI+ также может создавать из обычного стиля подчеркивание и перечеркивание.

Аналогичным образом, GDI+ может имитировать полужирный курсив из полужирного и курсивного стилей. Выходные данные программы показывают, что полужирный курсив доступен для семейства Times, несмотря на то, что TimesBd.tff (Times New Roman, полужирный) является единственным файлом Times в коллекции.

В этой таблице указаны несистемные шрифты, поддерживаемые GDI+.

Формат GDI GDI+ в Windows 7 GDI+ в Windows 8 DirectWrite
. FON да нет нет нет
. FNT да нет нет нет
. TTF да да да да
. OTF с TrueType да да да да
. OTF с Adobe CFF да нет да да
Adobe Type 1 да нет нет нет