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:
Hombre
2011-01-19 03:48:55 +01:00
parent 86e0660125
commit eb793cb46a
4 changed files with 62 additions and 38 deletions

View File

@@ -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;

View File

@@ -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());
@@ -607,7 +608,8 @@ void CropWindow::expose (Cairo::RefPtr<Cairo::Context> cr) {
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 ();
@@ -627,6 +629,8 @@ void CropWindow::expose (Cairo::RefPtr<Cairo::Context> cr) {
// if (cropHandler.cropParams.enabled)
// drawCrop (cr, x+imgX, y+imgY, imgW, imgH, cropX, cropY, zoomSteps[cropZoom].zoom, cropHandler.cropParams);
}
if (observedCropWin)
drawObservedFrame (cr);
}
else {
if (cropHandler.cropPixbuf) {
@@ -635,7 +639,7 @@ void CropWindow::expose (Cairo::RefPtr<Cairo::Context> cr) {
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();
@@ -666,32 +670,32 @@ void CropWindow::expose (Cairo::RefPtr<Cairo::Context> cr) {
}
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 ();
//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,7 +976,7 @@ 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);
@@ -976,16 +984,22 @@ void CropWindow::getObservedFrameArea (int& x, int& y, int& w, int& h) {
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);

View File

@@ -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;

View File

@@ -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);