Is it possible to fill a string or number with two colors?

Former Member
Former Member

For example, let's say I have the text "Hi". Can I paint the top 30% red and the bottom 70% green?

  • You can do some things with with transparency as is done in NoFrills where you have the two colors as background (Hermo uses waves).

  • Former Member
    Former Member over 5 years ago in reply to jim_m_58

    Sorry, beginner here. What exactly is NoFrills?

  • There are at least two obvious ways to do this.

    1) use a clipping rectangle to draw the top half in one color, and then update the clipping rectangle to draw the bottom in another.
    2) use a custom font that defines the font to look like cutouts (the glyph is transparent and the outside is opaque). Draw the colors you want as rectangles, and then overlay the text stencil. (the NoFrills technique).

    The following code should work. I haven't actually tried to compile or run it, but it is theoretically pretty close to what you'd need.

    function onUpdate(dc) {
    
        dc.setColor(Graphics.COLOR_GREEN, Graphics.COLOR_BLACK);
        dc.clear();
    
        // these could be member variables and you could change the values at
        // runtime as you see fit
        var text = "Hi!";
        var percentOfTextThatIsGreen = 0.30f;
    
        var font = Graphics.FONT_LARGE;
        var dims = dc.getTextDimensions(text, font);
    
        var width = dc.getWidth();
        var height = dc.getHeight();
    
        var centerx = width / 2;
        var centery = height / 2;
    
        // assumes that font glyphs fill the entire fontHeight. this is not true for
        // all built-in font glyphs, so you might want to use a custom font for this
    
        var topOfGreenText = centery - (dims[1] / 2);
        var botOfGreenText = topOfGreenText + (dims[1] * percentOfTextThatIsGreen);
    
        var topOfRedText = botOfGreenText;
        var botOfRedText = topOfGreenText + dims[1];
    
        // there may on off-by-one error here because i'm trying to center the text
        // at (centerx, centery).. the divide by 2 will truncate, possibly clipping
        // one pixel on the left.
        var leftOfText = centerx - dims[0] / 2;
        var rightOfText = leftOfText + dims[0];
    
        // draw the top in green
        dc.setColor(Graphics.COLOR_RED, Graphics.COLOR_TRANSPARENT);
        dc.setClip(leftOfText, topOfGreenText, rightOfText, botOfGreenText);
        dc.drawText(centerx, centery, font, "Hi", Graphics.TEXT_JUSTIFY_CENTER | Graphics.TEXT_JUSTIFY_VCENTER);
    
        // draw the bottom in red
        dc.setColor(Graphics.COLOR_RED, Graphics.COLOR_TRANSPARENT);
        dc.setClip(leftOfText, topOfRedText, rightOfText, botOfRedText);
        dc.drawText(centerx, centery, font, "Hi", Graphics.TEXT_JUSTIFY_CENTER | Graphics.TEXT_JUSTIFY_VCENTER);
    
        // reset the clipping area
        dc.clearClip();
    }

  • Former Member
    Former Member over 5 years ago in reply to Travis.ConnectIQ

    This worked on the newer watches (3.0+) but I am trying to make this watch face for the older ones as well (I have a Fenix3HR which runs version 1.3), and setClip() is only available in 2.3+. Is there any way to do this in the older watches as well?

  • #2 in what Travis posted.  That's the way Hermo does NoFrills.

  • Former Member
    Former Member over 5 years ago in reply to jim_m_58

    where can I find information on how to make a custom font as I am not familiar with the process?

  • There's a section in the programmer's guide, and here's a video showing how to make a WF with one:

    https://www.youtube.com/watch?v=PRQyA4BeqqE

    Petr's using BMfont to make the font.

    You should be able to use the same technique as nofrills with a native font.  Set the foreground color to transparent and overlay rectanges of the color/size you want.

  • Former Member
    Former Member over 5 years ago in reply to jim_m_58

    I see. How do you make cutouts with an opaque surrounding in BMfont? I tried playing around and going through all the settings but I couldn't find the option.

  • You do it based on colors when you use dc.drawText.  You can do this with a standard font too,

    dc.setColor(Gfx.COLOR_TRANSPARENT,Gfx.COLOR_BLUE);

    for example.