[TextField] How i get char bound

Hi all. I want get bound of character in textfiled.

With Flash, I just call function:

var bound:Rectangle = textfield.getCharBoundaries (indexChar);

But, function getCharBoundaries don’t implement in CPP and I don’t find any function to do get this.
Do you have any solutions?

FreeType probably gives us this information about each glyph, but it (obviously) has not been exposed to allow the use of getCharBoundaries, the TextField class has some missing pieces that would be great to have implemented.

Anyone interested in helping with this?

I’ll add it!

getCharBoundaries(charIndex:int):Rectangle

and the ‘inverse’

getCharIndexAtPoint(x:Number, y:Number):int

Some time ago I made a pull request for some improvements for html5-canvas TextField…

Hi All.
About this issue, I have the solution. I used textfield.getLineMetrics. But this is only a temporary solution and it just right in some cases.
I will wait for the next version.

It doesn’t look like that method is implemented yet either.

Is it working?

Are you only targeting flash?

I use getLineMetrics to calculate y and height. And textWidth can give me x and width. So I have x, y, width, height to create bound of char. But this solution is slow and it is not totally right.

What platform(s) does that work on?

Windows, Android, IOS, and Flash.

Hi all.
Here my code.
First, my textField like this.

var textField = new TextField ();
textField.defaultTextFormat = new TextFormat ("tahoma", 30, 0x000000);
textField.x = 100;
textField.y = 100;
textField.width = 400;
textField.selectable = false;
textField.wordWrap = true;
textField.multiline = true;
textField.autoSize = TextFieldAutoSize.LEFT;
addChild (textField);

Here my getCharBoundieses

public function getCharBoundaries (textField:TextField, text:String, targetIndex:Int):Rectangle
{
	textField.htmlText = text;
	
	var targetLine:Int = 0;
	var textLine:String = "";
	var textWidth:Float = textField.width;
	var textFormat:TextFormat = null;
	var metries:TextLineMetrics = null;
	
	var lineOffset:Int = 0;
	var bound:Rectangle = new Rectangle ();
	while (targetLine < textField.numLines)
	{
		metries = textField.getLineMetrics (targetLine);
		textLine = textField.getLineText (targetLine);
		lineOffset = textField.getLineOffset (targetLine);
		if (lineOffset <= targetIndex && targetIndex < lineOffset + textLine.length)
		{
			targetIndex -= lineOffset;
			bound.height = metries.height;
			break;
		}
		
		bound.y += metries.height;
		targetLine ++;
	}
	
	textFormat = textField.getTextFormat (targetLine);
	
	textField.htmlText = textLine.substr (0, targetIndex);
	bound.width = textField.textWidth;
	
	switch (textFormat.align)
	{
		case TextFormatAlign.RIGHT:
		bound.x = textField.textWidth + (textWidth - metries.width);

		case TextFormatAlign.CENTER:
		bound.x = textField.textWidth + (textWidth - metries.width) * 0.5;

		default:
		bound.x = textField.textWidth;
	}
	
	textField.htmlText = textLine.substring (0, targetIndex + 1);
	bound.width = textField.textWidth - bound.width;
	
	textField.htmlText = text;
	
	return bound;

Final, my test.

var htmlText:String = "<p align=\"center\">This is my test\n A B C def\n1 2 3 456\n.~!?</p>";
for (index in 0 ... 41)
{
	var rect:Rectangle = getCharBoundieses (textField, htmlText, index);
		
	graphics.lineStyle (1, 0xFF00FF, 1);
	graphics.beginFill (0xFFFFFF, 0.5);
	graphics.drawRect (textField.x + rect.x, textField.y + rect.y, rect.width, rect.height);
}

Results on windows

And results on flash if I use textField.getCharBoundieses.

1 Like

Anyone found a solution to get REAL char boundaries since?
Because calling Textfield.getLineMetrics(0).ascent or Textfield.getLineMetrics(0).height on a textfield with the text “e” will return exactly the same value as when called on the same textfield but with the text “t”. Wich means that the height returned is actually not dependent on the character but only on the font size and type (wich is the reason why all bound boxes have the same top and bottom in long2805l2 screenshot whereas we would like to have something like in his first post where “A” and “c” characters bound boxes have different height).
And textfield.getCharBoundaries().height seems to suffer from the same artefact has it actually return the font size and thus do not depend on the character at the index called in the function…

Hmm, I’m not sure if we can get any additional details from Freetype, although you could render the text (say, as black) to a BitmapData (using draw) and then (maybe) use getColorBoundsRect to see where the pixels drew?

I recently retried to get char real boundaries.
I thought I could have it with something like:

font.getGlyphMetrics(font.getGlyph("e")).height

to get the height of the “e” char for example (then need to be converted to a real height by taking into account font size)
But sadly this return 0…
So I might be not passing the correct argument to getGlyph() or I don’t understand what height is for glyphmetrics…

Drawing the char to a Bitmapdata and extracting colored pixels boundaries seems the only solution for now. Sadly (it consume a lot of CPU usage for just getting a char height).

Is this on HTML5, or elsewhere?

I think that font metrics on HTML5 canvas does not return height, only width :frowning:

No it is on cpp targets (windows and android)

I think font metrics might be the line height, and not specific to an exact glyph

Well it’s called GlyphMetrics so it is supposed to be the Glyph specific metrics.
the font general height is supposed to be returned by font.height
Anyway, there is probably a bug as, as said
font.getGlyphMetrics(font.getGlyph("e")).height
return a height of 0 (so even if this is the line height, it shouldn’t be 0…)