Creación de una colección de fuentes privadas
La clase PrivateFontCollection hereda de la clase base abstracta FontCollection . Puede usar un objeto PrivateFontCollection para mantener un conjunto de fuentes específicamente para la aplicación.
Una colección de fuentes privada puede incluir fuentes del sistema instaladas, así como fuentes que no se han instalado en el equipo. Para agregar un archivo de fuente a una colección de fuentes privada, llame al método PrivateFontCollection::AddFontFile de un objeto PrivateFontCollection .
Nota
Al usar la API de GDI+, nunca debe permitir que la aplicación descargue fuentes arbitrarias de orígenes que no son de confianza. El sistema operativo requiere privilegios elevados para asegurarse de que todas las fuentes instaladas son de confianza.
El método FontCollection::GetFamilies de un objeto PrivateFontCollection devuelve una matriz de objetos FontFamily . Antes de llamar a FontCollection::GetFamilies, debe asignar un búfer lo suficientemente grande como para contener esa matriz. Para determinar el tamaño del búfer necesario, llame al método FontCollection::GetFamilyCount y multiplique el valor devuelto por sizeof(FontFamily).
El número de familias de fuentes de una colección de fuentes privada no es necesariamente igual al número de archivos de fuente que se han agregado a la colección. Por ejemplo, supongamos que agrega los archivos ArialBd.tff, Times.tff y TimesBd.tff a una colección. Habrá tres archivos, pero solo dos familias en la colección, porque Times.tff y TimesBd.tff pertenecen a la misma familia.
En el ejemplo siguiente se agregan los tres archivos de fuente siguientes a un objeto PrivateFontCollection :
- C:\WINNT\Fonts\Arial.tff (Arial, normal)
- C:\WINNT\Fonts\CourBI.tff (Courier New, negrita cursiva)
- C:\WINNT\Fonts\TimesBd.tff (Times New Roman, bold)
El código llama al método FontCollection::GetFamilyCount del objeto PrivateFontCollection para determinar el número de familias de la colección privada y, a continuación, llama a FontCollection::GetFamilies para recuperar una matriz de objetos FontFamily .
Para cada objeto FontFamily de la colección, el código llama al método FontFamily::IsStyleAvailable para determinar si hay disponibles varios estilos (normal, negrita, cursiva, cursiva en negrita, subrayado y tachado). Los argumentos pasados al método FontFamily::IsStyleAvailable son miembros de la enumeración FontStyle , que se declara en Gdiplusenums.h.
Si hay disponible una combinación de estilo o familia determinada, se construye un objeto Font utilizando esa familia y estilo. El primer argumento pasado al constructor Font es el nombre de familia de fuentes (no un objeto FontFamily como sucede con otras variaciones del constructor Font ) y el argumento final es la dirección del objeto PrivateFontCollection . Una vez construido el objeto Font , su dirección se pasa al método DrawString de la clase Graphics para mostrar el nombre de familia junto con el nombre del estilo.
#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;
En la ilustración siguiente se muestra la salida del código anterior.
Arial.tff (que se agregó a la colección de fuentes privadas en el ejemplo de código anterior) es el archivo de fuente para el estilo normal de Arial. Observe que la salida del programa muestra varios estilos disponibles, además del normal, para la familia de fuentes Arial. Esto se debe a que Windows GDI+ puede simular los estilos en negrita, cursiva y cursiva en negrita del estilo normal. GDI+ también puede producir subrayados y tachados a partir del estilo normal.
Del mismo modo, GDI+ puede simular el estilo negrita cursiva a partir del estilo negrita o del estilo cursiva. En la salida del programa se muestra que el estilo negrita cursiva está disponible para la familia Times, aunque TimesBd.tff (Times New Roman, negrita) es el único archivo de Times de la colección.
Esta tabla especifica las fuentes que no son del sistema que admite GDI+.
Formato | GDI | GDI+ en Windows 7 | GDI+ en 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 |