Get character index based on Width

Asked

Viewed 72 times

3

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, simply:

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

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

Imagine that imageWidth = 644, but the result in textoWidth is greater than 644. Then I’ll need to know which character to overcome imageWidth.

  • First, call the Dispose() at hand is not a good idea. Second, this method variable statement is very strange. I could be wrong, but I doubt it’s possible to determine this without an extremely complex algorithm. It would be easier if it were guaranteed that the fountain was mono-spaced.

  • Thank you so much for the @bigown tips. I’m a junior dev yet, and I’d like to know what the problem is with calling Dispose() at hand? Is there a better alternative? What would be a mono-spaced font and how could I ensure that my string is a?

  • 3

    The problem of using the Dipose() at hand is the lack of assurance that it will be called. The best alternative is to use the block using that is nothing more than a try-finally what call Dispose. A source mono-espaçada é uma fonte onde todos os caracteres ocupam exatamente o mesmo espaço.

  • If there is an exception, he will not be called. http://answall.com/q/41175/101 and http://answall.com/q/22284/101. If this is not sufficient, ask a question about this. The mono font has all characters of the same width. Here it is easy to calculate the size of each one. There must be information inside the source that indicates that it is mono. I would need to search. But I don’t know if you want to guarantee this, it limits quite.

1 answer

2


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

My tip is: Take a letter from 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

Thank you so much for the @Maniero tips. I’m a junior dev still, and I’d like to know what the problem is with calling Dispose() at hand? Is there a better alternative? What would be a mono-spaced font and how could I ensure that my string is a?

  1. The problem of calling Dispose() in the hand is that you have no guarantee that it will run. This is because in the middle of the route (between the variable declaration and the Dispose()) it is possible that some exception will be launched and this will make with the Dipose() not be executed.

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

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

    Just out of curiosity, this block does exactly the same thing

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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.