How to efficiently create alphabet tracing app using Flutter?

I am trying to create an alphabets tracing app using Flutter. Below are the screenshots of what I intend to achieve and what I have achieved so far.

Intend to achieve: https://imgur.com/3KfWFA7

Achieved with below provided code: https://imgur.com/6LTcITG

import 'package:flutter/material.dart';

List<Offset> _drawPoints = <Offset>[];

void main() => runApp(MyDrawApp());

class MyDrawApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
            body: DrawCanvas(),
            floatingActionButton: FloatingActionButton(
                child: Icon(Icons.clear),
                onPressed: () {
                  _drawPoints.clear();
                },
            ),
        ),
    );
  }
}

class DrawCanvas extends StatefulWidget {
  @override
  _DrawCanvasState createState() => _DrawCanvasState();
}

class _DrawCanvasState extends State<DrawCanvas> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: ClipPath(
        child: detectGestureForPainting(),
        clipper: UpperCaseA(),
      ),
    );
  }

  Widget detectGestureForPainting() {
    return GestureDetector(
      onPanUpdate: (DragUpdateDetails details) {
        setState(() {
          RenderBox object = context.findRenderObject();
          Offset _localPosition = object.globalToLocal(details.globalPosition);
          _drawPoints = List.from(_drawPoints)..add(_localPosition);
        });
      },
      onPanEnd: (DragEndDetails details) => _drawPoints.add(null),
      child: CustomPaint(
        painter: PaintBrush(points: _drawPoints),
        child: Container(
          width: 500,
          height: 900,
        ),
        // size: Size.fromHeight(375),
      ),
    );
  }
}


class UpperCaseA extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    double _width = size.width;
    double _height = size.height;

    Path mypath = Path();

    print("Height = ${size.height}");
    print("Width = ${size.width}");

    mypath.moveTo(_width * 0.496, _height * 0.4373297);
    mypath.lineTo(_width * 0.330666667, _height * 0.671662125);
    mypath.lineTo(_width * 0.208, _height * 0.648501362);
    mypath.lineTo(_width * 0.434666667, _height * 0.328337875);
    mypath.lineTo(_width * 0.562666667, _height * 0.326975477);
    mypath.lineTo(_width * 0.789333333, _height * 0.648501362);
    mypath.lineTo(_width * 0.666666667, _height * 0.671662125);
    mypath.lineTo(_width * 0.610666667, _height * 0.59400545);
    mypath.lineTo(_width * 0.384, _height * 0.59400545);
    mypath.lineTo(_width * 0.432, _height * 0.525885559);
    mypath.lineTo(_width * 0.562666667, _height * 0.525885559);
    mypath.close();

    mypath.addArc(Rect.fromCircle(
            center: Offset(_width * 0.27, _height * 0.66),
            radius: _width * 0.0652), 0, 360);
    mypath.addArc(
        Rect.fromCircle(
            center: Offset(_width * 0.496, _height * 0.34),
            radius: _width * 0.0652), 0, 360);
    mypath.addArc(
        Rect.fromCircle(
            center: Offset(_width * 0.501, _height * 0.34),
            radius: _width * 0.0652),
        0,
        360);
    mypath.addArc(
        Rect.fromCircle(
            center: Offset(_width * 0.728, _height * 0.66),
            radius: _width * 0.0652),
        0,
        360);

    return mypath;

    // return Path.combine(PathOperation.reverseDifference, path, path1);
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}

class PaintBrush extends CustomPainter {
  List<Offset> points;

  PaintBrush({this.points});

  @override
  void paint(Canvas canvas, Size size) {
    canvas.drawColor(Colors.grey[350], BlendMode.src);

    Paint paint = new Paint()
      ..color = Colors.blueAccent.shade700
      ..strokeCap = StrokeCap.round
      ..strokeWidth = 100.0;

    for (int i = 0; i < points.length - 1; i++) {
      if (points[i] != null && points[i + 1] != null) {
        print("points[$i] = ${points[i]}");
        canvas.drawLine(points[i], points[i + 1], paint);
      }
    }
  }

  @override
  bool shouldRepaint(PaintBrush oldDelegate) => oldDelegate.points != points;
}

Could anyone please suggest:

  1. Since the chosen stroke width is 100.0, paint overflows to the other section, how to restrict them to the desired tracing path.

  2. Most challenging would be the curved edges, ex: 'B', how do I achieve them.

  3. Instead of plain paint, can a texture be used for tracing.

I understand its too many questions to ask for, but any help / suggestions / documentation / sample code will help a ton. I appreciate your time and effort.

Thanks in advance!!!