2009-04-14 10 views
0

Я рисую строку на холсте, используя GDI + на C++. Есть ли какой-либо API, чтобы вывести слой (ширину и высоту) строки в определенный шрифт? Большое спасибо! Большое спасибо решению программиста Windows. Я написал следующий код.Как получить длину и высоту слов при рисовании изображений на холсте в 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; 

Нужно ли использовать реальную графику для вызова MeasureString? Есть ли способ получить wordwidth, wordheight, без создания большого графического экземпляра? Я нашел, что это ресурс.

ответ

2

Графика :: MeasureString вычисляет приблизительное значение.

1

К сожалению, для этого вам необходимо использовать объект Graphics.

C# код я использую (который возвращает RectangleF, потому что я хочу знать, как ширину и высоту) выглядит следующим образом:

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

Это вернет RectangleF размера всего текста строка, обернутая слоем по мере необходимости, в соответствии с ограничивающей рамкой, указанной как __boundingBox. С положительной стороны объект Graphics уничтожается, как только завершается завершение выписки using ...

В качестве недостатка GDI + кажется довольно ненадежным; Я нашел, что это довольно плохо (см., Например, my question “Graphics.MeasureCharacterRanges giving wrong size calculations in C#.Net?”). Если вы можете использовать TextRenderer.DrawText от System.Windows.Forms, тогда сделайте.

1

Для полноты картины: он может просто быть сделано с GraphicsPath, что лучше, так как он не требует DeviceContext:

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 

Где текст данная строка и шрифт данного шрифта. Возвращает структуру SizeF. Я нашел результаты намного точнее, чем Graphics.MeasureString aka GdipMeasureString-API.