[Edit: this seems to have been some kind of build corruption. After upgrading to sdk 4.0.10, I can no longer repro, even when I downgrade to 4.0.9 again]
I've been trying to draw into a BufferedBitmap, and then copy that to the screen, and I was getting very strange results, so I created a new DataField project from the template, and replaced onUpdate with this:
function onUpdate(dc as Dc) as Void { dc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_WHITE); dc.clear(); var w = dc.getWidth() / 4; var h = dc.getHeight() / 4; drawAt( dc, w, h, false, [ Graphics.COLOR_BLACK, Graphics.COLOR_WHITE ] as Array<Graphics.ColorValue> ); drawAt( dc, w * 2, h, false, [ Graphics.COLOR_BLACK, Graphics.COLOR_WHITE, Graphics.COLOR_RED, Graphics.COLOR_BLUE ] as Array<Graphics.ColorValue> ); drawAt( dc, w * 3, h, false, [ Graphics.COLOR_RED, Graphics.COLOR_BLUE, Graphics.COLOR_BLACK, Graphics.COLOR_WHITE, ] as Array<Graphics.ColorValue> ); drawAt( dc, w, h * 2, false, [ 0x000000, 0x000055, 0x0000AA, 0x0000FF, 0x005500, 0x005555, 0x0055AA, 0x0055FF, 0x00AA00, 0x00AA55, 0x00AAAA, 0x00AAFF, 0x00FF00, 0x00FF55, 0x00FFAA, 0x00FFFF, 0x550000, 0x550055, 0x5500AA, 0x5500FF, 0x555500, 0x555555, 0x5555AA, 0x5555FF, 0x55AA00, 0x55AA55, 0x55AAAA, 0x55AAFF, 0x55FF00, 0x55FF55, 0x55FFAA, 0x55FFFF, 0xAA0000, 0xAA0055, 0xAA00AA, 0xAA00FF, 0xAA5500, 0xAA5555, 0xAA55AA, 0xAA55FF, 0xAAAA00, 0xAAAA55, 0xAAAAAA, 0xAAAAFF, 0xAAFF00, 0xAAFF55, 0xAAFFAA, 0xAAFFFF, 0xFF0000, 0xFF0055, 0xFF00AA, 0xFF00FF, 0xFF5500, 0xFF5555, 0xFF55AA, 0xFF55FF, 0xFFAA00, 0xFFAA55, 0xFFAAAA, 0xFFAAFF, 0xFFFF00, 0xFFFF55, 0xFFFFAA, 0xFFFFFF ] as Array<Graphics.ColorValue> ); drawAt( dc, w * 2, h * 2, false, [ 0xFFFFFF, 0xAAAAAA, 0x555555, 0x000000, 0xFF0000, 0xAA0000, 0xFF5500, 0xFF00FF, 0xFFAA00, 0xAA00FF, 0x00FF00, 0x00AA00, 0x00AAFF, 0x0000FF ] as Array<Graphics.ColorValue> ); drawAt( dc, w * 3, h * 2, false, null ); drawAt( dc, w, h * 3, true, [ Graphics.COLOR_BLACK, Graphics.COLOR_WHITE ] as Array<Graphics.ColorValue> ); drawAt( dc, w * 2, h * 3, true, [ Graphics.COLOR_BLACK, Graphics.COLOR_WHITE, Graphics.COLOR_RED, Graphics.COLOR_BLUE ] as Array<Graphics.ColorValue> ); drawAt( dc, w * 3, h * 3, true, [ Graphics.COLOR_RED, Graphics.COLOR_BLUE, Graphics.COLOR_BLACK, Graphics.COLOR_WHITE, ] as Array<Graphics.ColorValue> ); // dc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_YELLOW); // dc.drawText(dc.getWidth()/2, dc.getHeight()/2, Graphics.FONT_MEDIUM, // value.toString(), Graphics.TEXT_JUSTIFY_CENTER + Graphics.TEXT_JUSTIFY_VCENTER); } function drawAt(dc as Dc, x as Number, y as Number, fillRect as Boolean, palette as Array<Graphics.ColorValue>?) { x -= 25; y -= 25; var bitmapOpts = { :width => 50, :height => 50 }; if (palette != null) { bitmapOpts[:palette] = palette; } var bitmap = Graphics has :createBufferedBitmap ? Graphics.createBufferedBitmap(bitmapOpts).get() as BufferedBitmap : new Graphics.BufferedBitmap(bitmapOpts); bitmap.getDc().clearClip(); bitmap.getDc().setColor(Graphics.COLOR_BLACK, Graphics.COLOR_BLACK); bitmap.getDc().clear(); if (fillRect) { bitmap.getDc().fillRectangle(0, 0, 50, 50); } bitmap.getDc().setColor(Graphics.COLOR_WHITE, Graphics.COLOR_WHITE); bitmap.getDc().fillEllipse(25, 25, 15, 20); dc.drawBitmap(x, y, bitmap); }
Basically, drawAt creates a bitmap with an optional palette, clears it to black using dc.clear(), optionally clears it to black again using dc.fillRectangle() (this should be a no-op, but strangely wasn't), then fills an ellipse with white in the center of the bitmap. Then it draws the bitmap centered on the given location.
onUpdate then calls this function 9 times.
The first three (the top row) give 3 different palettes; the first is black and white; the second is black, white, red and blue; the third is red, blue, black and white (but note that in each case, the only colors I draw in are black and white).
The second three (middle row) give the 64 entry fenix5xplus palette (as extracted from Garmin/ConnectIQ/Devices/fenix5xplus/compiler.json), the 14 entry fr230 palette (obtained similarly), and no palette at all.
The third three are the same as the top row, except that in addition to dc.clear(), it also calls dc.fillRectangle() to fill the background with black (this shouldn't change anything).
So we should have nine identical black squares, each with a white ellipse carved out of the center. What I get in the simulator (for fenix5xplus) is this:
The only one that came out correct is the one with the fenix5xplus palette. Even the one with no palette (which is supposed to use the system palette) failed. Also note that I clear the background to black, and then draw in white... there should be no way for other colors to get in there. And where did the stripes come from?
I tried with the venu2 (choosing a watch that doesn't have a system palette), and got:
And this time, the only one thats correct is the one with the fr230 palette.
Finally if I run it on the device I get solid black squares except for the top right and bottom right, which are red, and the center which is white (or maybe transparent).
I see from the discussions that people are using BufferedBitmaps for their apps, so presumably they're not really this broken... what am I doing wrong?