Fixes blur rendering with RTSurface on hidpi screen
Other fixes: - Fixes splash image not rendered - Cleans commented code - Replaces deprecated librsvg functions - Updates Makefile librsvg required minimum version - Correctly uses RTSurface getWidth / getHeight functions - Improves lwbutton aspect Known issues: - Blur rendering with RTPixbuf on hidpi screen
This commit is contained in:
parent
7ee6fd795b
commit
36222d14a2
@ -467,7 +467,7 @@ pkg_check_modules(GTHREAD REQUIRED gthread-2.0>=2.48)
|
||||
pkg_check_modules(GOBJECT REQUIRED gobject-2.0>=2.48)
|
||||
pkg_check_modules(SIGC REQUIRED sigc++-2.0>=2.3.1)
|
||||
pkg_check_modules(LENSFUN REQUIRED lensfun>=0.2)
|
||||
pkg_check_modules(RSVG REQUIRED librsvg-2.0>=2.46)
|
||||
pkg_check_modules(RSVG REQUIRED librsvg-2.0>=2.52)
|
||||
|
||||
if(WIN32)
|
||||
add_definitions(-DWIN32)
|
||||
|
@ -168,8 +168,8 @@ std::vector<Glib::RefPtr<Gdk::Pixbuf>> BatchQueueEntry::getIconsOnImageArea ()
|
||||
void BatchQueueEntry::getIconSize (int& w, int& h) const
|
||||
{
|
||||
|
||||
w = savedAsIcon->get()->get_width ();
|
||||
h = savedAsIcon->get()->get_height ();
|
||||
w = savedAsIcon->getWidth ();
|
||||
h = savedAsIcon->getHeight ();
|
||||
}
|
||||
|
||||
|
||||
|
@ -195,8 +195,8 @@ void FileBrowserEntry::customBackBufferUpdate (Cairo::RefPtr<Cairo::Context> c)
|
||||
void FileBrowserEntry::getIconSize (int& w, int& h) const
|
||||
{
|
||||
|
||||
w = editedIcon->get()->get_width ();
|
||||
h = editedIcon->get()->get_height ();
|
||||
w = editedIcon->getWidth ();
|
||||
h = editedIcon->getHeight ();
|
||||
}
|
||||
|
||||
FileThumbnailButtonSet* FileBrowserEntry::getThumbButtonSet ()
|
||||
|
@ -25,8 +25,8 @@ LWButton::LWButton (std::shared_ptr<RTSurface> i, int aCode, void* aData, Alignm
|
||||
{
|
||||
|
||||
if (i) {
|
||||
w = i->getWidth () + 2;
|
||||
h = i->getHeight () + 2;
|
||||
w = i->getWidth ();
|
||||
h = i->getHeight ();
|
||||
} else {
|
||||
w = h = 2;
|
||||
}
|
||||
@ -65,8 +65,8 @@ void LWButton::setIcon (std::shared_ptr<RTSurface> i)
|
||||
icon = i;
|
||||
|
||||
if (i) {
|
||||
w = i->getWidth () + 2;
|
||||
h = i->getHeight () + 2;
|
||||
w = i->getWidth ();
|
||||
h = i->getHeight ();
|
||||
} else {
|
||||
w = h = 2;
|
||||
}
|
||||
@ -186,9 +186,9 @@ void LWButton::redraw (Cairo::RefPtr<Cairo::Context> context)
|
||||
{
|
||||
|
||||
GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected
|
||||
context->set_line_width (1.0);
|
||||
context->set_line_width (2.0); // Line width shall be even to avoid blur effect when upscaling
|
||||
context->set_antialias (Cairo::ANTIALIAS_SUBPIXEL);
|
||||
context->rectangle (xpos + 0.5, ypos + 0.5, w - 1.0, h - 1.0);
|
||||
context->rectangle (xpos, ypos, w, h);
|
||||
|
||||
if (state == Pressed_In) {
|
||||
context->set_source_rgb (fgr, fgg, fgb);
|
||||
@ -205,7 +205,7 @@ void LWButton::redraw (Cairo::RefPtr<Cairo::Context> context)
|
||||
}
|
||||
|
||||
context->stroke ();
|
||||
int dilat = 1;
|
||||
int dilat = 0;
|
||||
|
||||
if (state == Pressed_In) {
|
||||
dilat++;
|
||||
|
@ -36,7 +36,13 @@ void RTScalable::updateDPInScale(const Gtk::Window* window, double &newDPI, int
|
||||
if (window) {
|
||||
const auto screen = window->get_screen();
|
||||
newDPI = screen->get_resolution(); // Get DPI retrieved from the OS
|
||||
newScale = window->get_scale_factor(); // Get scale factor associated to the window
|
||||
|
||||
if (window->get_scale_factor() > 0) {
|
||||
// Get scale factor associated to the window
|
||||
newScale = window->get_scale_factor();
|
||||
} else {
|
||||
newScale = 1; // Default minimum value of 1 as scale is used to scale surface
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,21 +94,6 @@ Cairo::RefPtr<Cairo::ImageSurface> RTScalable::loadSurfaceFromIcon(const Glib::u
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// Scale current surface size to desired scaled size
|
||||
if (surface) {
|
||||
// Note: surface is considered made from squared icon
|
||||
const double scale_factor = static_cast<double>(size) / static_cast<double>(surface->get_width());
|
||||
surf = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32,
|
||||
static_cast<int>(surface->get_width() * scale_factor + 0.5),
|
||||
static_cast<int>(surface->get_height() * scale_factor + 0.5));
|
||||
const auto cr = Cairo::Context::create(surf);
|
||||
cr->scale(scale_factor, scale_factor);
|
||||
cr->set_source(surface, 0, 0);
|
||||
cr->paint();
|
||||
}
|
||||
*/
|
||||
|
||||
return surf;
|
||||
}
|
||||
|
||||
@ -174,33 +165,44 @@ Cairo::RefPtr<Cairo::ImageSurface> RTScalable::loadSurfaceFromSVG(const Glib::us
|
||||
return surf;
|
||||
}
|
||||
|
||||
int w, h;
|
||||
|
||||
if (width == -1 || height == -1) {
|
||||
// Use SVG image natural width and height
|
||||
RsvgDimensionData dim;
|
||||
rsvg_handle_get_dimensions(handle, &dim); // Get SVG image dimensions
|
||||
surf = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, dim.width, dim.height);
|
||||
double _w, _h;
|
||||
const bool has_dim = rsvg_handle_get_intrinsic_size_in_pixels(handle, &_w, &_h); // Get SVG image dimensions
|
||||
if (has_dim) {
|
||||
w = std::ceil(_w);
|
||||
h = std::ceil(_h);
|
||||
} else {
|
||||
w = h = 16; // Set to a default size of 16px (i.e. Gtk::ICON_SIZE_SMALL_TOOLBAR one)
|
||||
}
|
||||
} else {
|
||||
// Use given width and height
|
||||
surf = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, width, height);
|
||||
w = width;
|
||||
h = height;
|
||||
}
|
||||
|
||||
// Create an upscaled surface to avoid blur effect
|
||||
surf = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32,
|
||||
w * RTScalable::getScale(),
|
||||
h * RTScalable::getScale());
|
||||
|
||||
// Render (and erase with) default surface background
|
||||
Cairo::RefPtr<Cairo::Context> c = Cairo::Context::create(surf);
|
||||
c->set_source_rgba (0., 0., 0., 0.);
|
||||
c->set_operator (Cairo::OPERATOR_CLEAR);
|
||||
c->paint();
|
||||
|
||||
// Render surface based on SVG image
|
||||
// Render upscaled surface based on SVG image
|
||||
error = nullptr;
|
||||
RsvgRectangle rect = {
|
||||
.x = 0.,
|
||||
.y = 0.,
|
||||
.width = static_cast<double>(width * RTScalable::getScale()), // SVG image is upscaled to avoid blur effect
|
||||
.height = static_cast<double>(height * RTScalable::getScale()) // SVG image is upscaled to avoid blur effect
|
||||
.width = static_cast<double>(w * RTScalable::getScale()),
|
||||
.height = static_cast<double>(h * RTScalable::getScale())
|
||||
};
|
||||
c->set_operator (Cairo::OPERATOR_OVER);
|
||||
c->scale(1. / RTScalable::getScale(), 1. / RTScalable::getScale()); // Cairo surface is scaled to match image dimensions
|
||||
|
||||
const bool success = rsvg_handle_render_document(handle, c->cobj(), &rect, &error);
|
||||
|
||||
if (!success && error) {
|
||||
@ -210,6 +212,11 @@ Cairo::RefPtr<Cairo::ImageSurface> RTScalable::loadSurfaceFromSVG(const Glib::us
|
||||
}
|
||||
|
||||
rsvg_handle_free(handle);
|
||||
|
||||
// Set device scale to avoid blur effect
|
||||
cairo_surface_set_device_scale(surf->cobj(),
|
||||
static_cast<double>(RTScalable::getScale()),
|
||||
static_cast<double>(RTScalable::getScale()));
|
||||
} else {
|
||||
if (rtengine::settings->verbose) {
|
||||
std::cerr << "Failed to load SVG file \"" << fname << "\"" << std::endl;
|
||||
|
@ -90,7 +90,7 @@ int RTSurface::getWidth()
|
||||
{
|
||||
return
|
||||
surface
|
||||
? surface->get_width()
|
||||
? (surface->get_width() / RTScalable::getScale())
|
||||
: -1;
|
||||
}
|
||||
|
||||
@ -98,7 +98,7 @@ int RTSurface::getHeight()
|
||||
{
|
||||
return
|
||||
surface
|
||||
? surface->get_height()
|
||||
? (surface->get_height() / RTScalable::getScale())
|
||||
: -1;
|
||||
}
|
||||
|
||||
@ -152,8 +152,22 @@ RTPixbuf::RTPixbuf(const Glib::ustring &icon_name, const Gtk::IconSize iconSize)
|
||||
const Cairo::RefPtr<Cairo::ImageSurface> surface = RTScalable::loadSurfaceFromIcon(icon_name, iconSize);
|
||||
|
||||
if (surface) {
|
||||
// Downscale surface before creating pixbuf
|
||||
const Cairo::RefPtr<Cairo::Surface> _surface = Cairo::Surface::create(surface,
|
||||
Cairo::CONTENT_COLOR_ALPHA,
|
||||
surface->get_width() / RTScalable::getScale(),
|
||||
surface->get_height() / RTScalable::getScale());
|
||||
const auto c = Cairo::Context::create(_surface);
|
||||
c->scale(1. / static_cast<double>(RTScalable::getScale()), 1. / static_cast<double>(RTScalable::getScale()));
|
||||
c->set_source(surface, 0., 0.);
|
||||
c->paint();
|
||||
|
||||
// Create pixbuf from surface
|
||||
pixbuf = Gdk::Pixbuf::create(surface, 0, 0, surface->get_width(), surface->get_height());
|
||||
pixbuf = Gdk::Pixbuf::create(_surface,
|
||||
0,
|
||||
0,
|
||||
surface->get_width() / RTScalable::getScale(),
|
||||
surface->get_height() / RTScalable::getScale());
|
||||
|
||||
// Save private parameters
|
||||
type = RTPixbuf::IconType;
|
||||
@ -177,8 +191,22 @@ RTPixbuf::RTPixbuf(const Glib::ustring &fname) :
|
||||
const Cairo::RefPtr<Cairo::ImageSurface> surface = RTScalable::loadSurfaceFromPNG(fname);
|
||||
|
||||
if (surface) {
|
||||
// Downscale surface before creating pixbuf
|
||||
const Cairo::RefPtr<Cairo::Surface> _surface = Cairo::Surface::create(surface,
|
||||
Cairo::CONTENT_COLOR_ALPHA,
|
||||
surface->get_width() / RTScalable::getScale(),
|
||||
surface->get_height() / RTScalable::getScale());
|
||||
const auto c = Cairo::Context::create(_surface);
|
||||
c->scale(1. / static_cast<double>(RTScalable::getScale()), 1. / static_cast<double>(RTScalable::getScale()));
|
||||
c->set_source(surface, 0., 0.);
|
||||
c->paint();
|
||||
|
||||
// Create pixbuf from surface
|
||||
pixbuf = Gdk::Pixbuf::create(surface, 0, 0, surface->get_width(), surface->get_height());
|
||||
pixbuf = Gdk::Pixbuf::create(_surface,
|
||||
0,
|
||||
0,
|
||||
surface->get_width() / RTScalable::getScale(),
|
||||
surface->get_height() / RTScalable::getScale());
|
||||
|
||||
// Save private parameter
|
||||
type = RTPixbuf::PNGType;
|
||||
@ -192,8 +220,22 @@ RTPixbuf::RTPixbuf(const Glib::ustring &fname) :
|
||||
const Cairo::RefPtr<Cairo::ImageSurface> surface = RTScalable::loadSurfaceFromSVG(fname);
|
||||
|
||||
if (surface) {
|
||||
// Downscale surface before creating pixbuf
|
||||
const Cairo::RefPtr<Cairo::Surface> _surface = Cairo::Surface::create(surface,
|
||||
Cairo::CONTENT_COLOR_ALPHA,
|
||||
surface->get_width() / RTScalable::getScale(),
|
||||
surface->get_height() / RTScalable::getScale());
|
||||
const auto c = Cairo::Context::create(_surface);
|
||||
c->scale(1. / static_cast<double>(RTScalable::getScale()), 1. / static_cast<double>(RTScalable::getScale()));
|
||||
c->set_source(surface, 0., 0.);
|
||||
c->paint();
|
||||
|
||||
// Create pixbuf from surface
|
||||
pixbuf = Gdk::Pixbuf::create(surface, 0, 0, surface->get_width(), surface->get_height());
|
||||
pixbuf = Gdk::Pixbuf::create(_surface,
|
||||
0,
|
||||
0,
|
||||
surface->get_width() / RTScalable::getScale(),
|
||||
surface->get_height() / RTScalable::getScale());
|
||||
|
||||
// Save private parameter
|
||||
type = RTPixbuf::SVGType;
|
||||
|
@ -34,7 +34,7 @@ bool SplashImage::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr)
|
||||
{
|
||||
if (surface->hasSurface()) {
|
||||
cr->set_source(surface->get(), 0., 0.);
|
||||
cr->rectangle(0, 0, surface->get()->get_width(), surface->get()->get_height());
|
||||
cr->rectangle(0, 0, surface->getWidth(), surface->getHeight());
|
||||
cr->fill();
|
||||
|
||||
Cairo::FontOptions cfo;
|
||||
@ -68,7 +68,7 @@ bool SplashImage::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr)
|
||||
cr->set_source_rgb (0., 0., 0.);
|
||||
cr->set_line_width(3.);
|
||||
cr->set_line_join(Cairo::LINE_JOIN_ROUND);
|
||||
cr->move_to (surface->get()->get_width() - w - 32, surface->get()->get_height() - h - 20);
|
||||
cr->move_to (surface->getWidth() - w - 32, surface->getHeight() - h - 20);
|
||||
version->add_to_cairo_context (cr);
|
||||
cr->stroke_preserve();
|
||||
cr->set_source_rgb (1., 1., 1.);
|
||||
@ -87,12 +87,12 @@ Gtk::SizeRequestMode SplashImage::get_request_mode_vfunc () const
|
||||
|
||||
void SplashImage::get_preferred_height_vfunc (int &minimum_height, int &natural_height) const
|
||||
{
|
||||
minimum_height = natural_height = surface ? surface->get()->get_height() : RTScalable::scalePixelSize(100);
|
||||
minimum_height = natural_height = surface ? surface->getHeight() : RTScalable::scalePixelSize(100);
|
||||
}
|
||||
|
||||
void SplashImage::get_preferred_width_vfunc (int &minimum_width, int &natural_width) const
|
||||
{
|
||||
minimum_width = natural_width = surface ? surface->get()->get_width() : RTScalable::scalePixelSize(100);
|
||||
minimum_width = natural_width = surface ? surface->getWidth() : RTScalable::scalePixelSize(100);
|
||||
}
|
||||
|
||||
void SplashImage::get_preferred_height_for_width_vfunc (int width, int &minimum_height, int &natural_height) const
|
||||
|
Loading…
x
Reference in New Issue
Block a user