Auto resize text to fit a field

Anything beyond the basics in using the LiveCode language. Share your handlers, functions and magic here.

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

Post Reply
arkstar
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 70
Joined: Mon Dec 21, 2009 1:51 am

Auto resize text to fit a field

Post by arkstar » Thu Sep 22, 2011 3:30 am

Any ideas to resize text to fit in a field?
I have a badge printing program and want the name to resize if it is too long at the standard font size.

Any help would be greatly appreciated!

Thanks
Rob
Rob Glassman
ArkStar

WaltBrown
Posts: 466
Joined: Mon May 11, 2009 9:12 pm

Re: Auto resize text to fit a field

Post by WaltBrown » Thu Sep 22, 2011 6:20 am

Fun question to explore. LC has no way to get at the presented width (in pixels) of a string in a field. When I started looking I discovered that when you type in a field that is set to "dontWrap", when the string gets to the end of the field it gets a "scrollbarDrag" message, even if it doesn't have scroll bars. So that lead me to this script in the field:

Code: Select all

on scrollbarDrag
   set the textSize of me to the textSize of me -1
end scrollbarDrag

on backSpaceKey
   if (the length of me is 0) then 
       set the textSize of me to 200
   else 
       set the textSize of me to the textSize of me +1
   end if
   pass backSpaceKey  -- so it actually does what it is supposed to
end backSpaceKey

on initField
   put empty into me
   set the dontWrap of me to true
   set the textSize of me to 200
end initField
It's not very good but what it does is decrease the font size by one every time it gets a scrollbarDrag message, and increase by one at every backspace. You have to send it an "initField" from the message box to start.

Then I started thinking about the math. Most fixed width fonts (like Courier) have a fixed character width that is 5/8 the height - they have a 5x8 counter (the widest rectangle the capital letters fit in). So I made this instead (in the field script):

Code: Select all

global gWindowWidth  -- Only so it doesn't have to be retrieved each key stroke

on rawkeyDown pCode
   set the textSize of me to gWindowWidth/(the length of me+1) * 1.6
   -- Plus one so to avoid a divide by zero
   -- One point six is the inverse of the 5x8 character ratio
   pass rawkeyDown
end rawkeyDown

on initField
   put empty into me
   set the textAlign of me to center
   put the width of me into gWindowWidth
end initField
This works with any key press. If you chose a few selected fonts, you might be able to vary the ratio a bit to match each font, to reduce the inaccuracy. For example if you selected Blue Ridge Heavy you might want to change the 1.6 to say 1.1 or 1.2 because of the wider letters; or for a narrow font like Arial Narrow, 1.9 or 2.0.

Thanks. That was fun.

Walt
Walt Brown
Omnis traductor traditor

arkstar
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 70
Joined: Mon Dec 21, 2009 1:51 am

Re: Auto resize text to fit a field

Post by arkstar » Thu Sep 22, 2011 6:47 am

Wow! Thanks Walt!
I'll let you know how it works out!
Great ideas! Thanks again!

Rob
Rob Glassman
ArkStar

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4174
Joined: Sun Jan 07, 2007 9:12 pm

Re: Auto resize text to fit a field

Post by bn » Thu Sep 22, 2011 9:26 am

Hi,
LC has no way to get at the presented width (in pixels) of a string in a field
there is the formattedWidth that gives you the information. You can even get the formattedWidth of char 2 to 5 of field x, or the formattedHeight, or the formattedRect.

using the formattedwidth on a field that has the textalign set to center and the dontWrap set to true you could use something like this:

Code: Select all

local sMinTextSize = 8
local sDesiredTextSize = 30

on rawKeyUP
   
   repeat while the formattedWidth of me >= the width of me -(item 1 of the margins of me * 2)
      set the textSize of me to min (max ((the effective textSize of me - 1), sMinTextSize),sDesiredTextSize)
      if the textSize of me = sMinTextSize then exit repeat
   end repeat
   
   repeat while the formattedWidth of me < the width of me - (item 1 of the margins of me * 2)
      set the textSize of me to min (max ((the effective textSize of me + 1), sMinTextSize),sDesiredTextSize)
      if the textSize of me = sDesiredTextSize then exit repeat
   end repeat
   
   pass rawKeyUP
end rawKeyUP
Note the two script local variables at the top: sMinTextSize and sDesiredTextSize, they define the minimum and the regular textSize, adapt in the script to your needs.

There are some formatting problems with textsizes around 12 and below that I did not figure out. But basically it works.

Kind regards

Bernd

WaltBrown
Posts: 466
Joined: Mon May 11, 2009 9:12 pm

Re: Auto resize text to fit a field

Post by WaltBrown » Thu Sep 22, 2011 9:51 am

