Textbox leading - measureGlyphs sometimes inaccurate

Hi All,

I need a solution for TextBox leading (vertical line-spacing). My previous solutions are failing me at the moment. In the past I have hacked the OSX TextBox implementation to accomodate this but this is trickier on Windows. At the moment I am working on a cross platform solution using TextBox::measureGlyphs().

I first used this to calculate the number of lines and crop the generated texture into separate lines and reposition when drawing. However, this has some artefacts in some fonts/sizes when characters from some lines creep too close to others (the bottom of a lower case y for example).

So I then tried the approach of creating a TextBox texture just so that I can use TextBox::measureGlyphs() to calculate where the lines breaks are and then create a new TextBox for each line. This works perfectly some of the time however with some fonts, such as the OTF fonts I need to work with at the moment TextBox::measureGlyphs() returns an array size 2 less than the number of characters in the text.

This seems to happen if word wraps are used. I see the comment in the source code that word wraps are not supported by this function on windows but as I said this approach works with some fonts and the problem also occurs on both Windows and OSX. I tried converting the OTF font to TTF as I have other TTF fonts that work but this did not fix the problem.

Does anyone have any advice or a leading solution they use on windows?

I have my class used in a sample app here although the relevant logic for breaking up the lines is below:

	std::vector<std::pair<uint16_t,ci::vec2> >pairs = measureGlyphs();
	float y = pairs[0].second.y;

	string text = getText();
	vector<string> lines;

	string line = "";
	int i = 0;
	for (auto p : pairs ) {

		if ( p.second.y > y) {
			counter++;
			y = p.second.y;
			boost::trim(line);
			if (i>0) lines.push_back(line);
			line="";
		}
		line += text[i];
		i++;
	}
        line += text[ text.length()-1 ];
	boost::trim(line);
	lines.push_back(line);

EDIT - If someone is keen to take a look at a problem font please PM me and I can get one to you.

sigh, so this seems to be sorted by calling TextBox::ligate(false)
sorry for the noise but if anyone has a use for the now working class feel free!

EDIT - actually, this works on OSX but on windows measureGlyphs() returns 2 less glyphs than it should regardless of the ligate setting… help! I assume this is a bug in cinder’s text handling? strange that TextBox always renders correctly even if measureGlyphs() returns the wrong data.

Okay. so to get this working on windows I had to override the measureGlyphs() function and remove some flags in GetCharacterPlacementW(). Removing GCP_LIGATE did not suffice so I removed all flags. This seems to work fine for my purposes although I imagine there might be some issues for some languages other than english.

//this different to TextBox default:
if (!::GetCharacterPlacementW(ci::Font::getGlobalDc(), (wchar_t*)&wideText[0], wideText.length(), 0,
	&gcpResults, NULL )) { //removed these flags for accurate glyphs array size: GCP_DIACRITIC | GCP_LIGATE | GCP_GLYPHSHAPE | GCP_REORDER
	return vector<pair<uint16_t, vec2> >(); // failure
}