Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: possible to end up with an incompletely-updated display (width calculation error) #276

Open
dsalt opened this issue Jan 17, 2025 · 0 comments

Comments

@dsalt
Copy link

dsalt commented Jan 17, 2025

I noticed this bug manifesting itself as the result of display.displayWindow(21, 20, 72, 15). This is not byte-aligned, with 3 pixels from the first byte and 5 from the last.

Internal calculations in the main WatchyDisplay::_writeImagePart code proceed as follows:

x -= x % 8; ⇒ mask off the bottom 3 bits (same as x &= ~7), giving 16.
w = 8 * ((w + 7) / 8); ⇒ w = 8*((72+7)/8) = 8*(79/8) = 8*9 = 72.

This is now 72 pixels (or 72 bits) from X co-ordinate 16 rather than 72 pixels from X co-ordinate 21: the right edge is also shifted left by 5 pixels when it actually needs to be shifted 3 pixels right for byte alignment. The existing addition of 7 (given the subsequent division) would suffice if the rectangle were a little wider (between 73 and 77 pixels, in this case); but as the left edge is about to be moved left by 5 pixels, we need to add those 5 pixels to the width.

More generally, x & 7 (or x % 8, if you prefer) needs to be added before dividing by 8, which gives the following fix:

--- a/src/Display.cpp
+++ b/src/Display.cpp
@@ -182,8 +182,8 @@
   x_part -= x_part % 8; // byte boundary
   w = w_bitmap - x_part < w ? w_bitmap - x_part : w; // limit
   h = h_bitmap - y_part < h ? h_bitmap - y_part : h; // limit
+  w = 8 * ((w + (x & 7) + 7) / 8); // byte boundary, bitmaps are padded
   x -= x % 8; // byte boundary
-  w = 8 * ((w + 7) / 8); // byte boundary, bitmaps are padded
   int16_t x1 = x < 0 ? 0 : x; // limit
   int16_t y1 = y < 0 ? 0 : y; // limit
   int16_t w1 = x + w < int16_t(WIDTH) ? w : int16_t(WIDTH) - x; // limit

(A similar change may be needed at line 114, in the main variant of WatchyDisplay::_writeImage.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant