# A colour object representing shades of grey. Used primarily in PDF # document creation. class Color::GrayScale # The format of a DeviceGrey colour for PDF. In color-tools 2.0 this will # be removed from this package and added back as a modification by the # PDF::Writer package. PDF_FORMAT_STR = "%.3f %s" # Creates a greyscale colour object from fractional values 0..1. # # Color::GreyScale.from_fraction(0.5) def self.from_fraction(g = 0) color = Color::GrayScale.new color.g = g color end # Creates a greyscale colour object from percentages 0..100. # # Color::GrayScale.from_percent(50) def self.from_percent(g = 0) Color::GrayScale.new(g) end # Creates a greyscale colour object from percentages 0..100. # # Color::GrayScale.new(50) def initialize(g = 0) @g = g / 100.0 end # Compares the other colour to this one. The other colour will be # converted to GreyScale before comparison, so the comparison between a # GreyScale colour and a non-GreyScale colour will be approximate and # based on the other colour's #to_greyscale conversion. If there is no # #to_greyscale conversion, this will raise an exception. This will report # that two GreyScale values are equivalent if they are within # COLOR_TOLERANCE of each other. def ==(other) other = other.to_grayscale other.kind_of?(Color::GrayScale) and ((@g - other.g).abs <= Color::COLOR_TOLERANCE) end # Present the colour as a DeviceGrey fill colour string for PDF. This will # be removed from the default package in color-tools 2.0. def pdf_fill PDF_FORMAT_STR % [ @g, "g" ] end # Present the colour as a DeviceGrey stroke colour string for PDF. This # will be removed from the default package in color-tools 2.0. def pdf_stroke PDF_FORMAT_STR % [ @g, "G" ] end def to_255 [(@g * 255).round, 255].min end private :to_255 # Present the colour as an HTML/CSS colour string. def html gs = "%02x" % to_255 "##{gs * 3}" end # Present the colour as an RGB HTML/CSS colour string (e.g., "rgb(0%, 50%, # 100%)"). def css_rgb "rgb(%3.2f%%, %3.2f%%, %3.2f%%)" % [ gray, gray, gray ] end # Present the colour as an RGBA (with alpha) HTML/CSS colour string (e.g., # "rgb(0%, 50%, 100%, 1)"). def css_rgba "rgba(%3.2f%%, %3.2f%%, %3.2f%%, %1.2f)" % [ gray, gray, gray, 1 ] end # Present the colour as an HSL HTML/CSS colour string (e.g., "hsl(180, # 25%, 35%)"). Note that this will perform a #to_hsl operation. def css_hsl to_hsl.css_hsl end # Present the colour as an HSLA (with alpha) HTML/CSS colour string (e.g., # "hsla(180, 25%, 35%, 1)"). Note that this will perform a #to_hsl # operation. def css_hsla to_hsl.css_hsla end # Convert the greyscale colour to CMYK. def to_cmyk k = 1.0 - @g.to_f Color::CMYK.from_fraction(0, 0, 0, k) end # Convert the greyscale colour to RGB. def to_rgb(ignored = true) Color::RGB.from_fraction(g, g, g) end # Reflexive conversion. def to_grayscale self end alias to_greyscale to_grayscale # Lightens the greyscale colour by the stated percent. def lighten_by(percent) g = [@g + (@g * (percent / 100.0)), 1.0].min Color::GrayScale.from_fraction(g) end # Darken the greyscale colour by the stated percent. def darken_by(percent) g = [@g - (@g * (percent / 100.0)), 0.0].max Color::GrayScale.from_fraction(g) end # Returns the YIQ (NTSC) colour encoding of the greyscale value. This is # an approximation, as the values for I and Q are calculated by treating # the greyscale value as an RGB value. The Y (intensity or brightness) # value is the same as the greyscale value. def to_yiq y = @g i = (@g * 0.596) + (@g * -0.275) + (@g * -0.321) q = (@g * 0.212) + (@g * -0.523) + (@g * 0.311) Color::YIQ.from_fraction(y, i, q) end # Returns the HSL colour encoding of the greyscale value. def to_hsl Color::HSL.from_fraction(0, 0, @g) end # Returns the brightness value for this greyscale value; this is the # greyscale value itself. def brightness @g end # Returns the grayscale value as a percentage of white (100% gray is # white). def gray @g * 100.0 end alias grey gray # Returns the grayscale value as a fractional value of white in the range # 0.0 .. 1.0. def g @g end # Sets the grayscale value as a percentage of white. def gray=(gg) @g = Color.normalize(gg / 100.0) end alias grey= gray= ; # Returns the grayscale value as a fractional value of white in the range # 0.0 .. 1.0. def g=(gg) @g = Color.normalize(gg) end # Adds another colour to the current colour. The other colour will be # converted to grayscale before addition. This conversion depends upon a # #to_grayscale method on the other colour. # # The addition is done using the grayscale accessor methods to ensure a # valid colour in the result. def +(other) other = other.to_grayscale ng = self.dup ng.g += other.g ng end # Subtracts another colour to the current colour. The other colour will be # converted to grayscale before subtraction. This conversion depends upon # a #to_grayscale method on the other colour. # # The subtraction is done using the grayscale accessor methods to ensure a # valid colour in the result. def -(other) other = other.to_grayscale ng = self.dup ng.g -= other.g ng end def inspect "Gray [%.2f%%]" % [ gray ] end end # A synonym for Color::GrayScale. Color::GreyScale = Color::GrayScale