kmandrup-colorist 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +5 -0
 - data/.specification +66 -0
 - data/CHANGELOG.rdoc +10 -0
 - data/MIT_LICENSE.rdoc +19 -0
 - data/README.rdoc +43 -0
 - data/Rakefile +61 -0
 - data/VERSION +1 -0
 - data/extractions/extract_colors.rb +436 -0
 - data/kmandrup-colorist.gemspec +50 -0
 - data/lib/colorist/color.rb +415 -0
 - data/lib/colorist/color_names.rb +441 -0
 - data/lib/colorist/core_extensions.rb +26 -0
 - data/lib/kmandrup-colorist.rb +3 -0
 - metadata +81 -0
 
| 
         @@ -0,0 +1,50 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Generated by jeweler
         
     | 
| 
      
 2 
     | 
    
         
            +
            # DO NOT EDIT THIS FILE DIRECTLY
         
     | 
| 
      
 3 
     | 
    
         
            +
            # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
         
     | 
| 
      
 4 
     | 
    
         
            +
            # -*- encoding: utf-8 -*-
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            Gem::Specification.new do |s|
         
     | 
| 
      
 7 
     | 
    
         
            +
              s.name = %q{kmandrup-colorist}
         
     | 
| 
      
 8 
     | 
    
         
            +
              s.version = "0.1.2"
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
         
     | 
| 
      
 11 
     | 
    
         
            +
              s.authors = ["Michael Bleigh", "oleg dashevskii", "Slippy Douglas", "Kristian Mandrup"]
         
     | 
| 
      
 12 
     | 
    
         
            +
              s.date = %q{2010-05-27}
         
     | 
| 
      
 13 
     | 
    
         
            +
              s.description = %q{Colorist is a library built to handle the easy conversion and manipulation of colors with a special emphasis on W3C standards and CSS-style hex color notation.}
         
     | 
| 
      
 14 
     | 
    
         
            +
              s.email = %q{kmandrup@gmail.com}
         
     | 
| 
      
 15 
     | 
    
         
            +
              s.extra_rdoc_files = [
         
     | 
| 
      
 16 
     | 
    
         
            +
                "MIT_LICENSE.rdoc",
         
     | 
| 
      
 17 
     | 
    
         
            +
                 "README.rdoc"
         
     | 
| 
      
 18 
     | 
    
         
            +
              ]
         
     | 
| 
      
 19 
     | 
    
         
            +
              s.files = [
         
     | 
| 
      
 20 
     | 
    
         
            +
                ".gitignore",
         
     | 
| 
      
 21 
     | 
    
         
            +
                 ".specification",
         
     | 
| 
      
 22 
     | 
    
         
            +
                 "CHANGELOG.rdoc",
         
     | 
| 
      
 23 
     | 
    
         
            +
                 "MIT_LICENSE.rdoc",
         
     | 
| 
      
 24 
     | 
    
         
            +
                 "README.rdoc",
         
     | 
| 
      
 25 
     | 
    
         
            +
                 "Rakefile",
         
     | 
| 
      
 26 
     | 
    
         
            +
                 "VERSION",
         
     | 
| 
      
 27 
     | 
    
         
            +
                 "extractions/extract_colors.rb",
         
     | 
| 
      
 28 
     | 
    
         
            +
                 "kmandrup-colorist.gemspec",
         
     | 
| 
      
 29 
     | 
    
         
            +
                 "lib/colorist/color.rb",
         
     | 
| 
      
 30 
     | 
    
         
            +
                 "lib/colorist/color_names.rb",
         
     | 
| 
      
 31 
     | 
    
         
            +
                 "lib/colorist/core_extensions.rb",
         
     | 
| 
      
 32 
     | 
    
         
            +
                 "lib/kmandrup-colorist.rb"
         
     | 
| 
      
 33 
     | 
    
         
            +
              ]
         
     | 
