Anchorx text

I am trying to add text and I encounter problems when using anchorX. 

This is the small program: 

button1 = display.newRect(290,450,50,50)

button1:setFillColor(1,0,0,1)

– línea vertical de referencia.

alineacionvertical = display.newRect( 290,250,1,300)

alineacionvertical:setFillColor(0,255,0)

C=1

A=1

Final = display.newText(C, 0, 0, “Helvetica”, 35 )

Final:setTextColor(255,255,255)

Final.anchorX = 1

Final.x = 300

Final.y = 342

local function AA (event)

A=A+1

if A>3 then 

A=1

end

if A==1 then

C=1

end

if A==2 then

C=11

end

if A==3 then

C=111

end

Final.text= C

end

button1:addEventListener(“tap”, AA)

The red box is the button. Pressing I add text to the field. But I find that when anchorX = 0 works perfectly. Maintains position and add text smoothly. When anchorX = 1 there are small movements, and this is not desirable. 

What am I doing wrong?

You’re not doing anything wrong.

It’s the bounding box of the font that is adding extra padding at the end of the text.

I’ve modified your example to show the bounding box, and it stays in place with anchorX=1.

-- -- main.lua -- local button1 = display.newRect(290,450,50,50) button1:setFillColor(1,0,0,1) -- línea vertical de referencia. local alineacionvertical = display.newRect( 290,250,1,300) alineacionvertical:setFillColor(0,255,0) local C=1 local A=1 local Final = display.newText(C, 0, 0, "Courier", 35 ) Final:setTextColor(255,255,255) Final.anchorX = 1; local rect = display.newRect(0,0,Final.width, Final.height); rect:setFillColor(1, 0.8); rect.anchorX = 1; local grp = display.newGroup( ) grp:insert(rect); grp:insert(Final); grp.x = 300 grp.y = 342 grp.rect = rect; local function AA (event) A=A+1 if A\>3 then A=1 end if A==1 then C=1 end if A==2 then C=11 end if A==3 then C=111 end Final.text = C; grp.rect.width = Final.width; end button1:addEventListener("tap", AA) 

The bounding box is calculated from the font metrics in the font and will be different for each font.

As an example, if you change the font to “Courier” the offset will be smaller, but still visible.

Unfortunately there’s not much you can do to change this as it’s the font metrics that decide how a font is rendered, which is out of CoronaLabs control as well.

Thanks for your help. Thanks for your time . What you have done is to use a fixed-width font such as Courier to reduce displacement. It is a very good idea. But , as seen , there is still movement.

I say the problem is not Corona SDK . I’m not so sure. If you change the anchorX to zero , you will see that there is no problem. It works perfectly . I wonder because when the alignment is right and I have problems when left , no.

Anyway I found the solution . Not the best , from my point of view. Because it forces me to add more lines of code. That if I can still put the font I wanted, since Courier is horrible.

Looking between Corona SDK documents found when used in multiple text lines there is no displacement.

So what I did was use a box large enough to contain at least three characters of the example .

Here’s the code :

 

button1 = display.newRect ( 290,450,50,50 )

button1 : setFillColor ( 1,0,0,1 )

— Vertical reference line .

alineacionvertical = display.newRect ( 290,250,1,300 )

alineacionvertical : setFillColor ( 0,255,0 )

C = 1

A = 1

 

Local options = {

text = C ,

x = 300 ,

y = 342 ,

width = 200 ,

height = 300 ,

font = " GillSans "

fontSize = 35,

align = "right "

}

Final = display.newText (options)

Final : SetTextColor ( 255,255,255 )

Local AA function (event)

A = A +1

if A> 3 then

A = 1

end

if A == 1 then

C = 1

end

if A == 2 then

C = 11

end

if A == 3 then

C = 111

end

Final.text = C

end

 

button1 : addEventListener ( "tap " , AA)

Using “Courier” was a mistake on my part when posting. I just used it for testing and it happened to slip in.

My point is that I still don’t think CoronaLabs can do anything about it since the bounding box is created using the font metrics included in the font. The reason why it works with anchorX=0 is because the metrics are defined in a way that doesn’t create variable spacing at the beginning of the string.

The reason why it works with your solution is because you hardcode a width thus bypassing the metrics in the font to calculate the width of the bounding box for you.

Nice solution though.

Very good explanation. It’s very interesting what you’re writing. Thank you. 

Can not you could do something similar, but for a single line of text? 

I think so. And it would be a very good solution. 

You could keep hidden the width and height values. But it would be part of an internal calculation, hidden, for they ensure no movement between characters.

The root of the problem is that OpenGL knows nothing about text. It only handles images, which is why a bounding box must be created first so that text can be “painted” into it.

There are only two options to create the bounding box.

  1. Use the font metrics to calculate the width/height depending on the string to be displayed.

  2. Manually set the width/height completely disregarding the contents of the string.

Option 1 works most of the time, but has it’s issues. Sometimes you’ll even see clipping of the font if it’s allowed to “bleed” outside its bounds.

Option 2 can solve certain issues (like yours), but has its limitations. You must know the width/height of the text so that it will fit inside the bounding box which isn’t always practical.

You *could* create a helper function that uses option 1 where you pass in a string to newText() just to get the width/height, and then remove that object and create a new text-object using option 2 with a fixed width/height using the values from the first object.

Interesting, very interesting. You see it from the outside. But really, I do not know how OpenGL works. Now you know a little more. 

In the last paragraph you are showing the possible solution. 

