Fix "Xrender blurs adjacent images with bilinear scaling" (#633)

Many thanks to @wcout for providing this fix.

Xrender now draws images in the same way when tiling images
or not when FL_RGB_SCALING_BILINEAR is on.
This allows to remove static bool Fl_Tiled_Image::drawing_tiled_image()
which becomes unused.
This commit is contained in:
ManoloFLTK 2023-01-08 11:17:03 +01:00
parent 222b2ea2e8
commit 09db3a6dea
3 changed files with 10 additions and 16 deletions

View File

@ -30,16 +30,12 @@
color_average(), desaturate(), or inactive() methods.
*/
class FL_EXPORT Fl_Tiled_Image : public Fl_Image {
private:
static bool drawing_tiled_image_;
protected:
Fl_Image *image_; // The image that is tiled
int alloc_image_; // Did we allocate this image?
public:
/** Returns true when the FLTK library is currently drawing an Fl_Tiled_Image object. */
static inline bool drawing_tiled_image() { return drawing_tiled_image_;};
Fl_Tiled_Image(Fl_Image *i, int W = 0, int H = 0);
virtual ~Fl_Tiled_Image();

View File

@ -20,8 +20,6 @@
#include <FL/Fl_Window.H>
#include <FL/fl_draw.H>
bool Fl_Tiled_Image::drawing_tiled_image_ = false;
/**
The constructors create a new tiled image containing the specified image.
Use a width and height of 0 to tile the whole window/widget.
@ -183,7 +181,6 @@ Fl_Tiled_Image::draw(int X, // I - Starting X position
if (W == 0 || H == 0) return;
fl_push_clip(X, Y, W, H);
drawing_tiled_image_ = true;
if (cx > 0) iw -= cx; // crop image
if (cy > 0) ih -= cy;
@ -197,6 +194,5 @@ Fl_Tiled_Image::draw(int X, // I - Starting X position
}
}
}
drawing_tiled_image_ = false;
fl_pop_clip();
}

View File

@ -56,8 +56,11 @@
# include "../../Fl_XColor.H"
# include "../../flstring.h"
#if HAVE_XRENDER
#include <X11/extensions/Xrender.h>
#endif
# include <X11/extensions/Xrender.h>
# if RENDER_MAJOR * 100 + RENDER_MAJOR < 10
# define RepeatPad 2
# endif
#endif // HAVE_XRENDER
static XImage xi; // template used to pass info to X
static int bytes_per_pixel;
@ -806,8 +809,10 @@ int Fl_Xlib_Graphics_Driver::scale_and_render_pixmap(Fl_Offscreen pixmap, int de
static XRenderPictFormat *fmt24 = XRenderFindStandardFormat(fl_display, PictStandardRGB24);
static XRenderPictFormat *fmt32 = XRenderFindStandardFormat(fl_display, PictStandardARGB32);
static XRenderPictFormat *dstfmt = XRenderFindVisualFormat(fl_display, fl_visual->visual);
Picture src = XRenderCreatePicture(fl_display, (Pixmap)pixmap, has_alpha ?fmt32:fmt24, 0, &srcattr);
Picture dst = XRenderCreatePicture(fl_display, fl_window, dstfmt, 0, &srcattr);
srcattr.repeat = RepeatPad;
Picture src = XRenderCreatePicture(fl_display, (Pixmap)pixmap, has_alpha ?fmt32:fmt24,
CPRepeat, &srcattr);
Picture dst = XRenderCreatePicture(fl_display, fl_window, dstfmt, 0, 0);
if (!src || !dst) {
fprintf(stderr, "Failed to create Render pictures (%lu %lu)\n", src, dst);
return 0;
@ -824,10 +829,7 @@ int Fl_Xlib_Graphics_Driver::scale_and_render_pixmap(Fl_Offscreen pixmap, int de
{ XDoubleToFixed( 0 ), XDoubleToFixed( 0 ), XDoubleToFixed( 1 ) }
}};
XRenderSetPictureTransform(fl_display, src, &mat);
if (Fl_Image::scaling_algorithm() == FL_RGB_SCALING_BILINEAR &&
!Fl_Tiled_Image::drawing_tiled_image()) {
// The filter is not used when drawing tiled images because drawn image edges
// become somewhat blurry.
if (Fl_Image::scaling_algorithm() == FL_RGB_SCALING_BILINEAR) {
XRenderSetPictureFilter(fl_display, src, FilterBilinear, 0, 0);
// A note at https://www.talisman.org/~erlkonig/misc/x11-composite-tutorial/ :
// "When you use a filter you'll probably want to use PictOpOver as the render op,