From f6d2ba651bc22b59488ac4be658f0d725296e2fc Mon Sep 17 00:00:00 2001 From: ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> Date: Mon, 27 Nov 2023 10:02:59 +0100 Subject: Cairo graphics driver: Improve drawing of Fl_Pixmap and Fl_Bitmap --- src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H | 2 +- src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H b/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H index b965e0afa..8677a920f 100644 --- a/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H +++ b/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H @@ -153,7 +153,7 @@ public: void ps_translate(int, int); void ps_untranslate(); - void draw_cached_pattern_(Fl_Image *img, cairo_pattern_t *pat, int X, int Y, int W, int H, int cx, int cy); + void draw_cached_pattern_(Fl_Image *img, cairo_pattern_t *pat, int X, int Y, int W, int H, int cx, int cy, int cache_w, int cache_h); void draw_image(const uchar *data, int ix, int iy, int iw, int ih, int D, int LD) FL_OVERRIDE; 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; diff --git a/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx b/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx index be189f7bf..3f80cbd89 100644 --- a/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx +++ b/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx @@ -783,7 +783,7 @@ void Fl_Cairo_Graphics_Driver::overlay_rect(int x, int y, int w , int h) { } -void Fl_Cairo_Graphics_Driver::draw_cached_pattern_(Fl_Image *img, cairo_pattern_t *pat, int X, int Y, int W, int H, int cx, int cy) { +void Fl_Cairo_Graphics_Driver::draw_cached_pattern_(Fl_Image *img, cairo_pattern_t *pat, int X, int Y, int W, int H, int cx, int cy, int cache_w, int cache_h) { // compute size of output image in drawing units cairo_matrix_t matrix; cairo_get_matrix(cairo_, &matrix); @@ -794,7 +794,7 @@ void Fl_Cairo_Graphics_Driver::draw_cached_pattern_(Fl_Image *img, cairo_pattern int Hs = Fl_Scalable_Graphics_Driver::floor(Y - cy + img->h(), s) - Ys; if (Ws == 0 || Hs == 0) return; cairo_save(cairo_); - bool need_extend = (img->data_w() != Ws || img->data_h() != Hs || (W >= 2 && H >= 2)); + bool need_extend = (cache_w != Ws || cache_h != Hs || (W >= 2 && H >= 2)); if (need_extend || cx || cy || W < img->w() || H < img->h()) { // clip when necessary cairo_rectangle(cairo_, X - 0.5, Y - 0.5, W + 0.5, H + 0.5); cairo_clip(cairo_); @@ -809,7 +809,7 @@ void Fl_Cairo_Graphics_Driver::draw_cached_pattern_(Fl_Image *img, cairo_pattern CAIRO_FILTER_GOOD : CAIRO_FILTER_FAST); cairo_pattern_set_extend(pat, CAIRO_EXTEND_PAD); } - cairo_matrix_init_scale(&matrix, double(img->data_w())/Ws, double(img->data_h())/Hs); + cairo_matrix_init_scale(&matrix, double(cache_w)/Ws, double(cache_h)/Hs); cairo_matrix_translate(&matrix, -Xs , -Ys ); cairo_pattern_set_matrix(pat, &matrix); if (img->d() > 1) cairo_paint(cairo_); @@ -834,7 +834,7 @@ void Fl_Cairo_Graphics_Driver::draw_rgb(Fl_RGB_Image *rgb,int XP, int YP, int WP cache(rgb); pat = (cairo_pattern_t*)*Fl_Graphics_Driver::id(rgb); } - draw_cached_pattern_(rgb, pat, X, Y, W, H, cx, cy); + draw_cached_pattern_(rgb, pat, X, Y, W, H, cx, cy, rgb->cache_w(), rgb->cache_h()); } @@ -927,7 +927,10 @@ void Fl_Cairo_Graphics_Driver::draw_fixed(Fl_Bitmap *bm,int XP, int YP, int WP, } else { pat = (cairo_pattern_t*)*Fl_Graphics_Driver::id(bm); color(color()); - draw_cached_pattern_(bm, pat, XP, YP, WP, HP, cx, cy); + int old_w = bm->w(), old_h = bm->h(); + bm->scale(bm->cache_w(), bm->cache_h(), 0, 1); // transiently + draw_cached_pattern_(bm, pat, XP, YP, WP, HP, cx, cy, bm->cache_w(), bm->cache_h()); + bm->scale(old_w, old_h, 0, 1); // back } cairo_set_matrix(cairo_, &matrix); } @@ -1013,7 +1016,10 @@ void Fl_Cairo_Graphics_Driver::draw_fixed(Fl_Pixmap *pxm,int XP, int YP, int WP, Fl_Graphics_Driver::draw_empty(pxm, XP, YP); } else { pat = (cairo_pattern_t*)*Fl_Graphics_Driver::id(pxm); - draw_cached_pattern_(pxm, pat, XP, YP, WP, HP, cx, cy); + int old_w = pxm->w(), old_h = pxm->h(); + pxm->scale(pxm->cache_w(), pxm->cache_h(), 0, 1); // transiently + draw_cached_pattern_(pxm, pat, XP, YP, WP, HP, cx, cy, pxm->cache_w(), pxm->cache_h()); + pxm->scale(old_w, old_h, 0, 1); // back } cairo_set_matrix(cairo_, &matrix); } -- cgit v1.2.3 From 6ea31316fb64f64d346dc4a3a30984048f5df4cd Mon Sep 17 00:00:00 2001 From: ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> Date: Mon, 27 Nov 2023 12:15:21 +0100 Subject: Cairo graphics driver: Improve drawing of Fl_Pixmap and Fl_Bitmap --- src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx b/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx index 3f80cbd89..1de6822e1 100644 --- a/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx +++ b/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx @@ -805,8 +805,9 @@ void Fl_Cairo_Graphics_Driver::draw_cached_pattern_(Fl_Image *img, cairo_pattern cairo_set_matrix(cairo_, &matrix); if (img->d() >= 1) cairo_set_source(cairo_, pat); if (need_extend) { - cairo_pattern_set_filter(pat, Fl_RGB_Image::scaling_algorithm() == FL_RGB_SCALING_BILINEAR ? - CAIRO_FILTER_GOOD : CAIRO_FILTER_FAST); + bool condition = Fl_RGB_Image::scaling_algorithm() == FL_RGB_SCALING_BILINEAR && + (fabs(Ws/float(cache_w) - 1) > 0.02 || fabs(Hs/float(cache_h) - 1) > 0.02); + cairo_pattern_set_filter(pat, condition ? CAIRO_FILTER_GOOD : CAIRO_FILTER_FAST); cairo_pattern_set_extend(pat, CAIRO_EXTEND_PAD); } cairo_matrix_init_scale(&matrix, double(cache_w)/Ws, double(cache_h)/Hs); -- cgit v1.2.3 From 57371365d8933542ebe7c78651f621e1273733cf Mon Sep 17 00:00:00 2001 From: Albrecht Schlosser Date: Mon, 27 Nov 2023 15:33:53 +0100 Subject: Fix compiler warning, dependencies, and trailing whitespace MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The benign warning was: ‘Fl_Browser_::hscrollbar’ will be initialized after [-Wreorder] ‘int Fl_Browser_::linespacing_’ ... --- src/Fl_Browser_.cxx | 4 ++-- src/Fl_Tile.cxx | 6 +++--- src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx | 4 ++-- src/makedepend | 4 ++++ 4 files changed, 11 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/Fl_Browser_.cxx b/src/Fl_Browser_.cxx index b05772aea..56b751415 100644 --- a/src/Fl_Browser_.cxx +++ b/src/Fl_Browser_.cxx @@ -953,9 +953,9 @@ J1: */ Fl_Browser_::Fl_Browser_(int X, int Y, int W, int H, const char* L) : Fl_Group(X, Y, W, H, L), + linespacing_(0), scrollbar(0, 0, 0, 0, 0), // they will be resized by draw() - hscrollbar(0, 0, 0, 0, 0), - linespacing_(0) + hscrollbar(0, 0, 0, 0, 0) { box(FL_NO_BOX); align(FL_ALIGN_BOTTOM); diff --git a/src/Fl_Tile.cxx b/src/Fl_Tile.cxx index e1e2d85cc..c37f2da89 100644 --- a/src/Fl_Tile.cxx +++ b/src/Fl_Tile.cxx @@ -56,7 +56,7 @@ In this mode, the child that is marked resizable() will behave as it would in a regular Fl_Group widget. When dragging edges or intersections with the mouse, Fl_Tile will ensure that - none of the children shrinks to a size that is smaller than requested. + none of the children shrinks to a size that is smaller than requested. When resizing the Fl_Tile group, size ranges are not enforced by the tile. Instead, the size range of the enclosing window should be limited to a valid range. @@ -155,7 +155,7 @@ static Fl_Cursor Fl_Tile_cursors[4] = { static int fl_min(int a, int b) { return ab ? a : b; } -/** +/** Request for children to change their layout. drag_intersection requests that all children with the left edge at old_l to @@ -695,7 +695,7 @@ int Fl_Tile::handle(int event) { // if (damage()) return 1; // don't fall behind case FL_RELEASE: { if (!sdrag) break; - Fl_Widget* r = resizable(); + Fl_Widget* r = resizable(); if (size_range_ || !r) r = this; int newx; if (sdrag&DRAGH) { diff --git a/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx b/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx index 1de6822e1..cda328c17 100644 --- a/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx +++ b/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx @@ -910,7 +910,7 @@ void Fl_Cairo_Graphics_Driver::uncache(Fl_RGB_Image *img, fl_uintptr_t &id_, fl_ } -void Fl_Cairo_Graphics_Driver::draw_fixed(Fl_Bitmap *bm,int XP, int YP, int WP, int HP, +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(); @@ -999,7 +999,7 @@ void Fl_Cairo_Graphics_Driver::cache(Fl_Bitmap *bm) { } -void Fl_Cairo_Graphics_Driver::draw_fixed(Fl_Pixmap *pxm,int XP, int YP, int WP, int HP, +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(); diff --git a/src/makedepend b/src/makedepend index 0199f9d96..a7cf18d19 100644 --- a/src/makedepend +++ b/src/makedepend @@ -2439,6 +2439,7 @@ Fl_Input.o: ../FL/Fl_Image.H Fl_Input.o: ../FL/Fl_Input.H Fl_Input.o: ../FL/Fl_Input_.H Fl_Input.o: ../FL/Fl_Int_Input.H +Fl_Input.o: ../FL/Fl_Menu_Item.H Fl_Input.o: ../FL/Fl_Multiline_Input.H Fl_Input.o: ../FL/Fl_Multiline_Output.H Fl_Input.o: ../FL/Fl_Output.H @@ -3929,6 +3930,9 @@ Fl_Text_Display.o: ../FL/Fl_Export.H Fl_Text_Display.o: ../FL/Fl_Graphics_Driver.H Fl_Text_Display.o: ../FL/Fl_Group.H Fl_Text_Display.o: ../FL/Fl_Image.H +Fl_Text_Display.o: ../FL/Fl_Input.H +Fl_Text_Display.o: ../FL/Fl_Input_.H +Fl_Text_Display.o: ../FL/Fl_Menu_Item.H Fl_Text_Display.o: ../FL/Fl_Pixmap.H Fl_Text_Display.o: ../FL/Fl_Plugin.H Fl_Text_Display.o: ../FL/Fl_Preferences.H -- cgit v1.2.3 From 12af9dad3e004de7fc5ff7da358377ae29ee1f68 Mon Sep 17 00:00:00 2001 From: ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> Date: Tue, 28 Nov 2023 09:06:17 +0100 Subject: Remove PostScript graphics driver code redundant with Cairo driver --- .../PostScript/Fl_PostScript_Graphics_Driver.H | 7 +- src/drivers/PostScript/Fl_PostScript_image.cxx | 116 +-------------------- 2 files changed, 3 insertions(+), 120 deletions(-) (limited to 'src') diff --git a/src/drivers/PostScript/Fl_PostScript_Graphics_Driver.H b/src/drivers/PostScript/Fl_PostScript_Graphics_Driver.H index fef8ded71..0c0ec1aaf 100644 --- a/src/drivers/PostScript/Fl_PostScript_Graphics_Driver.H +++ b/src/drivers/PostScript/Fl_PostScript_Graphics_Driver.H @@ -1,7 +1,7 @@ // // Support for graphics output to PostScript file for the Fast Light Tool Kit (FLTK). // -// Copyright 2010-2022 by Bill Spitzak and others. +// Copyright 2010-2023 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -80,11 +80,6 @@ public: int not_clipped(int x, int y, int w, int h) FL_OVERRIDE; int clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H) FL_OVERRIDE; virtual int has_feature(driver_feature feature_mask) FL_OVERRIDE { return feature_mask & PRINTER; } - // draw image classes without caching them - void draw_rgb_bitmap_(Fl_Image *img,int XP, int YP, int WP, int HP, int cx, int cy); - void draw_pixmap(Fl_Pixmap * pxm,int XP, int YP, int WP, int HP, int cx, int cy) FL_OVERRIDE; - void draw_bitmap(Fl_Bitmap * bitmap,int XP, int YP, int WP, int HP, int cx, int cy) FL_OVERRIDE; - void draw_rgb(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, int cx, int cy) FL_OVERRIDE; }; #else // ! USE_PANGO diff --git a/src/drivers/PostScript/Fl_PostScript_image.cxx b/src/drivers/PostScript/Fl_PostScript_image.cxx index 64f9972bf..0ae56609a 100644 --- a/src/drivers/PostScript/Fl_PostScript_image.cxx +++ b/src/drivers/PostScript/Fl_PostScript_image.cxx @@ -1,7 +1,7 @@ // // Postscript image drawing implementation for the Fast Light Tool Kit (FLTK). // -// Copyright 1998-2022 by Bill Spitzak and others. +// Copyright 1998-2023 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -68,119 +68,7 @@ void Fl_PostScript_Graphics_Driver::draw_image(const uchar *data, int ix, int iy draw_image(draw_image_cb, &cb_data, ix, iy, iw, ih, abs(D)); } -#if USE_PANGO - -static void destroy_BGRA(void *data) { - delete[] (uchar*)data; -} - - -void Fl_PostScript_Graphics_Driver::draw_pixmap(Fl_Pixmap *pxm,int XP, int YP, int WP, int HP, int cx, int cy) { - Fl_RGB_Image *rgb = new Fl_RGB_Image(pxm); - draw_rgb_bitmap_(rgb, XP, YP, WP, HP, cx, cy); - delete rgb; -} - - -void Fl_PostScript_Graphics_Driver::draw_rgb(Fl_RGB_Image *rgb,int XP, int YP, int WP, int HP, int cx, int cy) { - draw_rgb_bitmap_(rgb, XP, YP, WP, HP, cx, cy); -} - - -void Fl_PostScript_Graphics_Driver::draw_bitmap(Fl_Bitmap *bitmap,int XP, int YP, int WP, int HP, int cx, int cy) { - draw_rgb_bitmap_(bitmap, XP, YP, WP, HP, cx, cy); -} - - -void Fl_PostScript_Graphics_Driver::draw_rgb_bitmap_(Fl_Image *img,int XP, int YP, int WP, int HP, int cx, int cy) -{ - cairo_surface_t *surf; - cairo_format_t format = (img->d() >= 1 ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_A1); - int stride = cairo_format_stride_for_width(format, img->data_w()); - uchar *BGRA = new uchar[stride * img->data_h()]; - memset(BGRA, 0, stride * img->data_h()); - if (img->d() >= 1) { // process Fl_RGB_Image of all depths - Fl_RGB_Image *rgb = (Fl_RGB_Image*)img; - int lrgb = rgb->ld() ? rgb->ld() : rgb->data_w() * rgb->d(); - uchar A = 0xff, R,G,B, *q; - const uchar *r; - float f = 1; - if (rgb->d() >= 3) { // color images - for (int j = 0; j < rgb->data_h(); j++) { - r = rgb->array + j * lrgb; - q = BGRA + j * stride; - for (int i = 0; i < rgb->data_w(); i++) { - R = *r; - G = *(r+1); - B = *(r+2); - if (rgb->d() == 4) { - A = *(r+3); - f = float(A)/0xff; - } - *q = B * f; - *(q+1) = G * f; - *(q+2) = R * f; - *(q+3) = A; - r += rgb->d(); q += 4; - } - } - } else if (rgb->d() == 1 || rgb->d() == 2) { // B&W - for (int j = 0; j < rgb->data_h(); j++) { - r = rgb->array + j * lrgb; - q = BGRA + j * stride; - for (int i = 0; i < rgb->data_w(); i++) { - G = *r; - if (rgb->d() == 2) { - A = *(r+1); - f = float(A)/0xff; - } - *(q) = G * f; - *(q+1) = G * f; - *(q+2) = G * f; - *(q+3) = A; - r += rgb->d(); q += 4; - } - } - } - } else { - Fl_Bitmap *bm = (Fl_Bitmap*)img; - uchar *r, p; - unsigned *q; - for (int j = 0; j < bm->data_h(); j++) { - r = (uchar*)bm->array + j * ((bm->data_w() + 7)/8); - q = (unsigned*)(BGRA + j * stride); - unsigned k = 0, mask32 = 1; - p = *r; - for (int i = 0; i < bm->data_w(); i++) { - if (p&1) (*q) |= mask32; - k++; - if (k % 8 != 0) p >>= 1; else p = *(++r); - if (k % 32 != 0) mask32 <<= 1; else {q++; mask32 = 1;} - } - } - } - surf = cairo_image_surface_create_for_data(BGRA, format, img->data_w(), img->data_h(), stride); - if (cairo_surface_status(surf) == CAIRO_STATUS_SUCCESS) { - static cairo_user_data_key_t key = {}; - (void)cairo_surface_set_user_data(surf, &key, BGRA, destroy_BGRA); - cairo_pattern_t *pat = cairo_pattern_create_for_surface(surf); - cairo_save(cairo_); - cairo_rectangle(cairo_, XP-0.5, YP-0.5, WP+1, HP+1); - cairo_clip(cairo_); - if (img->d() >= 1) cairo_set_source(cairo_, pat); - cairo_matrix_t matrix; - cairo_matrix_init_scale(&matrix, double(img->data_w())/(img->w()+1), double(img->data_h())/(img->h()+1)); - cairo_matrix_translate(&matrix, -XP+0.5+cx, -YP+0.5+cy); - cairo_pattern_set_matrix(pat, &matrix); - cairo_mask(cairo_, pat); - cairo_pattern_destroy(pat); - cairo_surface_destroy(surf); - cairo_restore(cairo_); - check_status(); - } -} - -#else // USE_PANGO +#if ! USE_PANGO // // Implementation of the /ASCII85Encode PostScript filter -- cgit v1.2.3 From 59bdb455668a896d9989f08446e24313f5de48d6 Mon Sep 17 00:00:00 2001 From: ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> Date: Tue, 28 Nov 2023 15:05:58 +0100 Subject: Rearrange PostScript graphics driver code redundant with Cairo driver --- src/drivers/PostScript/Fl_PostScript.cxx | 9 +- .../PostScript/Fl_PostScript_Graphics_Driver.H | 8 +- src/drivers/PostScript/Fl_PostScript_image.cxx | 118 ++++++++++++++++++++- 3 files changed, 128 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/drivers/PostScript/Fl_PostScript.cxx b/src/drivers/PostScript/Fl_PostScript.cxx index 4ce3f67b9..f5d8f8f11 100644 --- a/src/drivers/PostScript/Fl_PostScript.cxx +++ b/src/drivers/PostScript/Fl_PostScript.cxx @@ -145,12 +145,11 @@ Fl_PostScript_Graphics_Driver::Fl_PostScript_Graphics_Driver(void) //lang_level_ = 3; lang_level_ = 2; mask = 0; -#endif - ps_filename_ = NULL; - scale_x = scale_y = 1.; bg_r = bg_g = bg_b = 255; clip_ = NULL; - what = NONE; + scale_x = scale_y = 1.; +#endif + ps_filename_ = NULL; } /** \brief The destructor. */ @@ -1750,9 +1749,9 @@ Fl_EPS_File_Surface::Fl_EPS_File_Surface(int width, int height, FILE *eps, Fl_Co if (s != 1) { ps->clocale_printf("GR GR GS %f %f SC GS\n", s, s); } + Fl::get_color(background, ps->bg_r, ps->bg_g, ps->bg_b); #endif ps->scale_x = ps->scale_y = s; - Fl::get_color(background, ps->bg_r, ps->bg_g, ps->bg_b); } } diff --git a/src/drivers/PostScript/Fl_PostScript_Graphics_Driver.H b/src/drivers/PostScript/Fl_PostScript_Graphics_Driver.H index 0c0ec1aaf..904644f42 100644 --- a/src/drivers/PostScript/Fl_PostScript_Graphics_Driver.H +++ b/src/drivers/PostScript/Fl_PostScript_Graphics_Driver.H @@ -49,7 +49,6 @@ public: char *ps_filename_; int nPages; double pw_, ph_; - uchar bg_r, bg_g, bg_b; Fl_PostScript_Graphics_Driver(); ~Fl_PostScript_Graphics_Driver(); @@ -80,6 +79,13 @@ public: int not_clipped(int x, int y, int w, int h) FL_OVERRIDE; int clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H) FL_OVERRIDE; virtual int has_feature(driver_feature feature_mask) FL_OVERRIDE { return feature_mask & PRINTER; } +#if !FLTK_USE_CAIRO + // draw image classes without caching them + void draw_rgb_bitmap_(Fl_Image *img,int XP, int YP, int WP, int HP, int cx, int cy); + void draw_pixmap(Fl_Pixmap * pxm,int XP, int YP, int WP, int HP, int cx, int cy) FL_OVERRIDE; + void draw_bitmap(Fl_Bitmap * bitmap,int XP, int YP, int WP, int HP, int cx, int cy) FL_OVERRIDE; + void draw_rgb(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, int cx, int cy) FL_OVERRIDE; +#endif // !FLTK_USE_CAIRO }; #else // ! USE_PANGO diff --git a/src/drivers/PostScript/Fl_PostScript_image.cxx b/src/drivers/PostScript/Fl_PostScript_image.cxx index 0ae56609a..c78627727 100644 --- a/src/drivers/PostScript/Fl_PostScript_image.cxx +++ b/src/drivers/PostScript/Fl_PostScript_image.cxx @@ -68,7 +68,123 @@ void Fl_PostScript_Graphics_Driver::draw_image(const uchar *data, int ix, int iy draw_image(draw_image_cb, &cb_data, ix, iy, iw, ih, abs(D)); } -#if ! USE_PANGO +#if USE_PANGO + +#if !FLTK_USE_CAIRO + +static void destroy_BGRA(void *data) { + delete[] (uchar*)data; +} + + +void Fl_PostScript_Graphics_Driver::draw_pixmap(Fl_Pixmap *pxm,int XP, int YP, int WP, int HP, int cx, int cy) { + Fl_RGB_Image *rgb = new Fl_RGB_Image(pxm); + draw_rgb_bitmap_(rgb, XP, YP, WP, HP, cx, cy); + delete rgb; +} + + +void Fl_PostScript_Graphics_Driver::draw_rgb(Fl_RGB_Image *rgb,int XP, int YP, int WP, int HP, int cx, int cy) { + draw_rgb_bitmap_(rgb, XP, YP, WP, HP, cx, cy); +} + + +void Fl_PostScript_Graphics_Driver::draw_bitmap(Fl_Bitmap *bitmap,int XP, int YP, int WP, int HP, int cx, int cy) { + draw_rgb_bitmap_(bitmap, XP, YP, WP, HP, cx, cy); +} + + +void Fl_PostScript_Graphics_Driver::draw_rgb_bitmap_(Fl_Image *img,int XP, int YP, int WP, int HP, int cx, int cy) +{ + cairo_surface_t *surf; + cairo_format_t format = (img->d() >= 1 ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_A1); + int stride = cairo_format_stride_for_width(format, img->data_w()); + uchar *BGRA = new uchar[stride * img->data_h()]; + memset(BGRA, 0, stride * img->data_h()); + if (img->d() >= 1) { // process Fl_RGB_Image of all depths + Fl_RGB_Image *rgb = (Fl_RGB_Image*)img; + int lrgb = rgb->ld() ? rgb->ld() : rgb->data_w() * rgb->d(); + uchar A = 0xff, R,G,B, *q; + const uchar *r; + float f = 1; + if (rgb->d() >= 3) { // color images + for (int j = 0; j < rgb->data_h(); j++) { + r = rgb->array + j * lrgb; + q = BGRA + j * stride; + for (int i = 0; i < rgb->data_w(); i++) { + R = *r; + G = *(r+1); + B = *(r+2); + if (rgb->d() == 4) { + A = *(r+3); + f = float(A)/0xff; + } + *q = B * f; + *(q+1) = G * f; + *(q+2) = R * f; + *(q+3) = A; + r += rgb->d(); q += 4; + } + } + } else if (rgb->d() == 1 || rgb->d() == 2) { // B&W + for (int j = 0; j < rgb->data_h(); j++) { + r = rgb->array + j * lrgb; + q = BGRA + j * stride; + for (int i = 0; i < rgb->data_w(); i++) { + G = *r; + if (rgb->d() == 2) { + A = *(r+1); + f = float(A)/0xff; + } + *(q) = G * f; + *(q+1) = G * f; + *(q+2) = G * f; + *(q+3) = A; + r += rgb->d(); q += 4; + } + } + } + } else { + Fl_Bitmap *bm = (Fl_Bitmap*)img; + uchar *r, p; + unsigned *q; + for (int j = 0; j < bm->data_h(); j++) { + r = (uchar*)bm->array + j * ((bm->data_w() + 7)/8); + q = (unsigned*)(BGRA + j * stride); + unsigned k = 0, mask32 = 1; + p = *r; + for (int i = 0; i < bm->data_w(); i++) { + if (p&1) (*q) |= mask32; + k++; + if (k % 8 != 0) p >>= 1; else p = *(++r); + if (k % 32 != 0) mask32 <<= 1; else {q++; mask32 = 1;} + } + } + } + surf = cairo_image_surface_create_for_data(BGRA, format, img->data_w(), img->data_h(), stride); + if (cairo_surface_status(surf) == CAIRO_STATUS_SUCCESS) { + static cairo_user_data_key_t key = {}; + (void)cairo_surface_set_user_data(surf, &key, BGRA, destroy_BGRA); + cairo_pattern_t *pat = cairo_pattern_create_for_surface(surf); + cairo_save(cairo_); + cairo_rectangle(cairo_, XP-0.5, YP-0.5, WP+1, HP+1); + cairo_clip(cairo_); + if (img->d() >= 1) cairo_set_source(cairo_, pat); + cairo_matrix_t matrix; + cairo_matrix_init_scale(&matrix, double(img->data_w())/(img->w()+1), double(img->data_h())/(img->h()+1)); + cairo_matrix_translate(&matrix, -XP+0.5+cx, -YP+0.5+cy); + cairo_pattern_set_matrix(pat, &matrix); + cairo_mask(cairo_, pat); + cairo_pattern_destroy(pat); + cairo_surface_destroy(surf); + cairo_restore(cairo_); + check_status(); + } +} + +#endif // !FLTK_USE_CAIRO + +#else // ! USE_PANGO // // Implementation of the /ASCII85Encode PostScript filter -- cgit v1.2.3 From 82e838f1fdadd7dd346f4bce51c6ebdd1e26dd35 Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Tue, 28 Nov 2023 16:35:39 +0100 Subject: Adds OpenGL swap_interval for Wayland and X11. --- src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.H | 2 + .../Wayland/Fl_Wayland_Gl_Window_Driver.cxx | 18 +++++ src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx | 87 +++++++++++++++++----- 3 files changed, 88 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.H b/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.H index 83b13e155..df321fc10 100644 --- a/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.H +++ b/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.H @@ -46,6 +46,8 @@ private: void swap_buffers() FL_OVERRIDE; void resize(int is_a_resize, int w, int h) FL_OVERRIDE; char swap_type() FL_OVERRIDE; + void swap_interval(int) FL_OVERRIDE; + int swap_interval() const FL_OVERRIDE; Fl_Gl_Choice *find(int m, const int *alistp) FL_OVERRIDE; GLContext create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g) FL_OVERRIDE; void set_gl_context(Fl_Window* w, GLContext context) FL_OVERRIDE; diff --git a/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx index 4553c1a0e..ac625fe6f 100644 --- a/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx @@ -63,6 +63,9 @@ struct gl_start_support { // to support use of gl_start / gl_finish static EGLConfig wld_egl_conf = NULL; +static EGLint swap_interval_ = 1; +static EGLint max_swap_interval = 1000; +static EGLint min_swap_interval = 0; EGLDisplay Fl_Wayland_Gl_Window_Driver::egl_display = EGL_NO_DISPLAY; @@ -170,6 +173,9 @@ Fl_Gl_Choice *Fl_Wayland_Gl_Window_Driver::find(int m, const int *alistp) Fl::fatal("failed to choose an EGL config\n"); } + eglGetConfigAttrib(egl_display, g->egl_conf, EGL_MAX_SWAP_INTERVAL, &max_swap_interval); + eglGetConfigAttrib(egl_display, g->egl_conf, EGL_MIN_SWAP_INTERVAL, &min_swap_interval); + first = g; return g; } @@ -431,6 +437,18 @@ void Fl_Wayland_Gl_Window_Driver::gl_start() { glClear(GL_COLOR_BUFFER_BIT); } +void Fl_Wayland_Gl_Window_Driver::swap_interval(int interval) { + if (interval < min_swap_interval) interval = min_swap_interval; + if (interval > max_swap_interval) interval = max_swap_interval; + if (egl_display && eglSwapInterval(egl_display, interval)) + swap_interval_ = interval; + // printf("swap_interval_=%d\n",swap_interval_); +} + + +int Fl_Wayland_Gl_Window_Driver::swap_interval() const { + return swap_interval_; +} FL_EXPORT EGLContext fl_wl_glcontext(GLContext rc) { return (EGLContext)rc; } diff --git a/src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx b/src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx index fd07308fa..c2611e739 100644 --- a/src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx +++ b/src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx @@ -397,41 +397,90 @@ char Fl_X11_Gl_Window_Driver::swap_type() { return copy; } -typedef void (*SWAPINTERVALPROC) (Display *dpy, GLXDrawable drawable, int interval); -static SWAPINTERVALPROC glXSwapIntervalEXT = NULL; -static bool glXSwapIntervalChecked = false; -static void checkGlxXSwapInterval() { - if (!glXSwapIntervalChecked) { - glXSwapIntervalChecked = true; - glXSwapIntervalEXT = (SWAPINTERVALPROC)glXGetProcAddressARB((const GLubyte*)"glXSwapIntervalEXT"); + +// Start of swap_interval implementation in the three possibel ways for X11 + +// -1 = not yet initialized, 0 = none found, 1 = GLX, 2 = MESA, 3 = SGI +static signed char swap_interval_type = -1; + +typedef void (*GLX_Set_Swap_Iterval_Proc) (Display *dpy, GLXDrawable drawable, int interval); +typedef int (*MESA_Set_Swap_Iterval_Proc) (unsigned int interval); +typedef int (*MESA_Get_Swap_Iterval_Proc) (); +typedef int (*SGI_Set_Swap_Iterval_Proc) (int interval); + +static union { + GLX_Set_Swap_Iterval_Proc glXSwapIntervalEXT = NULL; + MESA_Set_Swap_Iterval_Proc glXSwapIntervalMESA; + SGI_Set_Swap_Iterval_Proc glXSwapIntervalSGI; +}; + +static MESA_Get_Swap_Iterval_Proc glXGetSwapIntervalMESA = NULL; + +static void init_swap_interval() { + if (swap_interval_type != -1) return; + int major = 1, minor = 0; + glXQueryVersion(fl_display, &major, &minor); + swap_interval_type = 0; + const char *extensions = glXQueryExtensionsString(fl_display, fl_screen); + if (strstr(extensions, "GLX_EXT_swap_control") && ((major > 1) || (minor >= 3))) { + glXSwapIntervalEXT = (GLX_Set_Swap_Iterval_Proc)glXGetProcAddressARB((const GLubyte*)"glXSwapIntervalEXT"); + swap_interval_type = 1; + } else if (strstr(extensions, "GLX_MESA_swap_control")) { + glXSwapIntervalMESA = (MESA_Set_Swap_Iterval_Proc)glXGetProcAddressARB((const GLubyte*)"glXSwapIntervalMESA"); + glXGetSwapIntervalMESA = (MESA_Get_Swap_Iterval_Proc)glXGetProcAddressARB((const GLubyte*)"glXGetSwapIntervalMESA"); + swap_interval_type = 2; + } else if (strstr(extensions, "GLX_SGI_swap_control")) { + glXSwapIntervalSGI = (SGI_Set_Swap_Iterval_Proc)glXGetProcAddressARB((const GLubyte*)"glXSwapIntervalSGI"); + swap_interval_type = 3; } } void Fl_X11_Gl_Window_Driver::swap_interval(int interval) { if (!fl_xid(pWindow)) return; - if (!glXSwapIntervalChecked) checkGlxXSwapInterval(); - if (glXSwapIntervalEXT) { - glXSwapIntervalEXT(fl_display, fl_xid(pWindow), interval); + if (swap_interval_type == -1) + init_swap_interval(); + switch (swap_interval_type) { + case 1: + if (glXSwapIntervalEXT) + glXSwapIntervalEXT(fl_display, fl_xid(pWindow), interval); + break; + case 2: + if (glXSwapIntervalMESA) + glXSwapIntervalMESA((unsigned int)interval); + break; + case 3: + if (glXSwapIntervalSGI) + glXSwapIntervalSGI(interval); + break; } } int Fl_X11_Gl_Window_Driver::swap_interval() const { if (!fl_xid(pWindow)) return -1; - if (!glXSwapIntervalChecked) checkGlxXSwapInterval(); - if (!glXSwapIntervalEXT) return -1; - static bool ext_checked = false, ext_exists = false; - if (!ext_checked) { - ext_checked = true; - ext_exists = (strstr(glXQueryExtensionsString(fl_display, fl_screen), "GLX_EXT_swap_control") != NULL); + if (swap_interval_type == -1) + init_swap_interval(); + int interval = -1; + switch (swap_interval_type) { + case 1: { + unsigned int val = 0; + glXQueryDrawable(fl_display, fl_xid(pWindow), 0x20F1 /*GLX_SWAP_INTERVAL_EXT*/, &val); + interval = (int)val; + break; } + case 2: + if (glXGetSwapIntervalMESA) + interval = glXGetSwapIntervalMESA(); + break; + case 3: + // not available + break; } - if (!ext_exists) return -1; - unsigned int interval = -1; - glXQueryDrawable(fl_display, fl_xid(pWindow), 0x20F1 /*GLX_SWAP_INTERVAL_EXT*/, &interval); return interval; } +// end of swap_interval implementation + void Fl_X11_Gl_Window_Driver::waitGL() { glXWaitGL(); } -- cgit v1.2.3