diff --git a/src/CanvasTheme.cpp b/src/CanvasTheme.cpp index 6773195..6fd0443 100644 --- a/src/CanvasTheme.cpp +++ b/src/CanvasTheme.cpp @@ -7,6 +7,32 @@ 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) {} @@ -37,13 +63,11 @@ void CanvasTheme::set_back_color(const Vector3f& newBackColor) { void CanvasTheme::set_tool_front_color(DrawingProgram& drawP) { Vector3f newHSV = rgb_to_hsv(backColor->c); - SkColor4f oldToolFrontColor = toolFrontColor; if(newHSV.z() >= 0.6f) toolFrontColor = SkColor4f{0.0f, 0.0f, 0.0f, 1.0f}; else toolFrontColor = SkColor4f{1.0f, 1.0f, 1.0f, 1.0f}; - if(oldToolFrontColor != toolFrontColor) - drawP.drawCache.clear_own_cached_surfaces(); + drawP.drawCache.clear_own_cached_surfaces(); } void CanvasTheme::register_class() { diff --git a/src/CanvasTheme.hpp b/src/CanvasTheme.hpp index 352bedf..501b352 100644 --- a/src/CanvasTheme.hpp +++ b/src/CanvasTheme.hpp @@ -6,6 +6,8 @@ #include #include +#include + class DrawingProgram; class World; @@ -21,6 +23,9 @@ class CanvasTheme { void write_create_message(cereal::PortableBinaryOutputArchive& a) const; 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 bd85e5e..b181fcd 100644 --- a/src/DrawingProgram/DrawingProgram.cpp +++ b/src/DrawingProgram/DrawingProgram.cpp @@ -522,6 +522,7 @@ SkPaint DrawingProgram::select_tool_line_paint() { selectLinePaint.setStrokeWidth(3); selectLinePaint.setColor4f(world.canvasTheme.get_tool_front_color()); selectLinePaint.setPathEffect(lassoLineDashEffect); + selectLinePaint.setBlender(CanvasTheme::get_visible_blend_mode()); return selectLinePaint; } diff --git a/src/DrawingProgram/Tools/BrushTool.cpp b/src/DrawingProgram/Tools/BrushTool.cpp index 1e52398..f649b3a 100644 --- a/src/DrawingProgram/Tools/BrushTool.cpp +++ b/src/DrawingProgram/Tools/BrushTool.cpp @@ -187,17 +187,21 @@ void BrushTool::draw(SkCanvas* canvas, const DrawData& drawData) { if(!drawP.world.main.input.isTouchDevice && drawData.main->world->drawProg.controls.cursorHoveringOverCanvas) { auto relativeWidthResult = drawP.world.main.toolConfig.get_relative_width_stroke_size(drawP, drawP.world.drawData.cam.c.inverseScale); if(relativeWidthResult.first.has_value()) { - SkPaint linePaint; - linePaint.setColor4f(drawP.world.canvasTheme.get_tool_front_color()); - linePaint.setStroke(true); - linePaint.setStrokeWidth(0.0f); float width = relativeWidthResult.first.value(); if(objInfoBeingEdited) width *= penWidth * 0.5f; else width *= 0.5f; + width += 1.0f; Vector2f pos = drawData.main->input.mouse.pos; - canvas->drawCircle(pos.x(), pos.y(), width, linePaint); + SkPaint linePaint; + linePaint.setColor4f({1.0f, 1.0f, 1.0f, 1.0f}); + 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); } } } diff --git a/src/DrawingProgram/Tools/EraserTool.cpp b/src/DrawingProgram/Tools/EraserTool.cpp index 701c756..5763781 100644 --- a/src/DrawingProgram/Tools/EraserTool.cpp +++ b/src/DrawingProgram/Tools/EraserTool.cpp @@ -2,6 +2,7 @@ #include "../DrawingProgram.hpp" #include "../../MainProgram.hpp" #include "../../DrawData.hpp" +#include #include EraserTool::EraserTool(DrawingProgram& initDrawP): @@ -118,14 +119,12 @@ void EraserTool::draw(SkCanvas* canvas, const DrawData& drawData) { auto relativeWidthResult = drawP.world.main.toolConfig.get_relative_width_stroke_size(drawP, drawP.world.drawData.cam.c.inverseScale); if(relativeWidthResult.first.has_value()) { float width = relativeWidthResult.first.value() * 0.5f; - SkColor4f c = drawP.world.canvasTheme.get_tool_front_color(); - c.fA = 0.5f; - SkPaint linePaint; - linePaint.setColor4f(c); + linePaint.setColor4f({1.0f, 1.0f, 1.0f, 0.5f}); linePaint.setStyle(SkPaint::kStroke_Style); linePaint.setStrokeCap(SkPaint::kRound_Cap); linePaint.setStrokeWidth(width * 2.0f); + linePaint.setBlender(CanvasTheme::get_visible_blend_mode()); SkPathBuilder erasePath; erasePath.moveTo(convert_vec2(lastPos)); erasePath.lineTo(convert_vec2(drawData.main->input.mouse.pos));