Graphics: fix cropping of images in strings when gfx instance is rotated by 90 degrees

fix https://github.com/espruino/BangleApps/issues/4053
This commit is contained in:
Gordon Williams 2025-11-04 17:07:08 +00:00
parent 7c8e7586bd
commit 50eabb8f69
3 changed files with 68 additions and 22 deletions

View File

@ -29,6 +29,7 @@
JIT: Fix floating point constants JIT: Fix floating point constants
Linux SDL: Use SDL2, more keys forwarded, allow resizing of gfx window Linux SDL: Use SDL2, more keys forwarded, allow resizing of gfx window
Fix Linux ARM64 build Fix Linux ARM64 build
Graphics: fix cropping of images in strings when gfx instance is rotated by 90 degrees
2v27 : nRF5x: Ensure Bluetooth notifications work correctly when two separate connections use the same handle for their characteristics 2v27 : nRF5x: Ensure Bluetooth notifications work correctly when two separate connections use the same handle for their characteristics
nRF5x: Remove handlers from our handlers array when a device is disconnected nRF5x: Remove handlers from our handlers array when a device is disconnected

View File

@ -414,21 +414,26 @@ NO_INLINE void _jswrap_drawImageSimple(JsGraphics *gfx, int xPos, int yPos, GfxD
int x1 = xPos, y1 = yPos, x2 = xPos+img->width-1, y2 = yPos+img->height-1; int x1 = xPos, y1 = yPos, x2 = xPos+img->width-1, y2 = yPos+img->height-1;
if (!jsvStringIteratorHasChar(it)) return; // no data if (!jsvStringIteratorHasChar(it)) return; // no data
#ifndef SAVE_ON_FLASH #ifndef SAVE_ON_FLASH
graphicsSetModifiedAndClip(gfx,&x1,&y1,&x2,&y2, true); // ensure we clip Y, coords were already rotated if (!(gfx->data.flags&JSGRAPHICSFLAGS_SWAP_XY)) {
/* force a skip forward as many bytes as we need. Ideally we would use /* if we've not swapped X/Y we can so some optimisations
jsvStringIteratorGotoUTF8 but we don't have the UTF8 index or to reduce what we draw - but if we swapped XY there's no real point
source string here. This is still better than trying to render every pixel! */ because of the difference in direction we scan out. Also it's hard to get right! */
if (y2<y1 || x2<x1) { // offscreen - skip everything and exit graphicsSetModifiedAndClip(gfx,&x1,&y1,&x2,&y2, true); // ensure we clip Y
if (parseFullImage) { /* force a skip forward as many bytes as we need. Ideally we would use
bits = -img->bpp*img->width*img->height; jsvStringIteratorGotoUTF8 but we don't have the UTF8 index or
while (bits < 0) { source string here. This is still better than trying to render every pixel! */
jsvStringIteratorNextUTF8(it); if (y2<y1 || x2<x1) { // offscreen - skip everything and exit
bits += 8; if (parseFullImage) {
bits = -img->bpp*img->width*img->height;
while (bits < 0) {
jsvStringIteratorNextUTF8(it);
bits += 8;
}
} }
} return;
return; } else // onscreen. y1!=yPos if clipped - ensure we skip enough bytes
} else // onscreen. y1!=yPos if clipped - ensure we skip enough bytes bits = -(y1-yPos)*img->bpp*img->width;
bits = -(y1-yPos)*img->bpp*img->width; }
#endif #endif
JsGraphicsSetPixelFn setPixel = graphicsGetSetPixelUnclippedFn(gfx, xPos, y1, xPos+img->width-1, y2, true); JsGraphicsSetPixelFn setPixel = graphicsGetSetPixelUnclippedFn(gfx, xPos, y1, xPos+img->width-1, y2, true);
for (int y=y1;y<=y2;y++) { for (int y=y1;y<=y2;y++) {

View File

@ -1,12 +1,12 @@
var g = Graphics.createArrayBuffer(64,8,8); var g = Graphics.createArrayBuffer(64,8,8);
g.dump = _=>{ Graphics.prototype.dump = _=>{
var s = ""; var s = "";
var b = new Uint8Array(g.buffer); var b = new Uint8Array(g.buffer);
var n = 0; var n = 0;
for (var y=0;y<g.getHeight();y++) { for (var y=0;y<g.getHeight();y++) {
s+="\n"; s+="\n";
for (var x=0;x<g.getWidth();x++) for (var x=0;x<g.getWidth();x++)
s+=".#"[b[n++]?1:0]; s+=".#"[g.getPixel(x,y)?1:0];
} }
return s; return s;
} }
@ -74,14 +74,54 @@ g.clear().setRotation(2);
g.setClipRect(0,0,63,5); g.setClipRect(0,0,63,5);
g.drawString(str,0,0); g.drawString(str,0,0);
SHOULD_BE(` SHOULD_BE(`
#.#.###.....#.....#....#.#..#..##..#...##.......................
#.#..#.........#.......#.#.#.#.#.#.#...#.#......................
###..#.........#.......###.#.#.#.#.#...#.#......................
#.#..#......#.....#....###.#.#.##..#...#.#......................
#.#.###......#####.....#.#..#..#.#.###.##.......................
................................................................ ................................................................
................................................................ ................................................................
................................................................ ................................................................`);
.......................##.###.#.#..#..#.#.....#####......###.#.#
......................#.#...#..##.#.#.###....#.....#......#..#.# // Test image draw within text *when rotated 90 degrees and clipped* - https://github.com/espruino/BangleApps/issues/4053
......................#.#...#.#.#.#.#.###.......#.........#..### var str = "HI \0"+img;
......................#.#...#.#.#.#.#.#.#.......#.........#..#.# g = Graphics.createArrayBuffer(32,32,8);
.......................##...#..##..#..#.#....#.....#.....###.#.#`); g.clear().setRotation(1);
g.setClipRect(0,0,63,5);
g.drawString(str,0,0);
SHOULD_BE(`
#.#.###.....#.....#.............
#.#..#.........#................
###..#.........#................
#.#..#......#.....#.............
#.#.###......#####..............
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................`);
result = ok; result = ok;