C# Como agregar fuentes true type fonts .ttf a proyecto de visual c# express, visual studio, etc

Al crear una aplicación, proyecto o (solución) en C# Express, Visual Studio 2005, Visual Studio 2008 etc, se pueden elegir las fuentes que uno desea muy fácilmente, simplemente eligiéndolas desde las propiedades de una solucion "Window Form ".

Pero el problema no esta aqui, que pasa si en el ordenador que la aplicación va a correr no se encuentra esa fuente?. Bueno, en ese caso, la tenemos que poner como un recurso embebido en la aplicación.

Ahora, si la fuente no es de las "comunes" como "Arial" , "Verdana" etc... No se pueden elegir así nada mas.

Tenemos que incluirlas a los recursos, luego marcar que sea interpretada como una cadena de bits, y por ultimo la cargaremos por medio de un flujo o "stream" a un objeto de la clase PrivateFontCollection.


AQUI ESTA TODO DETALLADO EN 6 PASOS

Paso 1:
Agregamos el archivo .ttf a los recursos (click derecho en el nombre de la solución y propiedades)

Paso 2:

Se va a abrir una solapa con las opciones o propiedades de nuestro proyecto.
Ir a Resources o Recursos y elegir Add Existing File o Añadir archivo existente y



navegaremos hasta donde tenemos el archivo .ttf





Paso 3:

Cambiamos las propiedades del recurso añadido (la fuente .ttf), Para ello hacemos click en
el objeto agregado al recurso y en la derecha, en las propiedades veremos que el tipo de archivo es Binario o Binary, si no es así lo indicamos para que así sea




Paso 4:

En el explorador de soluciones, veremos la carpeta Resources creada, y dentro de esta nuestro archivo .ttf, a este hacerle click derecho y propiedades




Cambiar en "Build Action" a "Embedded Resource" para que la fuente quede en el ejecutable (dentro).




Paso 5: (CÓDIGO)

INCLUIR ESTO:

VERSION TEXTOusing System.Runtime.InteropServices;
using System.Drawing.Text;




Dentro de la clase hay que hacer un llamado al gdi32.dll, de esta forma




VERSION TEXTO
[DllImport("gdi32.dll")]
private static extern IntPtr AddFontMemResourceEx(IntPtr pbFont, uint cbFont, IntPtr pdv, [In] ref uint pcFonts);



noten que he creado dos objetos, uno de tipo FontFamily llamado ff y uno de tipo Font llamado font.

FontFamily ff;
Font font;

Ahora creo 2 métodos, uno carga el PrivateFontCollection y el otro solo aplica la fuente a la etiqueta.

el primero es así.






VERSION TEXTO

private void CargoPrivateFontCollection()
{
// CREO EL BYTE[] Y TOMO SU LONGITUD
byte[] fontArray = FuentesTTF.Properties.Resources.Baby_Universe;
int dataLength = FuentesTTF.Properties.Resources.Baby_Universe.Length;


// ASIGNO MEMORIA Y COPIO BYTE[] EN LA DIRECCION
IntPtr ptrData = Marshal.AllocCoTaskMem(dataLength);
Marshal.Copy(fontArray, 0, ptrData, dataLength);


uint cFonts = 0;
AddFontMemResourceEx(ptrData, (uint)fontArray.Length, IntPtr.Zero, ref cFonts);

PrivateFontCollection pfc = new PrivateFontCollection();
//PASO LA FUENTE A LA PRIVATEFONTCOLLECTION
pfc.AddMemoryFont(ptrData, dataLength);

//LIBERO LA MEMORIA "UNSAFE"
Marshal.FreeCoTaskMem(ptrData);

ff = pfc.Families[0];
font = new Font(ff, 15f, FontStyle.Bold);
}


El segundo metodo solo carga la etiqueta llamada "label1" (la parque que tapa la w es
this.label1.Font = new Font(ff, 20, fontStyle);






VERSION TEXTO

private void CargoEtiqueta(Font font)
{
float size = 11f;
FontStyle fontStyle = FontStyle.Regular;

this.label1.Font = new Font(ff, 20, fontStyle);

}



Paso 6:

Invoco los métodos CargoPrivateFontCollection() y CargoEtiqueta(Font font), Yo los llame desde el el evento LOAD del window form, para que la fuente aparezca cambiada de entrada, pero también puede hacerse en un evento click, etc.




VERSION TEXTO

private void Form1_Load(object sender, EventArgs e)
{
CargoPrivateFontCollection();
CargoEtiqueta(font);
}



Paso 7 : LISTO!

Ya esta, solo resta compilarlo y ejecutarlo






NOTA: IMPORTANTE!!!!!!

CUANDO CREAN LA FUENTE DENTRO DEL METODO CargoPrivateFontCollection()
USEN UN FontStyle ADECUADO A ESA FUENTE
en el ejmplo utilizé "FontStyle.Bold " porque es un estilo que se que la fuente tiene, SI NO LO HACEN, QUEDARA UNA FUENTE POR DEFECTO PORQUE NO SE PUDO CREAR EL OBJETO CORRECTAMENTE.


Para descargar muchas fuentes ttf gratuitas ir www.creamundo.com.










Espero que les haya servido!!!!!!!!.



QUIZAS QUIERAS LEER TAMBIEN:
 
 
 

9 comments:

  1. me marca error en esta linea.
    byte[] fontArray = FuentesTTF.Properties.Resources.Baby_Universe;

    FuentesTTF no existe en el contexto actual

    ReplyDelete
  2. +1
    FuentesTTF no existe en el contexto actual

    ReplyDelete
    Replies
    1. FuentesTTF debe llamarse el nombre de tu proyecto, si no se llama igual no lo vas a encontrar, del mismo modo ocurriria con la fuente Baby_Universe si por ejemplo vos decidieras agregar otra tipografia. Saludos

      Delete
    2. Gracias por contestarle :)

      Delete
  3. internal static void InstalarFuente(string NombreFnt,string RutaFnt)
    {
    string CMD = string.Format("copy /Y \"{0}\" \"%WINDIR%\\Fonts\" ", RutaFnt);
    EjecutarCMD(CMD);

    System.IO.FileInfo FInfo = new System.IO.FileInfo(RutaFnt);
    CMD = string.Format("reg add \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts\" /v \"{0}\" /t REG_SZ /d {1} /f", NombreFnt, FInfo.Name);

    EjecutarCMD(CMD);
    }

    public static void EjecutarCMD(string Comando)
    {
    System.Diagnostics.ProcessStartInfo Info = new System.Diagnostics.ProcessStartInfo("cmd.exe");
    Info.Arguments = string.Format("/c {0}", Comando);
    Info.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
    System.Diagnostics.Process.Start(Info);
    }

    ReplyDelete
  4. Super!! funciona al 100%...muchas gracias

    ReplyDelete
  5. No me funciona el:

    //PASO LA FUENTE A LA PRIVATEFONTCOLLECTION
    pfc.AddMemoryFont(ptrData, dataLength);

    Me indica que no existe.

    Espero su ayuda porfavor.

    ReplyDelete
  6. This comment has been removed by the author.

    ReplyDelete
  7. Impresionante, muchas gracias... Ahora se podría usar segoeui symbol en windows xp...

    Muchas gracias por el método, hacia rato lo buscaba y ahora por accidente me lo cruce.

    ReplyDelete