class CMYKClass::CMYK

Attributes

attrs[R]

Public Class Methods

new(cmyk_attrs) click to toggle source

Attributes specified as a hash, representing CMYK percentages, i.e. Sass::Script::Value::CMYK.new({:cyan=>10, :magenta=>20, :yellow=>30, :black=>40}) is equivalent to cmyk(10%,20%,30%,40%)

# File lib/sass-cmyk.rb, line 11
def initialize(cmyk_attrs)
  # Reject all attribute values that are not numbers between 0 and 100
  cmyk_attrs.reject! {|k, v| !(v.class == Fixnum and v.between?(0, 100))}
  raise ArgumentError.new("CMYK Object must be initialized with hash values between 0 and 100 for :cyan, :magenta, :yellow, and :black") unless [:cyan, :magenta, :yellow, :black].all? {|k| cmyk_attrs.key? k}
  @attrs = cmyk_attrs        
end

Public Instance Methods

_normalize() click to toggle source
# File lib/sass-cmyk.rb, line 46
def _normalize
  # Normalize color components via the following algorithm, per SO (http://stackoverflow.com/a/1530158)
  # C = C - min(C, M, Y)
  # M = M - min(C, M, Y)
  # Y = Y - min(C, M, Y)
  # K = min(100, K + min(C, M, Y))
  cmy_min = [@attrs[:cyan], @attrs[:magenta], @attrs[:yellow]].min
  new_attrs = {:cyan => @attrs[:cyan] - cmy_min,
               :magenta => @attrs[:magenta] - cmy_min,
               :yellow => @attrs[:yellow] - cmy_min,
               :black => [100, @attrs[:black] + cmy_min].min}
end
black() click to toggle source
# File lib/sass-cmyk.rb, line 30
def black
  @attrs[:black]
end
cyan() click to toggle source
# File lib/sass-cmyk.rb, line 18
def cyan
  @attrs[:cyan]
end
div(other) click to toggle source
# File lib/sass-cmyk.rb, line 102
def div(other)
  raise ArgumentError.new("Cannot divide #{self} by #{other}. CMYK colors can only be divided by numbers") if !other.is_a?(Sass::Script::Value::Number)
  raise ArgumentError.new("Cannot divide CMYK color #{self} by zero") if other.value == 0
  reciprocal = Sass::Script::Value::Number.new(1.0/other.value)
  self.times(reciprocal)
end
magenta() click to toggle source
# File lib/sass-cmyk.rb, line 22
def magenta
  @attrs[:magenta]
end
minus(other) click to toggle source
# File lib/sass-cmyk.rb, line 76
def minus(other)
  raise NoMethodError.new("Cannot apply subtraction to #{self}. Subtraction not supported for CMYK colors.")
end
normalize() click to toggle source
# File lib/sass-cmyk.rb, line 34
def normalize
  # Return new CMYK object with normalized color components
  new_color_attrs = @attrs.merge(_normalize)
  Sass::Script::Value::CMYK.new(new_color_attrs)
end
normalize!() click to toggle source
# File lib/sass-cmyk.rb, line 40
def normalize!
  # Normalize color components in place
  @attrs.merge!(_normalize)
  self
end
plus(other) click to toggle source
# File lib/sass-cmyk.rb, line 59
def plus(other)
  if other.is_a?(Sass::Script::Value::CMYK)
    new_color_attrs = {}
    [:cyan, :magenta, :yellow, :black].each do |component|
      # Add corresponding components of each color, limiting to a max of 100
      component_sum = [self.attrs[component] + other.attrs[component], 100].min
      new_color_attrs[component] = component_sum
    end
    # Make new color from summed componenets
    new_color = Sass::Script::Value::CMYK.new(new_color_attrs)
    # Normalize component values
    new_color.normalize!
  else
    raise ArgumentError.new("Cannot add object of class #{other.class} to CMYK color #{self}. Only CMYK colors can be added to CMYK colors")
  end
end
times(other) click to toggle source

TODO: This does not work commutatively yet; only works for CMYK * scalar, and not scalar * CMYK To add support for scalar * CMYK, need to override “times” instance method on Sass::Script::Value::Number

# File lib/sass-cmyk.rb, line 82
def times(other)
  raise ArgumentError.new("Cannot multiply #{self} by #{other}. CMYK colors can only be multiplied by numbers") if !other.is_a?(Sass::Script::Value::Number)
  if other.is_unit?('%')
    scale_factor = other.value.to_f / 100
  else
    scale_factor = other.value
  end
  new_color_attrs = {}
  [:cyan, :magenta, :yellow, :black].each do |component|
    # Scale corresponding components of each color by "scale_factor"
    new_color_attrs[component] = (self.attrs[component] * scale_factor).round
  end
  # Raise error if any resulting component attribute is over 100%, as that would mean it's not possible to scale proportionally
  raise ArgumentError.new("Cannot scale #{self} proportionally by #{other}, as that would result in at least one component over 100%") if new_color_attrs.map {|k, v| v}.max > 100
  # Make new color from scaled components
  new_color = Sass::Script::Value::CMYK.new(new_color_attrs)
  # Normalize component values
  new_color.normalize!
end
to_s(opts = {}) click to toggle source
# File lib/sass-cmyk.rb, line 109
def to_s(opts = {})
  "cmyk(#{@attrs[:cyan]}%,#{@attrs[:magenta]}%,#{@attrs[:yellow]}%,#{@attrs[:black]}%)" 
end
yellow() click to toggle source
# File lib/sass-cmyk.rb, line 26
def yellow
  @attrs[:yellow]
end