B4J Tutorial [B4X] Text Along Any Curve

The example here uses a Bezier curve which is one of a lot of possible curves.
But the text drawing routine works on any list of points.
The attached .zip has all the code (140 lines).


Sub Class_Globals
    Type myPoint (x As Float, y As Float)
    Type bezierSpec (p0 As myPoint, p1 As myPoint, p2 As myPoint, p3 As myPoint)
    Private fx As JFX
    Private Root As B4XView
    Private xui As XUI
    Private cv As B4XCanvas
End Sub

Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Dim w As Float = 300dip
    Dim h As Float = 400dip
    Dim basePanel As B4XView = xui.CreatePanel("")
    basePanel.SetColorAndBorder(xui.Color_Transparent, 1dip, xui.Color_Black, 10dip)
    Root.AddView(basePanel, Root.Width / 2 - w /2, Root.Height / 2 - h / 2, w, h)
    Dim aw As Float = .5
    Dim ah As Float = -.7
    Dim p0 As myPoint = setP(0, 0)
    Dim p1 As myPoint = setP(aw * w, .05 * h)
    Dim p2 As myPoint = setP(ah * w, .95 * h)
    Dim p3 As myPoint = setP(w, h)
    Dim bz As bezierSpec = setSpec(p0, p1, p2, p3)
    Dim points As List = BuildBezierCurve(bz)
    TextOnCurve("The Time Has Come, the Walrus Said; to Speak of Many Things",    xui.CreateDefaultFont(16), 23dip, points)
    'Bezier curves have two end points and two intermediate control points
    'To show control points of bezier curve make sure width and height >= 1000 (in example, p2 is not in the panel)
    'Also see how easy it would be to animate the curve and text by varying the control points in small increments
    'and redrawing the text
    Dim cv2 As B4XCanvas
    cv2.DrawCircle(basePanel.Left + p0.x, basePanel.top + p0.y, 5dip, xui.Color_Red, True, 0)
    cv2.DrawCircle(basePanel.Left + p1.x, basePanel.top + p1.y, 5dip, xui.Color_Red, True, 0)
    cv2.DrawCircle(basePanel.Left + p2.x, basePanel.top + p2.y, 5dip, xui.Color_Red, True, 0)
    cv2.DrawCircle(basePanel.Left + p3.x, basePanel.top + p3.y, 5dip, xui.Color_Red, True, 0)

    cv2.DrawText("p0", basePanel.Left + p0.x + 5dip, basePanel.top + p0.y, xui.CreateDefaultFont(15), xui.Color_Black, "LEFT")
    cv2.DrawText("p1", basePanel.Left + p1.x + 5dip, basePanel.top + p1.y, xui.CreateDefaultFont(15), xui.Color_Black, "LEFT")
    cv2.DrawText("p2", basePanel.Left + p2.x + 5dip, basePanel.top + p2.y, xui.CreateDefaultFont(15), xui.Color_Black, "LEFT")
    cv2.DrawText("p3", basePanel.Left + p3.x + 5dip, basePanel.top + p3.y, xui.CreateDefaultFont(15), xui.Color_Black, "LEFT")

End Sub


  • CurvedText.zip
    51.9 KB · Views: 317

William Lancee

Well-Known Member
Licensed User
Longtime User
I can put the text on a curve but I didn't get the quote correct. The Poem by Lewis Carroll seems oddly appropriate for today's world.

The Walrus and the Carpenter Lewis Carroll - 1832-1898
(This poem is in the public domain)

The sun was shining on the sea, Shining with all his might:
He did his very best to make The billows smooth and bright
And this was odd, because it was The middle of the night.

The moon was shining sulkily, Because she thought the sun
Had got no business to be there After the day was done
"It's very rude of him," she said, "To come and spoil the fun!"

The sea was wet as wet could be, The sands were dry as dry.
You could not see a cloud because No cloud was in the sky:
No birds were flying overhead — There were no birds to fly.

The Walrus and the Carpenter Were walking close at hand:
They wept like anything to see Such quantities of sand:
"If this were only cleared away," They said, "it would be grand!"

"If seven maids with seven mops Swept it for half a year,
Do you suppose," the Walrus said, "That they could get it clear?"
"I doubt it," said the Carpenter, And shed a bitter tear.

"0 Oysters, come and walk with us!" The Walrus did beseech.
"A pleasant walk, a pleasant talk, Along the briny beach:
We cannot do with more than four, To give a hand to each."

The eldest Oyster looked at him, But never a word he said;
The eldest Oyster winked his eye, And shook his heavy head
Meaning to say he did not choose To leave the oyster-bed.

But four young Oysters hurried up, All eager for the treat:
Their coats were brushed, their faces washed, Their shoes were clean and neat
And this was odd, because, you know, They hadn't any feet.

Four other Oysters followed them, And yet another four;
And thick and fast they came at last, And more and more and more
All hopping through the frothy waves, And scrambling to the shore.

The Walrus and the Carpenter Walked on a mile or so,
And then they rested on a rock Conveniently low:
And all the little Oysters stood And waited in a row.

"The time has come," the Walrus said, "To talk of many things:
Of shoes—and ships—and sealing-wax — Of cabbages—and kings
And why the sea is boiling hot — And whether pigs have wings."

"But wait a bit," the Oysters cried, "Before we have our chat;
For some of us are out of breath, And all of us are fat!"
"No hurry!" said the Carpenter. They thanked him much for that.

"A loaf of bread," the Walrus said, "Is what we chiefly need:
Pepper and vinegar besides Are very good indeed
Now, if you're ready, Oysters dear, We can begin to feed."

"But not on us!" the Oysters cried, Turning a little blue.
"After such kindness, that would be A dismal thing to do!"
"The night is fine," the Walrus said, "Do you admire the view?

"It was so kind of you to come! And you are very nice!"
The Carpenter said nothing but "Cut us another slice.
I wish you were not quite so deaf — I've had to ask you twice!"

"It seems a shame," the Walrus said, "To play them such a trick.
After we've brought them out so far, And made them trot so quick!"
The Carpenter said nothing but "The butter's spread too thick!"

"I weep for you," the Walrus said: "I deeply sympathize."
With sobs and tears he sorted out Those of the largest size,
Holding his pocket-handkerchief Before his streaming eyes.

"O Oysters," said the Carpenter, "You've had a pleasant run!
Shall we be trotting home again?" But answer came there none
And this was scarcely odd, because They'd eaten every one.