love icon indicating copy to clipboard operation
love copied to clipboard

Expose coordinate of a specific glyph in a string

Open slime73 opened this issue 9 years ago • 12 comments

Original report by Landon “Karai” Manning (Bitbucket: karai17, GitHub: karai17).


I am trying to draw an input cursor for an input box. My problem is this: let's say I have the following string within a fixed width where | represents where I want the cursor to be:

[abc d|ef ghi      ]

To get the cursor position, I must loop through the string and measure the size of the sub string to see if I am passing where the mouse clicked:

is "a" > | ?
no

is "ab" > | ?
no

...

is "abc de" > | ?
yes

cursor is at "abc d"

Great, that was easy. But what about if my textbox is aligned to the right? Or heaven forbid, justified? This problem because very tedious at best.

[      abc d|ef ghi]

[abc    d|ef    ghi]

I propose exposing the coordinate of a particular glyph in a string:

local font = love.graphics.newFont("somefont.ttf")
local index = 9
local text = "Now this is a story all about how my life got flipped turned up-side-down!"
local x = 100
local y = 150
local limit = 300
local align = "right"

love.graphics.setFont(font)
local x, y = love.graphics.getGlyphPosition(index, text, x, y, limit, align)

You will note in my proposition that getGlyphPosition uses the same arguments as printf preceded by the desired glyph index. This would give you the exact same data that would be drawn to screen via printf, allowing for you to accurately get the coordinates of a particular glyph.

slime73 avatar Mar 18 '15 09:03 slime73

Original comment by Gabe Stilez (Bitbucket: z0r8, ).


If i might add something to this in the form of a question; might it make more sense to implement this as a method to the soon to-be 0.10 text objects, like to:posToCoords() or something instead? Or would this make sense even "outside" of text objects.

slime73 avatar Mar 18 '15 16:03 slime73

Original comment by Sasha Szpakowski (Bitbucket: slime73, GitHub: slime73).


It would most likely be a Font method.

It could work with Text objects too, but it would only make sense for text added to the object with Text:set, not Text:add.

slime73 avatar Mar 18 '15 16:03 slime73

Original comment by Gabe Stilez (Bitbucket: z0r8, ).


Okay, one more question, would it make sense for this or a similar function to work with l.g.print as well? (doesn't have alignment nor wrapping, but it does have transformations)

slime73 avatar Mar 18 '15 17:03 slime73

Original comment by Pablo Mayobre (Bitbucket: PabloMayobre, GitHub: PabloMayobre).


You always know the transformations in l.g.print so you can take the difference of the coordinate minus the transformation and you have the real coordinate, then you would use the font method.

The problem comes with right and center alignment, then you would need to specify all the arguments you would pass to l.g.printf which is kinda ugly

Text objects are not what I expected so I dont really like them hahaha. Yet you could store the bounding boxes of each string added/setted in the text object, and compare to that first, then use the standard method.

I'm not sure about the API either... specially the alignment part (too many arguments)

slime73 avatar Mar 29 '15 05:03 slime73

Original comment by Sasha Szpakowski (Bitbucket: slime73, GitHub: slime73).


Text objects are not what I expected so I dont really like them hahaha.

What did you expect?

slime73 avatar Mar 29 '15 05:03 slime73

Original comment by Pablo Mayobre (Bitbucket: PabloMayobre, GitHub: PabloMayobre).


Just one text (it wouldnt store more than one string), percharacter format, utf8 functions (string like, not just the ones provided in UTF-8)... Better wrapping, like a printf but waaaaaay more useful and customizable with lot more methods and stuff...

slime73 avatar Mar 30 '15 03:03 slime73

Original comment by Sasha Szpakowski (Bitbucket: slime73, GitHub: slime73).


utf8 functions (string like, not just the ones provided in UTF-8)

That doesn't seem like it should belong in a drawable object...

slime73 avatar Mar 30 '15 03:03 slime73

Original comment by Pablo Mayobre (Bitbucket: PabloMayobre, GitHub: PabloMayobre).


Well you are right there, haha

Anyway the most important feature I wanted would be percharacter format or rich formating, which would imply multiple font and sizes and would make using the font methods really awful (How would you handle a text object with more than one font?) so you would need to have some methods (getWidth, getHeight, getWrap and such plus this ones getCoordinate, getCharacter)...

slime73 avatar Mar 30 '15 03:03 slime73

Original comment by Sasha Szpakowski (Bitbucket: slime73, GitHub: slime73).


I don't think that's a direction that love.graphics text drawing will go in, for the foreseeable future. You can draw multiple individual pieces of text for that kind of thing (which, coincidentally, can now be a lot more efficient if Text objects – even multiple ones – are used.)

slime73 avatar Mar 30 '15 03:03 slime73

Original comment by Pablo Mayobre (Bitbucket: PabloMayobre, GitHub: PabloMayobre).


I though that was the issue you were trying to cover with Text objects but well (It's not like I hate them, they are really nice to have, plus are better than printing something a thousand times to the screen in a couple of seconds)

Coming back to the issue, how would you handle the limit and alignment? Would you need to pass them to the method? Also I consider the x and y of the text are pointless, you just need to pass the difference as I pointed above, same with translate and scale, the user can handle that I guess so you would assume that the text is drawn at 0,0 and that would reduce the number of arguments needed

slime73 avatar Mar 30 '15 03:03 slime73

Original comment by Pablo Mayobre (Bitbucket: PabloMayobre, GitHub: PabloMayobre).


API proposal

local x, y, width, height = font:getGlyphPosition(index, text, limit, align)

This one returns the x and y position of the character at the index position of the text which has a limit and an align mode. The index should probably be UTF-8. The width and height are optional, but would be nice

local index = font:getPositionGlyph(x, y, text, limit, align)

This one does the opposite, you pass the x, y position and it returns the index of the character under that point, if it is not over any character, returns nil. Again the index should probably be UTF-8.

Both of this functions assume that the text is drawn at 0,0 and x and y are relative to that.

PS: Not sure about the names hahaha

slime73 avatar Mar 30 '15 03:03 slime73

Original comment by Pablo Mayobre (Bitbucket: PabloMayobre, GitHub: PabloMayobre).


Well after designing many API's with textareas in mind, the above proposal I made more than a year ago still makes sense, would change the names though, they are horrible!

slime73 avatar Aug 20 '16 03:08 slime73