Thanks Bernd, I had completely forgotten about formattedWidth.

I am curious about the keyword "effective" in this case though. What is the difference between "the textSize" and "the effective textSize"? Does it mean "textSize" will stay at it's original value until the handler exits, but the "effective textSize" will be the potential new value when the handler exits?
Walt Brown
Omnis traductor traditor

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4174
Joined: Sun Jan 07, 2007 9:12 pm

Re: Auto resize text to fit a field

Post by bn » Thu Sep 22, 2011 10:01 am

Hi Walt,

the effective textSize is the textsize a field takes on as a default and inherits it from the stack. If you have not explicitly set the textsize of a field the textsize would be empty. Once you set the textsize of a field that value is not empty anymore. This is just a precaution for the first round, in case the textsize has not been set before. From than on: the textsize of a field = the effective textsize of a field.

Thus effective textsize reflects both conditions: new field without explicit textsize and a field whose textsize has explicitly been set.

Kind regards

Bernd

arkstar
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 70
Joined: Mon Dec 21, 2009 1:51 am

Re: Auto resize text to fit a field

Post by arkstar » Thu Sep 22, 2011 10:59 pm

Hi Bernd,

Thanks for your reply, input and code. However, when I ran your code, the text did not resize, the field did.
My goal is for the text to fit into a fixed sized field...

Any ideas?

Thanks again to you & Walt!!

Rob
Rob Glassman
ArkStar

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4174
Joined: Sun Jan 07, 2007 9:12 pm

Re: Auto resize text to fit a field

Post by bn » Thu Sep 22, 2011 11:25 pm

Hi Rob,

when I tested the text did resize, not the field.

I attach my stack. If the field works for you you can copy it to your stack as it is. You just might want to adjust the minimum and the desired text size in the script local variables as explained above.

The only thing the script really should need is the dontWrap property set to true.

Tell me how it works.
adjustTextSizeToField.livecode.zip
(1.07 KiB) Downloaded 396 times
Kind regards

Bernd

arkstar
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 70
Joined: Mon Dec 21, 2009 1:51 am

Re: Auto resize text to fit a field

Post by arkstar » Thu Sep 22, 2011 11:51 pm

Thanks Bernd!

I will try it out and certainly let you know!
What I can let you know now is how much I appreciate your help!

Rob
Rob Glassman
ArkStar

WaltBrown
Posts: 466
Joined: Mon May 11, 2009 9:12 pm

Re: Auto resize text to fit a field

Post by WaltBrown » Thu Sep 22, 2011 11:53 pm

FYI Bernd when I first opened it the field was set at Lucida Console, which seems to only present a 12 point setting on my machine. As soon as I changed the font it worked great.
Walt
Walt Brown
Omnis traductor traditor

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4174
Joined: Sun Jan 07, 2007 9:12 pm

Re: Auto resize text to fit a field

Post by bn » Fri Sep 23, 2011 12:09 am

Hi Walt,

Thanks for the observation. I did not check that and it turns out that once you set the textSize the font is also fixed for the field and not inherited from the stack.

Only if you make a new field and paste the code into it all the stack defaults apply. And on the Mac Lucida Grande is the default font, apparently on Windows only a subset of the Lucida Grande family is present.

So arkstar, either make a new field and paste the code or adjust the font manually on the example stack.

Kind regards

Bernd

arkstar
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 70
Joined: Mon Dec 21, 2009 1:51 am

Re: Auto resize text to fit a field

Post by arkstar » Fri Sep 23, 2011 2:16 am

Bernd,

Works perfectly! Thanks again!
Just what I wanted/needed.

Rob
Rob Glassman
ArkStar

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4174
Joined: Sun Jan 07, 2007 9:12 pm

Re: Auto resize text to fit a field

Post by bn » Fri Sep 23, 2011 12:01 pm

Hi Rob,

glad you like it.

I played around with the field and did not like the way text moves up when the textsize gets smaller. Since you mentioned you want the field to do badges I figured that it would look nice if the badges look similar, regardless of the text size.

I did a version that keeps the bottom of the first line constant (defined as a value in the script local variable sDesiredDistFromTop which you can adjust). It does so by setting the top margin on the fly.

You might want to have a try and see if it is useful for your purpose.
adjustTextSizeToField&TOPMargins.livecode.zip
(1.84 KiB) Downloaded 472 times
Kind regards

Bernd

arkstar
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 70
Joined: Mon Dec 21, 2009 1:51 am

Re: Auto resize text to fit a field

Post by arkstar » Sun Dec 11, 2011 4:22 pm

That's great!

Thanks again Bernd!
Rob Glassman
ArkStar

Post Reply