gregfriend has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I am wanting to create a CGI script that will take user input and place the text along a bezier curve. Are there any modules out there that I can use to further me in this task? I would like to be able to use TrueType fonts since I need to use a script font and I am not sure how well represented script is outside of TrueType. In addition to any modules that might help, could you point me to information about the process used or the math involved in doing such a thing?

Thanks,

Greg Friend

Replies are listed 'Best First'.
Re: CGI Text on a path -- Possible?
by matija (Priest) on Feb 26, 2004 at 22:49 UTC
    I don't think anybody has done exactly what you're looking for, but here is something that looks like a solid start:GD::Text::Arc.

    While it's not what you're looking for, it is probably a solid start. If you manage to create code that will do Bezier paths the way GD::Text::Arc does arcs, please package it as a module and put it on CPAN. Pretty please?

Re: CGI Text on a path -- Possible?
by kvale (Monsignor) on Feb 26, 2004 at 22:46 UTC
    I dont know of any modules that will do this explicitly. HTML doesn't do curved paths (yet), so you will have to create a graphic.

    The GD module has functions for printing type to an image. In particular, gdImageStringFT() can handle TrueType fonts and gdImageStringFTCircle() handles text along a circle. If you want to draw text along a bezier, try using Math::Bezier to model your bezier and draw single characters along the bezier.

    -Mark

Re: CGI Text on a path -- Possible?
by bart (Canon) on Feb 27, 2004 at 01:12 UTC
    The most important question for you is: "What image manipulation module that I can use from within Perl, can draw text on a curve?" I recall I once saw something like that in a use.perl journal... And here it is: GD::Text::Arc.

    Yes you can use GD from within a CGI script, to generate JPEG and PNG files — GIF has been abandoned out of protest against the ridiculous behaviour of the patent holder...

      I thought that the main gif (LZW) patent expired last year (at least in the United States).
Postscript
by sleepingsquirrel (Chaplain) on Feb 26, 2004 at 23:10 UTC
    It dosen't directly use perl, but you can do what you want with postscript code and ghostscript to produce a bitmap. Start with this example program from the Blue Book and modify it to suit your needs. Then use ghostscript to produce a suitable image format.
Re: CGI Text on a path -- Possible?
by Roger (Parson) on Feb 26, 2004 at 22:48 UTC
    That depends. Your question is too generic. What are you trying to do? Curve fitting? And also you haven't told us what is the expected output yet. If you only want to draw the text inside an image, that would be easy. You could do that with GD and similar packages. If you want to present output as plain text, then you need to add <pre> and </pre> tags around your output to preserve the returns. But the solution depends on your actual problem.

    So one step at a time. Please give more detail on the problem.

      The output file will be an image - jpg, bmp etc. Whatever I can manage. What I am wanting to do is to take a user's family tree information and format it in the actual shape of a tree where the names form the trunk and the branches. I was able to automate it pretty well with the VB sendkeys function and CorelDRAW providing the graphics engine (with built in text on a path support) but it still required quite a bit of manual tweaking to make it look good. The bezier curve requirement is because the branches look better and fit together better when there is a dual curve to them. I want to make it CGI because I would like to shift the burden of the manual tweaking to the user rather than me. :) So I guess in addition to the text on a path question I also need to know how to get that information into a jpg or bmp. Someone suggested the GD module but I haven't had a chance to look at it yet.

      Greg Friend
        I wrote a bezier text demo below, that will give you something to start with. It will be easy to convert this demo to work from the browser, just print appropriate content header, binmode the STDOUT, and dump the image to the STDOUT.
        use strict; use warnings; use Math::Bezier; use GD; use IO::File; my @control = ( 0, 0, 100, 200, 300, -200, 400, 0 ); my $bezier = Math::Bezier->new(@control); my $text = "Hello World, this is Perl"; my $len = length($text); my @curve = $bezier->curve($len); my @pos = map { my $idx = $_ * 2; [ $curve[$idx], $curve[$idx + 1] ] } 0 .. $len - 1; my $im = new GD::Image(1024, 768); my $white = $im->colorAllocate(0,0,0); my $black = $im->colorAllocate(255,255,255); my @chars = split //, $text; $im->string(gdGiantFont, $pos[$_][0] + 200, $pos[$_][1] + 500, $chars[$_], $black) for 0..$#chars; my $f = new IO::File "test.jpg", "w" or die; binmode $f; print $f $im->jpeg;

        You can also use the Windows version of ImageMagick which has built-in support for bezier text (I think), and it is an excellent graphics package.