The following post/code will achieve something to the effect of:
All this code, and this article was inspired by planetclegg.com/projects/WarpingTextToSplines.html.
Explanation of the math and why it works will come shortly. In the meantime, please see the above link for a detailed explanation.
This code assumes you have already drawn some text on your GraphicsPath. Here is the code to transform your GraphicsPath text to follow a cubic Bézier Spline:
GraphicsPath BezierWarp(GraphicsPath text,Size size)
{
// Control points for a cubic Bézier spline
PointF P0 = new PointF();
PointF P1 = new PointF();
PointF P2 = new PointF();
PointF P3 = new PointF();
float shrink = 20;
float shift = 0;
P0.X = shrink;
P0.Y = shrink+shift;
P1.X = size.Width-shrink;
P1.Y = shrink;
P2.X = shrink;
P2.Y = size.Height-shrink;
P3.X = size.Width-shrink;
P3.Y = size.Height-shrink-shift;
// Calculate coefficients A thru H from the control points
float A = P3.X - 3 * P2.X + 3 * P1.X - P0.X;
float B = 3 * P2.X - 6 * P1.X + 3 * P0.X;
float C = 3 * P1.X - 3 * P0.X;
float D = P0.X;
float E = P3.Y - 3 * P2.Y + 3 * P1.Y - P0.Y;
float F = 3 * P2.Y - 6 * P1.Y + 3 * P0.Y;
float G = 3 * P1.Y - 3 * P0.Y;
float H = P0.Y;
PointF[] pathPoints = text.PathPoints;
RectangleF textBounds = text.GetBounds();
for (int i =0; i < pathPoints.Length; i++)
{
PointF pt = pathPoints[i];
float textX = pt.X;
float textY = pt.Y;
// Normalize the x coordinate into the parameterized
// value with a domain between 0 and 1.
float t = textX / textBounds.Width;
float t2 = (t * t);
float t3 = (t * t * t);
// Calculate spline point for parameter t
float Sx = A * t3 + B * t2 + C * t + D;
float Sy = E * t3 + F * t2 + G * t + H;
// Calculate the tangent vector for the point
float Tx = 3 * A * t2 + 2 * B * t + C;
float Ty = 3 * E * t2 + 2 * F * t + G;
// Rotate 90 or 270 degrees to make it a perpendicular
float Px = - Ty;
float Py = Tx;
// Normalize the perpendicular into a unit vector
float magnitude = (float)Math.Sqrt((Px*Px) + (Py*Py));
Px /= magnitude;
Py /= magnitude;
// Assume that input text point y coord is the "height" or
// distance from the spline. Multiply the perpendicular
// vector with y. it becomes the new magnitude of the vector
Px *= textY;
Py *= textY;
// Translate the spline point using the resultant vector
float finalX = Px + Sx;
float finalY = Py + Sy;
pathPoints[i] = new PointF(finalX, finalY);
}
return new GraphicsPath(pathPoints,text.PathTypes);
}