feat(pen): persist brush kind so it survives reload
Some checks failed
CI / Windows build (push) Has been cancelled

Closes TODO(brush-persist). EditorStroke now serializes its brush as
the stable BrushKind name; sidecars written before this field, and any
unknown name, load as fountainPen (back-compat). PenStroke<->EditorStroke
carry brush both ways, so a ballpoint/highlighter/pencil stroke keeps
its opacity/blend after a document is closed and reopened.

Note: InkStroke (the note/scratchpad world-coord format) has no brush
field, so notes derive brush from the tool — highlighter is preserved,
ballpoint/pencil collapse to fountainPen on reload (TODO: extend
InkStroke). PDF documents persist brush fully. analyze clean,
379 tests green.
This commit is contained in:
2026-06-24 23:40:40 +08:00
parent 6c2dd71b82
commit 46589a4c87
8 changed files with 206 additions and 40 deletions

View File

@@ -339,13 +339,11 @@ class _PenEditorScreenState extends State<PenEditorScreen> {
kind: es.tool == EditorTool.highlighter
? PenStrokeKind.highlighter
: PenStrokeKind.pen,
// Brush isn't persisted yet (TODO(brush-persist)); derive it
// from the tool so a loaded highlighter still renders with the
// highlighter brush (flat width), and pens fall back to the
// fountainPen default.
brush: es.tool == EditorTool.highlighter
? BrushKind.highlighter
: BrushKind.fountainPen,
// Brush is now persisted on the EditorStroke; carry it through
// so a reopened ballpoint/pencil/highlighter keeps its
// opacity/blend. Old sidecars without the field decode to
// fountainPen (see EditorStroke.brush back-compat default).
brush: es.brush,
))
.toList();
}

View File

@@ -155,7 +155,8 @@ class _PenNoteScreenState extends ConsumerState<PenNoteScreen> {
}
/// EditorStroke → live PenStroke (mirror of the PDF editor's loader). Brush
/// is not persisted (TODO(brush-persist)); derive it from the tool.
/// is persisted on the EditorStroke now, so carry it through; old sidecars
/// without the field decode to fountainPen (back-compat default).
PenStroke _penStrokeFromEditor(EditorStroke es) => PenStroke(
points: es.points
.map((ep) => PenPoint(ep.x, ep.y, ep.pressure, tilt: ep.tilt))
@@ -165,9 +166,7 @@ class _PenNoteScreenState extends ConsumerState<PenNoteScreen> {
kind: es.tool == EditorTool.highlighter
? PenStrokeKind.highlighter
: PenStrokeKind.pen,
brush: es.tool == EditorTool.highlighter
? BrushKind.highlighter
: BrushKind.fountainPen,
brush: es.brush,
);
Future<void> _initPenConfig() async {