From 5cbcc9af80f262622924f3d617e2364d60ca8b6f Mon Sep 17 00:00:00 2001 From: Yousef Khadadeh Date: Fri, 3 Apr 2026 11:08:56 +0300 Subject: [PATCH] Image crop bounds limited to not cause integer division by zero error --- src/DrawingProgram/Tools/EditTool.cpp | 5 ++--- src/DrawingProgram/Tools/EditTool.hpp | 3 ++- src/DrawingProgram/Tools/EditTools/ImageEditTool.cpp | 5 +++-- src/InputManager.cpp | 4 ++-- src/RichText/TextBox.cpp | 5 +++++ src/RichText/TextBox.hpp | 1 + 6 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/DrawingProgram/Tools/EditTool.cpp b/src/DrawingProgram/Tools/EditTool.cpp index dd2b843..5970b74 100644 --- a/src/DrawingProgram/Tools/EditTool.cpp +++ b/src/DrawingProgram/Tools/EditTool.cpp @@ -102,7 +102,6 @@ void EditTool::input_mouse_button_on_canvas_callback(const InputManager::MouseBu if(SCollision::collide(mouseCircle, SCollision::Circle(drawP.world.drawData.cam.c.to_space(objInfoBeingEdited->obj->coords.from_space(h.coordMatrix * (*h.p))), drawP.drag_point_radius()))) { pointDragging = &h; isMovingPoint = true; - break; } } if(!isMovingPoint && !objInfoBeingEdited->obj->collides_with_cam_coords(drawP.world.drawData.cam.c, cMouseCircle)) @@ -141,9 +140,9 @@ void EditTool::input_mouse_motion_callback(const InputManager::MouseMotionCallba Vector2f newPos = pointDragging->coordMatrix.inverse() * objInfoBeingEdited->obj->coords.get_mouse_pos(drawP.world); if(newPos != *pointDragging->p) { if(pointDragging->min) - newPos = cwise_vec_max((*pointDragging->min + Vector2f{pointDragging->minimumDistanceBetweenBoundsAndPoint, pointDragging->minimumDistanceBetweenBoundsAndPoint}).eval(), newPos); + newPos = cwise_vec_max((*pointDragging->min + Vector2f{pointDragging->minimumDistanceBetweenMinAndPoint, pointDragging->minimumDistanceBetweenMinAndPoint}).eval(), newPos); if(pointDragging->max) - newPos = cwise_vec_min((*pointDragging->max - Vector2f{pointDragging->minimumDistanceBetweenBoundsAndPoint, pointDragging->minimumDistanceBetweenBoundsAndPoint}).eval(), newPos); + newPos = cwise_vec_min((*pointDragging->max - Vector2f{pointDragging->minimumDistanceBetweenMaxAndPoint, pointDragging->minimumDistanceBetweenMaxAndPoint}).eval(), newPos); *pointDragging->p = newPos; objInfoBeingEdited->obj->commit_update(drawP); } diff --git a/src/DrawingProgram/Tools/EditTool.hpp b/src/DrawingProgram/Tools/EditTool.hpp index 4e377cb..921b9bf 100644 --- a/src/DrawingProgram/Tools/EditTool.hpp +++ b/src/DrawingProgram/Tools/EditTool.hpp @@ -12,7 +12,8 @@ class EditTool : public DrawingProgramToolBase { Vector2f* p; Vector2f* min; Vector2f* max; - float minimumDistanceBetweenBoundsAndPoint = MINIMUM_DISTANCE_BETWEEN_BOUNDS; + float minimumDistanceBetweenMinAndPoint = MINIMUM_DISTANCE_BETWEEN_BOUNDS; + float minimumDistanceBetweenMaxAndPoint = MINIMUM_DISTANCE_BETWEEN_BOUNDS; Affine2f coordMatrix = Affine2f::Identity(); }; diff --git a/src/DrawingProgram/Tools/EditTools/ImageEditTool.cpp b/src/DrawingProgram/Tools/EditTools/ImageEditTool.cpp index ac567b0..3ab20fc 100644 --- a/src/DrawingProgram/Tools/EditTools/ImageEditTool.cpp +++ b/src/DrawingProgram/Tools/EditTools/ImageEditTool.cpp @@ -29,8 +29,9 @@ void ImageEditTool::edit_start(EditTool& editTool, CanvasComponentContainer::Obj Affine2f transformMat = Translation2f(a.d.p1) * AlignedScaling2f(a.d.p2 - a.d.p1) * Affine2f::Identity(); prevData = a.d; - editTool.add_point_handle({&a.d.cropP1, &staticZero, &a.d.cropP2, 0.0f, transformMat}); - editTool.add_point_handle({&a.d.cropP2, &a.d.cropP1, &staticOne, 0.0f, transformMat}); + constexpr float MINIMUM_DISTANCE_BETWEEN_IMAGE_CROP_POINTS = 0.02f; + editTool.add_point_handle({&a.d.cropP1, &staticZero, &a.d.cropP2, 0.0f, MINIMUM_DISTANCE_BETWEEN_IMAGE_CROP_POINTS, transformMat}); + editTool.add_point_handle({&a.d.cropP2, &a.d.cropP1, &staticOne, MINIMUM_DISTANCE_BETWEEN_IMAGE_CROP_POINTS, 0.0f, transformMat}); a.d.editing = true; comp->obj->commit_update(drawP); } diff --git a/src/InputManager.cpp b/src/InputManager.cpp index cfeff04..a2aabe7 100644 --- a/src/InputManager.cpp +++ b/src/InputManager.cpp @@ -140,13 +140,13 @@ void InputManager::Text::add_textbox_undo(const RichText::TextBox::Cursor& prevC if(!textBoxes.empty()) { auto& frontTextBox = textBoxes.front(); frontTextBox.textboxUndo.push({[textBox = frontTextBox.textBox, cursor = frontTextBox.cursor, prevCursor = prevCursor, prevRichText = prevRichText]() { - textBox->set_rich_text_data(prevRichText); + textBox->set_rich_text_data_for_undo_redo(prevRichText); cursor->selectionBeginPos = cursor->selectionEndPos = cursor->pos = std::max(prevCursor.selectionEndPos, prevCursor.selectionBeginPos); cursor->previousX = std::nullopt; return true; }, [textBox = frontTextBox.textBox, cursor = frontTextBox.cursor, currentCursor = *frontTextBox.cursor, currentRichText = frontTextBox.textBox->get_rich_text_data()]() { - textBox->set_rich_text_data(currentRichText); + textBox->set_rich_text_data_for_undo_redo(currentRichText); cursor->selectionBeginPos = cursor->selectionEndPos = cursor->pos = std::max(currentCursor.selectionEndPos, currentCursor.selectionBeginPos); cursor->previousX = std::nullopt; return true; diff --git a/src/RichText/TextBox.cpp b/src/RichText/TextBox.cpp index 8fe1777..3dd0c38 100644 --- a/src/RichText/TextBox.cpp +++ b/src/RichText/TextBox.cpp @@ -500,6 +500,11 @@ void TextBox::set_rich_text_data(const TextData& richText) { needsRebuild = true; } +void TextBox::set_rich_text_data_for_undo_redo(const TextData& richText) { + set_rich_text_data(richText); + if(onUserTextEdit) onUserTextEdit(); +} + std::string TextBox::get_string() { return get_text_between({0, 0}, move(TextBox::Movement::END, {0, 0})); } diff --git a/src/RichText/TextBox.hpp b/src/RichText/TextBox.hpp index 4da44f6..31a5c06 100644 --- a/src/RichText/TextBox.hpp +++ b/src/RichText/TextBox.hpp @@ -138,6 +138,7 @@ class TextBox { TextData get_rich_text_data(); void set_rich_text_data(const TextData& richText); + void set_rich_text_data_for_undo_redo(const TextData& richText); TextData get_rich_text_data_between(TextPosition p1, TextPosition p2); TextPosition insert_rich_text(TextPosition p, const TextData& richText);