Compartir a través de


Dibujar texto de diferentes fuentes en la misma línea

Los distintos estilos de tipo dentro de una familia de fuentes pueden tener distintos anchos. Por ejemplo, los estilos negrita y cursiva de una familia siempre son más amplios que el estilo romano para un tamaño de punto especificado. Al mostrar o imprimir varios estilos de tipo en una sola línea, debe realizar un seguimiento del ancho de la línea para evitar que los caracteres se muestren o impriman entre sí.

Puede usar dos funciones para recuperar el ancho (o extensión) del texto en la fuente actual. La función GetTabbedTextExtent calcula el ancho y el alto de una cadena de caracteres. Si la cadena contiene uno o varios caracteres de tabulación, el ancho de la cadena se basa en una matriz especificada de posiciones de tabulación. La función GetTextExtentPoint32 calcula el ancho y alto de una línea de texto.

Cuando sea necesario, el sistema sintetiza una fuente cambiando los mapas de bits de caracteres. Para sintetizar un carácter en una fuente negrita, el sistema dibuja el carácter dos veces: en el punto inicial y de nuevo un píxel a la derecha del punto inicial. Para sintetizar un carácter en una fuente en cursiva, el sistema dibuja dos filas de píxeles en la parte inferior de la celda de caracteres, mueve el punto inicial de un píxel a la derecha, dibuja las dos filas siguientes y continúa hasta que se haya dibujado el carácter. Al cambiar los píxeles, cada carácter parece ser desarchado a la derecha. La cantidad de es una función del alto del carácter.

Una manera de escribir una línea de texto que contiene varias fuentes es usar la función GetTextExtentPoint32 después de cada llamada a TextOut y agregar la longitud a una posición actual. En el ejemplo siguiente se escribe la línea "This is a sample string". using bold characters for "This is a", switch to italic characters for "sample" (Esto es una cadena de ejemplo). Después, vuelve a caracteres en negrita para "string". Después de imprimir todas las cadenas, restaura los caracteres predeterminados del sistema.

int XIncrement; 
int YStart; 
TEXTMETRIC tm; 
HFONT hfntDefault, hfntItalic, hfntBold; 
SIZE sz; 
LPSTR lpszString1 = "This is a "; 
LPSTR lpszString2 = "sample "; 
LPSTR lpszString3 = "string."; 
HRESULT hr;
size_t * pcch;
 
// Create a bold and an italic logical font.  
 
hfntItalic = MyCreateFont(); 
hfntBold = MyCreateFont(); 
 
 
// Select the bold font and draw the first string  
// beginning at the specified point (XIncrement, YStart).  
 
XIncrement = 10; 
YStart = 50; 
hfntDefault = SelectObject(hdc, hfntBold); 
hr = StringCchLength(lpszString1, 11, pcch);
        if (FAILED(hr))
        {
        // TODO: write error handler 
        }
TextOut(hdc, XIncrement, YStart, lpszString1, *pcch); 
 
// Compute the length of the first string and add  
// this value to the x-increment that is used for the  
// text-output operation.  

hr = StringCchLength(lpszString1, 11, pcch);
        if (FAILED(hr))
        {
        // TODO: write error handler 
        } 
GetTextExtentPoint32(hdc, lpszString1, *pcch, &sz); 
XIncrement += sz.cx; 
 
// Retrieve the overhang value from the TEXTMETRIC  
// structure and subtract it from the x-increment.  
// (This is only necessary for non-TrueType raster  
// fonts.)  
 
GetTextMetrics(hdc, &tm); 
XIncrement -= tm.tmOverhang; 
 
// Select an italic font and draw the second string  
// beginning at the point (XIncrement, YStart).  
 
hfntBold = SelectObject(hdc, hfntItalic); 
GetTextMetrics(hdc, &tm); 
XIncrement -= tm.tmOverhang;
hr = StringCchLength(lpszString2, 8, pcch);
        if (FAILED(hr))
        {
        // TODO: write error handler 
        } 
TextOut(hdc, XIncrement, YStart, lpszString2, *pcch); 
 
// Compute the length of the second string and add  
// this value to the x-increment that is used for the  
// text-output operation.  

hr = StringCchLength(lpszString2, 8, pcch);
        if (FAILED(hr))
        {
        // TODO: write error handler 
        }  
GetTextExtentPoint32(hdc, lpszString2, *pcch, &sz); 
XIncrement += sz.cx; 
 
// Reselect the bold font and draw the third string  
// beginning at the point (XIncrement, YStart).  
 
SelectObject(hdc, hfntBold);
hr = StringCchLength(lpszString3, 8, pcch);
        if (FAILED(hr))
        {
        // TODO: write error handler 
        }  
TextOut(hdc, XIncrement - tm.tmOverhang, YStart, lpszString3, 
            *pcch); 
 
// Reselect the original font.  
 
SelectObject(hdc, hfntDefault); 
 
// Delete the bold and italic fonts.  
 
DeleteObject(hfntItalic); 
DeleteObject(hfntBold); 

En este ejemplo, la función GetTextExtentPoint32 inicializa los miembros de una estructura SIZE con la longitud y el alto de la cadena especificada. La función GetTextMetrics recupera el voladizo de la fuente actual. Dado que el voladizo es cero si la fuente es una fuente TrueType, el valor de voladizo no cambia la ubicación de la cadena. Sin embargo, en el caso de las fuentes ráster, es importante usar el valor de voladizo.

El voladizo se resta de la cadena en negrita una vez, para acercar los caracteres posteriores al final de la cadena si la fuente es una fuente ráster. Dado que el voladizo afecta tanto al principio como al final de la cadena en cursiva en una fuente ráster, los glifos comienzan a la derecha de la ubicación especificada y terminan a la izquierda del extremo de la última celda de caracteres. (La función GetTextExtentPoint32 recupera la extensión de las celdas de caracteres, no la extensión de los glifos). Para tener en cuenta el voladizo en la cadena cursiva raster, el ejemplo resta el voladizo antes de colocar la cadena y lo resta de nuevo antes de colocar caracteres posteriores.

La función SetTextJustification agrega espacio adicional a los caracteres de interrupción en una línea de texto. Puede usar la función GetTextExtentPoint para determinar la extensión de una cadena y, a continuación, restar esa extensión de la cantidad total de espacio que debe ocupar la línea y usar la función SetTextJustification para distribuir el espacio adicional entre los caracteres de interrupción de la cadena. La función SetTextCharacterExtra agrega espacio adicional a cada celda de caracteres de la fuente seleccionada, incluido el carácter de interrupción. (Puede usar la función GetTextCharacterExtra para determinar la cantidad actual de espacio adicional que se va a agregar a las celdas de caracteres; el valor predeterminado es cero).

Puede colocar caracteres con mayor precisión mediante la función GetCharWidth32 o GetCharABCWidths para recuperar los anchos de caracteres individuales en una fuente. La función GetCharABCWidths es más precisa que la función GetCharWidth32 , pero solo se puede usar con fuentes TrueType.

El espaciado ABC también permite a una aplicación realizar una alineación de texto muy precisa. Por ejemplo, cuando la derecha de la aplicación alinea una fuente romana ráster sin usar el espaciado ABC, el ancho avanzado se calcula como el ancho del carácter. Esto significa que el espacio en blanco a la derecha del glifo del mapa de bits está alineado, no el propio glifo. Mediante el uso de anchos ABC, las aplicaciones tienen más flexibilidad en la colocación y eliminación de espacios en blanco al alinear el texto, ya que tienen información que les permite controlar el espaciado intercalado de forma fina.