Skip to main content

Generating ink content

Important note

This is documentation for WILL SDK for ink WILL2, which is no longer actively maintained. For up-to-date documentation, see the latest version (WILL3).

There are two modules that are key to the path generation process: the Path module and the Smoothing module.

The Path module converts raw input events into paths that follow the mathematical model that is used in the WILL Software Library. This model represents a stroke as a Catmull-Rom interpolated sequence of control points, in which each point has a 2D position and optional width and opacity values. The configuration that the application developer applies determines the exact properties of each point in a path.

The Smoothing module modifies the points generated by the Path module to improve the appearance of the stroke. The Path and Smoothing modules are designed to work together.

Path module

The Path module is designed to absorb the specifics of various input technologies and convert the input into a path that is independent of specific input technology. This conversion is achieved through components that can be configured to fit in all types of pointer input technologies: mouse, touch, and active pen.


The Path module contains two components called SpeedPathBuilder and PressurePathBuilder. These components provide two implementations of a single strategy for path generation. In principle, this strategy is as follows:

  1. Calculate the generator value from either the input speed or the input pressure.
  2. Use the generator value to vary stroke width and opacity (depending on the configuration).
  3. Adjust the position and the optionally-generated values to represent control points in a Catmull-Rom interpolated path.

The SpeedPathBuilder component calculates path geometry based on the speed of the input, and PressurePathBuilder calculates path geometry based on the input pressure.


Because both components share the same abstract strategy for path generation, they also share the same configuration options. These configuration options are as follows:

  • Minimum movement threshold The minimum distance that the pointer device must travel before the input is accepted for processing.
  • Min-max normalization of the input Minimum and maximum values of the width/opacity generator value. For the SpeedPathBuilder component, this normalization refers to the input velocity. For the PressurePathBuilder component, this normalization refers to the pressure.
  • Width configuration The start and end values, minimum and maximum values, and generation function (exponential, periodic, or sigmoid) for variable width generation.
  • Alpha configuration The start and end values, minimum and maximum values, and generation function (exponential, periodic, or sigmoid) for variable opacity generation.

Path construction

The path construction process is divided into three phases:

  1. Converting a pointer event into a partial path
  2. Adding the partial path to the existing path
  3. Finishing the existing path

Dividing the path construction gives you flexibility to process the partial path (for example, to smooth its control values) before adding it to the existing path.

Because a Catmull-Rom spline is not defined between the last two control points, there might be an offset between the last point defined by the path generation process and the position of the pointer on the screen. This offset can be perceived by the user as lag.

To eliminate this offset, you can use preliminary paths. This technique creates a preview path that connects the last point at which the path is defined to the current position of the pointer. The Path module components support this technique. At any time, the path builder can obtain the preliminary path without altering the original path that is under construction. The preliminary path is presented to the user temporarily for one frame (16 ms) to eliminate the perceived lag. For more information, see the tutorials on drawing preliminary paths for the desired platform.

A path is constructed in a linear vector that contains the control points represented as consequent float values. Depending on the configuration used, one control point can be represented by two, three, or four consequent float values. The number of the consequent values required to represent one control point is referred to as stride, as follows:

  • Stride two The stroke has position coordinates only. It will be drawn with constant width and opacity.
  • Stride three The stroke has position coordinates and either variable width or variable opacity. Use an additional variable in conjunction with the stroke to specify whether the opacity or the width is variable.
  • Stride four The stroke has position coordinates and both variable width and opacity.

Note: The stride concept is partially hidden in some of the platform-specific APIs.

Smoothing module

The Smoothing module provides a beautification algorithm that is optimized for control points generated using an input rate of 60 events per second. It greatly enhances the geometry of paths generated with the SpeedPathBuilder component.

The Smoothing module contains a component designed to be used in combination with PathBuilder components. When a partial path is generated by the PathBuilder component, you can invoke the smoothing component on the partial path. The smoothing component will alter the position of the control points.

The smoothing component instance works per channel (that is, position, width, or opacity). This allows the developer to apply the smoothing technique only on certain channels. For example, you can apply smoothing only to width values in the PathBuilder component, leaving the position unsmoothed to follow the user pointer more accurately. The Smoothing module includes a platform-specific helper to make its use more streamlined. It is important to note that the smoothing component works on a per-stroke basis and must therefore be reset between different strokes.

Smoothing preliminary paths

The smoothing technique increases the lag introduced by the Catmull-Rom spline. To counteract this, the smoothing component provides a smooth-finish technique that smooths a partial path between the last smoothed point and the position of the user pointer on the screen. This technique not only alters the position of the points in the partial path, but also generates new points to ensure that the smoothed partial path still reaches the pointer position. You can invoke this method on the partial path or the preliminary path obtained by the PathBuilder component.