* waveshare2in13v2: Populate bounds only once
The forthcoming introduction of image orientation will make the
computation slightly more complicated. The bounds are fixed during the
lifetime of a "Dev" instance, so it's better to retain them.
* waveshare2in13v2: Make sending image part of drawOpts
* waveshare2in13v2: Unexport drawSpec members
The members of the "drawSpec" structure are only for internal use, so
rename them to start with a lower-case letter.
* waveshare2in13v2: Implement support for rotating image
A new option named "Origin" controls which of the four corners of the
display should be used as the (0,0) position for the image. The
in-memory buffer is kept in logical orientation. The actual rotation
happens only when sending updates.
By aligning the buffer accordingly the code is already prepared for
a more efficient sending of image data for the "TopRight" and
"BottomLeft" origins. See the TODO comment on "drawSpec.BufferDstOffset"
for details.
Signed-off-by: Michael Hanselmann <public@hansmi.ch>
With the introduction of the shadow buffer in commit 4f99575 there's
always a sufficiently large memory buffer to keep the bytes to send for
clearing and the dedicated code using a smaller buffer is no longer
needed. This also has the advantage of automatically updating both
on-device buffers.
This is necessary for partial updates of the display--not just
incremental updates of the full display, but updating part of the
display in general.
On the horizontal axis only whole bytes can be written, so updates need
to be aligned to 8 pixels. One option would be to require the caller of
Dev.Draw to only operate at multiples of 8. Another would be to read
back the contents of bytes to be updated partially and combine the data.
According to the datasheet the controller supports that (command 0x27).
The simplest option, however, is to maintain a shadow buffer in the
driver. Updates are applied to the buffer from which only the changed
destination rectangle is sent to the display. The permanent cost is
a bit more than 4kB of memory for a 122x250 display while saving on
memory allocations for a temporary image buffer on updates.
Signed-off-by: Michael Hanselmann <public@hansmi.ch>
This is an API-breaking change, albeit a simple one: Previously the
Dev.Clear function received a byte named "color". It was sent directly
to the display, thus acting more like a pattern to fill the display
with. In practice only 0 and 255 are likely to be used.
With this change the function is changed to receive a value of type
color.Color which is then converted to image1bit.Bit before filling the
display. The latter is also given a unittest.
Signed-off-by: Michael Hanselmann <public@hansmi.ch>
When the destination rectangle didn't start at (0,0) or cover the whole
display the Dev.Draw function would continue to update the display in
full. Obviously that didn't result in a good output.
This change updates the drawing logic to only update the affected area
(aligned to whole bytes on the horizontal axis) and limits the amount of
transferred data to the minimum needed to cover the destination
rectangle.
The calculation of the various offsets as well as the function sending
the image data are written to support unittesting.
Signed-off-by: Michael Hanselmann <public@hansmi.ch>