Creazione di raccolte private di tipi di carattere
La classe PrivateFontCollection eredita dalla classe base astratta FontCollection . È possibile utilizzare un oggetto PrivateFontCollection per gestire un set di tipi di carattere specifico per l'applicazione.
Una raccolta di caratteri privati può includere tipi di carattere di sistema installati, nonché tipi di carattere non installati nel computer. Per aggiungere un file di tipo di carattere a una raccolta di tipi di carattere privato, chiamare il metodo PrivateFontCollection::AddFontFile di un oggetto PrivateFontCollection .
Nota
Quando si usa l'API GDI+, non è mai necessario consentire all'applicazione di scaricare tipi di carattere arbitrari da origini non attendibili. Il sistema operativo richiede privilegi elevati per garantire che tutti i tipi di carattere installati siano attendibili.
Il metodo FontCollection::GetFamilies di un oggetto PrivateFontCollection restituisce una matrice di oggetti FontFamily . Prima di chiamare FontCollection::GetFamilies, è necessario allocare un buffer di dimensioni sufficienti per contenere tale matrice. Per determinare le dimensioni del buffer necessario, chiamare il metodo FontCollection::GetFamilyCount e moltiplicare il valore restituito per sizeof(FontFamily).
Il numero di famiglie di caratteri in una raccolta di tipi di carattere privato non corrisponde necessariamente al numero di file di carattere aggiunti alla raccolta. Si supponga, ad esempio, di aggiungere i file ArialBd.tff, Times.tff e TimesBd.tff a una raccolta. Nella raccolta saranno presenti tre file, ma solo due famiglie perché Times.tff e TimesBd.tff appartengono alla stessa famiglia.
Nell'esempio seguente vengono aggiunti i tre file di carattere seguenti a un oggetto PrivateFontCollection :
- C:\WINNT\Fonts\Arial.tff (Arial, regular)
- C:\WINNT\Fonts\CourBI.tff (Courier New, grassetto corsivo)
- C:\WINNT\Fonts\TimesBd.tff (Times New Roman, bold)
Il codice chiama il metodo FontCollection::GetFamilyCount dell'oggetto PrivateFontCollection per determinare il numero di famiglie nell'insieme privato e quindi chiama FontCollection::GetFamilies per recuperare una matrice di oggetti FontFamily .
Per ogni oggetto FontFamily nell'insieme, il codice chiama il metodo FontFamily::IsStyleAvailable per determinare se sono disponibili vari stili (regolare, grassetto, corsivo, corsivo, sottolineato e barrato). Gli argomenti passati al metodo FontFamily::IsStyleAvailable sono membri dell'enumerazione FontStyle , dichiarata in Gdiplusenums.h.
Se è disponibile una particolare combinazione di famiglia/stile, un oggetto Font viene costruito utilizzando tale famiglia e stile. Il primo argomento passato al costruttore Font è il nome della famiglia di caratteri (non un oggetto FontFamily come per altre varianti del costruttore Font ) e l'argomento finale è l'indirizzo dell'oggetto PrivateFontCollection . Dopo aver costruito l'oggetto Font , il relativo indirizzo viene passato al metodo DrawString della classe Graphics per visualizzare il nome della famiglia insieme al nome dello stile.
#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;
La figura seguente mostra l'output del codice precedente.
Arial.tff (che è stato aggiunto alla raccolta di tipi di carattere privato nell'esempio di codice precedente) è il file di carattere per lo stile regolare Arial. Si noti, tuttavia, che l'output del programma mostra diversi stili disponibili diversi da quelli normali per la famiglia di caratteri Arial. Questo avviene perché Windows GDI+ può simulare gli stili grassetto, corsivo e grassetto dallo stile regolare. GDI+ può anche produrre sottolineature e strikeout dallo stile regolare.
Analogamente, GDI+ può simulare lo stile corsivo grassetto dallo stile grassetto o dal corsivo. L'output del programma mostra che lo stile corsivo grassetto è disponibile per la famiglia Times anche se TimesBd.tff (Times New Roman, bold) è l'unico file Times nella raccolta.
Questa tabella specifica i tipi di carattere non di sistema supportati da GDI+.
Formato | GDI | GDI+ in Windows 7 | GDI+ su Windows 8 | DirectWrite |
---|---|---|---|---|
. FON | sì | no | no | no |
. FNT | sì | no | no | no |
. TTF | sì | sì | sì | sì |
. OTF con TrueType | sì | sì | sì | sì |
. OTF con Adobe CFF | sì | no | sì | sì |
Adobe Type 1 | sì | no | no | no |