font size

How do you handle font size difference between device ?
  • Just me personally but two ways:
    1) For determining whether text of a given size will fit in a given area, I use getFontHeight or getTextDimensionsInPixels (*)
    2) For trying to make things look as perfect as possible, I apply hardcoded device specific adjustments :/

    (*) You will find that for certain devices like VA3, Approach S60 and 230/235/630, the height returned by the API (for medium sized number fonts) is larger than the height in the sim/display. For personally, in some cases I have my own getFontHeight2 function which returns the height that I personally observed by counting pixels. (It’s not great coding practice, but it allows me to use bigger fonts than normal.)

    For me there was a lot of trial and error and hardcoded tweaks. But that was only because I wanted to fit the largest numbers possible in a full screen 6 field data field app. I tried doing it the “proper” way (respecting the API font height), but then some users complained that the fonts were too small on 235.

    If you choose to do device specific stuff, it helps to look at the UI guide to identify the different device “families” which use the same fonts. I think it’s roughly:
    - 230/235/630/735
    - Vivoactive
    - 920XT (**)
    - VA HR
    - Fenix 3 (**) / D2 Bravo
    - VA3 (Music) / Approach S60
    - Fenix 5S / Chronos
    - 645 (Music), 935, Fenix 5, Fenix 5 Plus, Fenix 5S Plus, Fenix 5X, Fenix 5X Plus, D2 Charlie/Delta, Descent MK1
    - Edge

    (**) AFAIK, these are the only two that seem to use proportional fonts for numbers. Other devices seem to use fixed-width fonts for numbers, which obviously makes a lot more sense for numbers that are constantly changing, or for lining up numbers in rows.
  • 735 is like the other semi-round, and Chronos is like the f5s, and f3hr and d2 Bravo like the f3, and D2 Charlie/Delta and mk1 like the f5x.

    for direct dc something like this works for line spacing:
    //in onUpdate, something like this, and if you're doint runtime checks, can use screen shape, height, and width for different options
    font=Gfx.FONT_MEDIUM;
    fHeight=dc.getFontHeight(font);

    //then in onUpdate
    y=yStart;
    dc.drawText(x,y,font,line1,...
    y+=fHeight;
    dc.drawText(x,y,font,line2,...
    y+=fHeight;
    ...
    //where x and justification are whatever you want.


    You can also use layouts based on the device.
  • my problem is that I've used things like "FONT_MEDIUM" and screen width/height for positioning, and seen difference in simulator, like fenix3/fenix5/VA3
  • Could you post some sample code and describe what you are seeing vs what you expect to see? Or post screenshots?

    The font sizes are different between device families, and even the relative font sizes are different. e.g. FONT_LARGE is not always smaller than FONT_NUMBER_MILD, which surprised me.

    Typically I use the font height to help position things, as in Jim’s sample code, and depending on what I'm doing, I also use the text width -getTextDimensionsInPixels().
  • Vald - FONT_* are different between different devices. The font itself can be different, the height and width, the "boldness", etc.

    What you see in the sim, is really what the look like for a given target device, with the exception of the Oregon/Rino right now. They are still a bit off.

    If you want something to be exactly the same on all devices, instead of using things like FONT_MEDIUM, you could do a custom font and use that, but it comes at a cost, as custom fonts take memory, and are a bit slower to display. And also, what might work fine on a 240x240 display, might not on a 218x218 display.
  • Could you post some sample code and describe what you are seeing vs what you expect to see? Or post screenshots?

    The font sizes are different between device families, and even the relative font sizes are different. e.g. FONT_LARGE is not always smaller than FONT_NUMBER_MILD, which surprised me.

    Typically I use the font height to help position things, as in Jim’s sample code, and depending on what I'm doing, I also use the text width -getTextDimensionsInPixels().

    here is some screenshot, my reference was the VA3.
    and a sample of code I used.

    var _end = mModel.getCurrentEnd();

    dc.drawText(
    (_canvas_w / 2),
    _canvas_h/2 - 2 * Graphics.getFontHeight(Graphics.FONT_MEDIUM),
    Graphics.FONT_MEDIUM ,
    mEnds,
    Graphics.TEXT_JUSTIFY_CENTER);

    dc.drawText(
    (_canvas_w / 2),
    _canvas_h/2 + Graphics.getFontAscent(Graphics.FONT_MEDIUM) - 2 * Graphics.getFontHeight(Graphics.FONT_MEDIUM) ,
    Graphics.FONT_NUMBER_MEDIUM ,
    _end.format("%d"),
    community.garmin.com/.../1455852.jpg
  • What you might be seeing is some fonts (number fonts are most common) have extra white space at the top. Try drawing a line across the screen where you think "y" should place your font, and again where the font height indicates the bottom.
  • By the way, something you can try, is instead of using a top height for the font as "y", is use y+fontHeight/2, and then TEXT_JUSTIFY_VCENTER in addition to TEXT_JUSTIFY_CENTER
  • What you might be seeing is some fonts (number fonts are most common) have extra white space at the top.


    This is a more accurate description of the actual situation, where I said 230/235/630/735, Approach S60, and VA3 report a different font height than the physical number of pixels. It is actually that there's a significant amount of whitespace at the top for certain fonts (which means the fonts appear slightly smaller than expected, too).

    However, you should be able to write code which produces text that is laid out properly on all devices, except that some devices will have more whitespace than others.

    For me personally, on some apps I live with the extra whitespace (and slightly smaller fonts on the some devices). In other cases, when I want to use fonts as big as possible, or eliminate whitspace, I use various hacks on certain devices like:
    - Hardcoding the font height in pixels, and adjusting the vertical alignment by a fixed offset. This works when stuff is aligned vertically relative to other elements
    - Ignoring the font height and only going by font width. This works when stuff is aligned vertically based on a fixed position, and the horizontal space is also fixed (e.g. if the app draws a 4 or 6 field layout).

    Jim's solution is also a nice way of aligning things, under certain situations.

    I'll take a look at running your code snippet in the sim and see what results I get for F3, F5 and VA3.
  • vald70, okay I think I see the problem in your code. You are using FONT_MEDIUM for positioning, but drawing _end with FONT_NUMBER_MEDIUM, which is much larger. You are seeing different results per-device because the relative (and absolute) sizes of FONT_MEDIUM vs FONT_NUMBER_MEDIUM are different per-device.

    When drawing multiple elements that are vertically positioned relative to each other, I would adjust y appropriately after each call, instead of recalculating y from scratch at each point. This would produce code that is easier to understand and change if you change the font size at any point.

    Try something like this, which should produce results close to what you expected.. For simplification, I didn't use fontAscent or fontDescent, although you may wish to do so to make things look nicer on all devices. Another way to do it (which could look nicer on F5) would be to add your own padding (at top and bottom) based on available vertical space. Obviously this is a refinement that would be a bit more work.

    function onUpdate(dc) {
    var mEnds = "Ends";
    var _end = 123; // dummy data

    dc.setColor(0, Graphics.COLOR_WHITE);
    dc.clear();

    // calculate starting y position
    var y = _canvas_h/2 - Graphics.getFontHeight(Graphics.FONT_MEDIUM) - Graphics.getFontHeight(Graphics.FONT_NUMBER_MEDIUM);

    dc.drawText(
    (_canvas_w / 2),
    y,
    Graphics.FONT_MEDIUM ,
    mEnds,
    Graphics.TEXT_JUSTIFY_CENTER);
    y += Graphics.getFontHeight(Graphics.FONT_MEDIUM);


    dc.drawText(
    (_canvas_w / 2),
    y,
    Graphics.FONT_NUMBER_MEDIUM ,
    _end.format("%d"),
    Graphics.TEXT_JUSTIFY_CENTER);

    y += Graphics.getFontHeight(Graphics.FONT_NUMBER_MEDIUM);

    //... Draw everything else

    // draw a horizontal line that's vertically centered
    dc.drawLine(0, _canvas_h/2, _canvas_w, _canvas_h/2);
    }
    [IMG2=JSON]{"data-align":"none","data-size":"full","src":"https:\/\/i.postimg.cc\/L6vxv549\/draw-f3.png"}[/IMG2]
    [IMG2=JSON]{"data-align":"none","data-size":"full","src":"https:\/\/i.postimg.cc\/VkVDQhb2\/draw-f5.png"}[/IMG2]
    [IMG2=JSON]{"data-align":"none","data-size":"full","src":"https:\/\/i.postimg.cc\/L8XNWShz\/draw-v3.png"}[/IMG2]