Skip to content

Commit

Permalink
Graphics: Adjust image alignment when rotating images to avoid croppi…
Browse files Browse the repository at this point in the history
…ng (fix #2535)
  • Loading branch information
gfwilliams committed Aug 12, 2024
1 parent 9cc9268 commit ff487e0
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 46 deletions.
1 change: 1 addition & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
: ESP32C3: Get analogRead working correctly
Graphics: Adjust image alignment when rotating images to avoid cropping (fix #2535)

2v24 : Bangle.js2: Add 'Bangle.touchRd()', 'Bangle.touchWr()'
Bangle.js2: After Bangle.showTestScreen, put Bangle.js into a hard off state (not soft off)
Expand Down
18 changes: 9 additions & 9 deletions libs/graphics/jswrap_graphics.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,9 +289,9 @@ bool _jswrap_graphics_parseImage(JsGraphics *gfx, JsVar *image, size_t imageOffs
}

bool _jswrap_drawImageLayerGetPixel(GfxDrawImageLayer *l, uint32_t *result) {
int qx = l->qx+127;
int qy = l->qy+127;
if (qx>=0 && qy>=0 && qx<l->mx && qy<l->my) {
int qx = l->qx;
int qy = l->qy;
if (qx>=0 && qy>=0 && (qx&~255)<l->mx && (qy&~255)<l->my) {
unsigned int colData = 0;
int imagex = qx>>8;
int imagey = qy>>8;
Expand Down Expand Up @@ -333,8 +333,8 @@ NO_INLINE void _jswrap_drawImageLayerInit(GfxDrawImageLayer *l) {
// step values for blitting rotated image
double vcos = jswrap_math_cos(l->rotate);
double vsin = jswrap_math_sin(l->rotate);
l->sx = (int)((vcos/l->scale)*256 + 0.5);
l->sy = (int)((vsin/l->scale)*256 + 0.5);
l->sx = (int)((vcos/l->scale)*256);
l->sy = (int)((vsin/l->scale)*256);
// work out actual image width and height
int iw = (int)(0.5 + l->scale*(l->img.width*fabs(vcos) + l->img.height*fabs(vsin)));
int ih = (int)(0.5 + l->scale*(l->img.width*fabs(vsin) + l->img.height*fabs(vcos)));
Expand All @@ -346,10 +346,10 @@ NO_INLINE void _jswrap_drawImageLayerInit(GfxDrawImageLayer *l) {
l->x2 = l->x1 + iw*256;
l->y2 = l->y1 + ih*256;
// work out start position in the image
int centerx = l->img.width*128;
int centery = l->img.height*128;
l->px = centerx - (1 + (l->sx*iw) + (l->sy*ih)) / 2;
l->py = centery - (1 + (l->sx*ih) - (l->sy*iw)) / 2;
int centerx = (l->img.width)*128; // *256 / 2
int centery = (l->img.height)*128;
l->px = centerx - ((1 + (l->sx*iw) + (l->sy*ih)) / 2);
l->py = centery - ((1 + (l->sx*ih) - (l->sy*iw)) / 2);
// handle repetition
if (l->repeat) {
// for the range we're in, it's quicker/easier than modulo
Expand Down
38 changes: 19 additions & 19 deletions tests/test_graphics_drawImage3bit.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,25 +55,25 @@ SHOULD_BE(`
// Force almost identical draw, but with slow path using _jswrap_drawImageLayerGetPixel
g.clear(1).drawImage(img,0,0,{scale:1.0000001});
SHOULD_BE(`
......."""""".......
....."""""""""".....
...""""""""""""""...
..""""""""""""""""..
..""""""""""""""""..
.""""""""""""""*""".
."""""""""""""##*"".
......."""""""......
....."""""""""""....
..."""""""""""""""..
..""""""""""""""""".
..""""""""""""""""".
."""""""""""""""*"""
.""""""""""""""##*""
""""""""""""""###"""
"""""""""""""###""""
""""""""""""###"""""
"""""*"""""###""""""
""""*##"""###"""""""
"""""###"###""""""""
""""""#####"""""""""
.""""""###""""""""".
."""""""*"""""""""".
..""""""""""""""""..
..""""""""""""""""..
...""""""""""""""...
....."""""""""".....
......."""""".......`);
"""""*""""""###"""""
""""*##"""####""""""
""""*##"""####""""""
"""""###"####"""""""
""""""######""""""""
.""""""###""""""""""
."""""""*"""""""""""
..""""""""""""""""".
..""""""""""""""""".
..."""""""""""""""..
....."""""""""""....`);

result = ok;
36 changes: 18 additions & 18 deletions tests/test_graphics_drawImageRotate.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,29 +45,29 @@ SHOULD_BE(`
................................
................................
................................
................................
................#...............
...............###..............
..............#####.............
.............#######............
............###.#####...........
...........###...#####..........
..........###.....#####.........
.........###.......#####........
........###.........#####.......
.......###...........#####......
......###.............#####.....
......##...............####.....
.......##...............##......
........##.............##.......
.........##...........##........
..........##.........##.........
...........##.......##..........
............##.....##...........
.............##...##............
..............##.##.............
............#########...........
...........###..######..........
..........###....######.........
.........###......######........
........###........######.......
.......###..........######......
......###............######.....
.....###..............#####.....
......###..............####.....
.......###.............###......
........###...........###.......
.........###.........###........
..........###.......###.........
...........###.....###..........
............###...###...........
.............###.###............
..............#####.............
...............###..............
................#...............
................................
................................
................................
................................
Expand Down
117 changes: 117 additions & 0 deletions tests/test_graphics_drawImageRotate180.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
var g = Graphics.createArrayBuffer(16,16,8);
g.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++]&3];
}
return s;
}
g.print = _=>{
print("`"+g.dump()+"`");
}
var ok = true;
function SHOULD_BE(a) {
var b = g.dump();
if (a!=b) {
console.log("GOT :"+b+"\nSHOULD BE:"+a+"\n================");
ok = false;
}
}

var img = {
width : 8, height : 8, bpp : 8,
buffer : new Uint8Array([
3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,
3,1,1,1,1,1,1,3,
3,1,1,1,1,1,1,3,
3,1,1,1,1,1,1,3,
3,1,1,1,1,1,1,3,
3,1,1,1,1,1,1,3,
3,3,3,3,3,3,3,3,
]).buffer
};

g.clear().drawImage(img,4,4,{rotate:-0.000000001});
SHOULD_BE(`
########........
########........
#------#........
#------#........
#------#........
#------#........
#------#........
########........
................
................
................
................
................
................
................
................`);

g.clear().drawImage(img,4,4,{rotate:Math.PI/2});
SHOULD_BE(`
########........
#-----##........
#-----##........
#-----##........
#-----##........
#-----##........
#-----##........
########........
................
................
................
................
................
................
................
................`);


g.clear().drawImage(img,4,4,{rotate:Math.PI});
SHOULD_BE(`
########........
#------#........
#------#........
#------#........
#------#........
#------#........
########........
########........
................
................
................
................
................
................
................
................`);


g.clear().drawImage(img,4,4,{rotate:Math.PI*3/2});
SHOULD_BE(`
########........
##-----#........
##-----#........
##-----#........
##-----#........
##-----#........
##-----#........
########........
................
................
................
................
................
................
................
................`);

result = ok;

0 comments on commit ff487e0

Please sign in to comment.