PDA

View Full Version : Formula for justifying text?



nine-hundred
09-02-2007, 12:44 PM
Hey does any one know of a (preferably simple) formula for justifying text into a column? Or maybe someone can fix mine?

I have to write a prog in C to do this, I have the program all written out, but my output isn't as I would like it...

I calculate the number of spaces that should be between each word in a line using this:

spaces = ( m - c ) / (w - 1)

where:
m = maximum number of characters in line (e.g. column width)
c = the number of characters in the line I want to print (basically a combination of the lengths of all the words in the line)
w = number of words in the line

I think a lot of my problem may lie in that this fraction wouldn't always be coming out to a whole number and you can print say .3 of a space...

Salem
09-02-2007, 01:56 PM
Well if you pick a variable pitch font, then yes you need something far more sophisticated than that.

nine-hundred
09-02-2007, 02:17 PM
Well, for simplicity's sake, let's assume a monospace type of font

Yarin
09-02-2007, 02:28 PM
I don't see how you came up with ( ( m - c ) / (w - 1) ). Try somthing more like ( ( m / 2 ) - ( c / 2) ).

brewbuck
09-02-2007, 02:32 PM
I think a lot of my problem may lie in that this fraction wouldn't always be coming out to a whole number and you can print say .3 of a space...

Suppose you need to print 4.5 spaces between each word. That's 9 spaces between every two words. So if you alternate between 4 and 5 spaces, every other word, you insert, on average, 4.5 spaces per word.

You can generalize this in the following way:



double total_error = 0.0;
double nspace = (m - c) / (w - 1); /* Ideal number of spaces per word (not an integer) */
double space_error = nspace - floor(nspace); /* Fractional part of nspace */

for(each word)
{
if(total_error >= 1.0)
{
/* Error exceeds a space, so subtract a full unit of error and generate an extra
* space */
output_spaces(1);
total_error -= 1.0;
}
output(word);
output_spaces(floor(nspace));
total_error += space_error;
}


Where output_spaces() is a function that outputs the given number of spaces.

This is closely related to a few other algorithms, like Bresenham line drawing, or box-filter image scaling.

Also, it can be implemented entirely with integer math, but that's a trick I keep to myself.

nine-hundred
09-02-2007, 02:37 PM
Hmm.. I can try it, but why the division by two?

how I got mine was something like this (sorry I wasn't more clear):

(m - c) will be the number of unoccupied spaces on the line (e.g. if the words don't take up exactly all the space on the line but there is not enough room for another full word)

and then I divide this number by the number of words I have minus one (because I won't be placing any spaces after the last word, as the last character on the line should not be whitespace in the justification.

then I would print each word doing something like: printf("%*s",spaces, word);
except for the last one, of course.

It made sense to me...but obviously it doesn't seem to be doing it as I thought it would...

brewbuck
09-02-2007, 02:37 PM
I don't see how you came up with ( ( m - c ) / (w - 1) ). Try somthing more like ( ( m / 2 ) - ( c / 2) ).

Makes sense to me. m - c is the number of space characters needed to make the line exactly "m" characters long. These spaces need to be divided into w - 1 chunks, since there are w - 1 spaces in between w words.

nine-hundred
09-02-2007, 02:40 PM
Hah, oh, brewbuck posted while I was writing up my post.

Alright, thank you, brewbuck, I'll try that one

:)