diff options
| author | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2023-11-25 12:09:54 +0100 |
|---|---|---|
| committer | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2023-11-25 12:09:54 +0100 |
| commit | 4f894e4745280958e1e4a08f4e49bd94abb5ea36 (patch) | |
| tree | 601ccf06444641e8be938186a014c912e4dd6344 /src/drivers | |
| parent | 0beab855a053275b41368d3f32cddd2d6389ca2c (diff) | |
Cairo graphics driver: Improve drawing of Fl_Pixmap and Fl_Bitmap
Previously, these objects were drawn slightly blurred on HighDPI.
This commit has them resized to the pixel size of the area where
they are being drawn and then drawn.
Diffstat (limited to 'src/drivers')
| -rw-r--r-- | src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H | 6 | ||||
| -rw-r--r-- | src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx | 82 | ||||
| -rw-r--r-- | src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H | 1 | ||||
| -rw-r--r-- | src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx | 7 | ||||
| -rw-r--r-- | src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx | 1 |
5 files changed, 61 insertions, 36 deletions
diff --git a/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H b/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H index 6a782c3c5..b965e0afa 100644 --- a/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H +++ b/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H @@ -80,6 +80,7 @@ public: float scale_x; float scale_y; + int wld_scale; float angle; int left_margin; int top_margin; @@ -157,13 +158,13 @@ public: void draw_rgb(Fl_RGB_Image *rgb,int XP, int YP, int WP, int HP, int cx, int cy) FL_OVERRIDE; void cache(Fl_RGB_Image *rgb) FL_OVERRIDE; void uncache(Fl_RGB_Image *img, fl_uintptr_t &id_, fl_uintptr_t &mask_) FL_OVERRIDE; - void draw_bitmap(Fl_Bitmap *bm,int XP, int YP, int WP, int HP, int cx, int cy) FL_OVERRIDE; + void draw_fixed(Fl_Bitmap *bm,int XP, int YP, int WP, int HP, int cx, int cy) FL_OVERRIDE; static cairo_pattern_t *bitmap_to_pattern(Fl_Bitmap *bm, bool complement, cairo_surface_t **p_surface); void cache(Fl_Bitmap *img) FL_OVERRIDE; void delete_bitmask(fl_uintptr_t bm) FL_OVERRIDE; void cache(Fl_Pixmap *pxm) FL_OVERRIDE; - void draw_pixmap(Fl_Pixmap *rgb,int XP, int YP, int WP, int HP, int cx, int cy) FL_OVERRIDE; + void draw_fixed(Fl_Pixmap *rgb,int XP, int YP, int WP, int HP, int cx, int cy) FL_OVERRIDE; void uncache_pixmap(fl_uintptr_t p) FL_OVERRIDE; void font(Fl_Font fnum, Fl_Fontsize s) FL_OVERRIDE; @@ -189,7 +190,6 @@ public: Fl_Region XRectangleRegion(int x, int y, int w, int h) FL_OVERRIDE; void XDestroyRegion(Fl_Region r) FL_OVERRIDE; void add_rectangle_to_region(Fl_Region r, int X, int Y, int W, int H) FL_OVERRIDE; - void cache_size(Fl_Image *img, int &width, int &height) FL_OVERRIDE; char can_do_alpha_blending() FL_OVERRIDE; float override_scale() FL_OVERRIDE; void restore_scale(float) FL_OVERRIDE; diff --git a/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx b/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx index 37473f48c..be189f7bf 100644 --- a/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx +++ b/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx @@ -106,6 +106,7 @@ Fl_Cairo_Graphics_Driver::Fl_Cairo_Graphics_Driver() : Fl_Graphics_Driver() { linestyle_ = FL_SOLID; clip_ = NULL; scale_x = scale_y = 1; + wld_scale = 1; angle = 0; left_margin = top_margin = 0; needs_commit_tag_ = NULL; @@ -892,6 +893,10 @@ void Fl_Cairo_Graphics_Driver::cache(Fl_RGB_Image *rgb) { cairo_pattern_t *pat = cairo_pattern_create_for_surface(surf); cairo_surface_destroy(surf); *Fl_Graphics_Driver::id(rgb) = (fl_uintptr_t)pat; + int *pw, *ph; + cache_w_h(rgb, pw, ph); + *pw = rgb->data_w(); + *ph = rgb->data_h(); } @@ -904,21 +909,27 @@ void Fl_Cairo_Graphics_Driver::uncache(Fl_RGB_Image *img, fl_uintptr_t &id_, fl_ } -void Fl_Cairo_Graphics_Driver::draw_bitmap(Fl_Bitmap *bm,int XP, int YP, int WP, int HP, int cx, int cy) { - int X, Y, W, H; +void Fl_Cairo_Graphics_Driver::draw_fixed(Fl_Bitmap *bm,int XP, int YP, int WP, int HP, + int cx, int cy) { + cairo_pattern_t *pat = NULL; + float s = wld_scale * scale(); + XP = Fl_Scalable_Graphics_Driver::floor(XP, s); + YP = Fl_Scalable_Graphics_Driver::floor(YP, s); + cache_size(bm, WP, HP); + cx *= s; cy *= s; + cairo_matrix_t matrix; // temporarily remove scaling + cairo_get_matrix(cairo_, &matrix); + cairo_translate(cairo_, -0.5, -0.5); + cairo_scale(cairo_, 1./s, 1/s); + cairo_translate(cairo_, 0.5, 0.5); if (!bm->array) { draw_empty(bm, XP, YP); - return; - } - if (start_image(bm, XP,YP,WP,HP,cx,cy,X,Y,W,H)) return; - cairo_pattern_t *pat = (cairo_pattern_t*)*Fl_Graphics_Driver::id(bm); - if (!pat) { - cache(bm); + } else { pat = (cairo_pattern_t*)*Fl_Graphics_Driver::id(bm); + color(color()); + draw_cached_pattern_(bm, pat, XP, YP, WP, HP, cx, cy); } - if (pat) { - draw_cached_pattern_(bm, pat, X, Y, W, H, cx, cy); - } + cairo_set_matrix(cairo_, &matrix); } @@ -977,25 +988,34 @@ void Fl_Cairo_Graphics_Driver::cache(Fl_Bitmap *bm) { (void)cairo_surface_set_user_data(surf, &data_key_for_surface, BGRA, dealloc_surface_data); cairo_surface_destroy(surf); *Fl_Graphics_Driver::id(bm) = (fl_uintptr_t)pattern; -} - - -void Fl_Cairo_Graphics_Driver::draw_pixmap(Fl_Pixmap *pxm,int XP, int YP, int WP, int HP, int cx, int cy) { - int X, Y, W, H; + int *pw, *ph; + cache_w_h(bm, pw, ph); + *pw = bm->data_w(); + *ph = bm->data_h(); +} + + +void Fl_Cairo_Graphics_Driver::draw_fixed(Fl_Pixmap *pxm,int XP, int YP, int WP, int HP, + int cx, int cy) { + cairo_pattern_t *pat = NULL; + float s = wld_scale * scale(); + XP = Fl_Scalable_Graphics_Driver::floor(XP, s); + YP = Fl_Scalable_Graphics_Driver::floor(YP, s); + cache_size(pxm, WP, HP); + cx *= s; cy *= s; + cairo_matrix_t matrix; // temporarily remove scaling + cairo_get_matrix(cairo_, &matrix); + cairo_translate(cairo_, -0.5, -0.5); + cairo_scale(cairo_, 1/s, 1/s); + cairo_translate(cairo_, 0.5, 0.5); // Don't draw an empty image... if (!pxm->data() || !pxm->w()) { Fl_Graphics_Driver::draw_empty(pxm, XP, YP); - return; - } - if (start_image(pxm, XP, YP, WP, HP, cx, cy, X, Y, W, H)) { - return; - } - cairo_pattern_t *pat = (cairo_pattern_t*)*Fl_Graphics_Driver::id(pxm); - if (!pat) { - cache(pxm); + } else { pat = (cairo_pattern_t*)*Fl_Graphics_Driver::id(pxm); + draw_cached_pattern_(pxm, pat, XP, YP, WP, HP, cx, cy); } - draw_cached_pattern_(pxm, pat, X, Y, W, H, cx, cy); + cairo_set_matrix(cairo_, &matrix); } @@ -1005,6 +1025,10 @@ void Fl_Cairo_Graphics_Driver::cache(Fl_Pixmap *pxm) { *Fl_Graphics_Driver::id(pxm) = *Fl_Graphics_Driver::id(rgb); *Fl_Graphics_Driver::id(rgb) = 0; delete rgb; + int *pw, *ph; + cache_w_h(pxm, pw, ph); + *pw = pxm->data_w(); + *ph = pxm->data_h(); } @@ -1438,14 +1462,6 @@ void Fl_Cairo_Graphics_Driver::restore_clip() { } -void Fl_Cairo_Graphics_Driver::cache_size(Fl_Image *unused, int &width, int &height) { - cairo_matrix_t matrix; - cairo_get_matrix(cairo_, &matrix); - width *= matrix.xx; - height *= matrix.xx; -} - - char Fl_Cairo_Graphics_Driver::can_do_alpha_blending() { return 1; } diff --git a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H index b757a8a6e..8578bc59a 100644 --- a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H +++ b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H @@ -56,6 +56,7 @@ public: static struct wl_shm_pool *current_pool; void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen osrc, int srcx, int srcy) FL_OVERRIDE; + void cache_size(Fl_Image *img, int &width, int &height) FL_OVERRIDE; 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); diff --git a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx index 34e4971da..b2def3703 100644 --- a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx @@ -287,3 +287,10 @@ Fl_Image_Surface *Fl_Wayland_Graphics_Driver::custom_offscreen(int w, int h, cairo_set_user_data(off->draw_buffer.cairo_, &key, &off->draw_buffer, NULL); return new Fl_Image_Surface(w, h, 0, (Fl_Offscreen)off->draw_buffer.cairo_); } + + +void Fl_Wayland_Graphics_Driver::cache_size(Fl_Image *img, int &width, int &height) { + Fl_Graphics_Driver::cache_size(img, width, height); + width *= wld_scale; + height *= wld_scale; +} diff --git a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx index 0b228d83a..83865878a 100644 --- a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx @@ -370,6 +370,7 @@ void Fl_Wayland_Window_Driver::make_current() { } ((Fl_Wayland_Graphics_Driver*)fl_graphics_driver)->set_cairo( window->buffer->draw_buffer.cairo_, f * wld_s); + ((Fl_Cairo_Graphics_Driver*)fl_graphics_driver)->wld_scale = wld_s; int *poffset = Fl_Window_Driver::menu_offset_y(pWindow); if (poffset) { // for tall menu windows under KWIN to offset drawing inside window cairo_translate(window->buffer->draw_buffer.cairo_, 0, *poffset); |
