I am looking for stable algorithm to draw possibly long text horizontally and vertically centered on a 2D surface. This is not language specific, so if you can provide examples in any language it would be very helpful.
The following information I have about the text I want to draw and the surface:
Text infomation:
- size of the text in px (line height), is of course way smaller than the height of the surface
- the type face (could be any though)
- simple character set from ASCII32 to ASCII126
- text could be relatively long, words are separated by spaces
- text should break “automatically” on spaces once it will not fit in the width of the surface anymore
- text is in English.
Surface information:
- width and height
- x and y coordinates in the global coordinate system (assuming the origin is left top corner of the screen)
I did implement my own approach, but it was very unstable: text spread over the surface, alignment not correct, sometimes not centered at all. Also googled for some good approaches though couldn’t find something useful. I hope the stackoverflow community can help me. Thank you very much.
The approach is simple in concept, a bit involved in execution. It involves only a few steps:
The hard part is the first step. The rest is easy.
If you have a fixed-width font, then splitting the text into lines isn’t too hard. You simply compute how many characters will fit in the given width, index into the string to that position, and then back up to the previous word break. Grab the substring from the start of the previous line (or start of the string for the first line) to that position, and that’s your line. Repeat until you get to the end of the string.
With a variable-width font, things are a bit harder because you can’t just index into the string by
n * character_widthcharacters. Instead, you have to guess, test, refine the guess, etc. Every graphics subsystem I’ve worked with had some kind ofMeasureStringmethod that would tell me how many pixels it would take to render a string, given a particular font. Given that, what I’ve done in the past is:Once you’ve found the substring that will fit, move your start index forward to the start of the next line, and do it again until you reach the end of the string.
Vertically centering the group of lines:
Horizontally centering a line is easily accomplished:
You have to compute the
starting_position.Xfor each line. The Y coordinate is increased byline_heightfor each successive line.