From 18720665d2b1b48250f2049378cb93eb6e38eaa4 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Tue, 14 Mar 2023 16:39:00 +0100 Subject: [PATCH] Use clipping functions provided by SDL (#1426) --- src/renderer.c | 31 ++++++++++++++----------------- src/renwindow.c | 6 ++++-- src/renwindow.h | 1 - 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/renderer.c b/src/renderer.c index 59004bc0..226dbe71 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -378,7 +378,8 @@ double ren_font_group_get_width(RenWindow *window_renderer, RenFont **fonts, con double ren_draw_text(RenWindow *window_renderer, RenFont **fonts, const char *text, size_t len, float x, int y, RenColor color) { SDL_Surface *surface = renwin_get_surface(window_renderer); - const RenRect clip = window_renderer->clip; + SDL_Rect clip; + SDL_GetClipRect(surface, &clip); const int surface_scale = renwin_surface_scale(window_renderer); double pen_x = x * surface_scale; @@ -386,7 +387,7 @@ double ren_draw_text(RenWindow *window_renderer, RenFont **fonts, const char *te int bytes_per_pixel = surface->format->BytesPerPixel; const char* end = text + len; uint8_t* destination_pixels = surface->pixels; - int clip_end_x = clip.x + clip.width, clip_end_y = clip.y + clip.height; + int clip_end_x = clip.x + clip.w, clip_end_y = clip.y + clip.h; RenFont* last = NULL; double last_pen_x = x; @@ -479,28 +480,24 @@ static inline RenColor blend_pixel(RenColor dst, RenColor src) { void ren_draw_rect(RenWindow *window_renderer, RenRect rect, RenColor color) { if (color.a == 0) { return; } + SDL_Surface *surface = renwin_get_surface(window_renderer); const int surface_scale = renwin_surface_scale(window_renderer); - /* transforms coordinates in pixels. */ - rect.x *= surface_scale; - rect.y *= surface_scale; - rect.width *= surface_scale; - rect.height *= surface_scale; + SDL_Rect dest_rect = { rect.x * surface_scale, + rect.y * surface_scale, + rect.width * surface_scale, + rect.height * surface_scale }; - const RenRect clip = window_renderer->clip; - int x1 = rect.x < clip.x ? clip.x : rect.x; - int y1 = rect.y < clip.y ? clip.y : rect.y; - int x2 = rect.x + rect.width; - int y2 = rect.y + rect.height; - x2 = x2 > clip.x + clip.width ? clip.x + clip.width : x2; - y2 = y2 > clip.y + clip.height ? clip.y + clip.height : y2; - - SDL_Surface *surface = renwin_get_surface(window_renderer); - SDL_Rect dest_rect = { x1, y1, x2 - x1, y2 - y1 }; if (color.a == 0xff) { uint32_t translated = SDL_MapRGB(surface->format, color.r, color.g, color.b); SDL_FillRect(surface, &dest_rect, translated); } else { + // Seems like SDL doesn't handle clipping as we expect when using + // scaled blitting, so we "clip" manually. + SDL_Rect clip; + SDL_GetClipRect(surface, &clip); + if (!SDL_IntersectRect(&clip, &dest_rect, &dest_rect)) return; + uint32_t *pixel = (uint32_t *)draw_rect_surface->pixels; *pixel = SDL_MapRGBA(draw_rect_surface->format, color.r, color.g, color.b, color.a); SDL_BlitScaled(draw_rect_surface, NULL, surface, &dest_rect); diff --git a/src/renwindow.c b/src/renwindow.c index 85fd7a07..c700cedf 100644 --- a/src/renwindow.c +++ b/src/renwindow.c @@ -61,12 +61,14 @@ static RenRect scaled_rect(const RenRect rect, const int scale) { void renwin_clip_to_surface(RenWindow *ren) { SDL_Surface *surface = renwin_get_surface(ren); - ren->clip = (RenRect) {0, 0, surface->w, surface->h}; + SDL_SetClipRect(surface, NULL); } void renwin_set_clip_rect(RenWindow *ren, RenRect rect) { - ren->clip = scaled_rect(rect, renwin_surface_scale(ren)); + SDL_Surface *surface = renwin_get_surface(ren); + RenRect sr = scaled_rect(rect, renwin_surface_scale(ren)); + SDL_SetClipRect(surface, &(SDL_Rect){.x = sr.x, .y = sr.y, .w = sr.width, .h = sr.height}); } diff --git a/src/renwindow.h b/src/renwindow.h index 8edc03d8..7f08aa2f 100644 --- a/src/renwindow.h +++ b/src/renwindow.h @@ -3,7 +3,6 @@ struct RenWindow { SDL_Window *window; - RenRect clip; /* Clipping rect in pixel coordinates. */ #ifdef LITE_USE_SDL_RENDERER SDL_Renderer *renderer; SDL_Texture *texture;