fix: PDF finger ink, chrome UX, OneNote pens, and pen physics
Some checks failed
CI / Windows build (push) Has been cancelled

Wire finger drawing on PDF without breaking pinch; auto-hide page scrubber and fix bounce; share sticky tools with resize and per-page remember; side-button select; separate pen slots with colors; rnote pressure shapes plus tip-velocity width and lower stroke latency.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-06 16:01:01 +08:00
parent 85af037b7d
commit f31dd0fb52
17 changed files with 835 additions and 234 deletions

View File

@@ -1,5 +1,7 @@
// Tests for the configurable pen-pressure response (F5).
import 'dart:math' as math;
import 'package:flutter_test/flutter_test.dart';
import 'package:badnote/editor/input/pressure_curve.dart';
@@ -46,4 +48,59 @@ void main() {
// Even a light touch stays near full width.
expect(marker.apply(0.1), greaterThan(0.9));
});
group('PressureCurve.shaped', () {
const floor = 0.1;
test('every shape maps 0→floor and 1→1', () {
for (final shape in PressureCurveShape.values) {
final c = PressureCurve.shaped(shape, floor: floor);
expect(c.apply(0.0), closeTo(floor, 1e-9), reason: '$shape at 0');
expect(c.apply(1.0), closeTo(1.0, 1e-9), reason: '$shape at 1');
}
});
test('midpoints differ across shapes', () {
final mids = {
for (final shape in PressureCurveShape.values)
shape: PressureCurve.shaped(shape).apply(0.5),
};
expect(mids[PressureCurveShape.linear], closeTo(0.5, 1e-9));
expect(mids[PressureCurveShape.soft], closeTo(math.pow(0.5, 0.6), 1e-9));
expect(mids[PressureCurveShape.quadratic], closeTo(0.25, 1e-9));
expect(mids[PressureCurveShape.cubic], closeTo(0.125, 1e-9));
expect(mids[PressureCurveShape.sqrt], closeTo(math.sqrt(0.5), 1e-9));
final logMid = math.log(1 + kLogarithmicPressureK * 0.5) /
math.log(1 + kLogarithmicPressureK);
expect(mids[PressureCurveShape.logarithmic], closeTo(logMid, 1e-9));
// Soft (γ<1) > linear > quadratic > cubic at p=0.5; log is above linear.
expect(mids[PressureCurveShape.soft]! > mids[PressureCurveShape.linear]!,
isTrue);
expect(
mids[PressureCurveShape.linear]! >
mids[PressureCurveShape.quadratic]!,
isTrue);
expect(
mids[PressureCurveShape.quadratic]! >
mids[PressureCurveShape.cubic]!,
isTrue);
expect(
mids[PressureCurveShape.logarithmic]! >
mids[PressureCurveShape.linear]!,
isTrue);
// Distinct midpoints (no two shapes collide at p=0.5).
expect(mids.values.toSet().length, PressureCurveShape.values.length);
});
test('shaped presets set expected gamma (except log)', () {
expect(PressureCurve.shaped(PressureCurveShape.linear).gamma, 1.0);
expect(PressureCurve.shaped(PressureCurveShape.soft).gamma, 0.6);
expect(PressureCurve.shaped(PressureCurveShape.quadratic).gamma, 2.0);
expect(PressureCurve.shaped(PressureCurveShape.cubic).gamma, 3.0);
expect(PressureCurve.shaped(PressureCurveShape.sqrt).gamma, 0.5);
expect(PressureCurve.shaped(PressureCurveShape.logarithmic).shape,
PressureCurveShape.logarithmic);
});
});
}