Just to make the point. Wikipedia defines a monospaced font
as follows:
A monospaced
font, also called a fixed-pitch, fixed-width, or non-proportional font, is a font whose
letters and characters each occupy the same amount of horizontal space.
Now not everything you read on Wikipedia is necessarily true
but I am confident that a technical reader would be happy with that definition.
You might be less happy to find that the .NET Graphics.DrawString()
method does not adhere strictly to this approach. My earlier experience while
trying to measure a monospaced font character width was a clue that issues
might arise in actual usage. Arise they did.
You can’t see it at first but as printed lines become longer
then it becomes clear that the line length is less than it should be. Pixels in
the X axis are being “lost” along the way. My test data was printed at the
correct register for the first 7 characters but the 8th was one
pixel to the left of where it should have been. Somewhere around 90 plus characters
into a line the positioning is out by 10 pixels (a single character width for
the font in question).
Each character in every line is correctly positioned
relative to the other lines but incorrectly positioned based upon any rational
definition of a monospaced font.
The image below shows the 97th character (H) in
the first line of text showing correctly in position while the second line
rendered by the DrawString() method being passed the whole line of text shows
the “H” well to the left of the correct location.
In case you wondered the blue “divider” is placed by an algorithm
that looks for probable field positions by analysing transitions between
character types (in this case a white space prior to a “letter”)
So if (like me) you are working in the .NET environment and
you want to know where the nth character is on a “painted” surface of a
window/control using (for crying out loud) a monospaced font – then you need to
print each character individually at the correct location. On that basis, you
could do just as well with a nominally proportional font of course.
At least this showed that, at longer string lengths, there
was some consistency between MeasureString() and DrawString() even if both (in
this instance) are wrong.
Programming in .NET is sometimes all about fighting .NET (or
GDI+ or whatever is actually responsible for the rendering under the covers).
On reflection, this is true of every software platform I have ever worked on.
Final word:
While subsequently working on something else completely, I found out that MeasureString() uses GDI+ while by default .DrawString() uses GDI and their rendering is not the same. Well we live and learn I suppose but you would have expected consistency within the .NET defaults wouldn't you?
Final word:
While subsequently working on something else completely, I found out that MeasureString() uses GDI+ while by default .DrawString() uses GDI and their rendering is not the same. Well we live and learn I suppose but you would have expected consistency within the .NET defaults wouldn't you?
No comments:
Post a Comment