From c85fb11636522b794b147b0c94a113ed5cd1a87c Mon Sep 17 00:00:00 2001 From: Yousef Khadadeh Date: Wed, 15 Apr 2026 20:58:25 +0300 Subject: [PATCH] Make cursors and select tools visible without special blend modes --- src/CanvasTheme.cpp | 27 ------------------ src/CanvasTheme.hpp | 2 -- src/DrawingProgram/DrawingProgram.cpp | 29 ++++++++++++-------- src/DrawingProgram/DrawingProgram.hpp | 2 +- src/DrawingProgram/Tools/BrushTool.cpp | 4 ++- src/DrawingProgram/Tools/EraserTool.cpp | 13 ++++++--- src/DrawingProgram/Tools/LassoSelectTool.cpp | 5 +++- src/DrawingProgram/Tools/RectSelectTool.cpp | 5 +++- 8 files changed, 39 insertions(+), 48 deletions(-) diff --git a/src/CanvasTheme.cpp b/src/CanvasTheme.cpp index 8b0f4d4..799b5aa 100644 --- a/src/CanvasTheme.cpp +++ b/src/CanvasTheme.cpp @@ -2,37 +2,10 @@ #include "DrawingProgram/DrawingProgram.hpp" #include #include "MainProgram.hpp" -#include "Helpers/Networking/NetLibrary.hpp" #include "World.hpp" using namespace NetworkingObjects; -const char* visibleBlendModeCode = R"V( - vec4 main(vec4 src, vec4 dst) { - float value = max(max(dst.x, dst.y), dst.z) / dst.a; - vec4 actualSrc; - if(value > 0.6) - actualSrc = vec4(vec3(0.0), src.a); - else - actualSrc = vec4(src.a); - return actualSrc + (1.0 - actualSrc.a) * dst; - } -)V"; - -sk_sp CanvasTheme::get_visible_blend_mode() { - static sk_sp blender = nullptr; - if(!blender) { - auto effect = SkRuntimeEffect::MakeForBlender(SkString(visibleBlendModeCode)); - if(!effect.effect) { - std::cout << "[CanvasTheme::get_visible_blend_mode] " << " blender construction error\n"; - std::cout << effect.errorText.c_str() << std::endl; - throw std::runtime_error("Shader Compile Failure"); - } - blender = effect.effect->makeBlender(nullptr); - } - return blender; -} - CanvasTheme::CanvasTheme(World& w): world(w) {} diff --git a/src/CanvasTheme.hpp b/src/CanvasTheme.hpp index 501b352..a4d9ee6 100644 --- a/src/CanvasTheme.hpp +++ b/src/CanvasTheme.hpp @@ -24,8 +24,6 @@ class CanvasTheme { void save_file(cereal::PortableBinaryOutputArchive& a) const; void load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version); - static sk_sp get_visible_blend_mode(); - private: void set_tool_front_color(DrawingProgram& drawP); struct BackColor { diff --git a/src/DrawingProgram/DrawingProgram.cpp b/src/DrawingProgram/DrawingProgram.cpp index 53a64a8..022827a 100644 --- a/src/DrawingProgram/DrawingProgram.cpp +++ b/src/DrawingProgram/DrawingProgram.cpp @@ -575,20 +575,27 @@ bool DrawingProgram::prevent_undo_or_redo() { return drawTool->prevent_undo_or_redo(); } -SkPaint DrawingProgram::select_tool_line_paint(const DrawData& drawData) { - SkScalar intervals[] = {10, 5}; +std::pair DrawingProgram::select_tool_line_paint(const DrawData& drawData) { + SkScalar intervals[] = {10, 10}; + SkScalar intervalSum = intervals[0] + intervals[1]; float timeSinceEpoch = std::chrono::duration_cast>(std::chrono::steady_clock::now().time_since_epoch()).count(); - sk_sp lassoLineDashEffect = SkDashPathEffect::Make({intervals, 2}, -std::fmod(timeSinceEpoch * 50, 15)); + sk_sp lassoLineDashEffect1 = SkDashPathEffect::Make({intervals, 2}, -std::fmod(timeSinceEpoch * 10, intervalSum)); + sk_sp lassoLineDashEffect2 = SkDashPathEffect::Make({intervals, 2}, -std::fmod(timeSinceEpoch * 10, intervalSum) + 10); - SkPaint selectLinePaint; - selectLinePaint.setStyle(SkPaint::kStroke_Style); - selectLinePaint.setStrokeWidth(3); - selectLinePaint.setColor4f(world.canvasTheme.get_tool_front_color()); - selectLinePaint.setPathEffect(lassoLineDashEffect); - selectLinePaint.setBlender(CanvasTheme::get_visible_blend_mode()); - selectLinePaint.setAntiAlias(drawData.skiaAA); + std::pair selectLinePaintPair; + selectLinePaintPair.first.setStyle(SkPaint::kStroke_Style); + selectLinePaintPair.first.setStrokeWidth(3); + selectLinePaintPair.first.setColor4f(SkColor4f{1.0f, 1.0f, 1.0f, 1.0f}); + selectLinePaintPair.first.setPathEffect(lassoLineDashEffect1); + selectLinePaintPair.first.setAntiAlias(drawData.skiaAA); - return selectLinePaint; + selectLinePaintPair.second.setStyle(SkPaint::kStroke_Style); + selectLinePaintPair.second.setStrokeWidth(3); + selectLinePaintPair.second.setColor4f(SkColor4f{0.0f, 0.0f, 0.0f, 1.0f}); + selectLinePaintPair.second.setPathEffect(lassoLineDashEffect2); + selectLinePaintPair.second.setAntiAlias(drawData.skiaAA); + + return selectLinePaintPair; } void DrawingProgram::rebuild_cache() { diff --git a/src/DrawingProgram/DrawingProgram.hpp b/src/DrawingProgram/DrawingProgram.hpp index 25200e9..c74c216 100644 --- a/src/DrawingProgram/DrawingProgram.hpp +++ b/src/DrawingProgram/DrawingProgram.hpp @@ -89,7 +89,7 @@ class DrawingProgram { float drag_point_radius(); void draw_drag_circle(SkCanvas* canvas, const Vector2f& pos, const SkColor4f& c, const DrawData& drawData, float radiusMultiplier = 1.0f); - SkPaint select_tool_line_paint(const DrawData& drawData); + std::pair select_tool_line_paint(const DrawData& drawData); bool is_actual_selection_tool(DrawingProgramToolType typeToCheck); bool is_selection_allowing_tool(DrawingProgramToolType typeToCheck); diff --git a/src/DrawingProgram/Tools/BrushTool.cpp b/src/DrawingProgram/Tools/BrushTool.cpp index 581854d..121bd29 100644 --- a/src/DrawingProgram/Tools/BrushTool.cpp +++ b/src/DrawingProgram/Tools/BrushTool.cpp @@ -208,9 +208,11 @@ void BrushTool::draw(SkCanvas* canvas, const DrawData& drawData) { linePaint.setStyle(SkPaint::kStroke_Style); linePaint.setStrokeCap(SkPaint::kRound_Cap); linePaint.setStrokeWidth(0.0f); - linePaint.setBlender(CanvasTheme::get_visible_blend_mode()); SkPath circ = SkPath::Circle(pos.x(), pos.y(), width); canvas->drawPath(circ, linePaint); + linePaint.setColor4f({0.0f, 0.0f, 0.0f, 1.0f}); + circ = SkPath::Circle(pos.x(), pos.y(), width - 1.0f); + canvas->drawPath(circ, linePaint); } } } diff --git a/src/DrawingProgram/Tools/EraserTool.cpp b/src/DrawingProgram/Tools/EraserTool.cpp index 5a668d6..ebff085 100644 --- a/src/DrawingProgram/Tools/EraserTool.cpp +++ b/src/DrawingProgram/Tools/EraserTool.cpp @@ -125,15 +125,20 @@ void EraserTool::draw(SkCanvas* canvas, const DrawData& drawData) { float width = relativeWidthResult.first.value() * 0.5f; SkPaint linePaint; linePaint.setAntiAlias(drawData.skiaAA); - linePaint.setColor4f({1.0f, 1.0f, 1.0f, 0.5f}); + linePaint.setColor4f({0.0f, 0.0f, 0.0f, 0.4f}); linePaint.setStyle(SkPaint::kStroke_Style); linePaint.setStrokeCap(SkPaint::kRound_Cap); - linePaint.setStrokeWidth(width * 2.0f); - linePaint.setBlender(CanvasTheme::get_visible_blend_mode()); + linePaint.setStrokeWidth(width * 2.0f + 1.0f); SkPathBuilder erasePath; erasePath.moveTo(convert_vec2(lastPos)); erasePath.lineTo(convert_vec2(drawData.main->input.mouse.pos)); - canvas->drawPath(erasePath.detach(), linePaint); + + SkPath erasePathDetach = erasePath.detach(); + canvas->drawPath(erasePathDetach, linePaint); + + linePaint.setStrokeWidth(width * 2.0f); + linePaint.setColor4f({1.0f, 1.0f, 1.0f, 0.4f}); + canvas->drawPath(erasePathDetach, linePaint); } lastPos = drawData.main->input.mouse.pos; diff --git a/src/DrawingProgram/Tools/LassoSelectTool.cpp b/src/DrawingProgram/Tools/LassoSelectTool.cpp index b102457..4e74caa 100644 --- a/src/DrawingProgram/Tools/LassoSelectTool.cpp +++ b/src/DrawingProgram/Tools/LassoSelectTool.cpp @@ -138,7 +138,10 @@ void LassoSelectTool::draw(SkCanvas* canvas, const DrawData& drawData) { for(Vector2f& p : controls.lassoPoints | std::views::drop(1)) lassoPath.lineTo(convert_vec2(p)); - canvas->drawPath(lassoPath.detach(), drawP.select_tool_line_paint(drawData)); + auto paintPair = drawP.select_tool_line_paint(drawData); + SkPath lassoPathDetach = lassoPath.detach(); + canvas->drawPath(lassoPathDetach, paintPair.first); + canvas->drawPath(lassoPathDetach, paintPair.second); canvas->restore(); } diff --git a/src/DrawingProgram/Tools/RectSelectTool.cpp b/src/DrawingProgram/Tools/RectSelectTool.cpp index a0b4f30..2097609 100644 --- a/src/DrawingProgram/Tools/RectSelectTool.cpp +++ b/src/DrawingProgram/Tools/RectSelectTool.cpp @@ -100,7 +100,10 @@ void RectSelectTool::draw(SkCanvas* canvas, const DrawData& drawData) { controls.coords.transform_sk_canvas(canvas, drawData); SkRect r = SkRect::MakeLTRB(newT[0].x(), newT[0].y(), newT[2].x(), newT[2].y()); - canvas->drawRect(r, drawP.select_tool_line_paint(drawData)); + + auto paintPair = drawP.select_tool_line_paint(drawData); + canvas->drawRect(r, paintPair.first); + canvas->drawRect(r, paintPair.second); canvas->restore(); }