suClick
suClick

Reputation: 996

Is this right way to implement handwriting rendering in iOS without PencilKit?

Hello Apple development experts, I'm currently working on creating an iOS app that includes a handwriting drawing feature. Due to certain constraints, I'm unable to directly utilize PencilKit and need to render the handwriting using the MetalKit framework instead.

Before embarking on this task, I carefully examined the effects achieved by Apple's PencilKit (via the Notes app) and made some coding attempts. However, my attempts fall significantly short of the PencilKit's results, leading me to believe there might be flaws in my approach.

In the Notes app, the rendering of a stroke is impressively smooth and clear. For instance, a light tap with the iPencil produces an almost perfect circle with very smooth and clear edges. Similarly, slowly moving the iPencil creates smooth and clear irregular paths on the screen.

PencilKit Stroke PencilKit Stroke(zoomed)

After some research, I attempted the following drawing process:

  1. I collected a list of contact points between the iPencil and the screen, referred to as TouchPoints.
  2. I interpolated these TouchPoints using Bezier curves to form a generally smooth path of points, which we'll call BezierPoints.
  3. Since the interpolation in step two focuses more on the overall smoothness of the curve but might still leave considerable distances between points, I attempted to perform linear interpolation on the BezierPoints to create a final list of vertices for rendering with MetalKit, referred to as MetalVertices.
  4. These vertices, along with other attributes like color and size (not detailed here), were then submitted to MetalKit for rendering.

In step 4, I'd like to add a few points:

  1. When calling drawPrimitives, the primitive type provided is 'point'.
  2. In the fragment shader code, I've included some calculations for alpha transitions (the farther from the center of the primitive, the lower the alpha channel value) to mitigate some of the aliasing.

In summary, my current approach involves interpolating the trajectory of the handwriting into a very dense set of point primitives, which are then rendered on the screen.

Following these steps, I've been able to successfully render a stroke, but the edges of the stroke are still not as smooth and clear as those in PencilKit.

My attempted stroke My attempted stroke(zoomed)

Therefore, I'm looking to clarify two key points:

  1. Is the approach I've described above correct?
  2. Are there other methods that could achieve a better result, such as combining point primitives with triangle primitives, or calculating a high-precision CGPath for the strokes?

Given the uncertainty about whether my current approach is fundamentally flawed, I've opted not to post the lengthy source code here to avoid cluttering the discussion. If you think my current approach is on the right track, I can provide the source code for further discussion later.

Thank you for your insights!

Upvotes: 1

Views: 147

Answers (0)

Related Questions