Posted on by

FAQ Graphics

It’s Wednesday and time for another FAQ session. Here are five frequently asked questions (FAQ).

Question 1

Why is text spacing/positioning slightly different between the simulator and device?

Answer

The fonts are not the same between devices and simulator. The native.systemFont is different depending on the OS. On the Mac, it is LucidaGrande 24 pt. On iOS, it’s Helvetica. On Win, it’s something else. Different fonts have different font metrics even at the same point size, so that will mean differences in alignment.

Even for the same font, there can inevitably be differences, since the font rendering is done by the OS. While MacOS and iOS share similar code paths, the underlying text drawing is slightly different. The same fonts will have slight differences glyph rendering that is out of our control.

The only way to eliminate all inconsistencies and reliably get consistent font rendering is to use bitmap fonts.

Question 2

I have problems aligning text with display.newText. What’s the secret?

Answer

display.newText will treat the x,y parameters as the top left corner position. However, when you set the object’s (x,y) after it’s created, you are by default setting the center of the text. You can add object:setReferencePoint( display.TopLeftReferencePoint ) to bring back the same alignment used when the object was created. (This is confusing, so we are thinking of allowing you to control the alignment of the x,y parameter in these factory methods in a future Daily Build.)

There also may be some confusion in understanding how the calculation of width (w) and height (h) changes depending on how display.newText is called:

  • If w,h are not provided, then display.newText creates a single line object and sizes it appropriately for the string provided. Based on that w,h, it positions x,y at the top-left.
  • If w,h are both specified, then display.newText uses the supplied width/height to calculate the position so that x,y are at the top left. (If h is 0, then the height depends on the string supplied).

So when you set the x,y after creation, e.g. txt.x = xAlign, you are setting the center of the object, by default. So two text objects can have the same string but different widths. This means setting the center will make the left alignment appear off.

Question 3

I see “baseDirectory” used in a number of APIs so why doesn’t it support subdirectories?

Answer

The “baseDirectory” parameter used in display.newImage and other APIs is an optional parameter to specify one of the predefined system directories on the simulator or device. The file system is “sandboxed”, so the baseDirectory must be one of the following constants: system.ResourceDirectory, system.TemporaryDirectory, and system.DocumentsDirectory. If no baseDirectory is specified, it defaults to system.ResourceDirectory.

If you need to reference a subdirectory, the directory name is appended to the file name and not the baseDirectory parameter. Here’s are a couple of examples for accessing images from a subdirectory (“myImages”) in the Resource directory and Documents directory.


local image1 = display.newImage(  "myImages/redBall.png", 10, 200 )

-- This next line is the same as the previous
local image2 = display.newImage( "myImages/redBall.png", system.ResourceDirectory, 10, 200 )

local image3 = display.newImage( "myImages/redBall.png", system.DocumentsDirectory, 10, 200 ) 

Note: The Documents directory can be used to store images and other files but the application must first create/copy the files into the directory.

You may think that system.pathForFile could be used to specify the directory and subdirectory path, but it will not work where baseDirectory is required.

Question 4

I’m confused about when to use “.” and “/” for accessing subdirectories.

Answer

The simple answer is “.” is used to access modules in subdirectories loaded with the require API and “/” is used for all other APIs (like the display.newImage example in the last question). Since storyboard.gotoScene uses require under the hood, you would also use “.” to access scenes modules in subdirectories.

If I have a “movieclip.lua” module and images in the “assets” subdirectory, here is how they would be accessed:


local movieclip = require( "assets.movieclip" )
local image1 = display.newImage( "assets/redBall.png", 10, 200 )

Question 5

I don’t see a “baseDirectory” in the File I/O APIs. How do I specify the directory?

Answer

The io.open API is used to “open” a file for reading or writing. It specifies a “path”, which is a string containing the directory and file name. The string is created with system.pathForFile. Here is how you specify the directory using File I/O.


local path = system.pathForFile( "data.txt", system.DocumentsDirectory )

-- Open a file path
local fh, reason = io.open( path, "r" )

if fh then
    -- Read all the contents of the file into a string
    local contents = fh:read( "*a" )
    print( "Contents of " .. path .. "n" .. contents )
else
    print( "Reason open failed: " .. reason )
end

If you need to access the file in a subdirectory, you just append the subdirectory to the file name. The following example modifies “path” to access a subdirectory under the Resource directory.


local path = system.pathForFile( "myFiles/data.txt", system.ResourceDirectory )

That’s it for today’s questions. I hope you enjoyed it and even learned a few things.


Posted by . Thanks for reading...

7 Responses to “FAQ Wednesday #7”

  1. Jason Schroeder

    Quick correction to Answer #4: one exception to this rule is storyboard. For example, you still need to use periods for accessing subdirectories when using the storyboard.gotoScene() API, even though it’s not calling “require.”

    Or put another way:
    storyboard.gotoScene(“scenes/level1″) — this won’t work
    storyboard.gotoScene(“scenes.level1″) — this will work

    Sorry to correct you, Tom – keep these FAQs coming. They’re much appreciated!

    Reply
  2. Rebel Binary

    In regards to Question 1 and fonts not being at the correct height, this is a poor excuse. Even if it is the OS’s fault, the simulator’s job is to emulate what we will see on the device so it should make corrections for this.

    Case in point: The iOS simulator running on my mac displays the fonts correctly. The corona simulator does not.

    Reply

Leave a Reply

  • (Will Not Be Published)