Tutorial: Methods for Positioning Text

At the basic level, creating and positioning text in Corona SDK is simple: just create the object at the desired position in the specified font size and you’re done. For example:

1

local myText=display.newText("Hello World",200,200,native.systemFont,16)

However, when you need to position/align text in creative ways, things get a bit more complicated. In this tutorial, we’ll inspect the actual display object that Corona generates via display.newText() so that you can understand and achieve advanced positioning and alignment.

The Basics

Under the hood, Corona takes the information that you pass to the display.newText() API and it generates an image, rendered to texture memory like any other display object. Because Corona SDK uses the operating system’s font rendering, fonts may render differently between devices and the Corona Simulator, in particular between Windows and OS X.

Single-Line Method

The most basic usage of display.newText() is the single-line method. Using this method, you simply output a string of text to the screen. Once it’s rendered by Corona, the theoretical “bounding box” (indicated by the green line) will fit precisely around the text display object:

In regards to screen position, the x and y of this “box” is based upon its center point. You can, of course, position any text object via this center point, but if you’re building a series of text objects such as labels on a statistics screen, you’ll probably want to left-align all of them to a vertical “guide line.” This can be accomplished using anchor points, where — in regards to the x position — an anchor point of 0 indicates the left-most point of the object, 0.5 indicates the center x point, and 1 indicates the right-most point. A similar concept applies to the y anchor point, where a y anchor of 0 represents the object’s top, 0.5 the vertical middle, and 1 the object’s bottom.

Let’s inspect a basic example:

1

2

3

4

5

6

local myText=display.newText("Hello World",0,0,native.systemFont,16)

myText:setFillColor(0,0,0)

myText.anchorX=0

myText.x=10

myText.y=100

Because the anchorX value is set to 0 (the left edge), and the x value is set to 10, this code block positions the text with its left edge 10 points to the right of the content area’s vertical 0 point. Remember, however, that you’re not “aligning the text,” but rather positioning its bounding box (this point will become more important further on).

Multi-Line Method

For more advanced alignment, you may utilize the multi-line method. In this case, you pass a table of options to the display.newText() call. Most of these options mimic those from the “shorthand” single-line declaration outlined above, but there are three additional properties which extend the alignment possibilities: width, height, and align.

width

This property specifies the width of the multi-line “bounding box” in pixels. This is similar to drawing a flexible text box in a graphics application like Photoshop or Illustrator, where the text — no matter how much you enter within the box — will wrap within the confines of its boundaries. As expected, if a word is too long to fit within the remaining width available on that line, it will wrap to the next line.

height

If specified, the text will be cropped at this value, in pixels. If you want an “unlimited” height for the text box, set this value to 0 and the box height will adjust depending on the amount of text within it. However, it will never exceed the maximum texture size limit for the device.

align

This specifies the alignment of the text when the width parameter is supplied. Default value is "left". Valid values are "left", "center", or "right". We’ll discuss this in more detail shortly.

Principles of Alignment

Although it may seem non-intuitive to create a single line of text using the multi-line method, let’s explore the advantages from Corona’s standpoint:

1

2

3

4

5

6

7

8

9

10

11

12

local options=

text="Hello World",

x=display.contentCenterX,

y=display.contentCenterY,

fontSize=24,

width=200,

height=0,

align="left"

local textBox=display.newText(options)

textBox:setFillColor(0,0,0)

Because the string Hello World, in the default system font at size 24, fits within the width of 200 pixels, it won’t wrap to a second line. Thus, this code visually produces a single line of text. However, while it may appear the same as the first example, it’s important to understand that the “bounding box” is now 200 pixels wide, not the pixel width of the actual text that you see on the screen:

In this manner, you can build a series of fixed-width text boxes and position them in a more unified manner rather than dealing with various text object sizes produced via the single-line method.

Want to right-align the text? Simply change the align parameter to "right"…

Or you may change it to "center"…

In addition to these flexible alignment options, another advantage to multi-line method is that it lets you change the value of the .text property and, if the new string is longer or shorter, the box remains at the fixed width and the text won’t shift unexpectedly. In single-line mode, by comparison, if you position a text object by its center point and change the text string, the object may not align as you intended.

Multiple Lines

Of course, multi-line mode supports multiple lines as well! Let’s see how it looks in the three different alignment options:

“left”

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

local myText=[[Thisisalong,multi-line stringwhere we are randomly

inserting some blank

lines

of text.]]

local options=

text=myText,

x=display.contentCenterX,

y=display.contentCenterY,

width=200,

height=300,

fontSize=24,

align="left"

local textField=display.newText(options)

textField:setFillColor(0,0,0)

“center”

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

local myText=[[Thisisalong,multi-line stringwhere we are randomly

inserting some blank

lines

of text.]]

local options=

text=myText,

x=display.contentCenterX,

y=display.contentCenterY,

width=200,

height=300,

fontSize=24,

align="center"

--Output the text box with the specified options

local textField=display.newText(options)

textField:setFillColor(0,0,0)

“right”

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

local myText=[[Thisisalong,multi-line stringwhere we are randomly

inserting some blank

lines

of text.]]

local options=

text=myText,

x=display.contentCenterX,

y=display.contentCenterY,

width=200,

height=300,

fontSize=24,

align="right"

--Output the text box with the specified options

local textField=display.newText(options)

textField:setFillColor(0,0,0)

As you can see, the align option affects the positioning of the text within the box. In all of these examples, the height of the box is defined at 300. If you set the height to 0, the bounding box will match the actual height of the text. However, this may affect vertical alignment depending on the box’s y anchor setting. Also, while a height setting of 0 creates a text box of “unlimited” height, the text that is created will never exceed the device’s texture size limit. This is an important restriction to be aware of if you place a significant amount of text into a single text box.

On the Topic of Multiple Lines…

In Lua, there is some confusion around how to put line breaks into strings. While Lua supports the traditional double quotes ("...") or single quotes ('...'), it also supports multiple lines via the [[...]] declaration. As such, you may use this method or the Unix “Newline” character (n) within quotes:

1

2

3

4

5

6

7

longString=[[Thisisareally

longstring

with multiple

line breaks.]]

--OR...

longString="This is a reallynlong stringnwith multiplenline breaks."

Note that if you attempt to input multiple lines using Corona’s single-line method, the line breaks will be ignored.

In Summary

Hopefully this tutorial has shown you some useful techniques for aligning text in Corona SDK. With the single-line method and the more powerful multi-line method, almost any alignment scenario should be possible with just a few lines of code.

Disclaimer: SDKNews.com only syndicates the blog entries from various SDK blogs.
We are not the creator/author of these entries (posts). Product names, brand names
and company names mentioned on this site may be trademarks of their respective owners.