Regarding the code listed in my previous post, let’s take one step back and look at the problem from a very high level. Often, it’s easier to understand an approach to solving a problem if you can relate it to something similar, yet simpler. So, suppose your task were to render text one letter at a time with constant spacing (tracking) along a horizontal line. How would you write the program?

Starting at the beginning of the line (minimum x-coordinate if rendering LTR), you would probably place a letter then use its width (and the number of px spacing) to compute the x-coordinate of the next letter. The letter’s height would be used to compute the y-coordinate of the TextField relative to the y-coordinate of the horizontal line. So, if the horiztontal line starts at coordinates (100,100) and the first letter happens to be 22px tall and 20px wide and there is a constant 15px spacing between letters, a simple algorithm for placing that letter would be to position the TextField at (100, 100-22). The second letter would be positioned at (100+20+15, 100-22). In this simple approach, puncutation and text metrics are not taken into account. No consideration of lowercase descending characters, etc.

Next, suppose that the line is not horizontal. How does the algorithm change? Instead of positioning letters at strictly horizontal increments, we now have to move in increments along the line. So, if a letter is 20px wide with a 15px spacing, we need to increment a distance of 35px along the line in order to place the next letter. The easiest way to accomplish this task is to use a unit vector in the direction of the line.

We also have to orient (rotate) the TextField to match the slope of the line. The angle the unit vector makes with the horizontal provides this information. The TextField is offset from the line along the normal (perpendicular to the line) the same distance as the text height. Since we know the unit vector, we also know the normal vector as the rotation matrix for a CCW rotation of PI/2 is trivial.

In a simplistic sense, we are using Frenet-Serret coordinates (or frame – without the binormal) to position the text and the unit vector information to orient the text.

The final step in the overview is to translate the concept of a line with general orientation to a spline curve. The concept of distance along the line is now translated to distance along the spline. This is why it is important that the spline be parameterized on arc length. Arc-length parameterization allows us to request specific distances along the curve to compute the tangent and normal direction vectors. Once we have these vectors, the approach is exactly the same as the straight line.

In subsequent posts, I will deconstruct how the posted code accomplishes the simple algorithm for text distribution along a cubic Bezier spline.

OK, this is starting to make sense.