建立私人字型集合
PrivateFontCollection 類別繼承自 FontCollection 抽象基類。 您可以使用 PrivateFontCollection 物件來維護應用程式專用的一組字型。
私人字型集合可以包含已安裝的系統字型,以及計算機上尚未安裝的字型。 若要將字型檔案新增至私人字型集合,請呼叫 PrivateFontCollection 物件的 PrivateFontCollection::AddFontFile 方法。
注意
當您使用 GDI+ API 時,絕不會允許應用程式從不受信任的來源下載任意字型。 作系統需要更高的許可權,以確保所有已安裝的字型都受信任。
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.ttf(Courier New,粗斜體)
- 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;
下圖顯示上述程式代碼的輸出。
Arial.tff (在上述程式代碼範例中新增至私人字型集合) 是 Arial 一般樣式的字型檔案。 不過請注意,程序輸出會針對 Arial 字型系列顯示數個可用的樣式,而非一般樣式。 因為 Windows GDI+ 能夠從標準樣式模擬出粗體、斜體以及粗體斜體樣式。 GDI+ 也可以從一般字體樣式產生底線和刪除線。
同樣地,GDI+ 可以從粗體樣式或斜體樣式模擬粗體斜體樣式。 程序輸出顯示,儘管 TimesBd.tff (Times New Roman, bold) 是集合中唯一的 Times 檔案,但粗體斜體樣式仍可供 Times 系列使用。
下表指定 GDI+ 支援的非系統字型。
格式 | GDI | Windows 7 上的 GDI+ | Windows 8 上的 GDI+ | DirectWrite |
---|---|---|---|---|
.FON | 是的 | 不 | 不 | 不 |
.FNT | 是的 | 不 | 不 | 不 |
.TTF | 是的 | 是的 | 是的 | 是的 |
.OTF 搭配 TrueType | 是的 | 是的 | 是的 | 是的 |
.OTF 與 Adobe CFF | 是的 | 不 | 是的 | 是的 |
Adobe Type 1 | 是的 | 不 | 不 | 不 |