개인 글꼴 컬렉션 만들기

PrivateFontCollection 클래스는 FontCollection 추상 기본 클래스에서 상속됩니다. PrivateFontCollection 개체를 사용하여 애플리케이션에 맞게 특별히 글꼴 집합을 유지할 수 있습니다.

프라이빗 글꼴 컬렉션에는 컴퓨터에 설치되지 않은 글꼴뿐만 아니라 설치된 시스템 글꼴도 포함될 수 있습니다. 개인 글꼴 컬렉션에 글꼴 파일을 추가하려면 PrivateFontCollection 개체의 PrivateFontCollection::AddFontFile 메서드를 호출합니다.

참고

GDI+ API를 사용하는 경우 애플리케이션이 신뢰할 수 없는 원본에서 임의의 글꼴을 다운로드하도록 허용해서는 안 됩니다. 운영 체제에는 설치된 모든 글꼴을 신뢰할 수 있도록 하기 위해 상승된 권한이 필요합니다.

 

PrivateFontCollection 개체의 FontCollection::GetFamilies 메서드는 FontFamily 개체의 배열을 반환합니다. FontCollection::GetFamilies를 호출하기 전에 해당 배열을 보유할 수 있을 만큼 큰 버퍼를 할당해야 합니다. 필요한 버퍼의 크기를 확인하려면 FontCollection::GetFamilyCount 메서드를 호출하고 반환 값을 sizeof(FontFamily)로 곱합니다.

프라이빗 글꼴 컬렉션의 글꼴 패밀리 수가 반드시 컬렉션에 추가된 글꼴 파일 수와 동일하지는 않습니다. 예를 들어 ArialBd.tff, Times.tff, TimesBd.tff 파일을 컬렉션에 추가한다고 가정합니다. Times.tff와 TimesBd.tff가 같은 패밀리에 속하기 때문에 컬렉션에는 3개의 파일이 있지만 2개의 패밀리만 있습니다.

다음 예제에서는 다음 세 글꼴 파일을 PrivateFontCollection 개체에 추가합니다.

  • C:\WINNT\Fonts\Arial.tff(Arial, regular)
  • C:\WINNT\Fonts\CourBI.tff(Courier New, bold italic)
  • C:\WINNT\Fonts\TimesBd.tff(Times New Roman, bold)

이 코드는 PrivateFontCollection 개체의 FontCollection::GetFamilyCount 메서드를 호출하여 프라이빗 컬렉션의 패밀리 수를 확인한 다음 FontCollection::GetFamilies를 호출하여 FontFamily 개체의 배열을 검색합니다.

컬렉션의 각 FontFamily 개체에 대해 코드는 FontFamily::IsStyleAvailable 메서드를 호출하여 다양한 스타일(일반, 굵게, 기울임꼴, 굵은 기울임꼴, 밑줄 및 취소선)을 사용할 수 있는지 여부를 결정합니다. FontFamily::IsStyleAvailable 메서드에 전달된 인수는 Gdiplusenums.h에 선언된 FontStyle 열거형의 멤버입니다.

특정 패밀리/스타일 조합을 사용할 수 있는 경우 Font 개체는 해당 패밀리 및 스타일을 사용하여 생성됩니다. Font 생성자에 전달된 첫 번째 인수는 글꼴 패밀리 이름(FontFamily 개체가 아닌 Font 생성자의 다른 변형에 대한 경우)이며, 마지막 인수는 PrivateFontCollection 개체의 주소입니다. Font 개체가 생성되면 해당 주소가 Graphics 클래스의 DrawString 메서드에 전달되어 스타일 이름과 함께 패밀리 이름을 표시합니다.

#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;
            

다음 그림에서는 이전 코드의 출력을 보여 줍니다.

각각 명명된 글꼴을 보여 주는 9개의 글꼴 이름을 나열하는 창의 스크린샷

이전 코드 예제에서 개인 글꼴 컬렉션에 추가된 Arial.tff는 Arial 일반 스타일의 글꼴 파일입니다. 그러나 프로그램 출력에는 Arial 글꼴 패밀리에 대해 일반 스타일이 아닌 여러 가지 사용 가능한 스타일이 표시됩니다. Windows GDI+는 일반 스타일에서 굵게, 기울임꼴 및 굵은 기울임꼴 스타일을 시뮬레이션할 수 있기 때문입니다. GDI+는 일반 스타일에서 밑줄과 취소선을 생성할 수도 있습니다.

마찬가지로 GDI+는 굵은 스타일 또는 기울임꼴 스타일에서 굵은 기울임꼴 스타일을 시뮬레이션할 수 있습니다. 프로그램 출력은 TimesBd.tff(Times New Roman, 굵게)가 컬렉션의 유일한 Times 파일임에도 불구하고 Times 패밀리에서 굵은 기울임꼴 스타일을 사용할 수 있음을 보여 줍니다.

이 표에서는 GDI+에서 지원하는 비시스템 글꼴을 지정합니다.

서식 GDI Windows 7의 GDI+ Windows 8 GDI+ DirectWrite
. 폰 아니요 아니요 아니요
. Fnt 아니요 아니요 아니요
. Ttf
. TrueType을 사용하여 OTF
. Adobe CFF를 사용하여 OTF 아니요
Adobe Type 1 아니요 아니요 아니요