Complete
over 2 years ago

WERETECH-12048

Fix will be applied to next SDK release.

Devices affected will have firmware updates in a future firmware build.

No more transparency for font background on bufferd bitmap since SDK 4.0

Hi, 

I use a bufferedBitmap with color palette and custom bitmap fonts without antialiasing.

Since SDK 4.0 the font background  is not more transparent. The color is defined before:

dc.setColor(CustomColor, gfx.COLOR_TRANSPARENT);
   

The code is running many years without problem.

I don't understand, what's going wrong with new SDK

Parents
  • As  mentioned, the randomness is due to the lack of "COLOR_TRANPARNET" in the palette, so please make sure you have that added.

    That said, as the issue or BufferedBitmap retain the transparent attribute after drawText with transparent bg color, it's mostly by design.

    unlike the screen dc, BufferedBitmap is considered as a bitmap and clear it (or draw text ) with transparent bg color will result in the pixels in question area to be replaced by "transparent" pixel explicitly. So later on, when the BufferedBitmap is blit on top of the screen dc, we can though the transparent area in the BufferedBitmap.

    // fill screen with yellow bg color
    dc.setColor(Graphics.COLOR_YELLOW, Graphics.COLOR_YELLOW);
    dc.clear();
    var bb;
    var opts = {:width=>dc.getWidth(), :height=>dc.getHeight(), :palette=>[Graphics.COLOR_BLACK, Graphics.COLOR_RED, Graphics.COLOR_BLUE, Graphics.COLOR_TRANSPARENT]};
    if(Graphics has :createBufferedBitmap) {
        bb = Graphics.createBufferedBitmap();
    } else {
        bb = new Graphics.BufferedBitmap(opts);
    }
    var bbDc = bb.getDc();
    bbDc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_RED);
    bbDc.clear();
    // set bg to transparent
    bbDc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_TRANSPARENT);
    // draw text with transparent bg color will result in the text area to be
    // filled with "transparent" pixels
    // Note: _font must be 1-bpp, non-anti alias font
    bbDc.drawText(dc.getWidth()/2, dc.getHeight()/2, _font, "1234", Graphics.TEXT_JUSTIFY_CENTER);
    dc.drawBitmap(0, 0, bb);

    Here is the code I used to test, please feel free to play with it and let me know if this caused issues that you are not expecting.

Comment
  • As  mentioned, the randomness is due to the lack of "COLOR_TRANPARNET" in the palette, so please make sure you have that added.

    That said, as the issue or BufferedBitmap retain the transparent attribute after drawText with transparent bg color, it's mostly by design.

    unlike the screen dc, BufferedBitmap is considered as a bitmap and clear it (or draw text ) with transparent bg color will result in the pixels in question area to be replaced by "transparent" pixel explicitly. So later on, when the BufferedBitmap is blit on top of the screen dc, we can though the transparent area in the BufferedBitmap.

    // fill screen with yellow bg color
    dc.setColor(Graphics.COLOR_YELLOW, Graphics.COLOR_YELLOW);
    dc.clear();
    var bb;
    var opts = {:width=>dc.getWidth(), :height=>dc.getHeight(), :palette=>[Graphics.COLOR_BLACK, Graphics.COLOR_RED, Graphics.COLOR_BLUE, Graphics.COLOR_TRANSPARENT]};
    if(Graphics has :createBufferedBitmap) {
        bb = Graphics.createBufferedBitmap();
    } else {
        bb = new Graphics.BufferedBitmap(opts);
    }
    var bbDc = bb.getDc();
    bbDc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_RED);
    bbDc.clear();
    // set bg to transparent
    bbDc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_TRANSPARENT);
    // draw text with transparent bg color will result in the text area to be
    // filled with "transparent" pixels
    // Note: _font must be 1-bpp, non-anti alias font
    bbDc.drawText(dc.getWidth()/2, dc.getHeight()/2, _font, "1234", Graphics.TEXT_JUSTIFY_CENTER);
    dc.drawBitmap(0, 0, bb);

    Here is the code I used to test, please feel free to play with it and let me know if this caused issues that you are not expecting.

Children
  • Well said, thank you - it seems that this API now in SDK 4 allows no way to draw text without filling its rectangle.

    I think maybe a font could be hacked so that it has reportedly zero line height (unless you want a multiline text), which could force ConnectIQ to draw a zero height background, but it's an ugly hack.

  • Hi Johnny,

    Thank you for your reply. If as you say "the issue or BufferedBitmap retain the transparent attribute after drawText with transparent bg color, it's mostly by design", then why is the design inconsistent, so that the transparent attribute is retained when drawing text but it is not when drawing other things. What is the intended practical usage scenario that could benefit from this? In your example code you could achieve the same result much easier, just by drawing the text with a yellow background instead. On the other hand, there is at least one usage scenario that seems no longer possible: Drawing text over some kind of a background image, into a buffer with a custom palette, and then copying parts of this buffer during the onPartialUpdate(). This results in the second hand leaving traces on the 'transparent text background'. The only solution I can think of would be to try to redraw the affected parts of the screen each second, but that may be too costly and likely to trigger the power budget exception. Or did I miss something obvious how this could be dealt with?

    Please advise.

  • line 7 in the code should be the following

    bb = Graphics.createBufferedBitmap(opts).get();