Fix "Setting window custom cursor from SVG image crashes" (#1363)
This commit is contained in:
parent
14a5f705c8
commit
05a3f82a5c
@ -392,9 +392,12 @@ public:
|
||||
\sa void Fl_RGB_Image::max_size(size_t)
|
||||
*/
|
||||
static size_t max_size() {return max_size_;}
|
||||
/** Returns whether an image is an Fl_SVG_Image or not.
|
||||
/** Returns whether an RGB image is an Fl_SVG_Image or not.
|
||||
This virtual method returns a pointer to the Fl_SVG_Image if this object is an instance of Fl_SVG_Image or NULL if not. */
|
||||
virtual Fl_SVG_Image *as_svg_image() { return NULL; }
|
||||
/** Returns whether an RGB image is an Fl_SVG_Image or not.
|
||||
This virtual method returns a pointer to the Fl_SVG_Image if this object is an instance of const Fl_SVG_Image or NULL if not. */
|
||||
virtual const Fl_SVG_Image *as_svg_image() const { return NULL; }
|
||||
/** Makes sure the object is fully initialized.
|
||||
In particular, makes sure member variable \ref array is non-null. */
|
||||
virtual void normalize() {}
|
||||
|
||||
@ -170,6 +170,7 @@ public:
|
||||
void draw(int X, int Y, int W, int H, int cx = 0, int cy = 0) override;
|
||||
void draw(int X, int Y) { draw(X, Y, w(), h(), 0, 0); }
|
||||
Fl_SVG_Image *as_svg_image() override { return this; }
|
||||
const Fl_SVG_Image *as_svg_image() const override { return this; }
|
||||
void normalize() override;
|
||||
};
|
||||
|
||||
|
||||
@ -4161,6 +4161,11 @@ int Fl_Cocoa_Window_Driver::set_cursor(const Fl_RGB_Image *image, int hotx, int
|
||||
if ((hoty < 0) || (hoty >= image->h()))
|
||||
return 0;
|
||||
|
||||
if (image->as_svg_image()) {
|
||||
Fl_RGB_Image *image2 = (Fl_RGB_Image*)image->copy();
|
||||
image2->normalize();
|
||||
image = image2;
|
||||
}
|
||||
// OS X >= 10.6 can create a NSImage from a CGImage, but we need to
|
||||
// support older versions, hence this pesky handling.
|
||||
|
||||
@ -4220,6 +4225,7 @@ int Fl_Cocoa_Window_Driver::set_cursor(const Fl_RGB_Image *image, int hotx, int
|
||||
|
||||
[bitmap release];
|
||||
[nsimage release];
|
||||
if (image->as_svg_image()) delete image;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -2770,6 +2770,7 @@ int Fl_WinAPI_Window_Driver::set_cursor(Fl_Cursor c) {
|
||||
int Fl_WinAPI_Window_Driver::set_cursor(const Fl_RGB_Image *image, int hotx, int hoty) {
|
||||
HCURSOR new_cursor;
|
||||
Fl_RGB_Image *scaled_image = (Fl_RGB_Image*)image->copy();
|
||||
scaled_image->normalize();
|
||||
new_cursor = image_to_icon(scaled_image, false, hotx, hoty);
|
||||
delete scaled_image;
|
||||
if (new_cursor == NULL)
|
||||
|
||||
@ -3142,11 +3142,13 @@ int Fl_X11_Window_Driver::set_cursor(const Fl_RGB_Image *image, int hotx, int ho
|
||||
if ((hoty < 0) || (hoty >= image->h()))
|
||||
return 0;
|
||||
|
||||
cursor = XcursorImageCreate(image->w(), image->h());
|
||||
float s = image->as_svg_image() ? Fl::screen_scale(pWindow->screen_num()) : 1;
|
||||
cursor = XcursorImageCreate(image->w() * s, image->h() * s);
|
||||
if (!cursor)
|
||||
return 0;
|
||||
|
||||
image = (Fl_RGB_Image*)image->copy();
|
||||
image = (Fl_RGB_Image*)image->copy(image->w() * s, image->h() * s);
|
||||
((Fl_RGB_Image*)image)->normalize();
|
||||
const int extra_data = image->ld() ? (image->ld()-image->w()*image->d()) : 0;
|
||||
const uchar *i = (const uchar*)*image->data();
|
||||
XcursorPixel *o = cursor->pixels;
|
||||
|
||||
@ -1824,6 +1824,13 @@ int Fl_Wayland_Window_Driver::set_cursor(const Fl_RGB_Image *rgb, int hotx, int
|
||||
int Fl_Wayland_Window_Driver::set_cursor_4args(const Fl_RGB_Image *rgb, int hotx, int hoty,
|
||||
bool keep_copy) {
|
||||
if (keep_copy) {
|
||||
if (rgb->as_svg_image()) {
|
||||
int scale = wld_scale();
|
||||
Fl_RGB_Image *svg = (Fl_RGB_Image*)rgb->copy(rgb->w() * scale, rgb->h() * scale);
|
||||
svg->normalize();
|
||||
svg->scale(rgb->w(), rgb->h(), 0, 1);
|
||||
rgb = svg;
|
||||
} else {
|
||||
int ld = rgb->ld() ? rgb->ld() : rgb->data_w() * rgb->d();
|
||||
uchar *data = new uchar[ld * rgb->data_h()];
|
||||
memcpy(data, rgb->array, ld * rgb->data_h());
|
||||
@ -1832,6 +1839,7 @@ int Fl_Wayland_Window_Driver::set_cursor_4args(const Fl_RGB_Image *rgb, int hotx
|
||||
rgb2->scale(rgb->w(), rgb->h(), 0, 1);
|
||||
rgb = rgb2;
|
||||
}
|
||||
}
|
||||
// build a new wl_cursor and its image
|
||||
struct wld_window *xid = (struct wld_window *)Fl_Window_Driver::xid(pWindow);
|
||||
struct wl_cursor *new_cursor = (struct wl_cursor*)malloc(sizeof(struct wl_cursor));
|
||||
|
||||
Loading…
Reference in New Issue
Block a user