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

  • if under devices, you look under the fenix6 folder, it's in simulator.json

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

    I started developing CIQ apps when 3.2 was released so this is the method I used:
    1. Go to the desired CIQ sdk bin folder (e.g. %APPDATA%\GARMIN\ConnectIQ\Sdks\connectiq-sdk-win-3.2.5-2021-02-12-6d31f4357\bin)
    2. Extract file "monkeybrains.jar" with an extractor tool (e.g. 7Zip) to a subfolder (e.g. "monkeybrains")
    3. You can find the devices.xml in "com\garmin\monkeybrains\devices" path of the extracted subfolder

    In case you are using Notepad++ you can press ALT + 3, which will make browsing the file content much easier.

    Can you tell how you determine font's top padding from "datafieldlayouts" tag?

    With "datafieldlayouts" you don't need the top padding anymore as it contains the exact position and justification where the label or a value of the field will be placed. Find <datafieldlayouts> element inside the device that you want to know the label/value positions there you have "labelx", "labely" and "labeljustify" attributes which you can use for the dc.drawText method.

  • Thank you! So I'm guessing you use Garmin layouts intead of your own then? In your example above, how would you allign top of a number with top of the "k" in "km"?

  • Where exactly in simulator.json ? "datafieldlayouts" is not there. Check maca88 answer below - he is spot on!

  • for example,

    devices\fenix6\simulator.json if you have the fenix 6 device downloaded.

  • I see simulator.json file, but "datafieldlayouts" information is not there. Check maca88 answer, he has the right information, I was able to get the latest devices.xml using the method he described.

  • So I'm guessing you use Garmin layouts intead of your own then?

    I don't use these layouts as I discovered them too late, I precalculate these values based on the available space and also by using the top paddings described in the initial post.

    how would you allign top of a number with top of the "k" in "km"?

    good question, unfortunately "datafieldlayouts" element does not contain this information so you have the following options:
    - you need to have the top padding for the fonts and precalculate the units position based on them (this is what the mentioned app is currently doing)
    - Hardcode the units positions (needed only for two and more row units, like rpm or km/h) for each font that is used to display the value. For aligning the bottom row, you can use getFontDescent method.

    To be honest I don't like neither of them, but unfortunately with my current knowledge I don't know a better one.

  • Hardcode the units positions

    If I understand correctly from your previous posts, these hardcoded values might be different on different devices?

    And thanks for the info, very helpful !

  • Unfortunately yes, they can be different. So the best that you can do is to hardcode the values based on the devices that you own and for other devices use the simulator.

  • Look for "datafields" in simulator.json. You can also find the devices.xml in the monkeybrains.jar For example: 

    jar xf Sdks/connectiq-sdk-mac-7.4.3-2024-12-11-90ec25e45/bin/monkeybrains.jar com/garmin/monkeybrains/devices/devices.xml