Freigeben über


Zeichnen von Text aus verschiedenen Schriftarten in derselben Linie

Unterschiedliche Typstile innerhalb einer Schriftartenfamilie können unterschiedliche Breiten aufweisen. Beispielsweise sind fett formatierte und kursive Stile einer Familie für eine angegebene Punktgröße immer breiter als der romanische Stil. Wenn Sie mehrere Typarten in einer einzelnen Zeile anzeigen oder drucken, müssen Sie die Breite der Zeile nachverfolgen, um zu vermeiden, dass Zeichen übereinander angezeigt oder gedruckt werden.

Sie können zwei Funktionen verwenden, um die Breite (oder den Umfang) des Texts in der aktuellen Schriftart abzurufen. Die GetTabbedTextExtent-Funktion berechnet die Breite und Höhe einer Zeichenfolge. Wenn die Zeichenfolge ein oder mehrere Tabstoppzeichen enthält, basiert die Breite der Zeichenfolge auf einem angegebenen Array von Tabstopppositionen. Die GetTextExtentPoint32-Funktion berechnet die Breite und Höhe einer Textzeile.

Bei Bedarf synthetisiert das System eine Schriftart durch Ändern der Zeichenbittebits. Um ein Zeichen in einer fett formatierten Schriftart zu synthetisieren, zeichnet das System das Zeichen zweimal: am Anfangspunkt und erneut ein Pixel rechts neben dem Startpunkt. Um ein Zeichen in einer kursiv formatierten Schriftart zu synthetisieren, zeichnet das System zwei Zeilen von Pixeln am unteren Rand der Zeichenzelle, verschiebt den Startpunkt um ein Pixel nach rechts, zeichnet die nächsten beiden Zeilen und setzt fort, bis das Zeichen gezeichnet wurde. Durch Verschieben von Pixeln scheint jedes Zeichen nach rechts gestrichelt zu sein. Die Scherung ist eine Funktion der Höhe des Zeichens.

Eine Möglichkeit zum Schreiben einer Textzeile, die mehrere Schriftarten enthält, besteht darin, die GetTextExtentPoint32-Funktion nach jedem Aufruf von TextOut zu verwenden und die Länge einer aktuellen Position hinzuzufügen. Im folgenden Beispiel wird die Zeile "Dies ist eine Beispielzeichenfolge" geschrieben, wobei fett formatierte Zeichen für "This is a" verwendet werden, wechselt zu Kursivzeichen für "sample" und dann zurück zu fett formatierten Zeichen für "Zeichenfolge". Nach dem Drucken aller Zeichenfolgen werden die Standardzeichen des Systems wiederhergestellt.

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); 

In diesem Beispiel initialisiert die GetTextExtentPoint32-Funktion die Member einer SIZE-Struktur mit der Länge und Höhe der angegebenen Zeichenfolge. Die GetTextMetrics-Funktion ruft den Überhang für die aktuelle Schriftart ab. Da der Überhang null ist, wenn die Schriftart eine TrueType-Schriftart ist, ändert der Überhangwert die Zeichenfolgenplatzierung nicht. Für Rasterschriftarten ist es jedoch wichtig, den Überhangwert zu verwenden.

Der Überhang wird einmal von der fett formatierten Zeichenfolge subtrahiert, um nachfolgende Zeichen näher an das Ende der Zeichenfolge zu bringen, wenn die Schriftart eine Rasterschriftart ist. Da sich ein Überhang sowohl auf den Anfang als auch das Ende der Kursivzeichenfolge in einer Rasterschriftart auswirkt, beginnen die Glyphen rechts von der angegebenen Position und enden links neben dem Endpunkt der letzten Zeichenzelle. (Die GetTextExtentPoint32-Funktion ruft den Umfang der Zeichenzellen ab, nicht die Ausdehnung der Glyphen.) Um den Überhang in der kursiven Rasterzeichenfolge zu berücksichtigen, subtrahiert das Beispiel den Überhang vor dem Platzieren der Zeichenfolge und subtrahiert ihn erneut, bevor nachfolgende Zeichen platziert werden.

Die SetTextJustification-Funktion fügt den Umbruchzeichen in einer Textzeile zusätzlichen Platz hinzu. Sie können die GetTextExtentPoint-Funktion verwenden, um den Umfang einer Zeichenfolge zu bestimmen, dann diesen Bereich von der Gesamtmenge des Speicherplatzes subtrahieren, den die Zeile belegen soll, und die SetTextJustification-Funktion verwenden, um den zusätzlichen Leerraum auf die Umbruchzeichen in der Zeichenfolge zu verteilen. Die SetTextCharacterExtra-Funktion fügt jeder Zeichenzelle in der ausgewählten Schriftart, einschließlich des Umbruchzeichens, zusätzlichen Platz hinzu. (Sie können die GetTextCharacterExtra-Funktion verwenden, um die aktuelle Menge an zusätzlichem Speicherplatz zu bestimmen, der den Zeichenzellen hinzugefügt wird. Die Standardeinstellung ist null.)

Sie können Zeichen mit höherer Genauigkeit platzieren, indem Sie die Funktion GetCharWidth32 oder GetCharABCWidths verwenden, um die Breite einzelner Zeichen in einer Schriftart abzurufen. Die GetCharABCWidths-Funktion ist genauer als die GetCharWidth32-Funktion , kann aber nur mit TrueType-Schriftarten verwendet werden.

Abc-Abstand ermöglicht es einer Anwendung auch, eine sehr genaue Textausrichtung durchzuführen. Wenn die Anwendung z. B. eine römische Rasterschriftart ohne ABC-Abstand ausrichtet, wird die Erweiterte Breite als Zeichenbreite berechnet. Dies bedeutet, dass der Leerraum rechts neben der Glyphe in der Bitmap ausgerichtet ist, nicht die Glyphe selbst. Durch die Verwendung von ABC-Breiten haben Anwendungen mehr Flexibilität bei der Platzierung und Entfernung von Leerzeichen beim Ausrichten von Text, da sie Informationen haben, die es ihnen ermöglichen, den Interzeichenabstand fein zu steuern.