views:

128

answers:

2

I draw a string on a canvas, using GDI+ in C++. Is there any API to get the out layer (width, height ) of a string in a certain font? Thanks very much! Many thanks to Windows programmer's solution. I wrote the following code.

 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;

Need I use a real graphics to call MeasureString? Is there any way to get wordwidth,wordheight, without create a large Graphics Instance? I found it is resource comsuming.

+1  A: 

Graphics::MeasureString computes an approximation.

Windows programmer
+1  A: 

Unfortunately you do need to use a Graphics object to do this.

The code I use (which returns a RectangleF, because I want to know both the width and the height) is as follows:

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

This will return a RectangleF of the size of the entire text string, word-wrapped as necessary, according to the bounding box specified as __boundingBox. On the plus side, the Graphics object is destroyed as soon as the using statement is complete…

Owen Blacker
As an aside, GDI+ seems to be pretty unreliable at this; I've found it to be quite buggy (see <a href="http://stackoverflow.com/questions/2684894">issue 2684894</a>). If you can use regular GDI (or whatever Windows Presentation Foundation uses, if that's different), then do.And, obviously, my code sample was in C#, not C++. Sorry, it was crap of me not to have mentioned that at the time.
Owen Blacker