mirror of https://github.com/fltk/fltk
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:
parent
222b2ea2e8
commit
09db3a6dea
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue