diff --git a/src/CanvasComponents/MeshCanvasComponent.cpp b/src/CanvasComponents/MeshCanvasComponent.cpp index e122422..5c50408 100644 --- a/src/CanvasComponents/MeshCanvasComponent.cpp +++ b/src/CanvasComponents/MeshCanvasComponent.cpp @@ -42,6 +42,7 @@ template void skpath_write(const SkPath& p, Archive& a) { std::vector> contours; + bool moveHappened = false; SkPath::Iter iter(p, true); for(;;) { @@ -51,8 +52,10 @@ template void skpath_write(const SkPath& p, Archive& a) { switch(rec->fVerb) { case SkPathVerb::kClose: - if(!contours.back().empty()) + if(moveHappened) { contours.back().pop_back(); + moveHappened = false; + } break; case SkPathVerb::kLine: contours.back().emplace_back(rec->fPoints[1]); @@ -60,6 +63,7 @@ template void skpath_write(const SkPath& p, Archive& a) { case SkPathVerb::kMove: contours.emplace_back(); contours.back().emplace_back(rec->fPoints[0]); + moveHappened = true; break; default: throw std::runtime_error("[get_predraw_data_accurate] Illegal verb " + std::to_string(static_cast(rec->fVerb))); @@ -357,7 +361,10 @@ void MeshCanvasComponent::normalize_object_coordinates(CoordSpaceHelper& coords) SkRect pathBounds = d.meshPath.getBounds(); SkPoint center = pathBounds.center(); constexpr float MAX_COORDINATE = 1000.0f; - float maxDimScaleFactor = MAX_COORDINATE / (std::max(pathBounds.width(), pathBounds.height()) * 0.5f); // Scale must be uniform. This scale factor should force the maximum coordinate = MAX_COORDINATE after transformation + float maxDimScaleFactorDenominator = std::max(pathBounds.width(), pathBounds.height()) * 0.5f; + if(maxDimScaleFactorDenominator == 0.0f) // Can't normalize, path probably empty or contains one point + return; + float maxDimScaleFactor = MAX_COORDINATE / maxDimScaleFactorDenominator; // Scale must be uniform. This scale factor should force the maximum coordinate = MAX_COORDINATE after transformation SkMatrix m = SkMatrix::I(); m.postTranslate(-center.x(), -center.y()).postScale(maxDimScaleFactor, maxDimScaleFactor); std::optional tryTransformPath = d.meshPath.tryMakeTransform(m); diff --git a/src/DrawingProgram/Tools/EraserTool.cpp b/src/DrawingProgram/Tools/EraserTool.cpp index 3bea75c..7960593 100644 --- a/src/DrawingProgram/Tools/EraserTool.cpp +++ b/src/DrawingProgram/Tools/EraserTool.cpp @@ -88,7 +88,7 @@ void EraserTool::input_mouse_button_on_canvas_callback(const InputManager::Mouse BrushComponentCode::mouse_button(drawP, genData, drawP.world.drawData.cam.c, button, relativeWidthResult.first.value()); // NOTE: Must set erase path when isErasing is set to true to make sure that the Circle path from not erasing part doesn't reach the erase_on_path code - erasePath = BrushComponentCode::brush_stroke_to_skpath(genData.brushPoints, drawP.world.main.toolConfig.brush.hasRoundCaps); + erasePath = BrushComponentCode::brush_stroke_to_skpath(genData.brushPoints, true); eraserChanged = isErasing = true; } else if(!button.down && isErasing) { @@ -282,7 +282,7 @@ void EraserTool::switch_tool(DrawingProgramToolType newTool) { void EraserTool::commit_data() { if(isErasing) { - erasePath = BrushComponentCode::brush_stroke_to_skpath(genData.brushPoints, drawP.world.main.toolConfig.brush.hasRoundCaps); + erasePath = BrushComponentCode::brush_stroke_to_skpath(genData.brushPoints, true); if(drawP.world.main.conf.realTimeEraser) { if(eraserChanged) { erase_on_path();