diff --git a/libraries/pico_vector/pretty-poly.h b/libraries/pico_vector/pretty-poly.h index f9b76287..486b6450 100644 --- a/libraries/pico_vector/pretty-poly.h +++ b/libraries/pico_vector/pretty-poly.h @@ -488,45 +488,44 @@ void add_line_segment_to_nodes(const pp_point_t start, const pp_point_t end, pp_ x += xinc * xjump; } -// #ifdef USE_RP2040_INTERP -// interp1->base[1] = full_tile_width; -// interp1->accum[0] = x; + int32_t *pp_scanline_nodes = &pp_nodes[y * _pp_max_nodes_per_scanline * 2]; + const int32_t nodes_step = _pp_max_nodes_per_scanline * 2; -// // loop over scanlines -// while(count--) { -// // consume accumulated error -// while(e > dy) {e -= dy; interp1->add_raw[0] = xinc;} + const int full_tile_width = (tb->w << _pp_antialias); + if (false && _pp_min(x, ex) >= 0 && _pp_max(x, ex) <= full_tile_width) { + // loop over scanlines + while(count--) { + // consume accumulated error + while(e > dy) {e -= dy; x += xinc;} -// // clamp node x value to tile bounds -// const int nx = interp1->peek[0]; -// debug(" + adding node at %d, %d\n", x, y); -// // add node to node list -// pp_nodes[y][pp_node_counts[y]++] = nx; + //debug(" + adding node at %d, %d\n", x, y); + // add node to node list + pp_scanline_nodes[pp_node_counts[y]++] = x; -// // step to next scanline and accumulate error -// y++; -// e += einc; -// } -// #else - // loop over scanlines - - while(count--) { - int32_t *pp_scanline_nodes = &pp_nodes[y * _pp_max_nodes_per_scanline * 2]; - - // consume accumulated error - while(e > dy) {e -= dy; x += xinc;} - - // clamp node x value to tile bounds - int nx = _pp_max(_pp_min(x, (tb->w << _pp_antialias)), 0); - //debug(" + adding node at %d, %d\n", x, y); - // add node to node list - pp_scanline_nodes[pp_node_counts[y]++] = nx; - - // step to next scanline and accumulate error - y++; - e += einc; + // step to next scanline and accumulate error + y++; + e += einc; + pp_scanline_nodes += nodes_step; + } + } + else { + // loop over scanlines + while(count--) { + // consume accumulated error + while(e > dy) {e -= dy; x += xinc;} + + // clamp node x value to tile bounds + int nx = _pp_max(_pp_min(x, full_tile_width), 0); + //debug(" + adding node at %d, %d\n", x, y); + // add node to node list + pp_scanline_nodes[pp_node_counts[y]++] = nx; + + // step to next scanline and accumulate error + y++; + e += einc; + pp_scanline_nodes += nodes_step; + } } -//#endif } void build_nodes(pp_path_t *path, pp_rect_t *tb) { @@ -555,8 +554,9 @@ int compare_nodes(const void* a, const void* b) { } pp_rect_t render_nodes(pp_rect_t *tb) { - pp_rect_t rb = {PP_TILE_BUFFER_SIZE << _pp_antialias, PP_TILE_BUFFER_SIZE << _pp_antialias, 0, 0}; // render bounds - int maxx = 0, minx = PP_TILE_BUFFER_SIZE << _pp_antialias; + pp_rect_t rb = {PP_TILE_BUFFER_SIZE << _pp_antialias, 0, 0, 0}; // render bounds + int maxx = 0, maxy = -1; + const int antialias_mask = (1 << _pp_antialias) - 1; debug(" + render tile %d, %d - %d, %d\n", tb->x, tb->y, tb->w, tb->h); for(int y = 0; y < ((int)PP_TILE_BUFFER_SIZE << _pp_antialias); y++) { @@ -570,6 +570,9 @@ pp_rect_t render_nodes(pp_rect_t *tb) { unsigned char* row_data = &pp_tile_buffer[(y >> _pp_antialias) * PP_TILE_BUFFER_SIZE]; + bool rendered_any = false; + + rb.x = _pp_min(rb.x, *pp_scanline_nodes); for(uint32_t i = 0; i < pp_node_counts[y]; i += 2) { int sx = *pp_scanline_nodes++; int ex = *pp_scanline_nodes++; @@ -579,22 +582,44 @@ pp_rect_t render_nodes(pp_rect_t *tb) { } // update render bounds - rb.x = _pp_min(rb.x, sx); - rb.y = _pp_min(rb.y, y); - minx = _pp_min(_pp_min(sx, ex), minx); - maxx = _pp_max(_pp_max(sx, ex), maxx); - rb.h = y - rb.y + 1; + rendered_any = true; - //debug(" - render span at %d from %d to %d\n", y, sx, ex); + if (_pp_antialias) { + int ax = sx >> _pp_antialias; + const int aex = ex >> _pp_antialias; - // rasterise the span into the tile buffer - do { - row_data[sx >> _pp_antialias]++; - } while(++sx < ex); + if (ax == aex) { + row_data[ax] += ex - sx; + continue; + } + + row_data[ax] += (1 << _pp_antialias) - (sx & antialias_mask); + for(ax++; ax < aex; ax++) { + row_data[ax] += (1 << _pp_antialias); + } + + // This might add 0 to the byte after the end of the row, + // TODO check that's OK + row_data[ax] += ex & antialias_mask; + } + else { + for(int x = sx; x < ex; x++) { + row_data[x]++; + } + } + } + + maxx = _pp_max(*(pp_scanline_nodes-1) - 1, maxx); + if (rendered_any) { + maxy = y; + } + else if (y == rb.y) { + ++rb.y; } } - rb.w = maxx - minx; + rb.w = (maxx >= rb.x) ? maxx + 1 - rb.x : 0; + rb.h = (maxy >= rb.y) ? maxy + 1 - rb.y : 0; // shifting the width and height effectively "floors" the result which can // mean we lose a pixel off the right or bottom edge of the tile. by adding