| 
      
 34 
     | 
    
         
            +
              s.homepage = %q{http://github.com/kristianmandrup/colorist}
         
     | 
| 
      
 35 
     | 
    
         
            +
              s.rdoc_options = ["--main", "README.rdoc"]
         
     | 
| 
      
 36 
     | 
    
         
            +
              s.require_paths = ["lib"]
         
     | 
| 
      
 37 
     | 
    
         
            +
              s.rubygems_version = %q{1.3.7}
         
     | 
| 
      
 38 
     | 
    
         
            +
              s.summary = %q{A library built to handle the easy conversion and simple manipulation of colors.}
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
              if s.respond_to? :specification_version then
         
     | 
| 
      
 41 
     | 
    
         
            +
                current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
         
     | 
| 
      
 42 
     | 
    
         
            +
                s.specification_version = 3
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
         
     | 
| 
      
 45 
     | 
    
         
            +
                else
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
              else
         
     | 
| 
      
 48 
     | 
    
         
            +
              end
         
     | 
| 
      
 49 
     | 
    
         
            +
            end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
         @@ -0,0 +1,415 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Colorist
         
     | 
| 
      
 2 
     | 
    
         
            +
              # Color is the general class for storing and manipulating a color with the
         
     | 
| 
      
 3 
     | 
    
         
            +
              # Colorist gem. It provides methods to add, subtract, and calculate aspects
         
     | 
| 
      
 4 
     | 
    
         
            +
              # of the color based on W3C and other standards.
         
     | 
| 
      
 5 
     | 
    
         
            +
              class Color
         
     | 
| 
      
 6 
     | 
    
         
            +
                attr_accessor :r, :g, :b, :a
         
     | 
| 
      
 7 
     | 
    
         
            +
                
         
     | 
| 
      
 8 
     | 
    
         
            +
                CSS_COLOR_NAMES = {  "maroon"  => 0x800000,
         
     | 
| 
      
 9 
     | 
    
         
            +
                                     "red"     => 0xff0000,
         
     | 
| 
      
 10 
     | 
    
         
            +
                                     "orange"  => 0xffa500,
         
     | 
| 
      
 11 
     | 
    
         
            +
                                     "yellow"  => 0xffff00,
         
     | 
| 
      
 12 
     | 
    
         
            +
                                     "olive"   => 0x808000,
         
     | 
| 
      
 13 
     | 
    
         
            +
                                     "purple"  => 0x800080,
         
     | 
| 
      
 14 
     | 
    
         
            +
                                     "fuchsia" => 0xff00ff,
         
     | 
| 
      
 15 
     | 
    
         
            +
                                     "white"   => 0xffffff,
         
     | 
| 
      
 16 
     | 
    
         
            +
                                     "lime"    => 0x00ff00,
         
     | 
| 
      
 17 
     | 
    
         
            +
                                     "green"   => 0x008000,
         
     | 
| 
      
 18 
     | 
    
         
            +
                                     "navy"    => 0x000080,
         
     | 
| 
      
 19 
     | 
    
         
            +
                                     "blue"    => 0x0000ff,
         
     | 
| 
      
 20 
     | 
    
         
            +
                                     "aqua"    => 0x00ffff,
         
     | 
| 
      
 21 
     | 
    
         
            +
                                     "teal"    => 0x008080,
         
     | 
| 
      
 22 
     | 
    
         
            +
                                     "black"   => 0x000000,
         
     | 
| 
      
 23 
     | 
    
         
            +
                                     "silver"  => 0xc0c0c0,
         
     | 
| 
      
 24 
     | 
    
         
            +
                                     "gray"    => 0x808080  }
         
     | 
| 
      
 25 
     | 
    
         
            +
                
         
     | 
| 
      
 26 
     | 
    
         
            +
                # Creates a new color with the hex color provided as a number (i.e. 0x112233)
         
     | 
| 
      
 27 
     | 
    
         
            +
                def initialize(color = 0x000000, alpha = 1.0)
         
     | 
| 
      
 28 
     | 
    
         
            +
                  string = "%.6x" % color
         
     | 
| 
      
 29 
     | 
    
         
            +
                  @r = string[0..1].hex
         
     | 
| 
      
 30 
     | 
    
         
            +
                  @g = string[2..3].hex
         
     | 
| 
      
 31 
     | 
    
         
            +
                  @b = string[4..5].hex
         
     | 
| 
      
 32 
     | 
    
         
            +
                  @a = alpha
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
                
         
     | 
| 
      
 35 
     | 
    
         
            +
                # Initialize a color based on RGB values. By default, the values
         
     | 
| 
      
 36 
     | 
    
         
            +
                # should be between 0 and 255. If you use the option <tt>:percent => true</tt>,
         
     | 
| 
      
 37 
     | 
    
         
            +
                # the values should then be between 0.0 and 1.0.
         
     | 
| 
      
 38 
     | 
    
         
            +
                def self.from_rgb(r, g, b, options = {})
         
     | 
| 
      
 39 
     | 
    
         
            +
                  color = new
         
     | 
| 
      
 40 
     | 
    
         
            +
                  # convert from 0.0 to 1.0 to 0 to 255 if the :percent option is used
         
     | 
| 
      
 41 
     | 
    
         
            +
                  if options[:percent]
         
     | 
| 
      
 42 
     | 
    
         
            +
                    color.r, color.g, color.b = (r * 255).round, (g * 255).round, (b * 255).round
         
     | 
| 
      
 43 
     | 
    
         
            +
                  else
         
     | 
| 
      
 44 
     | 
    
         
            +
                    color.r, color.g, color.b = r, g, b
         
     | 
| 
      
 45 
     | 
    
         
            +
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
                  color
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
      
 48 
     | 
    
         
            +
                
         
     | 
| 
      
 49 
     | 
    
         
            +
                def self.from_rgba(r, g, b, a, options = {})
         
     | 
| 
      
 50 
     | 
    
         
            +
                  color = from_rgb(r, g, b, options)
         
     | 
| 
      
 51 
     | 
    
         
            +
                  color.a = a
         
     | 
| 
      
 52 
     | 
    
         
            +
                  color
         
     | 
| 
      
 53 
     | 
    
         
            +
                end
         
     | 
| 
      
 54 
     | 
    
         
            +
                
         
     | 
| 
      
 55 
     | 
    
         
            +
                # Initialize a colour based on HSV/HSB values. Hue should be between 0 and 360 (inclusive),
         
     | 
| 
      
 56 
     | 
    
         
            +
                # while saturation and value should be from 0.0 to 1.0.
         
     | 
| 
      
 57 
     | 
    
         
            +
                def self.from_hsv(hue, saturation, value)
         
     | 
| 
      
 58 
     | 
    
         
            +
                  saturation = 1 if saturation > 1
         
     | 
| 
      
 59 
     | 
    
         
            +
                  value = 1 if saturation > 1
         
     | 
| 
      
 60 
     | 
    
         
            +
                  
         
     | 
| 
      
 61 
     | 
    
         
            +
                  # Conversion formula taken from wikipedia
         
     | 
| 
      
 62 
     | 
    
         
            +
                  
         
     | 
| 
      
 63 
     | 
    
         
            +
                  f = (hue / 60.0) - (hue / 60).floor
         
     | 
| 
      
 64 
     | 
    
         
            +
                  
         
     | 
| 
      
 65 
     | 
    
         
            +
                  p = value * (1 - saturation)
         
     | 
| 
      
 66 
     | 
    
         
            +
                  q = value * (1 - (saturation * f))
         
     | 
| 
      
 67 
     | 
    
         
            +
                  t = value * (1 - (saturation * (1 - f)))
         
     | 
| 
      
 68 
     | 
    
         
            +
                  
         
     | 
| 
      
 69 
     | 
    
         
            +
                  r, g, b = case (hue / 60).floor % 6
         
     | 
| 
      
 70 
     | 
    
         
            +
                            when 0 then [ value, t, p ]
         
     | 
| 
      
 71 
     | 
    
         
            +
                            when 1 then [ q, value, p ]
         
     | 
| 
      
 72 
     | 
    
         
            +
                            when 2 then [ p, value, t ]
         
     | 
| 
      
 73 
     | 
    
         
            +
                            when 3 then [ p, q, value ]
         
     | 
| 
      
 74 
     | 
    
         
            +
                            when 4 then [ t, p, value ]
         
     | 
| 
      
 75 
     | 
    
         
            +
                            when 5 then [ value, p, q ]
         
     | 
| 
      
 76 
     | 
    
         
            +
                            end
         
     | 
| 
      
 77 
     | 
    
         
            +
                  
         
     | 
| 
      
 78 
     | 
    
         
            +
                  from_rgb(r, g, b, :percent => true)
         
     | 
| 
      
 79 
     | 
    
         
            +
                end
         
     | 
| 
      
 80 
     | 
    
         
            +
                
         
     | 
| 
      
 81 
     | 
    
         
            +
                def self.from_hsva(hue, saturation, value, alpha)
         
     | 
| 
      
 82 
     | 
    
         
            +
                  color = from_hsv(hue, saturation, value)
         
     | 
| 
      
 83 
     | 
    
         
            +
                  color.a = alpha
         
     | 
| 
      
 84 
     | 
    
         
            +
                  color
         
     | 
| 
      
 85 
     | 
    
         
            +
                end
         
     | 
| 
      
 86 
     | 
    
         
            +
                
         
     | 
| 
      
 87 
     | 
    
         
            +
                # Converts a CSS hex string into a color. Works both with the
         
     | 
| 
      
 88 
     | 
    
         
            +
                # full form (i.e. <tt>#ffffff</tt>) and the abbreviated form (<tt>#fff</tt>). Can
         
     | 
| 
      
 89 
     | 
    
         
            +
                # also take any of the 16 named CSS colors.
         
     | 
| 
      
 90 
     | 
    
         
            +
                def self.from_string(some_string)
         
     | 
| 
      
 91 
     | 
    
         
            +
                  if matched = some_string.match(/\A#([0-9a-f]{3})\z/i)
         
     | 
| 
      
 92 
     | 
    
         
            +
                    color = from_rgb(*matched[1].split(//).collect{|v| "#{v}#{v}".hex })
         
     | 
| 
      
 93 
     | 
    
         
            +
                  elsif matched = some_string.match(/\A#([0-9a-f]{6})\z/i)
         
     | 
| 
      
 94 
     | 
    
         
            +
                    color = new
         
     | 
| 
      
 95 
     | 
    
         
            +
                    color.r = matched[1][0..1].hex
         
     | 
| 
      
 96 
     | 
    
         
            +
                    color.g = matched[1][2..3].hex
         
     | 
| 
      
 97 
     | 
    
         
            +
                    color.b = matched[1][4..5].hex
         
     | 
| 
      
 98 
     | 
    
         
            +
                  elsif CSS_COLOR_NAMES.key?(some_string)
         
     | 
| 
      
 99 
     | 
    
         
            +
                    color = new(CSS_COLOR_NAMES[some_string])
         
     | 
| 
      
 100 
     | 
    
         
            +
                  else
         
     | 
| 
      
 101 
     | 
    
         
            +
                    raise ArgumentError, "Must provide a valid CSS hex color or color name.", caller
         
     | 
| 
      
 102 
     | 
    
         
            +
                  end
         
     | 
| 
      
 103 
     | 
    
         
            +
                  color
         
     | 
| 
      
 104 
     | 
    
         
            +
                end
         
     | 
| 
      
 105 
     | 
    
         
            +
                
         
     | 
| 
      
 106 
     | 
    
         
            +
                # Create a new color from the provided object. Duplicates Color objects
         
     | 
| 
      
 107 
     | 
    
         
            +
                # and attempts to call <tt>to_color</tt> on other objects. Will raise
         
     | 
| 
      
 108 
     | 
    
         
            +
                # an ArgumentError if it is unable to coerce the color.
         
     | 
| 
      
 109 
     | 
    
         
            +
                def self.from(some_entity)
         
     | 
| 
      
 110 
     | 
    
         
            +
                  case some_entity
         
     | 
| 
      
 111 
     | 
    
         
            +
                    when Colorist::Color
         
     | 
| 
      
 112 
     | 
    
         
            +
                      some_entity.dup
         
     | 
| 
      
 113 
     | 
    
         
            +
                    else
         
     | 
| 
      
 114 
     | 
    
         
            +
                      raise ArgumentError, "#{some_entity.class.to_s} cannot be coerced into a color.", caller unless some_entity.respond_to?(:to_color)
         
     | 
| 
      
 115 
     | 
    
         
            +
                      some_entity.to_color
         
     | 
| 
      
 116 
     | 
    
         
            +
                  end
         
     | 
| 
      
 117 
     | 
    
         
            +
                end
         
     | 
| 
      
 118 
     | 
    
         
            +
                
         
     | 
| 
      
 119 
     | 
    
         
            +
                # Create a duplicate of this color.
         
     | 
| 
      
 120 
     | 
    
         
            +
                def dup
         
     | 
| 
      
 121 
     | 
    
         
            +
                  self.class.from_rgba(@r, @g, @b, @a)
         
     | 
| 
      
 122 
     | 
    
         
            +
                end
         
     | 
| 
      
 123 
     | 
    
         
            +
                
         
     | 
| 
      
 124 
     | 
    
         
            +
                # Add the individual RGB values of two colors together.
         
     | 
| 
      
 125 
     | 
    
         
            +
                # You may also use an equivalent numeric or string color representation.
         
     | 
| 
      
 126 
     | 
    
         
            +
                # The alpha value is kept from the original color (left-hand side).
         
     | 
| 
      
 127 
     | 
    
         
            +
                #
         
     | 
| 
      
 128 
     | 
    
         
            +
                # Examples:
         
     | 
| 
      
 129 
     | 
    
         
            +
                #
         
     | 
| 
      
 130 
     | 
    
         
            +
                #   gray = Colorist::Color.new(0x333333)
         
     | 
| 
      
 131 
     | 
    
         
            +
                #   gray + "#300"   # => <Color #663333>
         
     | 
| 
      
 132 
     | 
    
         
            +
                #   gray + 0x000000 # => <Color #333333>
         
     | 
| 
      
 133 
     | 
    
         
            +
                #   white = "white".to_color
         
     | 
| 
      
 134 
     | 
    
         
            +
                #   gray + white    # => <Color #ffffff>
         
     | 
| 
      
 135 
     | 
    
         
            +
                def +(other_color)
         
     | 
| 
      
 136 
     | 
    
         
            +
                  other_color = self.class.from(other_color)
         
     | 
| 
      
 137 
     | 
    
         
            +
                  color = self.dup
         
     | 
| 
      
 138 
     | 
    
         
            +
                  color.r += other_color.r
         
     | 
| 
      
 139 
     | 
    
         
            +
                  color.g += other_color.g
         
     | 
| 
      
 140 
     | 
    
         
            +
                  color.b += other_color.b
         
     | 
| 
      
 141 
     | 
    
         
            +
                  color
         
     | 
| 
      
 142 
     | 
    
         
            +
                end
         
     | 
| 
      
 143 
     | 
    
         
            +
                
         
     | 
| 
      
 144 
     | 
    
         
            +
                # Subtract the individual RGB values of the two colors together.
         
     | 
| 
      
 145 
     | 
    
         
            +
                # You may also use an equivalent numeric or string color representation.
         
     | 
| 
      
 146 
     | 
    
         
            +
                # The alpha value is kept from the original color (left-hand side).
         
     | 
| 
      
 147 
     | 
    
         
            +
                def -(other_color)
         
     | 
| 
      
 148 
     | 
    
         
            +
                  other_color = self.class.from(other_color)
         
     | 
| 
      
 149 
     | 
    
         
            +
                  color = self.dup
         
     | 
| 
      
 150 
     | 
    
         
            +
                  color.r -= other_color.r
         
     | 
| 
      
 151 
     | 
    
         
            +
                  color.g -= other_color.g
         
     | 
| 
      
 152 
     | 
    
         
            +
                  color.b -= other_color.b
         
     | 
| 
      
 153 
     | 
    
         
            +
                  color
         
     | 
| 
      
 154 
     | 
    
         
            +
                end
         
     | 
| 
      
 155 
     | 
    
         
            +
                
         
     | 
| 
      
 156 
     | 
    
         
            +
                # Multiply the individual RGB values of two colors together or against a Float.
         
     | 
| 
      
 157 
     | 
    
         
            +
                # Colors divided in a way that is equivalent to each of the values being normalized to 0.0..1.0 prior to the operation
         
     | 
| 
      
 158 
     | 
    
         
            +
                #   and normalized back to 0.0..255.0 after the operation.
         
     | 
| 
      
 159 
     | 
    
         
            +
                # You may also use an equivalent numeric or string color representation.
         
     | 
| 
      
 160 
     | 
    
         
            +
                # The alpha value is kept from the original color (left-hand side).
         
     | 
| 
      
 161 
     | 
    
         
            +
                def *(other)
         
     | 
| 
      
 162 
     | 
    
         
            +
                  color = self.dup
         
     | 
| 
      
 163 
     | 
    
         
            +
                  
         
     | 
| 
      
 164 
     | 
    
         
            +
                  if other.is_a? Float
         
     | 
| 
      
 165 
     | 
    
         
            +
                    color.r *= other
         
     | 
| 
      
 166 
     | 
    
         
            +
                    color.g *= other
         
     | 
| 
      
 167 
     | 
    
         
            +
                    color.b *= other
         
     | 
| 
      
 168 
     | 
    
         
            +
                  else
         
     | 
| 
      
 169 
     | 
    
         
            +
                    other_color = self.class.from(other)
         
     | 
| 
      
 170 
     | 
    
         
            +
                    color.r = color.r * other_color.r / 255.0
         
     | 
| 
      
 171 
     | 
    
         
            +
                    color.g = color.g * other_color.g / 255.0
         
     | 
| 
      
 172 
     | 
    
         
            +
                    color.b = color.b * other_color.b / 255.0
         
     | 
| 
      
 173 
     | 
    
         
            +
                  end
         
     | 
| 
      
 174 
     | 
    
         
            +
                  
         
     | 
| 
      
 175 
     | 
    
         
            +
                  color
         
     | 
| 
      
 176 
     | 
    
         
            +
                end
         
     | 
| 
      
 177 
     | 
    
         
            +
                
         
     | 
| 
      
 178 
     | 
    
         
            +
                # Divide the individual RGB values of the two colors together or against a Float.
         
     | 
| 
      
 179 
     | 
    
         
            +
                # Colors divided in a way that is equivalent to each of the values being normalized to 0.0..1.0 prior to the operation
         
     | 
| 
      
 180 
     | 
    
         
            +
                #   and normalized back to 0.0..255.0 after the operation.
         
     | 
| 
      
 181 
     | 
    
         
            +
                # You may also use an equivalent numeric or string color representation.
         
     | 
| 
      
 182 
     | 
    
         
            +
                # The alpha value is kept from the original color (left-hand side).
         
     | 
| 
      
 183 
     | 
    
         
            +
                def /(other)
         
     | 
| 
      
 184 
     | 
    
         
            +
                  color = self.dup
         
     | 
| 
      
 185 
     | 
    
         
            +
                  
         
     | 
| 
      
 186 
     | 
    
         
            +
                  if other.is_a? Float
         
     | 
| 
      
 187 
     | 
    
         
            +
                    color.r /= other
         
     | 
| 
      
 188 
     | 
    
         
            +
                    color.g /= other
         
     | 
| 
      
 189 
     | 
    
         
            +
                    color.b /= other
         
     | 
| 
      
 190 
     | 
    
         
            +
                  else
         
     | 
| 
      
 191 
     | 
    
         
            +
                    other_color = self.class.from(other)
         
     | 
| 
      
 192 
     | 
    
         
            +
                    color.r = color.r / other_color.r * 255.0
         
     | 
| 
      
 193 
     | 
    
         
            +
                    color.g = color.g / other_color.g * 255.0
         
     | 
| 
      
 194 
     | 
    
         
            +
                    color.b = color.b / other_color.b * 255.0
         
     | 
| 
      
 195 
     | 
    
         
            +
                  end
         
     | 
| 
      
 196 
     | 
    
         
            +
                  
         
     | 
| 
      
 197 
     | 
    
         
            +
                  color
         
     | 
| 
      
 198 
     | 
    
         
            +
                end
         
     | 
| 
      
 199 
     | 
    
         
            +
                
         
     | 
| 
      
 200 
     | 
    
         
            +
                # Compares colors based on brightness.
         
     | 
| 
      
 201 
     | 
    
         
            +
                def <=>(other_color)
         
     | 
| 
      
 202 
     | 
    
         
            +
                  other_color = self.class.from(other_color)
         
     | 
| 
      
 203 
     | 
    
         
            +
                  brightness <=> other_color.brightness
         
     | 
| 
      
 204 
     | 
    
         
            +
                end
         
     | 
| 
      
 205 
     | 
    
         
            +
                
         
     | 
| 
      
 206 
     | 
    
         
            +
                # Compares colors based on brightness.
         
     | 
| 
      
 207 
     | 
    
         
            +
                def < (other_color)
         
     | 
| 
      
 208 
     | 
    
         
            +
                  other_color = self.class.from(other_color)
         
     | 
| 
      
 209 
     | 
    
         
            +
                  brightness < other_color.brightness
         
     | 
| 
      
 210 
     | 
    
         
            +
                end
         
     | 
| 
      
 211 
     | 
    
         
            +
                
         
     | 
| 
      
 212 
     | 
    
         
            +
                # Compares colors based on brightness.
         
     | 
| 
      
 213 
     | 
    
         
            +
                def > (other_color)
         
     | 
| 
      
 214 
     | 
    
         
            +
                  other_color = self.class.from(other_color)
         
     | 
| 
      
 215 
     | 
    
         
            +
                  brightness > other_color.brightness
         
     | 
| 
      
 216 
     | 
    
         
            +
                end
         
     | 
| 
      
 217 
     | 
    
         
            +
                
         
     | 
| 
      
 218 
     | 
    
         
            +
                # Equal if the red, green, blue, and alpha values are identical.
         
     | 
| 
      
 219 
     | 
    
         
            +
                def ==(other_color)
         
     | 
| 
      
 220 
     | 
    
         
            +
                  other_color = self.class.from(other_color)
         
     | 
| 
      
 221 
     | 
    
         
            +
                  other_color.r == self.r && other_color.g == self.g && other_color.b == self.b && other_color.a == self.a
         
     | 
| 
      
 222 
     | 
    
         
            +
                end
         
     | 
| 
      
 223 
     | 
    
         
            +
                
         
     | 
| 
      
 224 
     | 
    
         
            +
                # Equal if the brightnesses of the two colors are identical.
         
     | 
| 
      
 225 
     | 
    
         
            +
                def ===(other_color)
         
     | 
| 
      
 226 
     | 
    
         
            +
                  other_color = self.class.from(other_color)
         
     | 
| 
      
 227 
     | 
    
         
            +
                  other_color.brightness == brightness
         
     | 
| 
      
 228 
     | 
    
         
            +
                end
         
     | 
| 
      
 229 
     | 
    
         
            +
                
         
     | 
| 
      
 230 
     | 
    
         
            +
                def r=(value) #:nodoc:
         
     | 
| 
      
 231 
     | 
    
         
            +
                  @r = value; normalize; end
         
     | 
| 
      
 232 
     | 
    
         
            +
                def g=(value) #:nodoc:
         
     | 
| 
      
 233 
     | 
    
         
            +
                  @g = value; normalize; end
         
     | 
| 
      
 234 
     | 
    
         
            +
                def b=(value) #:nodoc:
         
     | 
| 
      
 235 
     | 
    
         
            +
                  @b = value; normalize; end
         
     | 
| 
      
 236 
     | 
    
         
            +
                def a=(value) #:nodoc:
         
     | 
| 
      
 237 
     | 
    
         
            +
                  @a = value; normalize; end
         
     | 
| 
      
 238 
     | 
    
         
            +
                
         
     | 
| 
      
 239 
     | 
    
         
            +
                # Outputs a string representation of the color in the desired format.
         
     | 
| 
      
 240 
     | 
    
         
            +
                # The available formats are:
         
     | 
| 
      
 241 
     | 
    
         
            +
                #
         
     | 
| 
      
 242 
     | 
    
         
            +
                # * <tt>:css</tt> - As a CSS hex string (i.e. <tt>#ffffff</tt>) (default)
         
     | 
| 
      
 243 
     | 
    
         
            +
                # * <tt>:css_rgb</tt> - As a CSS RGB value string (i.e. <tt>rgb(255, 255, 255)</tt>)
         
     | 
| 
      
 244 
     | 
    
         
            +
                # * <tt>:css_rgba</tt> - As a CSS RGBA value string (i.e. <tt>rgb(255, 255, 255, 1.0)</tt>)
         
     | 
| 
      
 245 
     | 
    
         
            +
                # * <tt>:rgb</tt> - As an RGB triplet (i.e. <tt>1.0, 1.0, 1.0</tt>)
         
     | 
| 
      
 246 
     | 
    
         
            +
                # * <tt>:rgba</tt> - As an RGBA quadruplet (i.e. <tt>1.0, 1.0, 1.0, 1.0</tt>)
         
     | 
| 
      
 247 
     | 
    
         
            +
                def to_s(format=:css)
         
     | 
| 
      
 248 
     | 
    
         
            +
                  case format
         
     | 
| 
      
 249 
     | 
    
         
            +
                    when :css
         
     | 
| 
      
 250 
     | 
    
         
            +
                      "#%.2x%.2x%.2x" % [r, g, b]
         
     | 
| 
      
 251 
     | 
    
         
            +
                    when :css_rgb
         
     | 
| 
      
 252 
     | 
    
         
            +
                      "rgb(%d, %d, %d)" % [r, g, b]
         
     | 
| 
      
 253 
     | 
    
         
            +
                    when :css_rgba
         
     | 
| 
      
 254 
     | 
    
         
            +
                      "rgba(%d, %d, %d, %.3f)" % [r, g, b, a]
         
     | 
| 
      
 255 
     | 
    
         
            +
                    when :rgb
         
     | 
| 
      
 256 
     | 
    
         
            +
                      "%.3f, %.3f, %.3f" % [r / 255, g / 255, b / 255]
         
     | 
| 
      
 257 
     | 
    
         
            +
                    when :rgba
         
     | 
| 
      
 258 
     | 
    
         
            +
                      "%.3f, %.3f, %.3f, %.3f" % [r / 255, g / 255, b / 255, a / 255]
         
     | 
| 
      
 259 
     | 
    
         
            +
                  end
         
     | 
| 
      
 260 
     | 
    
         
            +
                end
         
     | 
| 
      
 261 
     | 
    
         
            +
                
         
     | 
| 
      
 262 
     | 
    
         
            +
                # Returns an array of the hue, saturation and value of the color.
         
     | 
| 
      
 263 
     | 
    
         
            +
                # Hue will range from 0-359, hue and saturation will be between 0 and 1.
         
     | 
| 
      
 264 
     | 
    
         
            +
                
         
     | 
| 
      
 265 
     | 
    
         
            +
                def to_hsv
         
     | 
| 
      
 266 
     | 
    
         
            +
                  red, green, blue = *[r, g, b].collect {|x| x / 255.0}
         
     | 
| 
      
 267 
     | 
    
         
            +
                  max = [red, green, blue].max
         
     | 
| 
      
 268 
     | 
    
         
            +
                  min = [red, green, blue].min
         
     | 
| 
      
 269 
     | 
    
         
            +
                  
         
     | 
| 
      
 270 
     | 
    
         
            +
                  if min == max
         
     | 
| 
      
 271 
     | 
    
         
            +
                    hue = 0
         
     | 
| 
      
 272 
     | 
    
         
            +
                  elsif max == red
         
     | 
| 
      
 273 
     | 
    
         
            +
                    hue = 60 * ((green - blue) / (max - min))
         
     | 
| 
      
 274 
     | 
    
         
            +
                  elsif max == green
         
     | 
| 
      
 275 
     | 
    
         
            +
                    hue = 60 * ((blue - red) / (max - min)) + 120
         
     | 
| 
      
 276 
     | 
    
         
            +
                  elsif max == blue
         
     | 
| 
      
 277 
     | 
    
         
            +
                    hue = 60 * ((red - green) / (max - min)) + 240
         
     | 
| 
      
 278 
     | 
    
         
            +
                  end
         
     | 
| 
      
 279 
     | 
    
         
            +
                  
         
     | 
| 
      
 280 
     | 
    
         
            +
                  saturation = (max == 0) ? 0 : (max - min) / max
         
     | 
| 
      
 281 
     | 
    
         
            +
                  [hue % 360, saturation, max]
         
     | 
| 
      
 282 
     | 
    
         
            +
                end
         
     | 
| 
      
 283 
     | 
    
         
            +
                
         
     | 
| 
      
 284 
     | 
    
         
            +
                def inspect
         
     | 
| 
      
 285 
     | 
    
         
            +
                  "#<Color #{to_s(:css_rgba)}>"
         
     | 
| 
      
 286 
     | 
    
         
            +
                end
         
     | 
| 
      
 287 
     | 
    
         
            +
                
         
     | 
| 
      
 288 
     | 
    
         
            +
                # Returns the perceived brightness of the provided color on a
         
     | 
| 
      
 289 
     | 
    
         
            +
                # scale of 0.0 to 1.0 based on the formula provided. The formulas
         
     | 
| 
      
 290 
     | 
    
         
            +
                # available are:
         
     | 
| 
      
 291 
     | 
    
         
            +
                #
         
     | 
| 
      
 292 
     | 
    
         
            +
                # * <tt>:w3c</tt> - <tt>((r * 299 + g * 587 + b * 114) / 1000 / 255</tt>
         
     | 
| 
      
 293 
     | 
    
         
            +
                # * <tt>:standard</tt> - <tt>sqrt(0.241 * r^2 + 0.691 * g^2 + 0.068 * b^2) / 255</tt>
         
     | 
| 
      
 294 
     | 
    
         
            +
                def brightness(formula = :w3c)
         
     | 
| 
      
 295 
     | 
    
         
            +
                  case formula
         
     | 
| 
      
 296 
     | 
    
         
            +
                    when :standard
         
     | 
| 
      
 297 
     | 
    
         
            +
                      Math.sqrt(0.241 * r**2 + 0.691 * g**2 + 0.068 * b**2) / 255
         
     | 
| 
      
 298 
     | 
    
         
            +
                    when :w3c
         
     | 
| 
      
 299 
     | 
    
         
            +
                      ((r * 299 + g * 587 + b * 114) / 255000.0)
         
     | 
| 
      
 300 
     | 
    
         
            +
                  end
         
     | 
| 
      
 301 
     | 
    
         
            +
                end
         
     | 
| 
      
 302 
     | 
    
         
            +
                
         
     | 
| 
      
 303 
     | 
    
         
            +
                # Contrast this color with another color using the provided formula. The
         
     | 
| 
      
 304 
     | 
    
         
            +
                # available formulas are:
         
     | 
| 
      
 305 
     | 
    
         
            +
                #
         
     | 
| 
      
 306 
     | 
    
         
            +
                # * <tt>:w3c</tt> - <tt>(max(r1 r2) - min(r1 r2)) + (max(g1 g2) - min(g1 g2)) + (max(b1 b2) - min(b1 b2))</tt>
         
     | 
| 
      
 307 
     | 
    
         
            +
                def contrast_with(other_color, formula=:w3c)
         
     | 
| 
      
 308 
     | 
    
         
            +
                  other_color = self.class.from(other_color)
         
     | 
| 
      
 309 
     | 
    
         
            +
                  case formula
         
     | 
| 
      
 310 
     | 
    
         
            +
                    when :w3c
         
     | 
| 
      
 311 
     | 
    
         
            +
                      (([self.r, other_color.r].max - [self.r, other_color.r].min) +
         
     | 
| 
      
 312 
     | 
    
         
            +
                      ([self.g, other_color.g].max - [self.g, other_color.g].min) +
         
     | 
| 
      
 313 
     | 
    
         
            +
                      ([self.b, other_color.b].max - [self.b, other_color.b].min)) / 765.0
         
     | 
| 
      
 314 
     | 
    
         
            +
                  end
         
     | 
| 
      
 315 
     | 
    
         
            +
                end
         
     | 
| 
      
 316 
     | 
    
         
            +
                
         
     | 
| 
      
 317 
     | 
    
         
            +
                # Returns the opposite of the current color.
         
     | 
| 
      
 318 
     | 
    
         
            +
                def invert
         
     | 
| 
      
 319 
     | 
    
         
            +
                  self.class.from_rgba(255 - r, 255 - g, 255 - b, a)
         
     | 
| 
      
 320 
     | 
    
         
            +
                end
         
     | 
| 
      
 321 
     | 
    
         
            +
                
         
     | 
| 
      
 322 
     | 
    
         
            +
                alias opposite invert
         
     | 
| 
      
 323 
     | 
    
         
            +
                
         
     | 
| 
      
 324 
     | 
    
         
            +
                # Uses a naive formula to generate a gradient between this color and the given color.
         
     | 
| 
      
 325 
     | 
    
         
            +
                # Returns the array of colors that make the gradient, including this color and the
         
     | 
| 
      
 326 
     | 
    
         
            +
                # target color.  By default will return 10 colors, but this can be changed by supplying
         
     | 
| 
      
 327 
     | 
    
         
            +
                # an optional steps parameter.
         
     | 
| 
      
 328 
     | 
    
         
            +
                def gradient_to(color, steps = 10)
         
     | 
| 
      
 329 
     | 
    
         
            +
                  color_to = self.class.from(color)
         
     | 
| 
      
 330 
     | 
    
         
            +
                  red = color_to.r - r
         
     | 
| 
      
 331 
     | 
    
         
            +
                  green = color_to.g - g
         
     | 
| 
      
 332 
     | 
    
         
            +
                  blue = color_to.b - b
         
     | 
| 
      
 333 
     | 
    
         
            +
                  
         
     | 
| 
      
 334 
     | 
    
         
            +
                  result = (1..(steps - 3)).to_a.collect do |step|
         
     | 
| 
      
 335 
     | 
    
         
            +
                    percentage = step.to_f / (steps - 1)
         
     | 
| 
      
 336 
     | 
    
         
            +
                    self.class.from_rgb(r + (red * percentage), g + (green * percentage), b + (blue * percentage))
         
     | 
| 
      
 337 
     | 
    
         
            +
                  end
         
     | 
| 
      
 338 
     | 
    
         
            +
                  
         
     | 
| 
      
 339 
     | 
    
         
            +
                  # Add first and last colors to result, avoiding uneccessary calculation and rounding errors
         
     | 
| 
      
 340 
     | 
    
         
            +
                  
         
     | 
| 
      
 341 
     | 
    
         
            +
                  result.unshift(self.dup)
         
     | 
| 
      
 342 
     | 
    
         
            +
                  result.push(color.dup)
         
     | 
| 
      
 343 
     | 
    
         
            +
                  result
         
     | 
| 
      
 344 
     | 
    
         
            +
                end
         
     | 
| 
      
 345 
     | 
    
         
            +
                
         
     | 
| 
      
 346 
     | 
    
         
            +
                # Converts the current color to grayscale using the brightness
         
     | 
| 
      
 347 
     | 
    
         
            +
                # formula provided. See #brightness for a description of the
         
     | 
| 
      
 348 
     | 
    
         
            +
                # available formulas.
         
     | 
| 
      
 349 
     | 
    
         
            +
                def to_grayscale(formula = :w3c)
         
     | 
| 
      
 350 
     | 
    
         
            +
                  b = brightness(formula)
         
     | 
| 
      
 351 
     | 
    
         
            +
                  self.class.from_rgb(255 * b, 255 * b, 255 * b)
         
     | 
| 
      
 352 
     | 
    
         
            +
                end
         
     | 
| 
      
 353 
     | 
    
         
            +
                
         
     | 
| 
      
 354 
     | 
    
         
            +
                # Returns an appropriate text color (either black or white) based on
         
     | 
| 
      
 355 
     | 
    
         
            +
                # the brightness of this color. The +threshold+ specifies the brightness
         
     | 
| 
      
 356 
     | 
    
         
            +
                # cutoff point.
         
     | 
| 
      
 357 
     | 
    
         
            +
                def text_color(threshold = 0.6, formula = :standard)
         
     | 
| 
      
 358 
     | 
    
         
            +
                  brightness(formula) > threshold ? self.class.new(0x000000) : self.class.new(0xffffff)
         
     | 
| 
      
 359 
     | 
    
         
            +
                end
         
     | 
| 
      
 360 
     | 
    
         
            +
                
         
     | 
| 
      
 361 
     | 
    
         
            +
                # Adjusts any of H, S, V values with relative values: +opts[:h]+, +opts[:s]+, +opts[:v]+
         
     | 
| 
      
 362 
     | 
    
         
            +
                # and returns adjusted value.
         
     | 
| 
      
 363 
     | 
    
         
            +
                def adjust(opts = {})
         
     | 
| 
      
 364 
     | 
    
         
            +
                  unless [:h, :s, :v].any? { |part| opts.include? part }
         
     | 
| 
      
 365 
     | 
    
         
            +
                    raise ArgumentError, "please specify at least one of :h, :s, or :v options"
         
     | 
| 
      
 366 
     | 
    
         
            +
                  end
         
     | 
| 
      
 367 
     | 
    
         
            +
                  
         
     | 
| 
      
 368 
     | 
    
         
            +
                  h, s, v = *self.to_hsv
         
     | 
| 
      
 369 
     | 
    
         
            +
                  
         
     | 
| 
      
 370 
     | 
    
         
            +
                  h = (h + opts[:h]) % 360 if opts[:h]
         
     | 
| 
      
 371 
     | 
    
         
            +
                  s = _clamp(s + opts[:s], 0..1)   if opts[:s]
         
     | 
| 
      
 372 
     | 
    
         
            +
                  v = _clamp(v + opts[:v], 0..1)   if opts[:v]
         
     | 
| 
      
 373 
     | 
    
         
            +
                  
         
     | 
| 
      
 374 
     | 
    
         
            +
                  self.class.from_hsv(h, s, v)
         
     | 
| 
      
 375 
     | 
    
         
            +
                end
         
     | 
| 
      
 376 
     | 
    
         
            +
                
         
     | 
| 
      
 377 
     | 
    
         
            +
                # Adjusts any of R, G, B, or A values with aboslute values: opts[:a], opts[:r], opts[:b], opts[:a]
         
     | 
| 
      
 378 
     | 
    
         
            +
                # and returns adjusted value.
         
     | 
| 
      
 379 
     | 
    
         
            +
                def with(opts = {})
         
     | 
| 
      
 380 
     | 
    
         
            +
                  unless [:r, :g, :b, :a].any? { |part| opts.include? part }
         
     | 
| 
      
 381 
     | 
    
         
            +
                    raise ArgumentError, "please specify at least one of :r, :g, :b, or :a options"
         
     | 
| 
      
 382 
     | 
    
         
            +
                  end
         
     | 
| 
      
 383 
     | 
    
         
            +
                  
         
     | 
| 
      
 384 
     | 
    
         
            +
                  color = self.dup
         
     | 
| 
      
 385 
     | 
    
         
            +
                  
         
     | 
| 
      
 386 
     | 
    
         
            +
                  color.r = opts[:r] if opts[:r]
         
     | 
| 
      
 387 
     | 
    
         
            +
                  color.g = opts[:g] if opts[:g]
         
     | 
| 
      
 388 
     | 
    
         
            +
                  color.b = opts[:b] if opts[:b]
         
     | 
| 
      
 389 
     | 
    
         
            +
                  color.a = opts[:a] if opts[:a]
         
     | 
| 
      
 390 
     | 
    
         
            +
                  
         
     | 
| 
      
 391 
     | 
    
         
            +
                  color
         
     | 
| 
      
 392 
     | 
    
         
            +
                end
         
     | 
| 
      
 393 
     | 
    
         
            +
                
         
     | 
| 
      
 394 
     | 
    
         
            +
                protected
         
     | 
| 
      
 395 
     | 
    
         
            +
                
         
     | 
| 
      
 396 
     | 
    
         
            +
                def normalize #:nodoc:
         
     | 
| 
      
 397 
     | 
    
         
            +
                  @r = _clamp(@r, (0..255)) unless (0..255).include? @r
         
     | 
| 
      
 398 
     | 
    
         
            +
                  @g = _clamp(@g, (0..255)) unless (0..255).include? @g
         
     | 
| 
      
 399 
     | 
    
         
            +
                  @b = _clamp(@b, (0..255)) unless (0..255).include? @b
         
     | 
| 
      
 400 
     | 
    
         
            +
                  @a = _clamp(@a, (0.0..1.0)) unless (0.0..1.0).include? @a
         
     | 
| 
      
 401 
     | 
    
         
            +
                end
         
     | 
| 
      
 402 
     | 
    
         
            +
                
         
     | 
| 
      
 403 
     | 
    
         
            +
                def _clamp(value, range)
         
     | 
| 
      
 404 
     | 
    
         
            +
                  if value < range.first
         
     | 
| 
      
 405 
     | 
    
         
            +
                    range.first
         
     | 
| 
      
 406 
     | 
    
         
            +
                  elsif value > range.last
         
     | 
| 
      
 407 
     | 
    
         
            +
                    range.last
         
     | 
| 
      
 408 
     | 
    
         
            +
                  else
         
     | 
| 
      
 409 
     | 
    
         
            +
                    value
         
     | 
| 
      
 410 
     | 
    
         
            +
                  end
         
     | 
| 
      
 411 
     | 
    
         
            +
                end
         
     | 
| 
      
 412 
     | 
    
         
            +
                
         
     | 
| 
      
 413 
     | 
    
         
            +
              end # Color
         
     | 
| 
      
 414 
     | 
    
         
            +
              
         
     | 
| 
      
 415 
     | 
    
         
            +
            end # Colorist
         
     |