feat(pen): extensible brush model (4 brushes)
All checks were successful
CI / Windows build (push) Successful in 14m54s
All checks were successful
CI / Windows build (push) Successful in 14m54s
Replace the 2-tool ink system with a data-driven, Krita-style BrushProfile (lib/editor/engine/brush.dart). Adding a brush is a const map entry, not render-path branching. Four presets from the rnote/krita spec: - fountain pen: quadratic (p^2) pressure, wide dynamic width - ballpoint: near-constant width (thinning 0.15) - highlighter: flat width, square caps - pencil: sqrt(p) pressure, moderate width Pressure is pre-warped per brush via PressureCurve(gamma) before perfect_freehand; geometry fields (thinning/streamline/smoothing/ caps) flow through the shared stroke recipe so the PDF overlay and the note/slide PenCanvas both honor the brush. Brush kind is now persisted on the stroke model. Picker added to all three toolbars. Opacity/multiply and pencil grain are carried as data but not yet composited (TODO brush-opacity / brush-texture); this increment is width + pressure-curve differentiation. analyze clean, 283 tests.
This commit is contained in:
@@ -308,6 +308,12 @@ class PdfService {
|
||||
// ONE shared recipe with the on-screen painter (R7): export can no longer
|
||||
// drift from screen. Previously this hardcoded thinning:0.7/streamline:0.5,
|
||||
// which diverged from the screen's 0.85/0.32 → hairline export mismatch.
|
||||
//
|
||||
// TODO(brush-persist) / TODO(brush-export): InkStroke does not persist the
|
||||
// brush, so export can only use the legacy (no-brush) recipe — it does NOT
|
||||
// yet pass `brush:` here. Once the brush is persisted on InkStroke, resolve
|
||||
// brushProfileFor(stroke.brush) and pass it so export matches the brush-aware
|
||||
// screen geometry (taper/caps/per-brush thinning) for non-fountain brushes.
|
||||
final outline = freehandOutlinePoints(
|
||||
pfPoints: pfPoints,
|
||||
size: pixelWidth,
|
||||
|
||||
Reference in New Issue
Block a user