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; + int *pw, *ph; + cache_w_h(bm, pw, ph); + *pw = bm->data_w(); + *ph = bm->data_h(); } -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; +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);