From 0fa49f0ab4136262dc16c1b30bf07e3fcef36be5 Mon Sep 17 00:00:00 2001 From: ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> Date: Wed, 20 Mar 2024 15:20:31 +0100 Subject: Use type cairo_region_t* for Fl_Region under Wayland platform --- src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H | 4 -- src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx | 59 +++++++--------------- src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H | 2 +- src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx | 19 ++++--- src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx | 2 +- 5 files changed, 30 insertions(+), 56 deletions(-) (limited to 'src/drivers') diff --git a/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H b/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H index e55f051d7..ffbb0308b 100644 --- a/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H +++ b/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H @@ -28,10 +28,6 @@ typedef struct _PangoLayout PangoLayout; typedef struct _PangoContext PangoContext; typedef struct _PangoFontDescription PangoFontDescription; -struct flCairoRegion { - int count; - struct _cairo_rectangle *rects; -}; // a region is the union of a series of rectangles class Fl_Cairo_Font_Descriptor : public Fl_Font_Descriptor { public: diff --git a/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx b/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx index 40264c757..1c0ccd0bb 100644 --- a/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx +++ b/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx @@ -1396,41 +1396,19 @@ void Fl_Cairo_Graphics_Driver::text_extents(const char* txt, int n, int& dx, int // Fl_Region Fl_Cairo_Graphics_Driver::XRectangleRegion(int x, int y, int w, int h) { - struct flCairoRegion *R = (struct flCairoRegion*)malloc(sizeof(*R)); - R->count = 1; - R->rects = (cairo_rectangle_t *)malloc(sizeof(cairo_rectangle_t)); - R->rects->x=x, R->rects->y=y, R->rects->width=w; R->rects->height=h; - return (Fl_Region)R; -} - - -// r1 ⊂ r2 -static bool CairoRectContainsRect(cairo_rectangle_t *r1, cairo_rectangle_t *r2) { - return r1->x >= r2->x && r1->y >= r2->y && r1->x+r1->width <= r2->x+r2->width && - r1->y+r1->height <= r2->y+r2->height; + cairo_rectangle_int_t rect = {x, y, w, h}; + return cairo_region_create_rectangle(&rect); } void Fl_Cairo_Graphics_Driver::add_rectangle_to_region(Fl_Region r_, int X, int Y, int W, int H) { - struct flCairoRegion *r = (struct flCairoRegion*)r_; - cairo_rectangle_t arg = {double(X), double(Y), double(W), double(H)}; - int j; // don't add a rectangle totally inside the Fl_Region - for (j = 0; j < r->count; j++) { - if (CairoRectContainsRect(&arg, &(r->rects[j]))) break; - } - if (j >= r->count) { - r->rects = (cairo_rectangle_t*)realloc(r->rects, (++(r->count)) * sizeof(cairo_rectangle_t)); - r->rects[r->count - 1] = arg; - } + cairo_rectangle_int_t rect = {X, Y, W, H}; + cairo_region_union_rectangle((cairo_region_t*)r_, &rect); } void Fl_Cairo_Graphics_Driver::XDestroyRegion(Fl_Region r_) { - if (r_) { - struct flCairoRegion *r = (struct flCairoRegion*)r_; - free(r->rects); - free(r); - } + cairo_region_destroy((cairo_region_t*)r_); } #define fl_max(a,b) ((a) > (b) ? (a) : (b)) @@ -1440,27 +1418,24 @@ void Fl_Cairo_Graphics_Driver::restore_clip() { if (cairo_) { cairo_reset_clip(cairo_); // apply what's in rstack - struct flCairoRegion *r = (struct flCairoRegion*)rstack[rstackptr]; + cairo_region_t *r = (cairo_region_t*)rstack[rstackptr]; if (r) { if (!clip_) { clip_ = new Clip(); clip_->prev = NULL; } - for (int i = 0; i < r->count; i++) { - cairo_rectangle(cairo_, r->rects[i].x - 0.5, r->rects[i].y - 0.5, r->rects[i].width, r->rects[i].height); - // put in clip_ the bounding rect of region r - if (i == 0) { - clip_->x = r->rects[0].x; clip_->y = r->rects[0].y; - clip_->w = r->rects[0].width; clip_->h = r->rects[0].height; - } else { - int R = fl_max(r->rects[i].x + r->rects[i].width, clip_->x + clip_->w); - int B = fl_max(r->rects[i].y + r->rects[i].height, clip_->y + clip_->h); - clip_->x = fl_min(r->rects[i].x, clip_->x) ; - clip_->y = fl_min(r->rects[i].y, clip_->y); - clip_->w = R - clip_->x; - clip_->h = B - clip_->y; - } + int count = cairo_region_num_rectangles(r); + cairo_rectangle_int_t rect; + for (int i = 0; i < count; i++) { + cairo_region_get_rectangle(r, i, &rect); + cairo_rectangle(cairo_, rect.x - 0.5, rect.y - 0.5, rect.width, rect.height); } + // put in clip_ the bounding rect of region r + cairo_region_get_extents(r, &rect); + clip_->x = rect.x; + clip_->y = rect.y; + clip_->w = rect.width; + clip_->h = rect.height; cairo_clip(cairo_); } else if (clip_) { clip_->w = -1; diff --git a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H index c3730dee4..ac8786a47 100644 --- a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H +++ b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H @@ -60,7 +60,7 @@ public: static struct wld_buffer *create_wld_buffer(int width, int height, bool with_shm = true); static void create_shm_buffer(wld_buffer *buffer); static void buffer_release(struct wld_window *window); - static void buffer_commit(struct wld_window *window, struct flCairoRegion *r = NULL); + static void buffer_commit(struct wld_window *window, cairo_region_t *r = NULL); static void cairo_init(struct draw_buffer *buffer, int width, int height, int stride, cairo_format_t format); // used by class Fl_Wayland_Gl_Window_Driver diff --git a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx index ce9dcaf4e..1855bc20f 100644 --- a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx @@ -22,7 +22,7 @@ #include // for close() #include #include // for strerror() - +#include extern "C" { # include "../../../libdecor/src/os-compatibility.h" // for libdecor_os_create_anonymous_file() @@ -139,15 +139,18 @@ const struct wl_callback_listener *Fl_Wayland_Graphics_Driver::p_surface_frame_l // copy pixels in region r from the Cairo surface to the Wayland buffer -static void copy_region(struct wld_window *window, struct flCairoRegion *r) { +static void copy_region(struct wld_window *window, cairo_region_t *r) { struct Fl_Wayland_Graphics_Driver::wld_buffer *buffer = window->buffer; float f = Fl::screen_scale(window->fl_win->screen_num()) * Fl_Wayland_Window_Driver::driver(window->fl_win)->wld_scale(); - for (int i = 0; i < r->count; i++) { - int left = r->rects[i].x * f; - int top = r->rects[i].y * f; - int width = r->rects[i].width * f; - int height = r->rects[i].height * f; + int count = cairo_region_num_rectangles(r); + cairo_rectangle_int_t rect; + for (int i = 0; i < count; i++) { + cairo_region_get_rectangle(r, i, &rect); + int left = rect.x * f; + int top = rect.y * f; + int width = rect.width * f; + int height = rect.height * f; int offset = top * buffer->draw_buffer.stride + 4 * left; int W4 = 4 * width; for (int l = 0; l < height; l++) { @@ -163,7 +166,7 @@ static void copy_region(struct wld_window *window, struct flCairoRegion *r) { } -void Fl_Wayland_Graphics_Driver::buffer_commit(struct wld_window *window, struct flCairoRegion *r) +void Fl_Wayland_Graphics_Driver::buffer_commit(struct wld_window *window, cairo_region_t *r) { if (!window->buffer->wl_buffer) create_shm_buffer(window->buffer); cairo_surface_t *surf = cairo_get_target(window->buffer->draw_buffer.cairo_); diff --git a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx index 92e04d578..e8a0a1af9 100644 --- a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx @@ -408,7 +408,7 @@ void Fl_Wayland_Window_Driver::flush() { if (!window || !window->configured_width) return; Fl_X *ip = Fl_X::flx(pWindow); - struct flCairoRegion* r = (struct flCairoRegion*)ip->region; + cairo_region_t* r = (cairo_region_t*)ip->region; if (!window->buffer || pWindow->as_overlay_window()) r = NULL; Fl_Wayland_Window_Driver::in_flush_ = true; -- cgit v1.2.3