How many characters fit in an area?

  • Thread starter Thread starter Chris Austin
  • Start date Start date
C

Chris Austin

Hi,

I have an arbitrary string value and wish to determine how many characters
from that string will fit in a specified area with a specific font when
drawn.

I have looked at MeasureString and MeasureCharacterRanges, but neither of
these seems to provide this function.

So given the string "ABCDEFGHIJKL", I can draw that string, such that it is
clipped to an area, but I need to know how much of that string is visible.

Can anyone help,

Chris
 
Chris said:
Hi,

I have an arbitrary string value and wish to determine how many characters
from that string will fit in a specified area with a specific font when
drawn.

I have looked at MeasureString and MeasureCharacterRanges, but neither of
these seems to provide this function.

So given the string "ABCDEFGHIJKL", I can draw that string, such that it is
clipped to an area, but I need to know how much of that string is visible.

All I can propose is that you binary search for the length of the
longest substring that will fit. That is, repeatedly MeasureString on
the first n characters of the string, until you find the greatest n
that will fit. Or just linear search (for simpler code), if these
strings are going to be small.
 
I have an arbitrary string value and wish to determine how many characters
from that string will fit in a specified area with a specific font when
drawn.

With all fonts except for fixed-width fonts, the width of a character is different for each character. If one is working with an unknown set of characters, it is therefore impossible to pre-determine how many of any combination of them will fit into an area. That would be like guessing how many numbers add up to 100. Consider the illustration below:

R a N D o M s T r I n G
7 6 7 8 5 9 5 8 4 1 5 9


I measured each character in pixels on my machine. Now, tell me, without using this particular string, how many Arial 10 point characters could fit into an area 100 pixels wide? If they were all "I" you could fit nearly 100 of them (you would have to subtract for spacing). If they were all "M" you could only fit about 9.

That is why the Graphics.MeasureString method must have a String to measure.

So, knowing that this is true, you need to take a fresh look at your requirement, and find a different way of fulfilling it.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer

Presuming that God is "only an idea" -
Ideas exist.
Therefore, God exists.
 
I understand that. However, using MeasureString, you can get the width of a string when rendered with a specific font.

What I want is given a specific width, how much of a specific (it changes, but you will always know what it is) string can be rendered in that space.

As a previous poster suggested, calling MeasureString for an ever increasing number of characters from the string is one way (which I am currently doing), I just wondered if there was some method I had overlooked.

The reason I am doing this is because I need to know which character in a rendered string the user clicks on with a mouse.

Thanks for your help though,

Chris
Kevin Spencer said:
I have an arbitrary string value and wish to determine how many characters
from that string will fit in a specified area with a specific font when
drawn.

With all fonts except for fixed-width fonts, the width of a character is different for each character. If one is working with an unknown set of characters, it is therefore impossible to pre-determine how many of any combination of them will fit into an area. That would be like guessing how many numbers add up to 100. Consider the illustration below:

R a N D o M s T r I n G
7 6 7 8 5 9 5 8 4 1 5 9


I measured each character in pixels on my machine. Now, tell me, without using this particular string, how many Arial 10 point characters could fit into an area 100 pixels wide? If they were all "I" you could fit nearly 100 of them (you would have to subtract for spacing). If they were all "M" you could only fit about 9.

That is why the Graphics.MeasureString method must have a String to measure.

So, knowing that this is true, you need to take a fresh look at your requirement, and find a different way of fulfilling it.

--
HTH,

Kevin Spencer
Microsoft MVP
.Net Developer

Presuming that God is "only an idea" -
Ideas exist.
Therefore, God exists.
 
Thanks, this was the only solution I could come up with, just thought I may
have overlooked something.
 
Chris,
You could probably use the MeasureString overload that uses a SizeFarea.
Just make the SizeF the equivalent of 1 line high and your desired width and
measure using g.MeasureString(s, f, sz, sFmt, out nChars, out nLines). The
overload returns the # of lines fitted and the # of characters fitted. Note
that you will need to setup the StringFormat for word breaks as desired.

Ron Allen
I understand that. However, using MeasureString, you can get the width of a
string when rendered with a specific font.

What I want is given a specific width, how much of a specific (it changes,
but you will always know what it is) string can be rendered in that space.

As a previous poster suggested, calling MeasureString for an ever increasing
number of characters from the string is one way (which I am currently
doing), I just wondered if there was some method I had overlooked.

The reason I am doing this is because I need to know which character in a
rendered string the user clicks on with a mouse.

Thanks for your help though,

Chris
-----------snip---------------------------
 
I would suggest a more optimized alternative. Get the length of the string
and measure it. Get the ratio of the string length (in pixels) to the length
in pixels of the area to fit it in. Multiply that ratio times the length of
the string (and cast to int) to get a starting point. Then use MeasureString
starting with the Substring before that character. If the string is too
long, reduce it by one character. If it is too short increase it by one
character. This way you should only have to measure it a few times, rather
than starting at the first character.

Example:

Charaacters in string 200.
MeasureString = 500 pixels.
Area to Fit = 200 pixels.
Ratio = 200/500 = .4
..4 * 200 = 80.
Start with a Substring of 0, 80.
Go up or down as needed, one character at a time.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer

Presuming that God is "only an idea" -
Ideas exist.
Therefore, God exists.

Chris Austin said:
Thanks, this was the only solution I could come up with, just thought I
may have overlooked something.
 
Back
Top