ofTrueTypeFont setLetterSpacing setSpaceSize problem

#1

I’m doing some basic text formatting and I think there is an issue with setLetterSpacing and setSpaceSize (OF 10.1).

font.load("verdana.ttf", 20);
font.setSpaceSize(100.0);

52%20PM

font.load("verdana.ttf", 20);
font.setSpaceSize(1.0);

23%20PM

I think the spacing isn’t changing because of line 1071 in ofTrueTypeFont.cpp
pos.x += getGlyphProperties(' ').advance * spaceSize * (letterSpacing - 1.f) * directionX;

When letter spacing is at its default value of 1 this makes it all equal zero and spaceSize has no effect.

When letter spacing isn’t at default letterSpacing and spaceSize are correlated in a way that doesn’t feel intentional.

font.load("verdana.ttf", 20);
font.setLetterSpacing(1.3);

26%20PM

font.load("verdana.ttf", 20);
font.setLetterSpacing(1.3);
font.setSpaceSize(10.0);

font.load("verdana.ttf", 20);
font.setLetterSpacing(1.3);
font.setSpaceSize(100.0);

Shouldn’t setSpaceSize adjust just the space character and not have such a dramatic effect on the overall letter spacing?

Is setSpaceSizing() just legacy (mentioned here) and shouldn’t be used?

#2

Yes space size was something we used in the past cause we didn’t read the space size from the font itself. it seems at some point it got mixed up and now behaves as a factor of the space size rather than the size of the space. It looks like a bug anyway but not sure if we should just remove this function or bring back the original functionality where this function sets the size of the space

#3

For whatever it’s worth I think it’s a useful feature. That said I do not feel strongly about it, as it’s easy enough to write into the app. I modified iterateString in ofTrueTypeFont.cpp to make it work like I originally expected- letterSpacing and spaceSizing operating Independently of each other.

testSpacing

for(auto c: ofUTF8Iterator(str)){
		try{
			if (c == '\n') {
				pos.y += lineHeight*newLineDirection;
				pos.x = x ; //reset X Pos back to zero
				prevC = 0;
			} else if (c == '\t') {
				if (settings.direction == OF_TTF_LEFT_TO_RIGHT){
					f(c, pos);
					pos.x += (getGlyphProperties(' ').advance * letterSpacing) * TAB_WIDTH * directionX;
				} else{
					pos.x += (getGlyphProperties(' ').advance * letterSpacing) * TAB_WIDTH * directionX;
					f(c, pos);
				}
				prevC = c;
            }else if(c == ' '){
                pos.x += (getGlyphProperties(' ').advance * spaceSize) * TAB_WIDTH * directionX;
                f(c, pos);
                
            }else if(isValidGlyph(c)) {
				const auto & props = getGlyphProperties(c);
				if(prevC>0){
					pos.x += getKerning(c,prevC);
				}
				if(settings.direction == OF_TTF_LEFT_TO_RIGHT){
					f(c,pos);
					pos.x += props.advance  * directionX;
					pos.x += getGlyphProperties(' ').advance * (letterSpacing - 1.f) * directionX;
                    //ofLog()<<"posX2 "<<pos.x;
				}else{
					pos.x += props.advance  * directionX;
					pos.x += getGlyphProperties(' ').advance * (letterSpacing - 1.f) * directionX;
				    f(c,pos);
				}
				prevC = c;
			}
        }catch(...){
			break;
		}
    }

It seems too simple. Perhaps it’s not accounting for different alphabets?

#4

That looks good to me, i believe there are other types of spaces in other alphabets but we can just speficify in the docs that by now this only works for the latin alphabet space.

Also i think this is the only place where it’s needed but not 100% sure. in any case if you want to send a PR that would be great!

#5

Ooooh . First PR to OF. :sunglasses:
Cool. I’ll get to it.

#6

:slight_smile: thanks!