home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / tsw / TSW_3.4.0.exe / Apache2 / perl / colour.pm < prev    next >
Encoding:
Perl POD Document  |  2003-02-10  |  7.6 KB  |  372 lines

  1. #==========================================================================
  2. #              Copyright (c) 1995-1998 Martien Verbruggen
  3. #--------------------------------------------------------------------------
  4. #
  5. #   Name:
  6. #       GD::Graph::colour.pm
  7. #
  8. #   Description:
  9. #       Package of colour manipulation routines, to be used 
  10. #       with GD::Graph.
  11. #
  12. # $Id: colour.pm,v 1.10 2003/02/11 05:38:46 mgjv Exp $
  13. #
  14. #==========================================================================
  15.  
  16.  
  17. package GD::Graph::colour;
  18.  
  19. ($GD::Graph::colour::VERSION) = '$Revision: 1.10 $' =~ /\s([\d.]+)/;
  20.  
  21. =head1 NAME
  22.  
  23. GD::Graph::colour - Colour manipulation routines for use with GD::Graph
  24.  
  25. =head1 SYNOPSIS
  26.  
  27. use GD::Graph::colour qw(:colours :lists :files :convert);
  28.  
  29. =head1 DESCRIPTION
  30.  
  31. The B<GD::Graph::colour> package provides a few routines to work with
  32. colours. The functionality of this package is mainly defined by what is
  33. needed, now and historically, by the GD::Graph modules.
  34.  
  35. =cut
  36.  
  37. use vars qw( @EXPORT_OK %EXPORT_TAGS );
  38. use strict;
  39. require Exporter;
  40. use Carp;
  41.  
  42. @GD::Graph::colour::ISA = qw( Exporter );
  43.  
  44. @EXPORT_OK = qw( 
  45.     _rgb _luminance _hue add_colour
  46.     colour_list sorted_colour_list
  47.     read_rgb
  48.     hex2rgb rgb2hex
  49. );
  50. %EXPORT_TAGS = ( 
  51.     colours => [qw( add_colour _rgb _luminance _hue )],
  52.     lists => [qw( colour_list sorted_colour_list )],
  53.     files => [qw( read_rgb )],
  54.     convert => [qw( hex2rgb rgb2hex )],
  55. );
  56.  
  57. my %RGB = (
  58.     white   => [0xFF,0xFF,0xFF], 
  59.     lgray   => [0xBF,0xBF,0xBF], 
  60.     gray    => [0x7F,0x7F,0x7F],
  61.     dgray   => [0x3F,0x3F,0x3F],
  62.     black   => [0x00,0x00,0x00],
  63.     lblue   => [0x00,0x00,0xFF], 
  64.     blue    => [0x00,0x00,0xBF],
  65.     dblue   => [0x00,0x00,0x7F], 
  66.     gold    => [0xFF,0xD7,0x00],
  67.     lyellow => [0xFF,0xFF,0x00], 
  68.     yellow  => [0xBF,0xBF,0x00], 
  69.     dyellow => [0x7F,0x7F,0x00],
  70.     lgreen  => [0x00,0xFF,0x00], 
  71.     green   => [0x00,0xBF,0x00], 
  72.     dgreen  => [0x00,0x7F,0x00],
  73.     lred    => [0xFF,0x00,0x00], 
  74.     red     => [0xBF,0x00,0x00],
  75.     dred    => [0x7F,0x00,0x00],
  76.     lpurple => [0xFF,0x00,0xFF], 
  77.     purple  => [0xBF,0x00,0xBF],
  78.     dpurple => [0x7F,0x00,0x7F],
  79.     lorange => [0xFF,0xB7,0x00], 
  80.     orange  => [0xFF,0x7F,0x00],
  81.     pink    => [0xFF,0xB7,0xC1], 
  82.     dpink   => [0xFF,0x69,0xB4],
  83.     marine  => [0x7F,0x7F,0xFF], 
  84.     cyan    => [0x00,0xFF,0xFF],
  85.     lbrown  => [0xD2,0xB4,0x8C], 
  86.     dbrown  => [0xA5,0x2A,0x2A],
  87. );
  88.  
  89. =head1 FUNCTIONS
  90.  
  91. =head2 colour_list( I<number of colours> )
  92.  
  93. Returns a list of I<number of colours> colour names known to the package.
  94. Exported with the :lists tag.
  95.  
  96. =cut
  97.  
  98. sub colour_list 
  99. {
  100.     my $n = ( $_[0] ) ? $_[0] : keys %RGB;
  101.     return (keys %RGB)[0 .. $n-1]; 
  102. }
  103.  
  104. =head2 sorted_colour_list( I<number of colours> )
  105.  
  106. Returns a list of I<number of colours> colour names known to the package, 
  107. sorted by luminance or hue.
  108. B<NB.> Right now it always sorts by luminance. Will add an option in a later
  109. stage to decide sorting method at run time.
  110. Exported with the :lists tag.
  111.  
  112. =cut
  113.  
  114. sub sorted_colour_list 
  115. {
  116.     my $n = $_[0] ? $_[0] : keys %RGB;
  117.     return (sort by_luminance keys %RGB)[0 .. $n-1];
  118.     # return (sort by_hue keys %rgb)[0..$n-1];
  119.  
  120.     sub by_luminance { _luminance(@{$RGB{$b}}) <=> _luminance(@{$RGB{$a}}) }
  121.     sub by_hue       { _hue(@{$RGB{$b}}) <=> _hue(@{$RGB{$a}}) }
  122. }
  123.  
  124. =head2 _rgb( I<colour name> )
  125.  
  126. Returns a list of the RGB values of I<colour name>. if the colour name
  127. is a string of the form that is acceptable to the hex2rgb sub, then the
  128. colour will be added to the list dynamically.
  129. Exported with the :colours tag.
  130.  
  131. =cut
  132.  
  133. my %warned_clrs = ();
  134.  
  135. # return the RGB values of the colour name
  136. sub _rgb 
  137.     my $clr = shift or return;
  138.  
  139.     # Try adding the colour if it doesn't exist yet. It may be of a
  140.     # parseable form
  141.     add_colour($clr) unless exists $RGB{$clr};
  142.  
  143.     my $rgb_ref = $RGB{$clr};
  144.     if (!defined $rgb_ref)
  145.     {
  146.         $rgb_ref = $RGB{'black'};
  147.         unless ($warned_clrs{$clr})
  148.         {
  149.             $warned_clrs{$clr}++;
  150.             carp "Colour $clr is not defined, reverting to black"; 
  151.         }
  152.     };
  153.  
  154.     @{$rgb_ref};
  155. }
  156.  
  157. =head2 _hue( I<R,G,B> )
  158.  
  159. Returns the hue of the colour with the specified RGB values.
  160. Exported with the :colours tag.
  161.  
  162. =head2 _luminance( I<R,G,B> )
  163.  
  164. Returns the luminance of the colour with the specified RGB values.
  165. Exported with the :colours tag.
  166.  
  167. =cut
  168.  
  169. # return the luminance of the colour (RGB)
  170. sub _luminance 
  171.     (0.212671 * $_[0] + 0.715160 * $_[1] + 0.072169 * $_[2])/0xFF
  172. }
  173.  
  174. # return the hue of the colour (RGB)
  175. sub _hue 
  176.     ($_[0] + $_[1] + $_[2])/(3 * 0xFF) 
  177. }
  178.  
  179. =head2 add_colour(colourname => [$r, $g, $b]) or
  180. add_colour('#7fe310')
  181.  
  182. Self-explanatory.
  183. Exported with the :colours tag.
  184.  
  185. =cut
  186.  
  187. sub add_colour
  188. {
  189.     my $name = shift;
  190.     my $val  = shift;
  191.  
  192.     if (!defined $val)
  193.     {
  194.         my @rgb = hex2rgb($name) or return;
  195.         $val = [@rgb];
  196.     }
  197.  
  198.     if (ref $val && ref $val eq 'ARRAY')
  199.     {
  200.         $RGB{$name} = [@{$val}];
  201.         return $name;
  202.     }
  203.  
  204.     return;
  205. }
  206.  
  207. =head2 rgb2hex($red, $green, $blue)
  208.  
  209. =head2 hex2rgb('#7fe310')
  210.  
  211. These functions translate a list of RGB values into a hexadecimal
  212. string, as is commonly used in HTML and the Image::Magick API, and vice
  213. versa.
  214. Exported with the :convert tag.
  215.  
  216. =cut
  217.  
  218. # Color translation
  219. sub rgb2hex
  220. {
  221.     return unless @_ == 3;
  222.     my $color = '#';
  223.     foreach my $cc (@_)
  224.     {
  225.         $color .= sprintf("%02x", $cc);
  226.     }
  227.     return $color;
  228. }
  229.  
  230. sub hex2rgb
  231. {
  232.     my $clr = shift;
  233.     my @rgb = $clr =~ /^#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})$/i;
  234.     return unless @rgb;
  235.     return map { hex $_ } @rgb;
  236. }
  237.  
  238. =head2 read_rgb( F<file name> )
  239.  
  240. Reads in colours from a rgb file as used by the X11 system.
  241.  
  242. Doing something like:
  243.  
  244.     use GD::Graph::bars;
  245.     use GD::Graph::colour;
  246.  
  247.     GD::Graph::colour::read_rgb("rgb.txt") or die "cannot read colours";
  248.  
  249. Will allow you to use any colours defined in rgb.txt in your graph.
  250. Exported with the :files tag.
  251.  
  252. =cut
  253.  
  254. #
  255. # Read a rgb.txt file (X11)
  256. #
  257. # Expected format of the file:
  258. #
  259. # R G B colour name
  260. #
  261. # Fields can be separated by any number of whitespace
  262. # Lines starting with an exclamation mark (!) are comment and 
  263. # will be ignored.
  264. #
  265. # returns number of colours read
  266.  
  267. sub read_rgb($) # (filename)
  268. {
  269.     my $fn = shift;
  270.     my $n = 0;
  271.     my $line;
  272.  
  273.     open(RGB, $fn) or return 0;
  274.  
  275.     while (defined($line = <RGB>))
  276.     {
  277.         next if ($line =~ /\s*!/);
  278.         chomp($line);
  279.  
  280.         # remove leading white space
  281.         $line =~ s/^\s+//;
  282.  
  283.         # get the colours
  284.         my ($r, $g, $b, $name) = split(/\s+/, $line, 4);
  285.         
  286.         # Ignore bad lines
  287.         next unless (defined $name);
  288.  
  289.         $RGB{$name} = [$r, $g, $b];
  290.         $n++;
  291.     }
  292.  
  293.     close(RGB);
  294.  
  295.     return $n;
  296. }
  297.  
  298. sub version { $GD::Graph::colour::VERSION }
  299.  
  300. sub dump_colours
  301. {
  302.     my $max = $_[0] ? $_[0] : keys %RGB;
  303.     my $n = 0;
  304.  
  305.     my $clr;
  306.     foreach $clr (sorted_colour_list($max))
  307.     {
  308.         last if $n > $max;
  309.         print "colour: $clr, " . 
  310.             "${$RGB{$clr}}[0], ${$RGB{$clr}}[1], ${$RGB{$clr}}[2]\n"
  311.     }
  312. }
  313.  
  314.  
  315. "Just another true value";
  316.  
  317. __END__
  318.  
  319. =head1 PREDEFINED COLOUR NAMES
  320.  
  321. white,
  322. lgray,
  323. gray,
  324. dgray,
  325. black,
  326. lblue,
  327. blue,
  328. dblue,
  329. gold,
  330. lyellow,
  331. yellow,
  332. dyellow,
  333. lgreen,
  334. green,
  335. dgreen,
  336. lred,
  337. red,
  338. dred,
  339. lpurple,
  340. purple,
  341. dpurple,
  342. lorange,
  343. orange,
  344. pink,
  345. dpink,
  346. marine,
  347. cyan,
  348. lbrown,
  349. dbrown.
  350.  
  351. =head1 AUTHOR
  352.  
  353. Martien Verbruggen E<lt>mgjv@tradingpost.com.auE<gt>
  354.  
  355. =head2 Copyright
  356.  
  357. GIFgraph: Copyright (c) 1995-1999 Martien Verbruggen.
  358. Chart::PNGgraph: Copyright (c) 1999 Steve Bonds.
  359. GD::Graph: Copyright (c) 1999 Martien Verbruggen.
  360.  
  361. All rights reserved. This package is free software; you can redistribute
  362. it and/or modify it under the same terms as Perl itself.
  363.  
  364. =head1 SEE ALSO
  365.  
  366. L<GD::Graph>, 
  367. L<GD::Graph::FAQ>
  368.  
  369.