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

@@ -52,6 +52,13 @@ _$EditorStrokeImpl _$$EditorStrokeImplFromJson(Map<String, dynamic> json) =>
filled: json['filled'] as bool? ?? false,
textContent: json['textContent'] as String?,
fontSize: (json['fontSize'] as num?)?.toDouble() ?? 14.0,
brush:
$enumDecodeNullable(
_$BrushKindEnumMap,
json['brush'],
unknownValue: BrushKind.fountainPen,
) ??
BrushKind.fountainPen,
);
Map<String, dynamic> _$$EditorStrokeImplToJson(_$EditorStrokeImpl instance) =>
@@ -64,6 +71,7 @@ Map<String, dynamic> _$$EditorStrokeImplToJson(_$EditorStrokeImpl instance) =>
'filled': instance.filled,
'textContent': instance.textContent,
'fontSize': instance.fontSize,
'brush': _$BrushKindEnumMap[instance.brush]!,
};
const _$EditorToolEnumMap = {
@@ -71,3 +79,10 @@ const _$EditorToolEnumMap = {
EditorTool.highlighter: 'highlighter',
EditorTool.eraser: 'eraser',
};
const _$BrushKindEnumMap = {
BrushKind.fountainPen: 'fountainPen',
BrushKind.ballpoint: 'ballpoint',
BrushKind.highlighter: 'highlighter',
BrushKind.pencil: 'pencil',
};