diff --git a/src/api/system.c b/src/api/system.c index 99180ad8..be5fdea5 100644 --- a/src/api/system.c +++ b/src/api/system.c @@ -109,9 +109,11 @@ top: case SDL_WINDOWEVENT: if (e.window.event == SDL_WINDOWEVENT_RESIZED) { + int w = e.window.data1, h = e.window.data2; + ren_resize(w, h); lua_pushstring(L, "resized"); - lua_pushnumber(L, e.window.data1); - lua_pushnumber(L, e.window.data2); + lua_pushnumber(L, w); + lua_pushnumber(L, h); return 3; } else if (e.window.event == SDL_WINDOWEVENT_EXPOSED) { rencache_invalidate(); diff --git a/src/main.c b/src/main.c index 98dd6eb3..43652fbc 100644 --- a/src/main.c +++ b/src/main.c @@ -125,9 +125,6 @@ int main(int argc, char **argv) { window = SDL_CreateWindow( "", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, dm.w * 0.8, dm.h * 0.8, SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_HIDDEN); - - fprintf(stderr, "New window: %p\n", window); fflush(stderr); - init_window_icon(); ren_init(window); @@ -203,7 +200,7 @@ init_lua: } lua_close(L); - SDL_DestroyWindow(window); + ren_free_window_resources(); return EXIT_SUCCESS; } diff --git a/src/renderer.c b/src/renderer.c index da406c20..145e3f47 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -66,26 +66,17 @@ static const char* utf8_to_codepoint(const char *p, unsigned *dst) { } -static SDL_Surface *get_window_surface(SDL_Window *this_window) { - int w, h; - // fprintf(stderr, "get_window_surface: %p\n", this_window); fflush(stderr); - SDL_GL_GetDrawableSize(this_window, &w, &h); - // FIXME: check for errors ? - if (window_surface && w == window_w && h == window_h) { - fprintf(stderr, "get_window_surface: return current surface: %p\n", window_surface); fflush(stderr); - return window_surface; - } +static void init_window_surface() { if (window_surface) { - fprintf(stderr, "going to free: %p\n", window_surface); fflush(stderr); SDL_FreeSurface(window_surface); } - window_surface = SDL_CreateRGBSurfaceWithFormat(0, w, h, 24, SDL_PIXELFORMAT_BGR24); + SDL_GL_GetDrawableSize(window, &window_w, &window_h); + window_surface = SDL_CreateRGBSurfaceWithFormat(0, window_w, window_h, 32, SDL_PIXELFORMAT_BGRA32); + ren_set_clip_rect( (RenRect) { 0, 0, window_w, window_h } ); +} - fprintf(stderr, "NEW surface: %p, size: %d %d\n", window_surface, w, h); fflush(stderr); - - window_w = w; - window_h = h; +static SDL_Surface *get_window_surface() { return window_surface; } @@ -120,44 +111,56 @@ void ren_cp_replace_add(CPReplaceTable *rep_table, const char *src, const char * rep_table->size = table_size + 1; } +void ren_free_window_resources() { + SDL_DestroyWindow(window); + SDL_DestroyRenderer(window_renderer); + SDL_DestroyTexture(window_texture); + window = NULL; + window_renderer = NULL; +} + +static void setup_renderer(int w, int h) { + /* Note that w and h here should always be in pixels and obtained from + a call to SDL_GL_GetDrawableSize(). */ + if (window_renderer) { + SDL_DestroyRenderer(window_renderer); + SDL_DestroyTexture(window_texture); + } + window_renderer = SDL_CreateRenderer(window, -1, 0); + // May be we could use: SDL_CreateTextureFromSurface(sdlRenderer, mySurface); + window_texture = SDL_CreateTexture(window_renderer, SDL_PIXELFORMAT_BGRA32, SDL_TEXTUREACCESS_STREAMING, w, h); +} void ren_init(SDL_Window *win) { assert(win); window = win; - SDL_Surface *surf = get_window_surface(window); //SDL_GetWindowSurface(window); - fprintf(stderr, "New surface %p\n", surf); fflush(stderr); - ren_set_clip_rect( (RenRect) { 0, 0, surf->w, surf->h } ); + init_window_surface(); +} + + +void ren_resize(int w, int h) { + int new_w, new_h; + SDL_GL_GetDrawableSize(window, &new_w, &new_h); + /* Note that (w, h) may differ from (new_w, new_h) on retina displays. */ + if (new_w != window_h || new_h != window_h) { + init_window_surface(); + setup_renderer(new_w, new_h); + } } void ren_update_rects(RenRect *rects, int count) { -#if 0 - SDL_UpdateWindowSurfaceRects(window, (SDL_Rect*) rects, count); -#endif - fprintf(stderr, "ren_update_rects\n"); fflush(stderr); static bool initial_frame = true; if (initial_frame) { + int w, h; SDL_ShowWindow(window); + SDL_GL_GetDrawableSize(window, &w, &h); + setup_renderer(w, h); initial_frame = false; } - int w, h; - SDL_GL_GetDrawableSize(window, &w, &h); - - if (window_renderer && (w != window_w || h != window_h)) { - SDL_DestroyTexture(window_texture); - SDL_DestroyRenderer(window_renderer); - window_renderer = NULL; - } - - if (!window_renderer) { - window_renderer = SDL_CreateRenderer(window, -1, 0); - // SDL_CreateTextureFromSurface(sdlRenderer, mySurface); - window_texture = SDL_CreateTexture(window_renderer, SDL_PIXELFORMAT_BGR24, SDL_TEXTUREACCESS_STREAMING, w, h); - fprintf(stderr, "got new renderer and texture: %p %p\n", window_renderer, window_texture); fflush(stderr); - } // FIXME: we ignore the rects here. - SDL_UpdateTexture(window_texture, NULL, window_surface->pixels, window_w * 3); + SDL_UpdateTexture(window_texture, NULL, window_surface->pixels, window_w * 4); SDL_RenderCopy(window_renderer, window_texture, NULL, NULL); SDL_RenderPresent(window_renderer); } @@ -172,7 +175,7 @@ void ren_set_clip_rect(RenRect rect) { void ren_get_size(int *x, int *y) { - SDL_Surface *surf = get_window_surface(window); //SDL_GetWindowSurface(window); + SDL_Surface *surf = get_window_surface(window); *x = surf->w; *y = surf->h; } @@ -331,9 +334,6 @@ void ren_draw_rect(RenRect rect, RenColor color) { x2 = x2 > clip.right ? clip.right : x2; y2 = y2 > clip.bottom ? clip.bottom : y2; - // fprintf(stderr, "ren_draw_rect: clipped rect: (%d, %d) (%d, %d)\n", x1, y1, x2, y2); - - // SDL_Surface *surf = SDL_GetWindowSurface(window); SDL_Surface *surf = get_window_surface(window); RenColor *d = (RenColor*) surf->pixels; d += x1 + y1 * surf->w; @@ -346,41 +346,6 @@ void ren_draw_rect(RenRect rect, RenColor color) { } } -// FIXME: this function is never used -#if 0 -void ren_draw_image(RenImage *image, RenRect *sub, int x, int y, RenColor color) { - if (color.a == 0) { return; } - - int n; - if ((n = clip.left - x) > 0) { sub->width -= n; sub->x += n; x += n; } - if ((n = clip.top - y) > 0) { sub->height -= n; sub->y += n; x += n; } - if ((n = x + sub->width - clip.right ) > 0) { sub->width -= n; } - if ((n = y + sub->height - clip.bottom) > 0) { sub->height -= n; } - - if (sub->width <= 0 || sub->height <= 0) { - return; - } - - /* draw */ - SDL_Surface *surf = get_window_surface(window); //SDL_GetWindowSurface(window); - RenColor *s = image->pixels; - RenColor *d = (RenColor*) surf->pixels; - s += sub->x + sub->y * image->width; - d += x + y * surf->w; - int sr = image->width - sub->width; - int dr = surf->w - sub->width; - - for (int j = 0; j < sub->height; j++) { - for (int i = 0; i < sub->width; i++) { - *d = blend_pixel2(*d, *s, color); - d++; - s++; - } - d += dr; - s += sr; - } -} -#endif static int codepoint_replace(CPReplaceTable *rep_table, unsigned *codepoint) { for (int i = 0; i < rep_table->size; i++) { @@ -399,7 +364,7 @@ void ren_draw_text_subpixel(RenFont *font, const char *text, int x_subpixel, int { const char *p = text; unsigned codepoint; - SDL_Surface *surf = get_window_surface(window); // SDL_GetWindowSurface(window); + SDL_Surface *surf = get_window_surface(window); const FR_Color color_fr = { .r = color.r, .g = color.g, .b = color.b }; while (*p) { FR_Color color_rep; diff --git a/src/renderer.h b/src/renderer.h index 2b1f29d3..1ab82206 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -36,9 +36,11 @@ typedef struct CPReplaceTable CPReplaceTable; void ren_init(SDL_Window *win); +void ren_resize(int w, int h); void ren_update_rects(RenRect *rects, int count); void ren_set_clip_rect(RenRect rect); void ren_get_size(int *x, int *y); +void ren_free_window_resources(); RenImage* ren_new_image(int width, int height); void ren_free_image(RenImage *image); @@ -53,7 +55,6 @@ int ren_get_font_subpixel_scale(RenFont *font); int ren_font_subpixel_round(int width, int subpixel_scale, int orientation); void ren_draw_rect(RenRect rect, RenColor color); -void ren_draw_image(RenImage *image, RenRect *sub, int x, int y, RenColor color); void ren_draw_text(RenFont *font, const char *text, int x, int y, RenColor color, CPReplaceTable *replacements, RenColor replace_color); void ren_draw_text_subpixel(RenFont *font, const char *text, int x_subpixel, int y, RenColor color, CPReplaceTable *replacements, RenColor replace_color);