diff --git a/rtdata/languages/default b/rtdata/languages/default index db5063bcf..b3ac130cb 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1201,12 +1201,11 @@ TP_CROP_GTDIAGONALS;Rule of Diagonals TP_CROP_GTEPASSPORT;Biometric Passport TP_CROP_GTFRAME;Frame TP_CROP_GTGRID;Grid -TP_CROP_GTHARMMEANS1;Harmonic Means 1 -TP_CROP_GTHARMMEANS2;Harmonic Means 2 -TP_CROP_GTHARMMEANS3;Harmonic Means 3 -TP_CROP_GTHARMMEANS4;Harmonic Means 4 +TP_CROP_GTHARMMEANS;Harmonic Means TP_CROP_GTNONE;None TP_CROP_GTRULETHIRDS;Rule of Thirds +TP_CROP_GTTRIANGLE1;Golden Triangles 1 +TP_CROP_GTTRIANGLE2;Golden Triangles 2 TP_CROP_GUIDETYPE;Guide type: TP_CROP_H;Height TP_CROP_LABEL;Crop diff --git a/rtgui/crop.cc b/rtgui/crop.cc index 489bcde11..dc1e88f0f 100644 --- a/rtgui/crop.cc +++ b/rtgui/crop.cc @@ -174,11 +174,10 @@ Crop::Crop (): FoldableToolPanel(this, "crop", M("TP_CROP_LABEL"), false, true) guide->append_text (M("TP_CROP_GTFRAME")); guide->append_text (M("TP_CROP_GTRULETHIRDS")); guide->append_text (M("TP_CROP_GTDIAGONALS")); - guide->append_text (M("TP_CROP_GTHARMMEANS1")); - guide->append_text (M("TP_CROP_GTHARMMEANS2")); - guide->append_text (M("TP_CROP_GTHARMMEANS3")); - guide->append_text (M("TP_CROP_GTHARMMEANS4")); + guide->append_text (M("TP_CROP_GTHARMMEANS")); guide->append_text (M("TP_CROP_GTGRID")); + guide->append_text (M("TP_CROP_GTTRIANGLE1")); + guide->append_text (M("TP_CROP_GTTRIANGLE2")); guide->append_text (M("TP_CROP_GTEPASSPORT")); guide->set_active (0); @@ -277,18 +276,16 @@ void Crop::read (const ProcParams* pp, const ParamsEdited* pedited) { guide->set_active (2); else if (pp->crop.guide == "Rule of diagonals") guide->set_active (3); - else if (pp->crop.guide == "Harmonic means 1") + else if (!strncmp(pp->crop.guide.data(),"Harmonic means",14)) guide->set_active (4); - else if (pp->crop.guide == "Harmonic means 2") - guide->set_active (5); - else if (pp->crop.guide == "Harmonic means 3") - guide->set_active (6); - else if (pp->crop.guide == "Harmonic means 4") - guide->set_active (7); else if (pp->crop.guide == "Grid") - guide->set_active (8); + guide->set_active (5); + else if (pp->crop.guide == "Golden Triangle 1") + guide->set_active (6); + else if (pp->crop.guide == "Golden Triangle 2") + guide->set_active (7); else if (pp->crop.guide == "ePassport") - guide->set_active (9); + guide->set_active (8); x->set_value (pp->crop.x); y->set_value (pp->crop.y); @@ -362,16 +359,14 @@ void Crop::write (ProcParams* pp, ParamsEdited* pedited) { else if (guide->get_active_row_number()==3) pp->crop.guide = "Rule of diagonals"; else if (guide->get_active_row_number()==4) - pp->crop.guide = "Harmonic means 1"; + pp->crop.guide = "Harmonic means"; else if (guide->get_active_row_number()==5) - pp->crop.guide = "Harmonic means 2"; - else if (guide->get_active_row_number()==6) - pp->crop.guide = "Harmonic means 3"; - else if (guide->get_active_row_number()==7) - pp->crop.guide = "Harmonic means 4"; - else if (guide->get_active_row_number()==8) pp->crop.guide = "Grid"; - else if (guide->get_active_row_number()==9) + else if (guide->get_active_row_number()==6) + pp->crop.guide = "Golden Triangle 1"; + else if (guide->get_active_row_number()==7) + pp->crop.guide = "Golden Triangle 2"; + else if (guide->get_active_row_number()==8) pp->crop.guide = "ePassport"; if (pedited) { diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc index c52666244..449215e58 100755 --- a/rtgui/cropwindow.cc +++ b/rtgui/cropwindow.cc @@ -1302,7 +1302,7 @@ void CropWindow::expose (Cairo::RefPtr cr) { if (cropHandler.cropParams.enabled) { int cropX, cropY; cropHandler.getPosition (cropX, cropY); - drawCrop (cr, x+imgX, y+imgY, imgW, imgH, cropX, cropY, zoomSteps[cropZoom].zoom, cropHandler.cropParams,(this == iarea->mainCropWindow)); + drawCrop (cr, x+imgX, y+imgY, imgW, imgH, cropX, cropY, zoomSteps[cropZoom].zoom, cropHandler.cropParams,(this == iarea->mainCropWindow), true, zoomSteps[cropZoom].zoom <= cropHandler.getFitZoom() ); } if (observedCropWin) drawObservedFrame (cr); @@ -1407,7 +1407,7 @@ void CropWindow::expose (Cairo::RefPtr cr) { if (rough) { iarea->get_window()->draw_pixbuf (iarea->get_style()->get_base_gc(Gtk::STATE_NORMAL), rough, 0, 0, x+imgAreaX+(imgAreaW-rough->get_width())/2, y+imgAreaY+(imgAreaH-rough->get_height())/2, -1, -1, Gdk::RGB_DITHER_NORMAL, 0, 0); if (cropHandler.cropParams.enabled) { - drawCrop (cr, x+imgAreaX+(imgAreaW-rough->get_width())/2, y+imgAreaY+(imgAreaH-rough->get_height())/2, rough->get_width(), rough->get_height(), cropX, cropY, zoomSteps[cropZoom].zoom, cropHandler.cropParams, (this == iarea->mainCropWindow)); + drawCrop (cr, x+imgAreaX+(imgAreaW-rough->get_width())/2, y+imgAreaY+(imgAreaH-rough->get_height())/2, rough->get_width(), rough->get_height(), cropX, cropY, zoomSteps[cropZoom].zoom, cropHandler.cropParams, (this == iarea->mainCropWindow), true, zoomSteps[cropZoom].zoom <= cropHandler.getFitZoom()); } if (observedCropWin) drawObservedFrame (cr, rough->get_width(), rough->get_height()); diff --git a/rtgui/filebrowserentry.cc b/rtgui/filebrowserentry.cc index 7953bb327..33e948085 100644 --- a/rtgui/filebrowserentry.cc +++ b/rtgui/filebrowserentry.cc @@ -122,14 +122,15 @@ std::vector > FileBrowserEntry::getIconsOnImageArea () } void FileBrowserEntry::customBackBufferUpdate (Cairo::RefPtr c) { - - if (state==SCropSelecting || state==SResizeH1 || state==SResizeH2 || state==SResizeW1 || state==SResizeW2 || state==SResizeTL || state==SResizeTR || state==SResizeBL || state==SResizeBR || state==SCropMove) - drawCrop (c, prex, prey, prew, preh, 0, 0, scale, cropParams); - else { - rtengine::procparams::CropParams cparams = thumbnail->getProcParams().crop; - if (cparams.enabled && !thumbnail->isQuick()) // Quick thumb have arbitrary sizes, so don't apply the crop - drawCrop (c, prex, prey, prew, preh, 0, 0, scale, cparams); - } + if(scale != 1.0 && cropParams.enabled) { // somewhere in pipeline customBackBufferUpdate is called when scale == 1.0, which is nonsense for a thumb + if (state==SCropSelecting || state==SResizeH1 || state==SResizeH2 || state==SResizeW1 || state==SResizeW2 || state==SResizeTL || state==SResizeTR || state==SResizeBL || state==SResizeBR || state==SCropMove) + drawCrop (c, prex, prey, prew, preh, 0, 0, scale, cropParams, true, false); + else { + rtengine::procparams::CropParams cparams = thumbnail->getProcParams().crop; + if (cparams.enabled && !thumbnail->isQuick()) // Quick thumb have arbitrary sizes, so don't apply the crop + drawCrop (c, prex, prey, prew, preh, 0, 0, scale, cparams, true, false); + } + } } void FileBrowserEntry::getIconSize (int& w, int& h) { diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index 452e48e63..9835246a2 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -133,20 +133,19 @@ void writeFailed (Gtk::Window& parent, const std::string& filename) { msgd.run (); } -void drawCrop (Cairo::RefPtr cr, int imx, int imy, int imw, int imh, int startx, int starty, double scale, const rtengine::procparams::CropParams& cparams, bool drawGuide) { +void drawCrop (Cairo::RefPtr cr, int imx, int imy, int imw, int imh, int startx, int starty, double scale, const rtengine::procparams::CropParams& cparams, bool drawGuide, bool useBgColor, bool fullImageVisible) { cr->set_line_width (0.); cr->rectangle (imx, imy, imw, imh); cr->clip (); - + double c1x = (cparams.x-startx)*scale; double c1y = (cparams.y-starty)*scale; - double c2x = (cparams.x+cparams.w-1-startx)*scale; - double c2y = (cparams.y+cparams.h-1-starty)*scale; - + double c2x = (cparams.x+cparams.w-startx)*scale - (fullImageVisible ? 0.0 : 1.0); + double c2y = (cparams.y+cparams.h-starty)*scale - (fullImageVisible ? 0.0 : 1.0); // crop overlay color, linked with crop windows background - if (options.bgcolor==0) - cr->set_source_rgba (options.cutOverlayBrush[0], options.cutOverlayBrush[1], options.cutOverlayBrush[2], options.cutOverlayBrush[3]); + if (options.bgcolor==0 || !useBgColor) + cr->set_source_rgba (options.cutOverlayBrush[0], options.cutOverlayBrush[1], options.cutOverlayBrush[2], options.cutOverlayBrush[3]); else if (options.bgcolor==1) cr->set_source_rgb (0,0,0); else if (options.bgcolor==2) @@ -163,8 +162,14 @@ void drawCrop (Cairo::RefPtr cr, int imx, int imy, int imw, int if (cparams.guide!="None" && drawGuide) { double rectx1 = round(c1x) + imx + 0.5; double recty1 = round(c1y) + imy + 0.5; - double rectx2 = min(round(c2x) + imx + 0.5, imx+imw-0.5); - double recty2 = min(round(c2y) + imy + 0.5, imy+imh-0.5); + double rectx2 = round(c2x) + imx + 0.5; + double recty2 = round(c2y) + imy + 0.5; + + if(fullImageVisible) { + rectx2 = min(rectx2, imx+imw-0.5); + recty2 = min(recty2, imy+imh-0.5); + } + cr->set_line_width (1.0); cr->set_source_rgba (1.0, 1.0, 1.0, 0.618); cr->move_to (rectx1, recty1); @@ -186,7 +191,7 @@ void drawCrop (Cairo::RefPtr cr, int imx, int imy, int imw, int ds.resize (0); cr->set_dash (ds, 0); - if (cparams.guide!="Rule of diagonals") { + if (cparams.guide!="Rule of diagonals" && cparams.guide!="Golden Triangle 1" && cparams.guide!="Golden Triangle 2") { // draw guide lines std::vector horiz_ratios; std::vector vert_ratios; @@ -197,22 +202,12 @@ void drawCrop (Cairo::RefPtr cr, int imx, int imy, int imw, int vert_ratios.push_back (1.0/3.0); vert_ratios.push_back (2.0/3.0); } - else if (cparams.guide=="Harmonic means 1") { + else if (!strncmp(cparams.guide.data(),"Harmonic means",14)) { horiz_ratios.push_back (1.0-0.618); - vert_ratios.push_back (1.0-0.618); - } - else if (cparams.guide=="Harmonic means 2") { - horiz_ratios.push_back (0.618); - vert_ratios.push_back (1.0-0.618); - } - else if (cparams.guide=="Harmonic means 3") { - horiz_ratios.push_back (1.0-0.618); - vert_ratios.push_back (0.618); - } - else if (cparams.guide=="Harmonic means 4") { horiz_ratios.push_back (0.618); vert_ratios.push_back (0.618); - } + vert_ratios.push_back (1.0-0.618); + } else if (cparams.guide=="Grid") { // To have even distribution, normalize it a bit const int longSideNumLines=10; @@ -277,7 +272,7 @@ void drawCrop (Cairo::RefPtr cr, int imx, int imy, int imw, int cr->set_dash (ds, 0); } } - else { + else if (cparams.guide=="Rule of diagonals") { double corners_from[4][2]; double corners_to[4][2]; int mindim = min(rectx2-rectx1, recty2-recty1); @@ -312,6 +307,64 @@ void drawCrop (Cairo::RefPtr cr, int imx, int imy, int imw, int ds.resize (0); cr->set_dash (ds, 0); } + } else if (cparams.guide=="Golden Triangle 1" || cparams.guide=="Golden Triangle 2") { + // main diagonal + if(cparams.guide=="Golden Triangle 2") { + std:swap(rectx1,rectx2); + } + cr->set_source_rgba (1.0, 1.0, 1.0, 0.618); + cr->move_to (rectx1, recty1); + cr->line_to (rectx2, recty2); + cr->stroke (); + cr->set_source_rgba (0.0, 0.0, 0.0, 0.618); + std::valarray ds (1); + ds[0] = 4; + cr->set_dash (ds, 0); + cr->move_to (rectx1, recty1); + cr->line_to (rectx2, recty2); + cr->stroke (); + ds.resize (0); + cr->set_dash (ds, 0); + + double height = recty2 - recty1; + double width = rectx2 - rectx1; + double d = sqrt(height*height + width*width); + double alpha = asin(width/d); + double beta = asin(height/d); + double a = sin(beta) * height; + double b = sin(alpha) * height; + + double x = (a*b)/height; + double y = height - (b*(d-a))/width; + cr->set_source_rgba (1.0, 1.0, 1.0, 0.618); + cr->move_to (rectx1, recty2); + cr->line_to (rectx1+x, recty1+y); + cr->stroke (); + cr->set_source_rgba (0.0, 0.0, 0.0, 0.618); + ds.resize (1); + ds[0] = 4; + cr->set_dash (ds, 0); + cr->move_to (rectx1, recty2); + cr->line_to (rectx1+x, recty1+y); + cr->stroke (); + ds.resize (0); + cr->set_dash (ds, 0); + + x = width - (a*b)/height; + y = (b*(d-a))/width; + cr->set_source_rgba (1.0, 1.0, 1.0, 0.618); + cr->move_to (rectx2, recty1); + cr->line_to (rectx1+x, recty1+y); + cr->stroke (); + cr->set_source_rgba (0.0, 0.0, 0.0, 0.618); + ds.resize (1); + ds[0] = 4; + cr->set_dash (ds, 0); + cr->move_to (rectx2, recty1); + cr->line_to (rectx1+x, recty1+y); + cr->stroke (); + ds.resize (0); + cr->set_dash (ds, 0); } } cr->reset_clip (); diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index e7bab70e4..0511c8980 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -31,7 +31,7 @@ Glib::ustring removeExtension (const Glib::ustring& filename); Glib::ustring getExtension (const Glib::ustring& filename); bool confirmOverwrite (Gtk::Window& parent, const std::string& filename); void writeFailed (Gtk::Window& parent, const std::string& filename); -void drawCrop (Cairo::RefPtr cr, int imx, int imy, int imw, int imh, int startx, int starty, double scale, const rtengine::procparams::CropParams& cparams, bool drawGuide = true); +void drawCrop (Cairo::RefPtr cr, int imx, int imy, int imw, int imh, int startx, int starty, double scale, const rtengine::procparams::CropParams& cparams, bool drawGuide = true, bool useBgColor = true, bool fullImageVisible = true); /** * @brief Lock GTK for critical section. diff --git a/rtgui/previewwindow.cc b/rtgui/previewwindow.cc index cced2380b..fac3af502 100644 --- a/rtgui/previewwindow.cc +++ b/rtgui/previewwindow.cc @@ -63,7 +63,7 @@ void PreviewWindow::updatePreviewImage () { backBuffer->draw_pixbuf (get_style()->get_base_gc(Gtk::STATE_NORMAL), resPixbuf, 0, 0, imgX, imgY, -1, -1, Gdk::RGB_DITHER_NONE, 0, 0); Cairo::RefPtr cr = backBuffer->create_cairo_context(); if (previewHandler->getCropParams().enabled) - drawCrop (cr, imgX, imgY, imgW, imgH, 0, 0, zoom, previewHandler->getCropParams()); + drawCrop (cr, imgX, imgY, imgW, imgH, 0, 0, zoom, previewHandler->getCropParams(), true, false); } } }