#!/usr/bin/perl -w # Example 2-2. Make a billboard from user input use strict; use CGI; use GD; # The maximum number of characters allowed in the input string my $maxchars = 220; my $filename = 'blankbillboard.png', my ($x1, $y1) = (50,60); # starting point my ($cx, $cy) = ($x1, $y1); # The current point my ($width, $height) = (213,56); # dimensions of the drawing area my $dy = -.0657; # initial slope of the baseline my $ddy = .0003214; # change in slope with each line # Extract the CGI parameters my $q=new CGI; my $string = $q->param('string'); # Replace all space-like characters with spaces $string =~ s/\s+/ /g; # Check length of the string if (length($string) > $maxchars) { print "Content-type: text/html\n\n"; print < There is a problem with your submisison...

Sorry, can't be more than $maxchars chars...

ENDHTML exit; } # The text is displayed in one of three fonts, depending # on the number of characters in the string. my @fonts = (gdLargeFont, gdSmallFont,gdTinyFont); # Pick the font to use, based on a guesstimate of whether the # string fits within the block at a particular size. my $font = gdTinyFont; LOOP: foreach my $f (@fonts) { if (length($string) <= 750/$f->width()) { $font = $f; last LOOP; } } # Open the background image open (IMG, $filename) or die "Couldn't open image...\n"; my $img = newFromPng GD::Image(\*IMG); close IMG; # Allocate a color in which to draw text my $white = $img->colorAllocate(255,255,255); # Split the string into individual words my @words = split ' ', $string; my $w = 0; # Initialize the cumulative width my $starty = $y1; # Initialize the starting y coordinate WORD: while (@words) { my $word = shift (@words); # First take care of the case where a single string is longer # than the width if (($font->width() * length($word)) > $width ) { # Divide the string in two and push the two words # back on the list my $length = int($width/$font->width()); my $front = substr($word, 0, $length); my $remainder = substr($word, $length+1, length($string)-1); $word = $front; unshift @words, $remainder; } if ((($font->width() * length($word)) + $w) > $width ) { # Start a new line $cx = $x1; $cy = $starty + $font->height(); # Move the current y pt $starty = $cy; $dy = $dy + $ddy * ($cy - $y1); $w = 0; # Move to next word if the line starts with a space if ($word eq ' ') { next WORD; } } # Now draw each character individually my @chars = split '', $word; push @chars, ' '; # Push a space on the end foreach my $char (@chars) { $img->char($font, $cx, $cy, $char, $white); # Move the current point $w = $w + $font->width(); $cx = $cx + $font->width(); $cy = $starty + int($w * $dy); } } # Write the image as a PNG print $q->header(-type => 'image/png'); binmode(STDOUT); print $img->png; exit;