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

View File

@ -1,12 +1,12 @@
var g = Graphics.createArrayBuffer(64,8,8);
g.dump = _=>{
Graphics.prototype.dump = _=>{
var s = "";
var b = new Uint8Array(g.buffer);
var n = 0;
for (var y=0;y<g.getHeight();y++) {
s+="\n";
for (var x=0;x<g.getWidth();x++)
s+=".#"[b[n++]?1:0];
s+=".#"[g.getPixel(x,y)?1:0];
}
return s;
}
@ -74,14 +74,54 @@ g.clear().setRotation(2);
g.setClipRect(0,0,63,5);
g.drawString(str,0,0);
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;