c# – Get character index based on Width

Question:

I have the following method to calculate the width of a text:

public float GetWidthOfString(string str, Font font, int bitmapWidth, int bitmapHeight)
{
        Bitmap objBitmap = default(Bitmap);
        Graphics objGraphics = default(Graphics);

        objBitmap = new Bitmap(bitmapWidth, bitmapHeight);
        objGraphics = Graphics.FromImage(objBitmap);

        SizeF stringSize = objGraphics.MeasureString(str, font);

        objBitmap.Dispose();
        objGraphics.Dispose();
        return stringSize.Width;
}

To use the method, just:

var font = new Font("Arial", 50, FontStyle.Bold);
var texto = "Stackoverflow em Português";

var textoWidth = GetWidthOfString(texto, font, imageWidth, imageHeight);

imageWidth = 644 that imageWidth = 644 , but the result in textoWidth is greater than 644 . So I'm going to need to know from which character imageWidth to pass imageWidth .

Answer:

I don't think there's anything ready for that.

My tip is: Take a letter out of the text while the text is longer than the image.

Ex.:

while(texto.Length > imagem.Width)
{
    texto = texto.Remove(texto.Length - 1);
}

About your question in the comment

Thanks so much for the @Maniero tips. I'm still junior dev, and would like to know what's the problem with calling Dispose() by hand? Is there a better alternative? What would a monospaced font be and how could I guarantee that my string is one?

  1. The problem with calling Dispose() by hand is that you are not guaranteed that it will be executed. This is because in the middle of the path (between the variable declaration and Dispose() ) it is possible that an exception is thrown and this will cause Dipose() not to be executed.

  2. Yes, there is a better alternative. You can "circle" your variable in a using block, causing Dispose() be called automatically after using it. Ex.:

     using(var objBitmap = new Bitmap(bitmapWidth, bitmapHeight)) { // Ao final desse bloco, o Dispose será chamado }

    Just for the sake of curiosity, this block does the exact same thing as

     var objBitmap = new Bitmap(bitmapWidth, bitmapHeight); try{ // Fazer alguma coisa }finally{ objBitmap.Dispose(); }
  3. Monospaced fonts are fonts where all characters are exactly the same width, this makes it easy to calculate how much space a particular word, phrase or text will take up.

Scroll to Top