Thanks for your help. Was all very fruitful.

Just as a clarification, when we render text we call the operating system’s font rendering and generate an image.  In single line mode (where you do not specify and width and/or height), we take whatever the OS gives us back and if there is a changing amount of padding on the right side, there really isn’t much we can do.

Now if you use multi-line mode, you specify a width and the image will be that width, period.  You can then tell us to align the font to the right.  It might be worth trying that and see if it helps with the right side padding.

Rob

Thanks Rob. Very attentive and helpful as ever.

You’re not doing anything wrong.

It’s the bounding box of the font that is adding extra padding at the end of the text.

I’ve modified your example to show the bounding box, and it stays in place with anchorX=1.

-- -- main.lua -- local button1 = display.newRect(290,450,50,50) button1:setFillColor(1,0,0,1) -- línea vertical de referencia. local alineacionvertical = display.newRect( 290,250,1,300) alineacionvertical:setFillColor(0,255,0) local C=1 local A=1 local Final = display.newText(C, 0, 0, "Courier", 35 ) Final:setTextColor(255,255,255) Final.anchorX = 1; local rect = display.newRect(0,0,Final.width, Final.height); rect:setFillColor(1, 0.8); rect.anchorX = 1; local grp = display.newGroup( ) grp:insert(rect); grp:insert(Final); grp.x = 300 grp.y = 342 grp.rect = rect; local function AA (event) A=A+1 if A\>3 then A=1 end if A==1 then C=1 end if A==2 then C=11 end if A==3 then C=111 end Final.text = C; grp.rect.width = Final.width; end button1:addEventListener("tap", AA) 

The bounding box is calculated from the font metrics in the font and will be different for each font.

As an example, if you change the font to “Courier” the offset will be smaller, but still visible.

Unfortunately there’s not much you can do to change this as it’s the font metrics that decide how a font is rendered, which is out of CoronaLabs control as well.

Thanks for your help. Thanks for your time . What you have done is to use a fixed-width font such as Courier to reduce displacement. It is a very good idea. But , as seen , there is still movement.

I say the problem is not Corona SDK . I’m not so sure. If you change the anchorX to zero , you will see that there is no problem. It works perfectly . I wonder because when the alignment is right and I have problems when left , no.

Anyway I found the solution . Not the best , from my point of view. Because it forces me to add more lines of code. That if I can still put the font I wanted, since Courier is horrible.

Looking between Corona SDK documents found when used in multiple text lines there is no displacement.

So what I did was use a box large enough to contain at least three characters of the example .

Here’s the code :

 

button1 = display.newRect ( 290,450,50,50 )

button1 : setFillColor ( 1,0,0,1 )

— Vertical reference line .

alineacionvertical = display.newRect ( 290,250,1,300 )

alineacionvertical : setFillColor ( 0,255,0 )

C = 1

A = 1

 

Local options = {

text = C ,

x = 300 ,

y = 342 ,

width = 200 ,

height = 300 ,

font = " GillSans "

fontSize = 35,

align = "right "

}

Final = display.newText (options)

Final : SetTextColor ( 255,255,255 )

Local AA function (event)

A = A +1

if A> 3 then

A = 1

end

if A == 1 then

C = 1

end

if A == 2 then

C = 11

end

if A == 3 then

C = 111

end

Final.text = C

end

 

button1 : addEventListener ( "tap " , AA)

Using “Courier” was a mistake on my part when posting. I just used it for testing and it happened to slip in.

My point is that I still don’t think CoronaLabs can do anything about it since the bounding box is created using the font metrics included in the font. The reason why it works with anchorX=0 is because the metrics are defined in a way that doesn’t create variable spacing at the beginning of the string.

The reason why it works with your solution is because you hardcode a width thus bypassing the metrics in the font to calculate the width of the bounding box for you.

Nice solution though.

Very good explanation. It’s very interesting what you’re writing. Thank you. 

Can not you could do something similar, but for a single line of text? 

I think so. And it would be a very good solution. 

You could keep hidden the width and height values. But it would be part of an internal calculation, hidden, for they ensure no movement between characters.

The root of the problem is that OpenGL knows nothing about text. It only handles images, which is why a bounding box must be created first so that text can be “painted” into it.

There are only two options to create the bounding box.

  1. Use the font metrics to calculate the width/height depending on the string to be displayed.

  2. Manually set the width/height completely disregarding the contents of the string.

Option 1 works most of the time, but has it’s issues. Sometimes you’ll even see clipping of the font if it’s allowed to “bleed” outside its bounds.

Option 2 can solve certain issues (like yours), but has its limitations. You must know the width/height of the text so that it will fit inside the bounding box which isn’t always practical.

You *could* create a helper function that uses option 1 where you pass in a string to newText() just to get the width/height, and then remove that object and create a new text-object using option 2 with a fixed width/height using the values from the first object.

Interesting, very interesting. You see it from the outside. But really, I do not know how OpenGL works. Now you know a little more. 

In the last paragraph you are showing the possible solution. 

Thanks for your help. Was all very fruitful.

Just as a clarification, when we render text we call the operating system’s font rendering and generate an image.  In single line mode (where you do not specify and width and/or height), we take whatever the OS gives us back and if there is a changing amount of padding on the right side, there really isn’t much we can do.

Now if you use multi-line mode, you specify a width and the image will be that width, period.  You can then tell us to align the font to the right.  It might be worth trying that and see if it helps with the right side padding.

Rob

Thanks Rob. Very attentive and helpful as ever.