Handling differences between system fonts in simulators and devices

As many of you know system fonts may differ between a simulator and device and the reason why was explained in the following thread:
https://forums.garmin.com/developer/connect-iq/f/discussion/6234/drawtext-positioning-differences-between-edge520-device-and-simulator

That is very unfortunate for us developers as we don't own or have access to all Garmin devices to test, so we have to choose between these options:
- Release the CIQ application only for devices that we own
- Align fonts on the simulator and hope that it would look good enough on a real device
- Use custom fonts

Every of the above option has its own drawbacks, so I would like to propose a fourth one. Based on the tests that I've done in the past, in order to vertically align a text the same in a simulator and a real device we need to have the top padding for each system font, which is the green line in the below picture:

The blue line (font baseline) can be retrieved by using getFontDescent method, which is very accurate on simulators and my Edge 1000. Please correct me if I am wrong as my testing is based on only one real device. In my CIQ applications I used the green and blue line to vertically align text, which you can check the source code if interested:
https://github.com/maca88/E-Bike-Edge-MultiField
https://github.com/maca88/SmartBikeLights

The problem of this approach is that it requires the top paddings of each screen-resolution family (e.g. round-260x260) and each language that has a different font (English, Chinese, Vietnamese, Japanese, Korean, Thai). So for anyone that is interested and would like to contribute the values of real devices you can do the following:
1. Download the project: https://github.com/maca88/E-Bike-Edge-MultiField/tree/master/Source/FontPaddingTest
2. In the folder resources-[screen]-[resolution] of your device add jsonData resource "DeviceFontPaddings", with the language that you want to contribute (e.g. english: <jsonData id="DeviceFontPaddings">{ "EN": [0, 0, 0, 0, 0, 0, 0, 0, 0] }</jsonData>). The "DeviceFontPaddings" array values represents the top font paddings for each font (the first value in the array is the top padding for FONT_XTINY, second for FONT_TINY, ...)
3. Compile the application and run it on your device
4. Modify "DeviceFontPaddings" array values until the green lines are touching the top of the fonts like in the above picture
5. Post the results here or on GitHub

Currently the only real device paddings are for Edge 1000, which you can check here (the biggest differences are for the first five fonts):
https://github.com/maca88/E-Bike-Edge-MultiField/blob/master/Source/FontPaddingTest/resources-rectangle-240x400/data.xml

In my short experience with developing CIQ applications the biggest struggle for me was the text alignment, which took me way more time that it should and that is also my reasoning for creating this thread. It would be great to have one place where we could see the font differences so that we could use them when needed. Let me know your thoughts on this, thanks.

Top Replies

All Replies

  • One thing that may help is instead of using ascent/decent, use dc.getFontHeight for spacing and use that value instead of a hard coded one in the app.  Fonts vary by device, and that won't change - I can think of a number of variations just on 240x240 watches.  But all in all, the sim is pretty accurate for a specific device.

  • use dc.getFontHeight for spacing

    Unfortunately for cases when the font needs to start for example five pixels from the top of the screen using only getFontHeight won't be enough as the top padding may be different. In my case I was trying to have the field label, value and units on the same position and with the same font size as a native field would have, example:

    Fonts vary by device

    You are correct, I randomly checked some devices with the same screen-resolution that had the same fonts and wrongly assumed that the fonts are the same for them. This would multiply the number of variations that I initially considered, which brings me to the conclusion that what I proposed is too ambitious to achieve and unpractical to use due to the large number of font variations.

    the sim is pretty accurate for a specific device

    On my Edge 1000 the difference on smaller fonts are different enough that caused me issues when I was working on the logic to dynamically calculate the units font size and their positions. For example "km" and "h" in the following picture:

    on the simulator the logic correctly calculated the font, but not on the device due to the bigger font spacing. I would be better off with hardcoding these values, but for some reason I choose the hard way :)

  • Look at adding TEXT_VCENTER to the mix.  With that you use the center of the font and not the top.

  • Another option is to use custom fonts, but that will impact the size of the prg.

  • For my case the solution lied in the devices.xml the "datafieldlayouts" tag, which contains what I needed but unfortunately I discovered it much later when I already had a working version. If I would knew about it earlier I would extract the containing data and would be able to achieve the same in much less time. Anyway thanks for your suggestions :)

  • Hi, thank you for the information. Can you tell how you determine font's top padding from "datafieldlayouts" tag?

    Also, I can't find devices.xml in new SDK or DEVICES. Found one in old SDK though.

  • It went away with CIQ 3.2  Devices are now in AppData/roaming//garmin/connectIQ/devices on windows systems.

  • Thanks, but it is not in Devices either...

  • With 3.2, devices.xml no longer exists.  In the folder I indicated, there's a folder for each device, and this kind of info is in files there.

  • I guess I didn't explain what I'm asking for. Which file contains this information now? I saw Devices, nothing looks readable in there...