drawing text along a curved line?

newguy

Well-known member
Joined
Jun 30, 2008
Messages
611
Location
Denver Co, USA
Programming Experience
1-3
Working on drawing text along a curved line that contains 4 points. The text part works, but as I change/move the points the text has different spacings B/T the letters. I would like to see if I could get the text to remain the same spacing - any ideas on how I would change this code? Or if this it is poss to fix this. Here is the sub I am using:
VB.NET:
Private Sub DrawTextOnPath(ByVal target As Graphics, _
                ByVal baseLine As GraphicsPath, ByVal text As String, ByVal fnt As Font, ByVal col As Color)
    'SUB: Draws a string that has been fitted to a base curve defined inside the graphicspath
    'the effect is similar to WordArt in MS Word.  This assumes that there is a curve in the path object.
    Try
      Dim x, y, dx, dy As Single
      Dim letters As Char() = text.ToCharArray()
      Dim fontScale As Single = fnt.Size * fnt.FontFamily.GetCellAscent(fnt.Style) / fnt.FontFamily.GetEmHeight(fnt.Style)
      Dim m As Matrix = New Matrix
      'break up the smooth curve into a sequence of straight lines (tight curves may become jagged)
      baseLine.Flatten(m, DEFAULT_FLATNESS)
      'the matrix is just a default one
      'upper bound for loop counter
      Dim upper As Integer = Math.Min(baseLine.PathPoints.Length - 2, text.Length - 1)
      Dim scale As Single = 0
      Dim textBrush As Brush = New SolidBrush(col)
      With baseLine
        For i As Integer = 0 To upper
          x = .PathPoints(i).X
          y = .PathPoints(i).Y
          'find the normal by swapping the coords and negating the final y falue
          dx = .PathPoints(i + 1).Y - y
          dy = x - .PathPoints(i + 1).X
          ''dx = .PathPoints(i + 1).Y - y
          ''dy = x - .PathPoints(i + 1).X
          'change the dx, dy vector into a unit vector ("normalize" the normal)
          scale = (fontScale / CType(Math.Sqrt((dx * dx) + (dy * dy)), Single))
          dx *= scale
          dy *= scale
          m.Reset()
          'position the character
          m.Translate(x + dx, y + dy)
          'rotate the character to align it to the curve
          m.Rotate(CType((Math.Atan2(dy, dx) * TO_DEGREES) + 90, Single))
          target.Transform = m                            'apply the transformation to the target surface
          'draw a single character onto the target surface
          target.DrawString(letters(i), fnt, textBrush, 0, 0)
        Next i
      End With
    Catch
    End Try
End Sub
 

Attachments

  • myLine.jpg
    myLine.jpg
    3.9 KB · Views: 88
Has any figured out a way to arch text? I am working on a project that requires text from a string to be arched along the top of an oval. Any ideas?
 
Have you tried the link JohnH posted? I haven't looked at the code but the results look very good. I think you would only have to make the path _gp in the author's Usage Example in a different way. Instead of defining the path from an array of points, you should use _gp.AddArc with arguments to define the ellipse segment you want to use.

Alternatively you could try a method I posted (as my alter ego boops boops) for deforming text into a curved shape. In that example the text has a pincushion shape with an ellipse at the top and bottom. It works by adding text to a graphics path with GraphicsPath.AddString and then modifying the path's PathPoints with a trig function. It's not fast, but I like the results. You could get an arched shape by replacing the line that sets the value of newY, for example to this:
VB.NET:
	Dim newY = pf.Y + 200 * (1 - Math.Cos(pf.X / w))
You would have to experiment with the values to get the particular shape you want, and it will also depend on the font you use.

Vic
 
Back
Top