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


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

Класс 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, обычный)
  • 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, является имя семейства шрифтов (а не объект FontFamily, как в случае с другими вариантами конструктора Font), а последним аргументом является адрес объекта PrivateFontCollection. После создания объекта шрифта его адрес передается методу 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
. ФОН да Нет Нет Нет
. FNT да Нет Нет Нет
.TTF да да да да
.OTF с TrueType да да да да
.OTF с Adobe CFF да Нет да да
Adobe Type 1 да Нет Нет Нет