diff --git a/include/fbgfx/surface.h b/include/fbgfx/surface.h index f9c77c9..c800325 100644 --- a/include/fbgfx/surface.h +++ b/include/fbgfx/surface.h @@ -27,6 +27,7 @@ typedef struct SURFACE { int bytes_per_pixel; int width; int height; + uint32_t top_left_index; int x_inc; int y_inc; RECT clip_region; @@ -83,10 +84,7 @@ static inline uint32_t surface_get_buffer_size(const SURFACE *surface) { } static inline uint32_t surface_get_index_of(const SURFACE *surface, int x, int y) { - if (surface->flags & SURFACE_FLAGS_SIDEWAYS_BUFFER) - return (uint32_t)((x * surface->height) + (surface->height - y - 1)) * surface->bytes_per_pixel; - else - return (uint32_t)(x + (y * surface->width)) * surface->bytes_per_pixel; + return (uint32_t)(surface->top_left_index + (surface->x_inc * x) + (surface->y_inc * y)); } static inline COLOR_COMPONENT* surface_get_pointer_to(const SURFACE *surface, int x, int y) { diff --git a/src/fbgfx/surface.c b/src/fbgfx/surface.c index b829683..923f91f 100644 --- a/src/fbgfx/surface.c +++ b/src/fbgfx/surface.c @@ -44,6 +44,13 @@ void surface_swap_framebuffers() { */ } +static uint32_t get_index(const SURFACE *surface, int x, int y) { + if (surface->flags & SURFACE_FLAGS_SIDEWAYS_BUFFER) + return (uint32_t)((x * surface->height) + (surface->height - y - 1)) * surface->bytes_per_pixel; + else + return (uint32_t)(x + (y * surface->width)) * surface->bytes_per_pixel; +} + void setup_initial_surface_properties(SURFACE *surface, int width, int height, SURFACE_FORMAT format, SURFACE_FLAGS flags) { surface->width = width; surface->height = height; @@ -54,10 +61,11 @@ void setup_initial_surface_properties(SURFACE *surface, int width, int height, S surface->clip_region = rect_create(0, 0, surface->width, surface->height); - // lazy calculation for the win - uint32_t reference_index = surface_get_index_of(surface, 0, 0); - surface->x_inc = surface_get_index_of(surface, 1, 0) - reference_index; - surface->y_inc = surface_get_index_of(surface, 0, 1) - reference_index; + // lazy calculations for the win + uint32_t reference_index = get_index(surface, 0, 0); + surface->top_left_index = reference_index; + surface->x_inc = get_index(surface, 1, 0) - reference_index; + surface->y_inc = get_index(surface, 0, 1) - reference_index; } SURFACE* surface_create(int width, int height, SURFACE_FORMAT format, SURFACE_FLAGS flags) { diff --git a/test/test_surfaces.c b/test/test_surfaces.c index 0b7c218..cf4eb0e 100644 --- a/test/test_surfaces.c +++ b/test/test_surfaces.c @@ -124,7 +124,38 @@ void test_coords_and_offsets(SURFACE_FLAGS flags) { surface_destroy(surface); } +void test_increments(SURFACE_FLAGS flags) { + SURFACE *surface = surface_create(1024, 1024, SURFACE_FORMAT_RGBA, flags); + assert(surface != NULL); + + int x = 0; + int y = 0; + uint32_t index = surface_get_index_of(surface, x, y); + + // this is a kind of silly test, but meh, a nice simple-ish validation + // over a wide range of possible coordinates + + for (; y < surface->height; ++y) { + uint32_t temp = index; + + for (; x < surface->width; ++x) { + uint32_t this_index = surface_get_index_of(surface, x, y); + assert(index == this_index); + index += surface->x_inc; + } + + // because the previous x_inc increments make this unnecessary, but we want to test + // this increment too ... + index = temp; + index += surface->y_inc; + } + + surface_destroy(surface); +} + int main(int argc, char **argv) { + test_increments(SURFACE_FLAGS_NONE); + test_increments(SURFACE_FLAGS_SIDEWAYS_BUFFER); test_coords_and_offsets(SURFACE_FLAGS_NONE); test_coords_and_offsets(SURFACE_FLAGS_SIDEWAYS_BUFFER); test_rgba(SURFACE_FLAGS_NONE);