diff --git a/.gitignore b/.gitignore index 290e9a0..c3860f3 100644 --- a/.gitignore +++ b/.gitignore @@ -26,4 +26,6 @@ po/Makevars.template po/*.sin po/*quot* -data/nitrogen.desktop \ No newline at end of file +data/nitrogen.desktop +.cache/ +compile_commands.json diff --git a/src/NWindow.cc b/src/NWindow.cc index 1c2efd7..bea1527 100644 --- a/src/NWindow.cc +++ b/src/NWindow.cc @@ -360,6 +360,7 @@ void NWindow::setup_select_boxes() { this->select_mode.add_image_row( icon, _("Zoomed"), SetBG::mode_to_string(SetBG::SET_ZOOM), false ); this->select_mode.add_image_row( icon, _("Zoomed Fill"), SetBG::mode_to_string(SetBG::SET_ZOOM_FILL), false ); + this->select_mode.add_image_row( icon, _("Zoomed Image Fill"), SetBG::mode_to_string(SetBG::SET_ZOOM_IMG_FILL), false ); // @TODO GET ALL THIS INTEL FROM THE SETTER diff --git a/src/SetBG.cc b/src/SetBG.cc index 1f08d1c..b7bac0d 100644 --- a/src/SetBG.cc +++ b/src/SetBG.cc @@ -493,28 +493,27 @@ Glib::RefPtr SetBG::make_zoom_fill(const Glib::RefPtr // depends on bigger side unsigned orig_w = orig->get_width(); - unsigned orig_h = orig->get_height(); + unsigned orig_h = orig->get_height(); - int dw = winw - orig_w; - int dh = winh - orig_h; - - // what if we expand it to fit the screen width? - x = 0; - w = winw; - h = winw * orig_h / orig_w; - y = (h - winh) / 2; - - if (!(h >= winh)) { - // the image isn't tall enough that way! - // expand it to fit the screen height - y = 0; - w = winh * orig_w / orig_h; - h = winh; - x = (w - winw) / 2; - } + int dw = winw - orig_w; + int dh = winh - orig_h; - Glib::RefPtr tmp = orig->scale_simple(w, h, - Gdk::INTERP_BILINEAR); + // what if we expand it to fit the screen width? + x = 0; + w = winw; + h = winw * orig_h / orig_w; + y = (h - winh) / 2; + + if (!(h >= winh)) { + // the image isn't tall enough that way! + // expand it to fit the screen height + y = 0; + w = winh * orig_w / orig_h; + h = winh; + x = (w - winw) / 2; + } + + Glib::RefPtr tmp = orig->scale_simple(w, h, Gdk::INTERP_BILINEAR); Glib::RefPtr retval = Gdk::Pixbuf::create( orig->get_colorspace(), orig->get_has_alpha(), orig->get_bits_per_sample(), winw, winh); @@ -528,6 +527,70 @@ Glib::RefPtr SetBG::make_zoom_fill(const Glib::RefPtr return retval; } +/** + * Handles SET_ZOOM_IMG_FILL mode. + * + * @param orig The original pixbuf + * @param winw Width of the window + * @param winh Height of the window + * @param bgcolor Background color + */ +Glib::RefPtr SetBG::make_zoom_img_fill(const Glib::RefPtr orig, const gint winw, const gint winh, Gdk::Color bgcolor) { + + int x, y, w, h, resx, resy; + + unsigned orig_w = orig->get_width(); + unsigned orig_h = orig->get_height(); + + Glib::RefPtr tmp; + Glib::RefPtr retval = Gdk::Pixbuf::create( + orig->get_colorspace(), orig->get_has_alpha(), + orig->get_bits_per_sample(), winw, winh); + + retval->fill(GdkColorToUint32(bgcolor)); + + // apply the zoom fill image first + x = 0; + w = winw; + h = winw * orig_h / orig_w; + y = (h - winh) / 2; + + if (!(h >= winh)) { + y = 0; + w = winh * orig_w / orig_h; + h = winh; + x = (w - winw) / 2; + } + + tmp = orig->scale_simple(w, h, Gdk::INTERP_BILINEAR); + tmp->copy_area(x, y, winw, winh, retval, 0, 0); + + // apply the zoom image + if ( orig_w > orig_h && ((float)orig_w / (float)orig_h) > ((float)winw / (float)winh)) { + resx = winw; + resy = (int)(((float)(orig->get_height()*resx))/(float)orig->get_width()); + x = 0; + y = (winh - resy) >> 1; + + } else { + resy = winh; + resx = (int)(((float)(orig->get_width()*resy))/(float)orig->get_height()); + y = 0; + x = (winw - resx) >> 1; + + } + + if ( resx > winw ) resx = winw; + if ( resy > winh ) resy = winh; + if ( x < 0 ) x = 0; + if ( y < 0 ) y = 0; + + tmp = orig->scale_simple(resx, resy, Gdk::INTERP_BILINEAR); + tmp->copy_area(0, 0, tmp->get_width(), tmp->get_height(), retval, x, y); + + return retval; +} + /** * Utility function to convert a mode (an enum) to a string. */ @@ -551,6 +614,9 @@ Glib::ustring SetBG::mode_to_string( const SetMode mode ) { case SET_ZOOM_FILL: ret = Glib::ustring(_("ZoomFill")); break; + case SET_ZOOM_IMG_FILL: + ret = Glib::ustring(_("ZoomImgFill")); + break; case SET_AUTO: ret = Glib::ustring(_("Auto")); break; @@ -575,6 +641,8 @@ SetBG::SetMode SetBG::string_to_mode( const Glib::ustring str ) { return SetBG::SET_ZOOM; else if ( str == Glib::ustring(_("ZoomFill")) ) return SetBG::SET_ZOOM_FILL; + else if ( str == Glib::ustring(_("ZoomImgFill")) ) + return SetBG::SET_ZOOM_IMG_FILL; else if ( str == Glib::ustring(_("Auto")) ) return SetBG::SET_AUTO; @@ -824,6 +892,9 @@ Glib::RefPtr SetBG::make_resized_pixbuf(Glib::RefPtr p outpixbuf = SetBG::make_zoom_fill(pixbuf, tarw, tarh, bgcolor); break; + case SetBG::SET_ZOOM_IMG_FILL: + outpixbuf = SetBG::make_zoom_img_fill(pixbuf, tarw, tarh, bgcolor); + default: std::cerr << _("Unknown mode for saved bg") << std::endl; // @TODO: raise exception diff --git a/src/SetBG.h b/src/SetBG.h index 1f57d63..d5debbf 100644 --- a/src/SetBG.h +++ b/src/SetBG.h @@ -47,7 +47,8 @@ class SetBG { SET_CENTER, SET_ZOOM, SET_AUTO, - SET_ZOOM_FILL + SET_ZOOM_FILL, + SET_ZOOM_IMG_FILL, }; enum RootWindowType { @@ -104,6 +105,7 @@ class SetBG { static Glib::RefPtr make_center(const Glib::RefPtr, const gint, const gint, Gdk::Color); static Glib::RefPtr make_zoom(const Glib::RefPtr, const gint, const gint, Gdk::Color); static Glib::RefPtr make_zoom_fill(const Glib::RefPtr, const gint, const gint, Gdk::Color); + static Glib::RefPtr make_zoom_img_fill(const Glib::RefPtr, const gint, const gint, Gdk::Color); static SetMode get_real_mode(const Glib::RefPtr, const gint, const gint); static guint32 GdkColorToUint32(const Gdk::Color);