cropwindow: use a stateful custom crop ratio to avoid imprecision due to intermediate rounding

See the comments by @heckflosse in #1489
This commit is contained in:
Alberto Griggio
2017-04-13 21:41:03 +02:00
parent 594b78118b
commit 68e7c5ce23
2 changed files with 17 additions and 11 deletions

View File

@@ -40,7 +40,8 @@ CropWindow::CropWindow (ImageArea* parent, bool isLowUpdatePriority_, bool isDet
backColor(options.bgcolor), decorated(true), isFlawnOver(false), titleHeight(30), sideBorderWidth(3), lowerBorderWidth(3), backColor(options.bgcolor), decorated(true), isFlawnOver(false), titleHeight(30), sideBorderWidth(3), lowerBorderWidth(3),
upperBorderWidth(1), sepWidth(2), xpos(30), ypos(30), width(0), height(0), imgAreaX(0), imgAreaY(0), imgAreaW(0), imgAreaH(0), upperBorderWidth(1), sepWidth(2), xpos(30), ypos(30), width(0), height(0), imgAreaX(0), imgAreaY(0), imgAreaW(0), imgAreaH(0),
imgX(-1), imgY(-1), imgW(1), imgH(1), iarea(parent), cropZoom(0), zoomVersion(0), exposeVersion(0), cropgl(nullptr), imgX(-1), imgY(-1), imgW(1), imgH(1), iarea(parent), cropZoom(0), zoomVersion(0), exposeVersion(0), cropgl(nullptr),
pmlistener(nullptr), pmhlistener(nullptr), observedCropWin(nullptr) pmlistener(nullptr), pmhlistener(nullptr), observedCropWin(nullptr),
crop_custom_ratio(0.f)
{ {
initZoomSteps(); initZoomSteps();
@@ -337,6 +338,11 @@ void CropWindow::buttonPress (int button, int type, int bstate, int x, int y)
press_y = height; press_y = height;
} else { } else {
if (onArea (CropImage, x, y)) { // events inside of the image domain if (onArea (CropImage, x, y)) { // events inside of the image domain
crop_custom_ratio = 0.f;
if ((bstate & GDK_SHIFT_MASK) && cropHandler.cropParams.w > 0 && cropHandler.cropParams.h > 0) {
crop_custom_ratio = float(cropHandler.cropParams.w) / float(cropHandler.cropParams.h);
}
if (iarea->getToolMode () == TMColorPicker) { if (iarea->getToolMode () == TMColorPicker) {
if (hoveredPicker) { if (hoveredPicker) {
if ((bstate & GDK_CONTROL_MASK) && !(bstate & GDK_SHIFT_MASK)) { if ((bstate & GDK_CONTROL_MASK) && !(bstate & GDK_SHIFT_MASK)) {
@@ -759,8 +765,6 @@ void CropWindow::pointerMoved (int bstate, int x, int y)
EditSubscriber *editSubscriber = iarea->getCurrSubscriber(); EditSubscriber *editSubscriber = iarea->getCurrSubscriber();
float cur_crop_ratio = (bstate & GDK_SHIFT_MASK) && cropHandler.cropParams.w > 0 && cropHandler.cropParams.h > 0 ? float(cropHandler.cropParams.w) / float(cropHandler.cropParams.h) : 0.0;
if (state == SCropWinMove) { if (state == SCropWinMove) {
setPosition (press_x + x - action_x, press_y + y - action_y); setPosition (press_x + x - action_x, press_y + y - action_y);
iarea->redraw (); iarea->redraw ();
@@ -809,21 +813,21 @@ void CropWindow::pointerMoved (int bstate, int x, int y)
int oy = cropHandler.cropParams.y; int oy = cropHandler.cropParams.y;
cropHandler.cropParams.y = action_y + (y - press_y) / zoomSteps[cropZoom].zoom; cropHandler.cropParams.y = action_y + (y - press_y) / zoomSteps[cropZoom].zoom;
cropHandler.cropParams.h += oy - cropHandler.cropParams.y; cropHandler.cropParams.h += oy - cropHandler.cropParams.y;
cropgl->cropHeight1Resized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h, cur_crop_ratio); cropgl->cropHeight1Resized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h, crop_custom_ratio);
iarea->redraw (); iarea->redraw ();
} else if (state == SResizeH2 && cropgl) { } else if (state == SResizeH2 && cropgl) {
cropHandler.cropParams.h = action_y + (y - press_y) / zoomSteps[cropZoom].zoom; cropHandler.cropParams.h = action_y + (y - press_y) / zoomSteps[cropZoom].zoom;
cropgl->cropHeight2Resized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h, cur_crop_ratio); cropgl->cropHeight2Resized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h, crop_custom_ratio);
iarea->redraw (); iarea->redraw ();
} else if (state == SResizeW1 && cropgl) { } else if (state == SResizeW1 && cropgl) {
int ox = cropHandler.cropParams.x; int ox = cropHandler.cropParams.x;
cropHandler.cropParams.x = action_x + (x - press_x) / zoomSteps[cropZoom].zoom; cropHandler.cropParams.x = action_x + (x - press_x) / zoomSteps[cropZoom].zoom;
cropHandler.cropParams.w += ox - cropHandler.cropParams.x; cropHandler.cropParams.w += ox - cropHandler.cropParams.x;
cropgl->cropWidth1Resized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h, cur_crop_ratio); cropgl->cropWidth1Resized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h, crop_custom_ratio);
iarea->redraw (); iarea->redraw ();
} else if (state == SResizeW2 && cropgl) { } else if (state == SResizeW2 && cropgl) {
cropHandler.cropParams.w = action_x + (x - press_x) / zoomSteps[cropZoom].zoom; cropHandler.cropParams.w = action_x + (x - press_x) / zoomSteps[cropZoom].zoom;
cropgl->cropWidth2Resized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h, cur_crop_ratio); cropgl->cropWidth2Resized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h, crop_custom_ratio);
iarea->redraw (); iarea->redraw ();
} else if (state == SResizeTL && cropgl) { } else if (state == SResizeTL && cropgl) {
int ox = cropHandler.cropParams.x; int ox = cropHandler.cropParams.x;
@@ -832,26 +836,26 @@ void CropWindow::pointerMoved (int bstate, int x, int y)
int oy = cropHandler.cropParams.y; int oy = cropHandler.cropParams.y;
cropHandler.cropParams.y = action_y + (y - press_y) / zoomSteps[cropZoom].zoom; cropHandler.cropParams.y = action_y + (y - press_y) / zoomSteps[cropZoom].zoom;
cropHandler.cropParams.h += oy - cropHandler.cropParams.y; cropHandler.cropParams.h += oy - cropHandler.cropParams.y;
cropgl->cropTopLeftResized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h, cur_crop_ratio); cropgl->cropTopLeftResized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h, crop_custom_ratio);
iarea->redraw (); iarea->redraw ();
} else if (state == SResizeTR && cropgl) { } else if (state == SResizeTR && cropgl) {
cropHandler.cropParams.w = action_x + (x - press_x) / zoomSteps[cropZoom].zoom; cropHandler.cropParams.w = action_x + (x - press_x) / zoomSteps[cropZoom].zoom;
int oy = cropHandler.cropParams.y; int oy = cropHandler.cropParams.y;
cropHandler.cropParams.y = action_y + (y - press_y) / zoomSteps[cropZoom].zoom; cropHandler.cropParams.y = action_y + (y - press_y) / zoomSteps[cropZoom].zoom;
cropHandler.cropParams.h += oy - cropHandler.cropParams.y; cropHandler.cropParams.h += oy - cropHandler.cropParams.y;
cropgl->cropTopRightResized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h, cur_crop_ratio); cropgl->cropTopRightResized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h, crop_custom_ratio);
iarea->redraw (); iarea->redraw ();
} else if (state == SResizeBL && cropgl) { } else if (state == SResizeBL && cropgl) {
int ox = cropHandler.cropParams.x; int ox = cropHandler.cropParams.x;
cropHandler.cropParams.x = action_x + (x - press_x) / zoomSteps[cropZoom].zoom; cropHandler.cropParams.x = action_x + (x - press_x) / zoomSteps[cropZoom].zoom;
cropHandler.cropParams.w += ox - cropHandler.cropParams.x; cropHandler.cropParams.w += ox - cropHandler.cropParams.x;
cropHandler.cropParams.h = action_y + (y - press_y) / zoomSteps[cropZoom].zoom; cropHandler.cropParams.h = action_y + (y - press_y) / zoomSteps[cropZoom].zoom;
cropgl->cropBottomLeftResized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h, cur_crop_ratio); cropgl->cropBottomLeftResized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h, crop_custom_ratio);
iarea->redraw (); iarea->redraw ();
} else if (state == SResizeBR && cropgl) { } else if (state == SResizeBR && cropgl) {
cropHandler.cropParams.w = action_x + (x - press_x) / zoomSteps[cropZoom].zoom; cropHandler.cropParams.w = action_x + (x - press_x) / zoomSteps[cropZoom].zoom;
cropHandler.cropParams.h = action_y + (y - press_y) / zoomSteps[cropZoom].zoom; cropHandler.cropParams.h = action_y + (y - press_y) / zoomSteps[cropZoom].zoom;
cropgl->cropBottomRightResized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h, cur_crop_ratio); cropgl->cropBottomRightResized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h, crop_custom_ratio);
iarea->redraw (); iarea->redraw ();
} else if (state == SCropMove && cropgl) { } else if (state == SCropMove && cropgl) {
cropHandler.cropParams.x = action_x + (x - press_x) / zoomSteps[cropZoom].zoom; cropHandler.cropParams.x = action_x + (x - press_x) / zoomSteps[cropZoom].zoom;

View File

@@ -97,6 +97,8 @@ class CropWindow : public LWButtonListener, public CropDisplayHandler, public Ed
CropWindow* observedCropWin; // Pointer to the currently active detail CropWindow CropWindow* observedCropWin; // Pointer to the currently active detail CropWindow
float crop_custom_ratio;
bool onArea (CursorArea a, int x, int y); bool onArea (CursorArea a, int x, int y);
void updateCursor (int x, int y); void updateCursor (int x, int y);
void drawDecoration (Cairo::RefPtr<Cairo::Context> cr); void drawDecoration (Cairo::RefPtr<Cairo::Context> cr);