Cover for src/colors/color_value.cr


Lines
20 / 20 (100.00%)

1
require "./any_number"
2

        
3
module Colors
4
1
  MAX_INTENSITY = 255_u8
5
1
  MIN_INTENSITY =   0_u8
6

        
7
  # The value one primary color has out of a RGB color.
8
  class ColorValue
9
1007
    def initialize(@value : UInt8 = MIN_INTENSITY); end
10

        
11
    # Create a `ColorValue` from a number or another color value.
12
    #
13
    # Raises `OverflowError` if the value won't fit in a `UInt8`; I.E. if the
14
    # value is less than 0 or greater than 255, or not an integer; E.G. `3.0`,
15
    # `100u64`, `255f64`, or `ColorValue::new(100u8)` are acceptable
16
    # parameters, `-1`, `256u16`, or `123.456` will throw.
17
    def initialize(value : AnyNumber | ColorValue)
18
3721
      @value = value.to_u8
19
    end
20

        
21
    # Create a `ColorValue` from a string representation: either a
22
    # **hexadecimal** numeric value between 0 and 255, or the words `"full"` or
23
    # `"off"` which translate to `MAX_INTENSITY` and `MIN_INTENSITY`,
24
    # respectively.
25
    #
26
    # Raises if the value isn't a valid **base-16** integer which fits into 8
27
    # bits, unsigned.
28
    def initialize(value : String = "0")
29
21
      if value == "full"
30
2
        @value = MAX_INTENSITY
31
19
      elsif value == "off"
32
2
        @value = MIN_INTENSITY
33
      else
34
17
        @value = value.to_i(base: 16).to_u8
35
      end
36
    end
37

        
38
    def self.off
39
31
      ColorValue.new MIN_INTENSITY
40
    end
41

        
42
    def self.full
43
13
      ColorValue.new MAX_INTENSITY
44
    end
45

        
46
    def self.max
47
4
      ColorValue.new MAX_INTENSITY
48
    end
49

        
50
    def self.min
51
2
      ColorValue.new MIN_INTENSITY
52
    end
53

        
54
    def to_s(io)
55
25
      io.printf "%02X", @value
56
    end
57

        
58
    def to_i
59
20
      @value.to_i
60
    end
61

        
62
    def to_u8
63
5119
      @value
64
    end
65

        
66
    def to_f
67
2
      @value.to_f
68
    end
69

        
70
    # boolean operators
71
5
    {% for op in [:==, :>, :<, :<=, :>=] %}
72
    def {{op.id}}(other)
73
      @value {{op.id}} other.to_u8
74
    end
75
    {% end %}
76

        
77
    # regular and bitwise operators
78
8
    {% for op in [:-, :+, :*, :/, :%, :&, :|, :"^"] %}
79
      # Defines a new color where this color {{op.id}} other
80
      def {{op.id}}(other)
81
        ColorValue.new( @value {{ op.id }} other )
82
      end
83
    {% end %}
84

        
85
    def abs
86
2
      @value # unsigned so always positive
87
    end
88
  end
89
end
90