Short pen strike shows up as an ink blob
Before submitting an issue, please check the following
- [X] I have searched for similar issues (both open and closed) and cannot find a duplicate
- [X] I agree to follow the Code of Conduct
Describe the bug
When I'm writing, short line (see picture) shows up as ink blob almost half the time. This doesn't happen with another writing/drawing app.
To reproduce
I don't have procedure that can reproduce this consistently
- Open up Saber and connect POCO Smart Pen
- Create a blank notes
- Write something with short line strike
- Line shows up as blob
Expected behavior
Short line strike shows up as line, following what were written
Saber version
v0.25.1 Google Play (25010)
Device
- Device: Poco Pad Model 2405CPCFBG
- OS: Xiaomi HyperOS 1.0.9.0
- Pen: POCO Smart Pen (fw: 2.1.16)
Anything else?
This happens more frequently on Fountain pen but also occurs in Ballpoint pen
The size of the blob seems inconsistent but roughly follows how long the line length and/or the pen pressure
I have the same issue with my wacom tablet on Linux (snap, v0.25.2 edge). For me, the blob appears when I activate the rubber or continue writing a new strike. Disabling pressure sensibility makes the problem disappear.
Those dots appear whenever a stroke consists of only 1 or 2 points. If it consists of two points, the dots diameter is equal to their vertical distance. https://github.com/saber-notes/saber/blob/main/lib%2Fcomponents%2Fcanvas%2F_canvas_painter.dart#L138-L143 So, if you draw a small stroke so quickly that it is only registered as two points, the result is a dot.
@ZebraVogel94349 I see the intention. Do you think reducing the threshold to a single point will have unintended behavior? I think those circles are meant to help with writing lowercase i, j, amongst other.
I've tried to patch that line and recompile, I can confirm that this works for eliminating the unexpected dot with short pen strike. I haven't found any side effects yet but I'll update this if I found any. That snippet should have purpose so I don't want to submit a pull request, that and my limited understanding of the codebase.
Diff for anyone interested
diff -U 3 a/lib/components/canvas/_canvas_painter.dart b/lib/components/canvas/_canvas_painter.dart
--- a/lib/components/canvas/_canvas_painter.dart
+++ b/lib/components/canvas/_canvas_painter.dart
@@ -135,7 +135,8 @@
),
shapePaint,
);
- } else if (stroke.length <= 2) {
+ // change default behavior
+ } else if (stroke.length == 1) {
// a dot
final bounds = stroke.lowQualityPath.getBounds();
final radius = max(bounds.size.width, stroke.options.size) / 2;
@@ -167,8 +168,8 @@
..setFloat(2, color.blue / 255);
paint.maskFilter = _getPencilMaskFilter(currentStroke!.options.size);
}
-
- if (currentStroke!.length <= 2) {
+ // change default behavior
+ if (currentStroke!.length == 1) {
// a dot
final bounds = currentStroke!.highQualityPath.getBounds();
final radius = max(
on a side note, maybe having the dot a notch above stroke.options.size is preferable?
I've tried to patch that line and recompile, I can confirm that this works for eliminating the unexpected dot with short pen strike. I haven't found any side effects yet but I'll update this if I found any. That snippet should have purpose so I don't want to submit a pull request, that and my limited understanding of the codebase.
I tried the same fix as well, but it seems to have some side effects. For example, this note contains only a single stroke which consists of two points. If you open the note and zoom in, the point seems to disappear and you get the error Another exception was thrown: RangeError (length): Invalid value: Not in inclusive range 0..1: 4. Also, you can't see any other strokes you create afterwards, unless you zoom out.
Edit: I believe, this is actually a bug in the Perfect Freehand library. In get_stroke_points.dart in line 53 points[i] = points[i].copyWith(pressure: pressure); is called with i==4, when there are only two points, because the for loop in line 81 iterates over pts instead of points, which differ because points are added to pts when there are only two points to make the lines look better in lines 27-36. Changing points[i] = points[i].copyWith(pressure: pressure); to
if(points.length == 2 && i >= 2) { if(i == pts.length - 1) { points[1] = points[1].copyWith(pressure: pressure); } } else{ points[i] = points[i].copyWith(pressure: pressure); }
seems to fix the problem.
I just made a pull request to fix the bug in the library. After that is fixed your fix for the ink blobs should work.
I've tried your upstream patch and that seems to fix the problem along with your first proposed patch. If anyone interested, you can add the package and external commits on dependencies-override in pubspec.yaml
--- pubspec.yaml 2024-11-26 03:40:09.453711560 +0000
+++ pubspec.yaml 2024-11-26 03:53:24.435837659 +0000
@@ -175,6 +175,13 @@
url: https://github.com/adil192/json2yaml
ref: fix-string-ends-with-colon
+ # https://github.com/saber-notes/saber/issues/1391#issuecomment-2498941398
+ # https://github.com/steveruizok/perfect-freehand-dart/pull/21
+ perfect_freehand:
+ git:
+ url: https://github.com/ZebraVogel94349/perfect-freehand-dart.git
+ ref: patch-1
+
# https://github.com/KasemJaffer/receive_sharing_intent/pull/333
receive_sharing_intent:
git:
this is still happening on Onyx Boox devices as well, with or without the Onyx SDK working. good to know the issue is with Perfect Freehand. do we need Perfect Freehand, strictly speaking?
fwiw this seems to be related to SoC power. it is much worse on my Snapdragon 680 Go 10.3 than it is on my Snapdragon 690 (which is sort of like a 750G, significantly faster) Go 7. this is REAL bad.
This issue is not fixed, yet. In components/canvas/_canvas_painter.dart else if (stroke.length <= 2) still needs to be replaced by else if (stroke.length == 1), which is possible now without errors because the perfect freehand library can now correctly handle strokes consisting of exactly two points.
Thanks, I'll do a test for the latest binary release
where does one get that latest binary release?