I am implementing a halftone fill capability (for monochrome displays).
In lvgl 5.3 I did this by modifying the sw_color_fill function. halftone issue
In 5.3 the absolute address was passed in via mem_area
In 6.0 this function has changed parameters, how do I retrieve the absolute address of each pixel?
What MCU/Processor/Board and compiler are you using?
IMXRT1052
What do you want to achieve?
Halftone fill function
What have you tried so far?
Modifying sw_color_file with the following code.
Code to reproduce
Here is part of the sw_color_file code I modified (this is using a relative address, row or col, not absolute)
The code block(s) should be formatted like:
static void sw_color_fill(lv_color_t * mem, lv_coord_t mem_width, const lv_area_t * fill_area, lv_color_t color, lv_opa_t opa)
{
/*Set all row in vdb to the given color*/
lv_coord_t row;
lv_coord_t col;
lv_disp_t * disp = lv_refr_get_disp_refreshing();
if(disp->driver.set_px_cb) {
for(col = fill_area->x1; col <= fill_area->x2; col++) {
for(row = fill_area->y1; row <= fill_area->y2; row++) {
disp->driver.set_px_cb(&disp->driver, (uint8_t *)mem, mem_width, col, row, color, opa);
}
}
} else {
mem += fill_area->y1 * mem_width; /*Go to the first row*/
/*Run simpler function without opacity*/
if(opa == LV_OPA_COVER) {
...
}
else if(opa == LV_OPA_HALFTONE)
{
//printf("half: %d\n", opa);
/*Fill the first two rows with halftone pattern*/
for(col = fill_area->x1; col <= fill_area->x2; col++)
{
if(col % 2 == 0)
{
mem[col] = color;
}
else
{
mem[col] = LV_COLOR_BLACK;
}
}
lv_color_t * mem_first = &mem[fill_area->x1];
mem += mem_width;
for(col = fill_area->x1; col <= fill_area->x2; col++)
{
if(col % 2 == 0)
{
mem[col] = LV_COLOR_BLACK;
}
else
{
mem[col] = color;
}
}
/*Copy the correct row to all other rows*/
lv_color_t * mem_second = &mem[fill_area->x1];
lv_coord_t copy_size = (fill_area->x2 - fill_area->x1 + 1) * sizeof(lv_color_t);
mem += mem_width;
for(row = fill_area->y1 + 2; row <= fill_area->y2; row++) {
if(row % 2 == 0)
{
memcpy(&mem[fill_area->x1], mem_first, copy_size);
}
else
{
memcpy(&mem[fill_area->x1], mem_second, copy_size);
}
mem += mem_width;
}
}
/*Calculate with alpha too*/
else {
...
Screenshot and/or video
If possible, add screenshots and/or videos about the current state.
Parameters that are sent to the sw_color_fill(...) function,
they are already relative area, not entire screen.
Then the area in your manual halftone_set_px_cb() is relative area too.
I’ve tried on my system color16bit by the following code.
(Not sure on the monochrome system is worked or not. )
Thanks for trying it!
It looks like it still suffers from the same problem, without the absolute coords, there is no guarantee that a pixel will be the same color every time and you get mismatches, on the edges of the buffer, during redraw, etc.
That is also because of the relative coords (I assume) where the edges of the buffer are. You can see the same effect a bit in my animation before I fixed it with absolute coords.
Also, is this something that others would be interested in adding to the core library?
It is a fairly common way of adding variation to a monochrome display. I also added different halftone sizes, so instead of 1x1 squares, using larger 2x2, etc.
Ideally the OPA enumeration would be changed or another enumeration would be added for halftone, right now I “hijack” a couple of opacity values to designate halftone fill types, which requires changes to lv_color.h