Assuming that you have read Drawing 2d text

Here is a WebGL example showing what’s taking place in Sketch.h and Sketch.cpp from the DrawingTextOnPath project’s source folder.

Sketch.cpp

Inside setup()

At this stage, you should understand what is going on. Anyway, we create a FollowablePath2D by sampling a peanut-shaped B-spline (it has been covered in Moving on paths.)

Inside draw()

font->beginSequence(sequence);
drawTextOnPath(*font, TEXT, path, -clock()->getTime() * 75.0f, XFont::ALIGN_MIDDLE);
font->endSequence();
font->replaySequence(sequence);

We create a dynamic sequence, which makes the text follow the path. Let’s take a look at drawTextOnPath():

void Sketch::drawTextOnPath(XFont &font, const u16string &text, const FollowablePath2D &path, float offset, XFont::Alignment alignY)
{
  float offsetY = font.getOffsetY(alignY);
  Matrix matrix;

  for (auto c : text)
  {
    auto glyphIndex = font.getGlyphIndex(c);
    float halfWidth = font.getGlyphAdvance(glyphIndex) / 2;
    offset += halfWidth;

    if (glyphIndex >= 0)
    {
        path
          .offsetToValue(offset, halfWidth * 2)
          .applyToMatrix(matrix);

        font.addGlyph(matrix, glyphIndex, -halfWidth, offsetY);
    }

    offset += halfWidth;
  }
}

For each character in the text, we call offsetToValue() with 2 parameters. The first one is the offset (or distance) on the path and the second is the sample-size, which is related to the size of the object that we’re going to animate on the path (for instance, we use the width of the glyph.) Then, this function returns a value, which is a structure containing information about the 2d position and the rotation at the specified offset. Finally, we apply this value to a 4x4 matrix, which we use for drawing the glyph.

As usual, the idea of using halfWidth is to properly draw the glyph from its horizontal center.