Cleanup the crop mask (top left border), bring back the crop preview while selecting it, and bring back a clean zooming when the preview doesn't fill the preview area.
This commit is contained in:
@@ -153,6 +153,9 @@ void CropHandler::getPosition (int& x, int& y) {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create the piece of preview image that will be integrally copied in the preview area
|
||||
*/
|
||||
int createpixbufs (void* data) {
|
||||
|
||||
gdk_threads_enter ();
|
||||
@@ -191,9 +194,13 @@ int createpixbufs (void* data) {
|
||||
if (imh>ch->wh)
|
||||
imh = ch->wh;
|
||||
|
||||
// Create a temporary pixbuf to copy the piece of the full size image
|
||||
Glib::RefPtr<Gdk::Pixbuf> tmpPixbuf = Gdk::Pixbuf::create_from_data (ch->cropimg, Gdk::COLORSPACE_RGB, false, 8, ch->cropimg_width, ch->cropimg_height, 3*ch->cropimg_width);
|
||||
// Create the real preview image
|
||||
ch->cropPixbuf = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, false, 8, imw, imh);
|
||||
// Rescale the piece of the full size image and put it in the preview image
|
||||
tmpPixbuf->scale (ch->cropPixbuf, 0, 0, imw, imh, 0, 0, czoom/1000.0, czoom/1000.0, Gdk::INTERP_NEAREST);
|
||||
// Delete the temporary pixbuf
|
||||
tmpPixbuf.clear ();
|
||||
}
|
||||
delete [] ch->cropimg;
|
||||
|
@@ -53,7 +53,7 @@ CropWindow::CropWindow (ImageArea* parent, rtengine::StagedImageProcessor* ipc_)
|
||||
: onResizeArea(false), deleted(false), fitZoomEnabled(true), fitZoom(false),
|
||||
backColor(options.bgcolor), decorated(true), titleHeight(30),
|
||||
sideBorderWidth(3), lowerBorderWidth(3), upperBorderWidth(1), sepWidth(2),
|
||||
imgX(0), imgY(0), imgW(1), imgH(1), xpos(30), ypos(30), iarea(parent),
|
||||
xpos(30), ypos(30), imgX(0), imgY(0), imgW(1), imgH(1), iarea(parent),
|
||||
cropZoom(0), cropgl(NULL), pmlistener(NULL), observedCropWin(NULL) {
|
||||
|
||||
Glib::RefPtr<Pango::Context> context = parent->get_pango_context () ;
|
||||
@@ -307,6 +307,7 @@ void CropWindow::buttonPress (int button, int type, int bstate, int x, int y) {
|
||||
else if (iarea->getToolMode () == TMCropSelect && cropgl) {
|
||||
state = SCropSelecting;
|
||||
translateCoord (x, y, press_x, press_y);
|
||||
cropHandler.cropParams.enabled = true;
|
||||
cropHandler.cropParams.x = press_x;
|
||||
cropHandler.cropParams.y = press_y;
|
||||
cropHandler.cropParams.w = cropHandler.cropParams.h = 1;
|
||||
@@ -588,16 +589,16 @@ void CropWindow::updateCursor (int x, int y) {
|
||||
|
||||
void CropWindow::expose (Cairo::RefPtr<Cairo::Context> cr) {
|
||||
|
||||
MyTime t1, t2, t3, t4;
|
||||
//MyTime t1, t2, t3, t4;
|
||||
|
||||
t1.set ();
|
||||
//t1.set ();
|
||||
|
||||
if (decorated)
|
||||
drawDecoration (cr);
|
||||
|
||||
int x = xpos, y = ypos, h = height, w = width;
|
||||
|
||||
// draw border
|
||||
// draw the background
|
||||
if (backColor==0) {
|
||||
Gdk::Color cback = iarea->get_style()->get_bg(Gtk::STATE_NORMAL);
|
||||
cr->set_source_rgb (cback.get_red_p(), cback.get_green_p(), cback.get_blue_p());
|
||||
@@ -606,8 +607,9 @@ void CropWindow::expose (Cairo::RefPtr<Cairo::Context> cr) {
|
||||
cr->set_source_rgb (0,0,0);
|
||||
else if (backColor==2)
|
||||
cr->set_source_rgb (1,1,1);
|
||||
|
||||
cr->rectangle (x+imgAreaX+0.5, y+imgAreaY+0.5, imgAreaW, imgAreaH);
|
||||
|
||||
cr->set_line_width (0.);
|
||||
cr->rectangle (x+imgAreaX, y+imgAreaY, imgAreaW, imgAreaH);
|
||||
cr->stroke_preserve ();
|
||||
cr->fill ();
|
||||
|
||||
@@ -624,18 +626,20 @@ void CropWindow::expose (Cairo::RefPtr<Cairo::Context> cr) {
|
||||
Glib::RefPtr<Gdk::Pixbuf> rough = iarea->getPreviewHandler()->getRoughImage (cropX, cropY, imgAreaW, imgAreaH, zoomSteps[cropZoom].zoom);
|
||||
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)
|
||||
// if (cropHandler.cropParams.enabled)
|
||||
// drawCrop (cr, x+imgX, y+imgY, imgW, imgH, cropX, cropY, zoomSteps[cropZoom].zoom, cropHandler.cropParams);
|
||||
}
|
||||
if (observedCropWin)
|
||||
drawObservedFrame (cr);
|
||||
}
|
||||
else {
|
||||
else {
|
||||
if (cropHandler.cropPixbuf) {
|
||||
imgW = cropHandler.cropPixbuf->get_width ();
|
||||
imgH = cropHandler.cropPixbuf->get_height ();
|
||||
imgX = imgAreaX + (imgAreaW-imgW)/2;
|
||||
imgY = imgAreaY + (imgAreaH-imgH)/2;
|
||||
// PERFORMANCE BOTTLENECK STARTS HERE
|
||||
t3.set ();
|
||||
//t3.set ();
|
||||
bool showcs = iarea->indClippedPanel->showClippedShadows();
|
||||
bool showch = iarea->indClippedPanel->showClippedHighlights();
|
||||
|
||||
@@ -662,36 +666,36 @@ void CropWindow::expose (Cairo::RefPtr<Cairo::Context> cr) {
|
||||
else if (showcs && (curr[0]<=options.shadowThreshold || curr[1]<=options.shadowThreshold || curr[2]<=options.shadowThreshold))
|
||||
curr[0] = curr[1] = curr[2] = 255;
|
||||
}
|
||||
iarea->get_window()->draw_pixbuf (iarea->get_style()->get_base_gc(Gtk::STATE_NORMAL), tmp, 0, 0, x+imgX, y+imgY, -1, -1, Gdk::RGB_DITHER_NONE, 0, 0);
|
||||
iarea->get_window()->draw_pixbuf (iarea->get_style()->get_base_gc(Gtk::STATE_NORMAL), tmp, 0, 0, x+imgX, y+imgY, -1, -1, Gdk::RGB_DITHER_NONE, 0, 0);
|
||||
}
|
||||
else
|
||||
iarea->get_window()->draw_pixbuf (iarea->get_style()->get_base_gc(Gtk::STATE_NORMAL), cropHandler.cropPixbuf, 0, 0, x+imgX, y+imgY, -1, -1, Gdk::RGB_DITHER_NONE, 0, 0);
|
||||
t4.set ();
|
||||
iarea->get_window()->draw_pixbuf (iarea->get_style()->get_base_gc(Gtk::STATE_NORMAL), cropHandler.cropPixbuf, 0, 0, x+imgX, y+imgY, -1, -1, Gdk::RGB_DITHER_NONE, 0, 0);
|
||||
//t4.set ();
|
||||
// END OF BOTTLENECK
|
||||
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);
|
||||
}
|
||||
if (observedCropWin)
|
||||
drawObservedFrame (cr);
|
||||
}
|
||||
else {
|
||||
// cropHandler.cropPixbuf is null
|
||||
int cropX, cropY;
|
||||
cropHandler.getPosition (cropX, cropY);
|
||||
Glib::RefPtr<Gdk::Pixbuf> rough = iarea->getPreviewHandler()->getRoughImage (cropX, cropY, imgAreaW, imgAreaH, zoomSteps[cropZoom].zoom);
|
||||
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) {
|
||||
int cropX, cropY;
|
||||
cropHandler.getPosition (cropX, cropY);
|
||||
drawCrop (cr, x+imgX, y+imgY, imgW, imgH, cropX, cropY, zoomSteps[cropZoom].zoom, cropHandler.cropParams);
|
||||
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);
|
||||
}
|
||||
if (observedCropWin)
|
||||
drawObservedFrame (cr, rough->get_width(), rough->get_height());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (observedCropWin)
|
||||
drawObservedFrame (cr);
|
||||
|
||||
// if cursor stays above resize area, draw the icon
|
||||
if (decorated && (state==SCropWinResize || onResizeArea)) {
|
||||
int rw = resizeSurface->get_width ();
|
||||
@@ -713,7 +717,7 @@ void CropWindow::expose (Cairo::RefPtr<Cairo::Context> cr) {
|
||||
if (state==SNormal && iarea->getToolMode () == TMSpotWB)
|
||||
drawSpotWBRectangle (cr);
|
||||
|
||||
t2.set ();
|
||||
//t2.set ();
|
||||
cropHandler.cimg.unlock ();
|
||||
// printf ("etime --> %d, %d\n", t2.etime (t1), t4.etime (t3));
|
||||
}
|
||||
@@ -792,11 +796,15 @@ void CropWindow::redrawNeeded (LWButton* button) {
|
||||
|
||||
void CropWindow::changeZoom (int zoom, bool notify, int centerx, int centery) {
|
||||
|
||||
cropZoom = zoom;
|
||||
if (cropZoom<0)
|
||||
cropZoom = 0;
|
||||
else if (cropZoom>MAXZOOMSTEPS)
|
||||
cropZoom = MAXZOOMSTEPS;
|
||||
if (zoom<0)
|
||||
zoom = 0;
|
||||
else if (zoom>MAXZOOMSTEPS)
|
||||
zoom = MAXZOOMSTEPS;
|
||||
if (cropZoom == zoom)
|
||||
// We are already at the start/end of the zoom range, so we do nothing
|
||||
return;
|
||||
else
|
||||
cropZoom = zoom;
|
||||
|
||||
cropLabel = zoomSteps[cropZoom].label;
|
||||
cropHandler.setZoom (zoomSteps[cropZoom].czoom, centerx, centery);
|
||||
@@ -968,24 +976,30 @@ void CropWindow::drawSpotWBRectangle (Cairo::RefPtr<Cairo::Context> cr) {
|
||||
cr->reset_clip ();
|
||||
}
|
||||
|
||||
void CropWindow::getObservedFrameArea (int& x, int& y, int& w, int& h) {
|
||||
|
||||
void CropWindow::getObservedFrameArea (int& x, int& y, int& w, int& h, int rw, int rh) {
|
||||
|
||||
int cropX, cropY, cropW, cropH;
|
||||
observedCropWin->getCropRectangle (cropX, cropY, cropW, cropH);
|
||||
int myCropX, myCropY, myCropW, myCropH;
|
||||
getCropRectangle (myCropX, myCropY, myCropW, myCropH);
|
||||
|
||||
// translate it to screen coordinates
|
||||
x = xpos + imgX + (cropX-myCropX)*zoomSteps[cropZoom].zoom;
|
||||
y = ypos + imgY + (cropY-myCropY)*zoomSteps[cropZoom].zoom;
|
||||
if (rw) {
|
||||
x = xpos + imgAreaX+(imgAreaW-rw)/2 + (cropX-myCropX)*zoomSteps[cropZoom].zoom;
|
||||
y = ypos + imgAreaY+(imgAreaH-rh)/2 + (cropY-myCropY)*zoomSteps[cropZoom].zoom;
|
||||
}
|
||||
else {
|
||||
x = xpos + imgX + (cropX-myCropX)*zoomSteps[cropZoom].zoom;
|
||||
y = ypos + imgY + (cropY-myCropY)*zoomSteps[cropZoom].zoom;
|
||||
}
|
||||
w = cropW * zoomSteps[cropZoom].zoom;
|
||||
h = cropH * zoomSteps[cropZoom].zoom;
|
||||
}
|
||||
|
||||
void CropWindow::drawObservedFrame (Cairo::RefPtr<Cairo::Context> cr) {
|
||||
|
||||
void CropWindow::drawObservedFrame (Cairo::RefPtr<Cairo::Context> cr, int rw, int rh) {
|
||||
|
||||
int x, y, w, h;
|
||||
getObservedFrameArea (x, y, w, h);
|
||||
getObservedFrameArea (x, y, w, h, rw, rh);
|
||||
|
||||
cr->set_source_rgb (1.0, 1.0, 1.0);
|
||||
cr->set_line_width (4);
|
||||
|
@@ -59,11 +59,15 @@ class CropWindow : public LWButtonListener, public CropHandlerListener {
|
||||
int backColor;
|
||||
bool decorated;
|
||||
|
||||
// sizes, positions
|
||||
// crop frame description
|
||||
int titleHeight, sideBorderWidth, lowerBorderWidth, upperBorderWidth, sepWidth, minWidth;
|
||||
int imgAreaX, imgAreaY, imgAreaW, imgAreaH;
|
||||
int imgX, imgY, imgW, imgH;
|
||||
// size & position of the crop relative to the top left corner
|
||||
// of the main preview area (to be confirmed)
|
||||
int xpos, ypos, width, height;
|
||||
// size & pos of the drawable area relative to the top left corner of the crop
|
||||
int imgAreaX, imgAreaY, imgAreaW, imgAreaH;
|
||||
// size & pos of the piece of preview image relative to the top left corner of the crop
|
||||
int imgX, imgY, imgW, imgH;
|
||||
|
||||
// image handling
|
||||
|
||||
@@ -72,7 +76,7 @@ class CropWindow : public LWButtonListener, public CropHandlerListener {
|
||||
|
||||
// crop gui listener
|
||||
CropGUIListener* cropgl;
|
||||
PointerMotionListener* pmlistener;
|
||||
PointerMotionListener* pmlistener;
|
||||
std::list<CropWindowListener*> listeners;
|
||||
|
||||
CropWindow* observedCropWin;
|
||||
@@ -82,10 +86,10 @@ class CropWindow : public LWButtonListener, public CropHandlerListener {
|
||||
void drawDecoration (Cairo::RefPtr<Cairo::Context> cr);
|
||||
void drawStraightenGuide (Cairo::RefPtr<Cairo::Context> cr);
|
||||
void drawSpotWBRectangle (Cairo::RefPtr<Cairo::Context> cr);
|
||||
void drawObservedFrame (Cairo::RefPtr<Cairo::Context> cr);
|
||||
void drawObservedFrame (Cairo::RefPtr<Cairo::Context> cr, int rw=0, int rh=0);
|
||||
void translateCoord (int phyx, int phyy, int& imgx, int& imgy);
|
||||
void changeZoom (int zoom, bool notify=true, int centerx=-1, int centery=-1);
|
||||
void getObservedFrameArea(int& x, int& y, int& w, int& h);
|
||||
void getObservedFrameArea(int& x, int& y, int& w, int& h, int rw=0, int rh=0);
|
||||
|
||||
public:
|
||||
CropHandler cropHandler;
|
||||
|
@@ -75,7 +75,6 @@ void drawCrop (Cairo::RefPtr<Cairo::Context> cr, int imx, int imy, int imw, int
|
||||
|
||||
cr->set_source_rgba (options.cutOverlayBrush[0], options.cutOverlayBrush[1], options.cutOverlayBrush[2], options.cutOverlayBrush[3]);
|
||||
|
||||
// TODO: not sure if this is right. Seems to leave a thin border on the left/top, but might be bug in calling code
|
||||
cr->rectangle (imx, imy, imw, c1y);
|
||||
cr->rectangle (imx, imy+c2y, imw, imh-c2y);
|
||||
cr->rectangle (imx, imy+c1y, c1x, c2y-c1y+1);
|
||||
|
Reference in New Issue
Block a user