Use clipping functions provided by SDL (#1426)
This commit is contained in:
parent
ca29728e34
commit
94e2df991c
|
@ -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) {
|
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);
|
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);
|
const int surface_scale = renwin_surface_scale(window_renderer);
|
||||||
double pen_x = x * surface_scale;
|
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;
|
int bytes_per_pixel = surface->format->BytesPerPixel;
|
||||||
const char* end = text + len;
|
const char* end = text + len;
|
||||||
uint8_t* destination_pixels = surface->pixels;
|
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;
|
RenFont* last = NULL;
|
||||||
double last_pen_x = x;
|
double last_pen_x = x;
|
||||||
|
@ -479,39 +480,28 @@ static inline RenColor blend_pixel(RenColor dst, RenColor src) {
|
||||||
void ren_draw_rect(RenWindow *window_renderer, RenRect rect, RenColor color) {
|
void ren_draw_rect(RenWindow *window_renderer, RenRect rect, RenColor color) {
|
||||||
if (color.a == 0) { return; }
|
if (color.a == 0) { return; }
|
||||||
|
|
||||||
|
SDL_Surface *surface = renwin_get_surface(window_renderer);
|
||||||
const int surface_scale = renwin_surface_scale(window_renderer);
|
const int surface_scale = renwin_surface_scale(window_renderer);
|
||||||
|
|
||||||
/* transforms coordinates in pixels. */
|
SDL_Rect dest_rect = { rect.x * surface_scale,
|
||||||
rect.x *= surface_scale;
|
rect.y * surface_scale,
|
||||||
rect.y *= surface_scale;
|
rect.width * surface_scale,
|
||||||
rect.width *= surface_scale;
|
rect.height * 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) {
|
if (color.a == 0xff) {
|
||||||
uint32_t translated = SDL_MapRGB(surface->format, color.r, color.g, color.b);
|
uint32_t translated = SDL_MapRGB(surface->format, color.r, color.g, color.b);
|
||||||
SDL_Rect rect = { x1, y1, x2 - x1, y2 - y1 };
|
SDL_Rect rect = { x1, y1, x2 - x1, y2 - y1 };
|
||||||
SDL_FillRect(surface, &rect, translated);
|
SDL_FillRect(surface, &rect, translated);
|
||||||
} else {
|
} else {
|
||||||
RenColor current_color;
|
// Seems like SDL doesn't handle clipping as we expect when using
|
||||||
RenColor blended_color;
|
// scaled blitting, so we "clip" manually.
|
||||||
for (int j = y1; j < y2; j++) {
|
SDL_Rect clip;
|
||||||
for (int i = x1; i < x2; i++, d++) {
|
SDL_GetClipRect(surface, &clip);
|
||||||
SDL_GetRGB(*d, surface->format, ¤t_color.r, ¤t_color.g, ¤t_color.b);
|
if (!SDL_IntersectRect(&clip, &dest_rect, &dest_rect)) return;
|
||||||
blended_color = blend_pixel(current_color, color);
|
|
||||||
*d = SDL_MapRGB(surface->format, blended_color.r, blended_color.g, blended_color.b);
|
uint32_t *pixel = (uint32_t *)draw_rect_surface->pixels;
|
||||||
}
|
*pixel = SDL_MapRGBA(draw_rect_surface->format, color.r, color.g, color.b, color.a);
|
||||||
d += dr;
|
SDL_BlitScaled(draw_rect_surface, NULL, surface, &dest_rect);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,12 +73,14 @@ static RenRect scaled_rect(const RenRect rect, const int scale) {
|
||||||
|
|
||||||
void renwin_clip_to_surface(RenWindow *ren) {
|
void renwin_clip_to_surface(RenWindow *ren) {
|
||||||
SDL_Surface *surface = renwin_get_surface(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) {
|
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});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
struct RenWindow {
|
struct RenWindow {
|
||||||
SDL_Window *window;
|
SDL_Window *window;
|
||||||
RenRect clip; /* Clipping rect in pixel coordinates. */
|
|
||||||
#ifdef LITE_USE_SDL_RENDERER
|
#ifdef LITE_USE_SDL_RENDERER
|
||||||
SDL_Renderer *renderer;
|
SDL_Renderer *renderer;
|
||||||
SDL_Texture *texture;
|
SDL_Texture *texture;
|
||||||
|
|
Loading…
Reference in New Issue