Closed rageworx closed 1 year ago
This bug is belonged to fl_imgtk::rescale(). fl_imgtk::rescale() cannot scaling image from SVG, how to consider source image is Fl_RGB or Fl_SVG ?
Fl_SVG_Image render SVG source to Fl_RGBImage by rasterize(W,H) in step of resize().
void Fl_SVG_Image::rasterize_(int W, int H) {
static NSVGrasterizer *rasterizer = nsvgCreateRasterizer();
double fx, fy;
if (proportional) {
fx = svg_scaling_(W, H);
fy = fx;
} else {
fx = (double)W / counted_svg_image_->svg_image->width;
fy = (double)H / counted_svg_image_->svg_image->height;
}
array = new uchar[W*H*4];
nsvgRasterizeXY(rasterizer, counted_svg_image_->svg_image, 0, 0, float(fx), float(fy), (uchar* )array, W, H, W*4);
alloc_array = 1;
data((const char * const *)&array, 1);
d(4);
if (to_desaturate_) Fl_RGB_Image::desaturate();
if (average_weight_ < 1) Fl_RGB_Image::color_average(average_color_, average_weight_);
rasterized_ = true;
raster_w_ = W;
raster_h_ = H;
}
But question is, why SVG image breaks ?
Maybe the wrong w()
and h()
at time of resizing by this step ?
void usr_scale(Fl_RGB_Image* s, int x, int y, int w, int h, Fl_RGB_Image** o)
{
Fl::lock();
if ( s != NULL )
{
if ( s->array != NULL )
{
Fl_RGB_Image* tmpi = (Fl_RGB_Image*)s->copy( s->data_w(), s->data_h() );
if ( tmpi != NULL )
{
*o = fl_imgtk::rescale( tmpi, w, h, fl_imgtk::BICUBIC );
}
delete tmpi;
}
}
else
if ( *o != NULL ) /// delete by user.
{
delete (Fl_RGB_Image*)*o;
*o = NULL;
}
Fl::unlock();
}
Need to duplicated Fl_RGB_Image, and checks data_w() and data_h() to real size.
void usr_scale(Fl_RGB_Image* s, int x, int y, int w, int h, Fl_RGB_Image** o)
{
Fl::lock();
// Using fl_imgtk fast rescaling method here.
if ( ( s != NULL ) & ( w > 0 ) & ( h > 0 ) )
{
if ( s->array != NULL )
{
// To rescale in safe way, some Fl_RGB_Image like from SVG, need to
// check with data_w() and data_h().
Fl_RGB_Image* tmpi = (Fl_RGB_Image*)s->copy( s->data_w(), s->data_h() );
if ( tmpi != NULL )
{
*o = fl_imgtk::rescale( tmpi, w, h, fl_imgtk::BICUBIC );
}
delete tmpi;
}
}
else
// It must be implemented for removing image.
if ( ( *o != NULL ) & ( x == 0 ) & ( y == 0 ) & ( w == 0 ) & ( h == 0 ) )
{
delete (Fl_RGB_Image*)*o;
*o = NULL;
}
Fl::unlock();
}
It is a fixed in latest change of fltk-1.4.0-dev, and fl_imgtk. It was cause of Fl_SVG_Image rasterizing and fl_imgtk need to refer to actual data width and height when rescaling factor.
Issue tested and closing now.
Found this issue while testing Make Image 'O HDR, with Ctrl+'+'/'-' to scaling up/down.
Normal Fl_SVG_Image:
Wrong scaling down Fl_SVG_Image: