Getting the width of a text character

Hi all,

     I am playing around with text editing in Corona and I decided I would like to program a custom cursor.  I am able to display and format text fine with display.newText.  I am having problems when it comes to repositioning the cursor after inserting new text.  When repositioning the cursor, I figured I could just create a text object with one character in it ( I am using a monospaced text, so which one doesn’t matter ) and adding that width to the cursor’s current x coordinate.  When I do this, however, I get a “drifting” effect where the cursor ends up farther down the string of text than I intended.  It seems like the .width property of a text object returns more than the actual width of the characters contained in it.  With this intuition, I just decided I would subtract some value from the width and use that value.  The trouble is, I cannot pin down exactly which value to use in order to escape this drifting effect.  Is there some minute detail in the .width property that I can use to fix this problem, or is there something else I can do?

Thanks

Hi.

I’ve run into this, too. It’s possible the value you need is the kerning (see e.g. http://www.divine-project.com/wp-content/uploads/images/font-attributes.jpg, or click the checkbox in the first item here: http://nodebox.github.io/opentype.js/),,) either being added or omitted. Since you know which font you’re using, maybe you can dig those out beforehand (and scale them to the font size); otherwise, I don’t think there’s enough support available to figure it out.

What I’ve tried to do in my own case, which works so-so, is assign the string before the cursor to an invisible text object and ask its width: https://github.com/ggcrunchy/corona_ui/blob/master/patterns/editable.lua#L129

EDIT : It occurred to me that you might be able to compute the kernings by getting the pre-cursor string, the string + cursor-occupied character, and the character-only string,  and comparing their widths.

StarCrunch,

     Thanks for the info.  I am going to give a shot at the second technique you suggested.  I will let you know how it turns out.

StarCrunch,

     After a long delay, I have been able to sit down and work on this issue.  Your idea about getting the length of a similar string works flawlessly!  Here is the solution in code:

function findStringDist( str, pos )

    local t = display.newText( str:sub( 1, pos ), 0, 0, “myFont”, myFontSize )

    local w = t.width

    t:removeSelf()

    t = nil

    return w

end

Just adding this to this bit of code:

textBody.x - textBody.width*0.5 + textBodyGroup.x

places the cursor exactly where it needs to be.

Hi.

I’ve run into this, too. It’s possible the value you need is the kerning (see e.g. http://www.divine-project.com/wp-content/uploads/images/font-attributes.jpg, or click the checkbox in the first item here: http://nodebox.github.io/opentype.js/),,) either being added or omitted. Since you know which font you’re using, maybe you can dig those out beforehand (and scale them to the font size); otherwise, I don’t think there’s enough support available to figure it out.

What I’ve tried to do in my own case, which works so-so, is assign the string before the cursor to an invisible text object and ask its width: https://github.com/ggcrunchy/corona_ui/blob/master/patterns/editable.lua#L129

EDIT : It occurred to me that you might be able to compute the kernings by getting the pre-cursor string, the string + cursor-occupied character, and the character-only string,  and comparing their widths.

StarCrunch,

     Thanks for the info.  I am going to give a shot at the second technique you suggested.  I will let you know how it turns out.

StarCrunch,

     After a long delay, I have been able to sit down and work on this issue.  Your idea about getting the length of a similar string works flawlessly!  Here is the solution in code:

function findStringDist( str, pos )

    local t = display.newText( str:sub( 1, pos ), 0, 0, “myFont”, myFontSize )

    local w = t.width

    t:removeSelf()

    t = nil

    return w

end

Just adding this to this bit of code:

textBody.x - textBody.width*0.5 + textBodyGroup.x

places the cursor exactly where it needs to be.