Comment 29 for bug 1001033

Revision history for this message
Steve White (stevan-white) wrote :

Thanks, Sam!

(Sorry for being testy.)

Your problem of where to put the cursor is kind of messy for general fonts (and I don't know the right answer -- probably one has to ask the font rasterizer). But for monospace fonts, there should be a comprehensible solution at some higher level, such as your pygame thing.

Here's the arithmetic problem, as I see it.

For simplicity, say the advance widths of all characters are equal in the font. Suppose you scale the font, so the scaled width is some non-integer multiple of the device pixel width.

Now you have made an API call to get the character width, and it returns an integer.

What does that integer mean? Maybe it's the non-integer multiple, rounded. Or maybe as I suggested it has something to do with which pixels are turned on in the rendered graphic. (And maybe there really is a bug--I'm still not sure about this.) In any case, the documentation ought to explain it -- but I checked, and it doesn't.

Suggestion:

To place your cursor between letters. Where should it go? If you just get the width of a single character, and multiply by the character string index, the cursor is likely to be badly misplaced, due to rounding.
It might be better to find the pixel width of a longer string, and divide by the number of characters to get a floating-point value, and use that as the single-character width. I the simple scenario, this should get you within a pixel of the expected position every time.

For completeness:

In general, the placement of the cursor in text is substantially more subtle than that. Even in a monospace font, it's permissible for a character to have 0 width. Furthermore, OpenType fonts can do various tricks such as ligature substitution, that change the glyphs that are actually rendered. For this, the only safe way to place the cursor is to ask the font rendering interface. (This is just a deduction--I've never done it myself.)

I don't know if Pygame has a representation of such an interface...

(And... let's please not talk about CPU cycles here. It's just embarrassing.)

Cheers!