No flat cap eraser, fixed path writing, fixed divide by NaN

This commit is contained in:
Yousef Khadadeh 2026-06-07 09:28:54 +03:00
parent cceeb9b613
commit 77b001cbc9
2 changed files with 11 additions and 4 deletions

View file

@ -42,6 +42,7 @@
template <typename Archive> void skpath_write(const SkPath& p, Archive& a) {
std::vector<std::vector<SkPoint>> contours;
bool moveHappened = false;
SkPath::Iter iter(p, true);
for(;;) {
@ -51,8 +52,10 @@ template <typename Archive> 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 <typename Archive> 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<unsigned>(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<SkPath> tryTransformPath = d.meshPath.tryMakeTransform(m);

View file

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