From 674cdb93be3b607e2b72f526a7ceb38d9cdf5da0 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Thu, 16 Mar 2017 23:32:02 +0100 Subject: [PATCH] improved "zoom to fit" functionality - fix regression in image quality for the previous zoom levels - ignore the finer-grained zoom levels when zooming manually (either with the scroll wheel or with the buttons), but use them only only for zoom to fit --- rtgui/crophandler.cc | 21 ++++++++++----------- rtgui/cropwindow.cc | 39 +++++++++++++++++++-------------------- rtgui/cropwindow.h | 6 ++++-- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/rtgui/crophandler.cc b/rtgui/crophandler.cc index 28be67705..4b010d387 100644 --- a/rtgui/crophandler.cc +++ b/rtgui/crophandler.cc @@ -176,8 +176,8 @@ void CropHandler::setZoom (int z, int centerx, int centery) cw = ww * 1000 / zoom; ch = wh * 1000 / zoom; } else { - cw = ww * zoom / 10; - ch = wh * zoom / 10; + cw = ww * (zoom / 10); + ch = wh * (zoom / 10); } cx = cax - cw / 2; @@ -221,8 +221,8 @@ void CropHandler::setWSize (int w, int h) cw = ww * 1000 / zoom; ch = wh * 1000 / zoom; } else { - cw = ww * zoom/10; - ch = wh * zoom/10; + cw = ww * (zoom / 10); + ch = wh * (zoom / 10); } compDim (); @@ -320,7 +320,7 @@ void CropHandler::setDetailedCrop (IImage8* im, IImage8* imtrue, rtengine::procp cropimgtrue = nullptr; - if (ax == cropX && ay == cropY && aw == cropW && ah == cropH && askip == (zoom >= 1000 ? 1 : zoom/10)) { + if (ax == cropX && ay == cropY && aw == cropW && ah == cropH && askip == (zoom >= 1000 ? 1 : zoom / 10)) { cropimg_width = im->getWidth (); cropimg_height = im->getHeight (); cropimg = new unsigned char [3 * cropimg_width * cropimg_height]; @@ -362,14 +362,13 @@ void CropHandler::setDetailedCrop (IImage8* im, IImage8* imtrue, rtengine::procp } if (ch->cropimg) { - if (ch->cix == ch->cropX && ch->ciy == ch->cropY && ch->ciw == ch->cropW && ch->cih == ch->cropH && ch->cis == (ch->zoom >= 1000 ? 1 : ch->zoom/10)) { + if (ch->cix == ch->cropX && ch->ciy == ch->cropY && ch->ciw == ch->cropW && ch->cih == ch->cropH && ch->cis == (ch->zoom >= 1000 ? 1 : ch->zoom / 10)) { // calculate final image size - //int czoom = ch->zoom < 1000 ? 1000 : ch->zoom; float czoom = ch->zoom >= 1000 ? ch->zoom / 1000.f : float((ch->zoom/10) * 10) / float(ch->zoom); - int imw = ch->cropimg_width * czoom;// / 1000; - int imh = ch->cropimg_height * czoom;// / 1000; + int imw = ch->cropimg_width * czoom; + int imh = ch->cropimg_height * czoom; if (imw > ch->ww) { imw = ch->ww; @@ -381,12 +380,12 @@ void CropHandler::setDetailedCrop (IImage8* im, IImage8* imtrue, rtengine::procp Glib::RefPtr tmpPixbuf = Gdk::Pixbuf::create_from_data (ch->cropimg, Gdk::COLORSPACE_RGB, false, 8, ch->cropimg_width, 2 * ch->cropimg_height, 3 * ch->cropimg_width); ch->cropPixbuf = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, false, 8, imw, imh); - tmpPixbuf->scale (ch->cropPixbuf, 0, 0, imw, imh, 0, 0, czoom /* / 1000.0*/, czoom /* / 1000.0*/, Gdk::INTERP_NEAREST); + tmpPixbuf->scale (ch->cropPixbuf, 0, 0, imw, imh, 0, 0, czoom, czoom, Gdk::INTERP_NEAREST); tmpPixbuf.clear (); Glib::RefPtr tmpPixbuftrue = Gdk::Pixbuf::create_from_data (ch->cropimgtrue, Gdk::COLORSPACE_RGB, false, 8, ch->cropimg_width, 2 * ch->cropimg_height, 3 * ch->cropimg_width); ch->cropPixbuftrue = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, false, 8, imw, imh); - tmpPixbuftrue->scale (ch->cropPixbuftrue, 0, 0, imw, imh, 0, 0, czoom /* / 1000.0*/, czoom /* / 1000.0*/, Gdk::INTERP_NEAREST); + tmpPixbuftrue->scale (ch->cropPixbuftrue, 0, 0, imw, imh, 0, 0, czoom, czoom, Gdk::INTERP_NEAREST); tmpPixbuftrue.clear (); } diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc index 412851dde..996ec33f7 100644 --- a/rtgui/cropwindow.cc +++ b/rtgui/cropwindow.cc @@ -93,31 +93,22 @@ CropWindow::~CropWindow () void CropWindow::initZoomSteps() { - zoomSteps.push_back(ZoomStep(" 1%", 0.01, 999)); - zoomSteps.push_back(ZoomStep(" 2%", 0.02, 500)); - zoomSteps.push_back(ZoomStep(" 5%", 0.05, 200)); - zoomSteps.push_back(ZoomStep(" 6%", 1.0/15.0, 150)); - zoomSteps.push_back(ZoomStep(" 8%", 1.0/12.0, 120)); + zoomSteps.push_back(ZoomStep(" 1%", 0.01, 999, true)); + zoomSteps.push_back(ZoomStep(" 2%", 0.02, 500, true)); + zoomSteps.push_back(ZoomStep(" 5%", 0.05, 200, true)); + zoomSteps.push_back(ZoomStep(" 6%", 1.0/15.0, 150, true)); + zoomSteps.push_back(ZoomStep(" 8%", 1.0/12.0, 120, true)); char lbl[64]; - for (int s = 100; s >= 50; s -= 5) { + for (int s = 100; s >= 11; --s) { float z = 10./float(s); sprintf(lbl, "% 2d%%", int(z * 100)); - zoomSteps.push_back(ZoomStep(lbl, z, s)); - } - for (int s = 45; s >= 27; s -= 3) { - float z = 10./float(s); - sprintf(lbl, "% 2d%%", int(z * 100)); - zoomSteps.push_back(ZoomStep(lbl, z, s)); - } - for (int s = 25; s >= 11; --s) { - float z = 10./float(s); - sprintf(lbl, "% 2d%%", int(z * 100)); - zoomSteps.push_back(ZoomStep(lbl, z, s)); + bool is_major = (s == s/10 * 10); + zoomSteps.push_back(ZoomStep(lbl, z, s, is_major)); } zoom11index = zoomSteps.size(); for (int s = 1; s <= 8; ++s) { sprintf(lbl, "%d00%%", s); - zoomSteps.push_back(ZoomStep(lbl, s, s * 1000)); + zoomSteps.push_back(ZoomStep(lbl, s, s * 1000, true)); } } @@ -1928,7 +1919,11 @@ void CropWindow::zoomIn (bool toCursor, int cursorX, int cursorY) } } - changeZoom (cropZoom + 1, true, x, y); + int z = cropZoom + 1; + while (z < int(zoomSteps.size()) && !zoomSteps[z].is_major) { + ++z; + } + changeZoom (z, true, x, y); fitZoom = false; } @@ -1944,7 +1939,11 @@ void CropWindow::zoomOut (bool toCursor, int cursorX, int cursorY) } zoomVersion = exposeVersion; - changeZoom (cropZoom - 1, true, x, y); + int z = cropZoom - 1; + while (z >= 0 && !zoomSteps[z].is_major) { + --z; + } + changeZoom (z, true, x, y); fitZoom = false; } diff --git a/rtgui/cropwindow.h b/rtgui/cropwindow.h index 935928b88..66b6405c5 100644 --- a/rtgui/cropwindow.h +++ b/rtgui/cropwindow.h @@ -118,9 +118,11 @@ class CropWindow : public LWButtonListener, public CropDisplayHandler, public Ed Glib::ustring label; double zoom; int czoom; + bool is_major; - explicit ZoomStep(const Glib::ustring &l="", double z=0.0, int cz=0): - label(l), zoom(z), czoom(cz) {} + explicit ZoomStep(const Glib::ustring &l="", double z=0.0, + int cz=0, bool m=false): + label(l), zoom(z), czoom(cz), is_major(m) {} }; std::vector zoomSteps; size_t zoom11index;