So I'm working on a game using LibGDX, and I have a problem.

To make my game fit most resolutions, I created a base asset for each aspect ratio, for example, a main menu background image, I made it in 800X600 for 4:3, 1280X720 for 16:9 etc.

Now I am trying to incorporate TextButtons into the game, for the options; My problem is that I can't figure out which font sizes match with which screen resolutions. Is there a way to figure this out, or do I have to go one by one through each of the resolutions I have and just manually match the text to the resolution?

up vote 15 down vote accepted

It's easy: Fonts do not need to match resolution, they need to match pixel density.

Pixel density is measured as pixels per inch(PPI), or pixels per centimeter. There's also a measure unit called density independent pixels(DP). It is defined that 1dp is the size one pixel has on a 160 PPI screen.

Now coming back to fonts, try to make this test: put your laptop to run on 720p. Take a look on the size of the font. Now plug it into the 1080p 42" monitor of your desktop. If your monitor outputs the right information about its size, then the font should have EXACTLY the same size it had on the 720p screen. Imagine how weird it would be if text in your laptop had a different size than the text on your desktop monitor. With that said, larger resolutions should give more detail to the font, larger screens should give more content to be shown.

The same fact can be observed on text editors. A 72pt font should look on the screen the same it would when printed on paper.

All this means you probably should want the same size across all display sizes (with some exceptions). If you want to base yourself somewhere, websites usually use 12pt fonts, MS Windows uses 11pt and 12pt fonts.

This chart (also included in the bottom of the answer) tell us 12pt in CSS is roughly equal to 16px also in CSS (As if this wasn't confusing enough, a px in CSS is the same as dp everywhere else), so let's say you'll make your fonts 16dp on LibGDX.

On your game, use the FreeTypeFontGenerator to generate fonts dynamically, this way you can consider the screen density when creating them:

BitmapFont createFont(FreeTypeFontGenerator ftfg, float dp)
{
    return ftfg.generateFont((int)(dp * Gdx.graphics.getDensity()));
}
//On Init
BitmapFont buttonFont = createFont(arial, 16); //16dp == 12pt

This works because Gdx.graphics.getDensity() is equal to YourScreenDensity/160 thus, is a "scale factor" to bring things to the size they would be on a 160ppi screen.

About the exceptions I mentioned earlier: you'll probably want fonts re-sizing accordingly to screen size in case of logos, promos, etc. But keep in mind that you'll be better off making these on a graphics editor like Photoshop or Gimp, anyway.

The other exception is text on tiny screens. 4.5" or smaller phone screens, wearables. Usually you won't have time to make scrolling content, or you just won't be able to afford putting so much content on that screen. You may try to scale the font 1dp down, as the reader will probably have the phone very close to their face, they probably won't have a problem reading. Keep in mind you may annoy the player reading unreadable small text.

TL;DR:

  • Physical size roughly won't change directly with screen size or resolution, but with a combination of both (screenSize/resolution the famous PPI)
  • Think of pt and dp. Forget about screen pixels until you have to draw the final result.
  • Create your font at runtime with a reasonable size.
  • Converting dp to screen pixels: pixels = dp * Gdx.graphics.getDensity();
  • If you are using a engine which does no give you converter to dp like LibGDX's Gdx.graphics.getDensity(), you can try: densityFactor = Screen.getPixelsPerInch() / 160.0f, then pixels = dp * densityFactor

EDIT:

2014, Jun 25 on Google IO, Matias announced a new style guidelines for Android, it includes a new Roboto font and typography guidelines. Take this table as a guide:

Android font size guidelines, taken fron google.com/design

EDIT2:

Included CSS font size chart in case the link goes rot: CSS font sizes

  • 1
    +1, great answer. The viewing distance is also a very important factor. You will need bigger fonts for games that run on a console/TV compared to ones for PC or even a Tablet (where the viewing distance is quite short). – bummzack Jun 14 '14 at 22:21
  • 1
    @bummzack great that you pointed this out! You can achieve this by adding a scaling factor to the formula, like this: dp * Gdx.graphics.getDensity() * distanceFactor. You can make distanceFactor an constant and define it to 2 when compiling for console/TV, 1 otherwise. Of course you should find better values for this. – Gustavo Maciel Jun 14 '14 at 22:50
  • I am having problems with this. When I just put the SP size into the generator as size for pixels I get the exact same size on my desktop app as the ones in the image, and other online sources about this. When I multiply by getDensity() == 0.6 they are unreadable on my desktop. They get small, but nicely sized on my Galaxy S8 where `getDensity() == 3'. I have calculated the density myself and they seem correct, then I actually held my phone next to my desktop application and they indeed are equal. But shouldn't they be the size of the actual image viewed on my desktop? – Madmenyo Jul 21 at 22:41
  • @Madmenyo That's the scaling factor I talked about. You should use density scaling to keep text size the same on devices that are of the same form-factor. So instead of just dp * getDensity(), you should probably do dp * getDensity() * scalingFactor, which scalingFactor should be decided at compile time, and something like this could work: Phones: scalingFactor = 1 Computer: scalingFactor = 3 and TV: scalingFactor = 5. Play with these numbers! – Gustavo Maciel Jul 23 at 22:26
  • GetDensity does not return the exact density as it turns out. github.com/libgdx/libgdx/issues/5322#issuecomment-406902114 you have to do something like getPpiX() / 160) to get a better result. However, getDensity() does a good enough job I guess in most cases. – Madmenyo Jul 24 at 13:58

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.