Class: Emfsvg::Svg::Color

Inherits:
Object
  • Object
show all
Defined in:
lib/emfsvg/svg/color.rb

Overview

SVG color value object. Holds an RGB triplet (0..255 each) or represents a "null" color (fill="none" / stroke="none").

Parses CSS color syntax:

* #RGB / #RRGGBB hex
* rgb(r, g, b) functional
* CSS Level 1+2 named colors (17 basic)

Anything else raises Emfsvg::FormatError. The translation layer relies on a normalized RGB triplet — no transparency, no currentColor.

Constant Summary collapse

NULL =
NullColor = Class.new do
  def null? = true
  def red = 0
  def green = 0
  def blue = 0
  def to_emf_wire = Emf::Model::Geometry::Color.new(red: 0, green: 0, blue: 0)
  def ==(other) = other.is_a?(self.class)
  alias_method :eql?, :==
  def hash = NullColor.hash
end.new.freeze
NAMED_COLORS =
{
  "black" => [0x00, 0x00, 0x00],
  "silver" => [0xC0, 0xC0, 0xC0],
  "gray" => [0x80, 0x80, 0x80],
  "grey" => [0x80, 0x80, 0x80],
  "white" => [0xFF, 0xFF, 0xFF],
  "maroon" => [0x80, 0x00, 0x00],
  "red" => [0xFF, 0x00, 0x00],
  "purple" => [0x80, 0x00, 0x80],
  "fuchsia" => [0xFF, 0x00, 0xFF],
  "magenta" => [0xFF, 0x00, 0xFF],
  "green" => [0x00, 0x80, 0x00],
  "lime" => [0x00, 0xFF, 0x00],
  "olive" => [0x80, 0x80, 0x00],
  "yellow" => [0xFF, 0xFF, 0x00],
  "navy" => [0x00, 0x00, 0x80],
  "blue" => [0x00, 0x00, 0xFF],
  "teal" => [0x00, 0x80, 0x80],
  "aqua" => [0x00, 0xFF, 0xFF],
  "cyan" => [0x00, 0xFF, 0xFF]
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(red:, green:, blue:) ⇒ Color

Returns a new instance of Color.



18
19
20
21
22
# File 'lib/emfsvg/svg/color.rb', line 18

def initialize(red:, green:, blue:)
  @red = clamp(red)
  @green = clamp(green)
  @blue = clamp(blue)
end

Instance Attribute Details

#blueObject (readonly)

Returns the value of attribute blue.



16
17
18
# File 'lib/emfsvg/svg/color.rb', line 16

def blue
  @blue
end

#greenObject (readonly)

Returns the value of attribute green.



16
17
18
# File 'lib/emfsvg/svg/color.rb', line 16

def green
  @green
end

#redObject (readonly)

Returns the value of attribute red.



16
17
18
# File 'lib/emfsvg/svg/color.rb', line 16

def red
  @red
end

Class Method Details

.expand_short_hex(digits) ⇒ Object



92
93
94
95
96
# File 'lib/emfsvg/svg/color.rb', line 92

def self.expand_short_hex(digits)
  new(red: (digits[0] * 2).to_i(16),
      green: (digits[1] * 2).to_i(16),
      blue: (digits[2] * 2).to_i(16))
end

.parse(value) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/emfsvg/svg/color.rb', line 74

def self.parse(value)
  return NULL if value.nil? || value.strip == "none" || value.strip.empty?

  v = value.strip
  if (m = v.match(/\A#([0-9a-fA-F]{3})\z/))
    expand_short_hex(m[1])
  elsif (m = v.match(/\A#([0-9a-fA-F]{6})\z/))
    new(red: m[1][0, 2].to_i(16), green: m[1][2, 2].to_i(16), blue: m[1][4, 2].to_i(16))
  elsif (m = v.match(/\Argb\(\s*(-?\d+)\s*,\s*(-?\d+)\s*,\s*(-?\d+)\s*\)\z/i))
    new(red: m[1].to_i, green: m[2].to_i, blue: m[3].to_i)
  elsif NAMED_COLORS.key?(v.downcase)
    r, g, b = NAMED_COLORS[v.downcase]
    new(red: r, green: g, blue: b)
  else
    raise FormatError, "unsupported SVG color: #{value.inspect}"
  end
end

Instance Method Details

#==(other) ⇒ Object Also known as: eql?



32
33
34
# File 'lib/emfsvg/svg/color.rb', line 32

def ==(other)
  other.is_a?(self.class) && red == other.red && green == other.green && blue == other.blue
end

#hashObject



37
38
39
# File 'lib/emfsvg/svg/color.rb', line 37

def hash
  [self.class, red, green, blue].hash
end

#null?Boolean

Returns:

  • (Boolean)


24
25
26
# File 'lib/emfsvg/svg/color.rb', line 24

def null?
  false
end

#to_emf_wireObject



28
29
30
# File 'lib/emfsvg/svg/color.rb', line 28

def to_emf_wire
  Emf::Model::Geometry::Color.new(red: red, green: green, blue: blue)
end