2009-04-14 10 views
0

Ich zeichne eine Zeichenfolge auf einer Leinwand, mit GDI + in C++. Gibt es eine API, um die Out-Layer (Breite, Höhe) eines Strings in einer bestimmten Schriftart zu erhalten? Vielen Dank! Vielen Dank an Windows-Programmierer-Lösung. Ich habe den folgenden Code geschrieben.Wie erhalten Wörter Länge und Höhe, beim Zeichnen der Bilder auf einer Leinwand in GDI +

Bitmap bitmap(1000,1000); 
    Graphics graphics(&bitmap); 
    RectF rec; 
    RectF useless; 
    graphics.MeasureString(m_sWords, -1, m_pFont.get(), useless, &rec); 
    int WordWidth = rec.Width + 1; 
    int WordHeight Height = rec.Height + 1; 

Benötige ich eine echte Grafik, um MeasureString aufzurufen? Gibt es eine Möglichkeit, die Wortbreite WordHeight zu erhalten, ohne eine große Grafikinstanz zu erstellen? Ich habe festgestellt, dass es Ressourcenverbraucher ist.

Antwort

2

Graphics :: MeasureString berechnet eine Approximation.

1

Leider müssen Sie dazu ein Objekt Graphics verwenden.

Der C# -Code Ich verwende (die eine RectangleF zurückgibt, weil ich sowohl die Breite und die Höhe wissen wollen) ist wie folgt:

/// <summary> The text bounding box. </summary> 
private static readonly RectangleF __boundingBox = new RectangleF(29, 25, 90, 40); 

/// <summary> 
/// Gets the width of a given string, in the given font, with the given 
/// <see cref="StringFormat"/> options. 
/// </summary> 
/// <param name="text">The string to measure.</param> 
/// <param name="font">The <see cref="Font"/> to use.</param> 
/// <param name="fmt">The <see cref="StringFormat"/> to use.</param> 
/// <returns> The floating-point width, in pixels. </returns> 
private static RectangleF GetStringBounds(string text, Font font, 
    StringFormat fmt) 
{ 
    CharacterRange[] range = { new CharacterRange(0, text.Length) }; 
    StringFormat myFormat = fmt.Clone() as StringFormat; 
    myFormat.SetMeasurableCharacterRanges(range); 

    using (Graphics g = Graphics.FromImage(
     new Bitmap((int) __boundingBox.Width, (int) __boundingBox.Height))) 
    { 
     Region[] regions = g.MeasureCharacterRanges(text, font, 
     __boundingBox, myFormat); 
     return regions[0].GetBounds(g); 
    } 
} 

Dies wird eine RectangleF der Größe des gesamten Textes zurückkehren Zeichenkette, die bei Bedarf mit einem Wort umbrochen wird, entsprechend der Begrenzungsbox, die als __boundingBox angegeben ist. Auf der positiven Seite ist das Graphics Objekt zerstört, sobald die using Anweisung abgeschlossen ist ...

Nebenbei scheint GDI + ziemlich unzuverlässig zu sein; Ich habe festgestellt, dass es ziemlich fehlerhaft ist (siehe zum Beispiel my question “Graphics.MeasureCharacterRanges giving wrong size calculations in C#.Net?”). Wenn Sie TextRenderer.DrawText von System.Windows.Forms verwenden können, dann tun.

1

Um das Bild komplett zu machen: Es kann einfach mit einem Graphic erfolgen, die, da sie erfordert keine Device besser ist:

Dim p As New GraphicsPath 

Using stringFormat As New StringFormat() 
    stringFormat.Trimming = StringTrimming.EllipsisCharacter 
    stringFormat.LineAlignment = StringAlignment.Center 
    stringFormat.Alignment = StringAlignment.Near 

    p.AddString(text, font.FontFamily, font.Style, font.SizeInPoints, Point.Empty, stringFormat) 
End Using 

Return p.GetBounds.Size 

Wo Text ist eine Zeichenkette und Schriftart eine bestimmte Schriftart. Gibt eine SizeF-Struktur zurück. Ich habe festgestellt, dass die Ergebnisse viel genauer sind als Graphics.MeasureString alias GdipMeasureString-API.