diff options
author | Harry Jeffery <harry@exec64.co.uk> | 2019-06-15 14:28:29 +0100 |
---|---|---|
committer | Harry Jeffery <harry@exec64.co.uk> | 2019-07-03 20:50:19 +0100 |
commit | 7c7dc660e587eac1aa3c8b3405eba95ba558e682 (patch) | |
tree | 81d12d560b60d397be23c7d132e32a5de30e409a /src/image.c | |
parent | 20e9d23b82f55a751c3cf1166cb59ef26775ee00 (diff) | |
download | imv-7c7dc660e587eac1aa3c8b3405eba95ba558e682.tar.gz |
Big glfw refactor
I did a lot of this in a very ad-hoc fashion with no proper commit
history. As such, the kindest thing to do seemed to be to just squash it
into this one commit.
Diffstat (limited to 'src/image.c')
-rw-r--r-- | src/image.c | 182 |
1 files changed, 46 insertions, 136 deletions
diff --git a/src/image.c b/src/image.c index e57d2c9..f4df7c9 100644 --- a/src/image.c +++ b/src/image.c @@ -1,170 +1,80 @@ #include "image.h" -#include "log.h" -#include <stdbool.h> +#include "bitmap.h" struct imv_image { - int width; /* width of the image overall */ - int height; /* height of the image overall */ - int num_chunks; /* number of chunks allocated */ - SDL_Texture **chunks; /* array of chunks */ - int num_chunks_wide; /* number of chunks per row of the image */ - int num_chunks_tall; /* number of chunks per column of the image */ - int chunk_width; /* chunk width */ - int chunk_height; /* chunk height */ - int last_chunk_width; /* width of rightmost chunk */ - int last_chunk_height; /* height of bottommost chunk */ - SDL_Renderer *renderer; /* SDL renderer to draw to */ + int width; + int height; + struct imv_bitmap *bitmap; + #ifdef IMV_BACKEND_LIBRSVG + RsvgHandle *svg; + #endif }; -struct imv_image *imv_image_create(SDL_Renderer *r) +struct imv_image *imv_image_create_from_bitmap(struct imv_bitmap *bmp) { - struct imv_image *image = malloc(sizeof *image); - memset(image, 0, sizeof(struct imv_image)); - image->renderer = r; - - SDL_RendererInfo ri; - SDL_GetRendererInfo(r, &ri); - image->chunk_width = ri.max_texture_width != 0 ? ri.max_texture_width : 4096; - image->chunk_height = ri.max_texture_height != 0 ? ri.max_texture_height : 4096; + struct imv_image *image = calloc(1, sizeof *image); + image->width = bmp->width; + image->height = bmp->height; + image->bitmap = bmp; return image; } -void imv_image_free(struct imv_image *image) +#ifdef IMV_BACKEND_LIBRSVG +struct imv_image *imv_image_create_from_svg(RsvgHandle *handle) { - if(!image) { - return; - } - if(image->num_chunks > 0) { - for(int i = 0; i < image->num_chunks; ++i) { - SDL_DestroyTexture(image->chunks[i]); - } - free(image->chunks); - image->num_chunks = 0; - image->chunks = NULL; - image->renderer = NULL; - } - free(image); -} + struct imv_image *image = calloc(1, sizeof *image); + image->svg = handle; -static int convert_pixelformat(enum imv_pixelformat fmt) -{ - if (fmt == IMV_ARGB) { - return SDL_PIXELFORMAT_ARGB8888; - } else if (fmt == IMV_ABGR) { - return SDL_PIXELFORMAT_ABGR8888; - } else { - imv_log(IMV_WARNING, "Unknown pixel format. Defaulting to ARGB\n"); - return SDL_PIXELFORMAT_ARGB8888; - } + RsvgDimensionData dim; + rsvg_handle_get_dimensions(handle, &dim); + image->width = dim.width; + image->height = dim.height; + return image; } +#endif -int imv_image_set_bitmap(struct imv_image *image, struct imv_bitmap *bmp) +void imv_image_free(struct imv_image *image) { - image->width = bmp->width; - image->height = bmp->height; - - /* figure out how many chunks are needed, and create them */ - if(image->num_chunks > 0) { - for(int i = 0; i < image->num_chunks; ++i) { - SDL_DestroyTexture(image->chunks[i]); - } - free(image->chunks); - } - - image->num_chunks_wide = 1 + image->width / image->chunk_width; - image->num_chunks_tall = 1 + image->height / image->chunk_height; - - image->last_chunk_width = image->width % image->chunk_width; - image->last_chunk_height = image->height % image->chunk_height; - - if(image->last_chunk_width == 0) { - image->last_chunk_width = image->chunk_width; - } - if(image->last_chunk_height == 0) { - image->last_chunk_height = image->chunk_height; + if (!image) { + return; } - image->num_chunks = image->num_chunks_wide * image->num_chunks_tall; - image->chunks = malloc(sizeof(SDL_Texture*) * image->num_chunks); - - const int format = convert_pixelformat(bmp->format); - size_t failed_at = -1; - for(int y = 0; y < image->num_chunks_tall; ++y) { - for(int x = 0; x < image->num_chunks_wide; ++x) { - const bool is_last_h_chunk = (x == image->num_chunks_wide - 1); - const bool is_last_v_chunk = (y == image->num_chunks_tall - 1); - const size_t index = x + y * image->num_chunks_wide; - image->chunks[index] = - SDL_CreateTexture(image->renderer, - format, - SDL_TEXTUREACCESS_STATIC, - is_last_h_chunk ? image->last_chunk_width : image->chunk_width, - is_last_v_chunk ? image->last_chunk_height : image->chunk_height); - SDL_SetTextureBlendMode(image->chunks[index], - SDL_BLENDMODE_BLEND); - if (image->chunks[index] == NULL) { - failed_at = x + y * image->num_chunks_wide; - break; - } - } + if (image->bitmap) { + imv_bitmap_free(image->bitmap); } - if (failed_at != (size_t)-1) { - for (size_t i = 0; i < failed_at; ++i) { - SDL_DestroyTexture(image->chunks[i]); - } - free(image->chunks); - image->num_chunks = 0; - image->chunks = NULL; - return 1; +#ifdef IMV_BACKEND_LIBRSVG + if (image->svg) { + GError *error = NULL; + rsvg_handle_close(image->svg, &error); } +#endif - for (int y = 0; y < image->num_chunks_tall; ++y) { - for (int x = 0; x < image->num_chunks_wide; ++x) { - ptrdiff_t offset = 4 * x * image->chunk_width + - y * 4 * image->width * image->chunk_height; - unsigned char* addr = bmp->data + offset; - SDL_UpdateTexture(image->chunks[x + y * image->num_chunks_wide], - NULL, addr, 4 * image->width); - } - } + free(image); +} - return 0; +int imv_image_width(const struct imv_image *image) +{ + return image ? image->width : 0; } -void imv_image_draw(struct imv_image *image, int bx, int by, double scale) +int imv_image_height(const struct imv_image *image) { - int offset_x = 0; - int offset_y = 0; - for(int y = 0; y < image->num_chunks_tall; ++y) { - for(int x = 0; x < image->num_chunks_wide; ++x) { - int img_w, img_h; - SDL_QueryTexture(image->chunks[x + y * image->num_chunks_wide], NULL, NULL, - &img_w, &img_h); - SDL_Rect view_area = { - bx + offset_x, - by + offset_y, - img_w * scale, - img_h * scale - }; - SDL_RenderCopy(image->renderer, - image->chunks[x + y * image->num_chunks_wide], NULL, &view_area); - offset_x += image->chunk_width * scale; - } - offset_x = 0; - offset_y += image->chunk_height * scale; - } + return image ? image->height : 0; } -int imv_image_width(const struct imv_image *image) +/* Non-public functions, only used by imv_canvas */ +struct imv_bitmap *imv_image_get_bitmap(const struct imv_image *image) { - return image->width; + return image->bitmap; } -int imv_image_height(const struct imv_image *image) +#ifdef IMV_BACKEND_LIBRSVG +RsvgHandle *imv_image_get_svg(const struct imv_image *image) { - return image->height; + return image->svg; } +#endif /* vim:set ts=2 sts=2 sw=2 et: */ |