#!/usr/bin/perl -T #By Ben Jacobs 2001 # "Use": Colors a string with a gradient. The user inputs # the string and two colors in hexedcimal. # Comments welcome, I know this isn't a very efficient # script but it's the best I could come up with. use strict; use warnings; use CGI qw/:standard/; use HTML::Entities; # Set globals my $error = ''; my $string_length_limit = 50; $|++; # kill buffering # Grab params my $string = param('string'); my $bgcolor = param('bgcolor'); my $fromcolor = param('fromcolor'); my $tocolor = param('tocolor'); # untaint everything my ( $safe_string ) = ( $string =~ /^(.*)$/ ); $safe_string = encode_entities( $safe_string ); my ( $safe_bgcolor ) = ( $bgcolor =~ /^([a-fA-F0-9]{6})$/ ); my ( $safe_fromcolor ) = ( $fromcolor =~ /^([a-fA-F0-9]{6})$/ ); my ( $safe_tocolor ) = ( $tocolor =~ /^([a-fA-F0-9]{6})$/ ); # validate data if ( length $safe_string > $string_length_limit ) { $safe_string = substr $safe_string, 0, $string_length_limit; param( 'string', $safe_string ); # truncate param to 50 characters so sticky fields # don't overflow $error .= p( 'Length of input string must not be longer than 50 characters' ); } if ( ! defined $safe_bgcolor ) { $error .= p( '"Background Color" must be a six digit hexadecimal number.' ); } if ( ! defined $safe_fromcolor ) { $error .= p( '"From Color" must be a six digit hexadecimal number.' ); } if ( ! defined $safe_tocolor ) { $error .= p( '"To Color" must be a six digit hexadecimal number.' ); } my $error_html = ''; if ( $error and param( 'not_first_run' ) ) { $error_html = error( $error ); } print header, start_html( -title => 'Text Gradient', -bgcolor => $bgcolor ), start_form, $error_html, table( { -border => 0, -cellspacing => 0, -cellpadding => 3 }, Tr( [ td( [ 'String', textfield( -name => 'string', -default => 'This is a test', -size => $string_length_limit, -maxlength => $string_length_limit ) ], ), td( [ 'Background', textfield( -name => 'bgcolor', -default => 'FFFFFF', -size => 6, -maxlength => 6 ) ], ), td( [ 'From color', textfield( -name => 'tocolor', -default => 'FFFFCC', -size => 6, -maxlength => 6 ) ], ), td( [ 'To color', textfield( -name => 'fromcolor', -default => '0000CC', -size => 6, -maxlength => 6 ) ], ) ] ) ), submit, hidden( -name => "not_first_run", -value => "yes" ), end_form; print p( color($string, $fromcolor, $tocolor) ) if ! $error; print end_html; sub hexify { my $red = shift; my $green = shift; my $blue = shift; sprintf("%.2x%.2x%.2x", $red, $green, $blue); } sub color { my $string = shift; my $FromColor = shift; my $ToColor = shift; my @letters = split //, $string; my ($fromR, $fromG, $fromB) = ( $FromColor =~ /(\w{2})(\w{2})(\w{2})/ ); my ($toR, $toG, $toB) = ( $ToColor =~ /(\w{2})(\w{2})(\w{2})/ ); $fromR = hex($fromR); $toR = hex($toR); $fromG = hex($fromG); $toG = hex($toG); $fromB = hex($fromB); $toB = hex($toB); my $rstep; my $gstep; my $bstep; if ( $fromR > $toR) { $rstep = ($fromR - $toR) / length($string); } elsif ( $fromR < $toR) { $rstep = ($toR - $fromR) / length($string); } if ( $fromG > $toG) { $gstep = ($fromG - $toG) / length($string); } elsif ( $fromR < $toR) { $gstep = ($toG - $fromG) / length($string); } if ( $fromB > $toB) { $bstep = ($fromB - $toB) / length($string); } elsif ( $fromR < $toR) { $bstep = ($toB - $fromB) / length($string); } my $happystring = ''; my $r = 0; my $g = 0; my $b = 0; foreach my $letter (@letters) { if($r == 1) { $fromR -= $rstep; } else { $fromR += $rstep; } if($g == 1) { $fromG -= $rstep; } else { $fromG += $gstep; } if($b == 1) { $fromB -= $bstep; } else { $fromB += $bstep; } if ( $fromR > 255) { $r = 1; } elsif ( $fromR < 0) { $r = 0; } if ( $fromG > 255) { $g = 1; } elsif ( $fromG < 0) { $g = 0; } if ( $fromB > 255) { $b = 1; } elsif ( $fromB < 0) { $b = 0; } my $hexcolors = hexify($fromR, $fromG, $fromB); $happystring .= font( { -color => "#$hexcolors" }, $letter ); } $happystring; } sub error { my $error = shift; return ( h1( 'Error in User Input' ) . p( $error ) ); }