Fixed git clone URL
[sixth-3d.git] / src / main / java / eu / svjatoslav / sixth / e3d / renderer / raster / Color.java
1 /*
2  * Sixth 3D engine. Author: Svjatoslav Agejenko.
3  * This project is released under Creative Commons Zero (CC0) license.
4  */
5 package eu.svjatoslav.sixth.e3d.renderer.raster;
6
7 public final class Color {
8
9     public static final Color RED = new Color(255, 0, 0, 255);
10     public static final Color GREEN = new Color(0, 255, 0, 255);
11     public static final Color BLUE = new Color(0, 0, 255, 255);
12     public static final Color YELLOW = new Color(255, 255, 0, 255);
13     public static final Color WHITE = new Color(255, 255, 255, 255);
14     public static final Color BLACK = new Color(0, 0, 0, 255);
15     public static final Color PURPLE = new Color(255, 0, 255, 255);
16     public static final Color TRANSPARENT = new Color(0, 0, 0, 0);
17
18     /**
19      * Red component. 0-255.
20      */
21     public final int r;
22
23     /**
24      * Green component. 0-255.
25      */
26     public final int g;
27
28     /**
29      * Blue component. 0-255.
30      */
31     public final int b;
32
33     /**
34      * Alpha component.
35      * 0 - transparent.
36      * 255 - opaque.
37      */
38     public int a;
39
40     public Color(final Color parentColor) {
41         r = parentColor.r;
42         g = parentColor.g;
43         b = parentColor.b;
44         a = parentColor.a;
45     }
46
47     public Color(final double r, final double g, final double b, final double a) {
48         this.r = ensureByteLimit((int) (r * 255d));
49         this.g = ensureByteLimit((int) (g * 255d));
50         this.b = ensureByteLimit((int) (b * 255d));
51         this.a = ensureByteLimit((int) (a * 255d));
52     }
53
54     /**
55      * @param colorHexCode color code in hex format.
56      *                     Supported formats are:
57      *                     <pre>
58      *                     RGB
59      *                     RGBA
60      *                     RRGGBB
61      *                     RRGGBBAA
62      *                     </pre>
63      */
64     public Color(String colorHexCode) {
65         switch (colorHexCode.length()) {
66             case 3:
67                 r = parseHexSegment(colorHexCode, 0, 1) * 16;
68                 g = parseHexSegment(colorHexCode, 1, 1) * 16;
69                 b = parseHexSegment(colorHexCode, 2, 1) * 16;
70                 a = 255;
71                 return;
72
73             case 4:
74                 r = parseHexSegment(colorHexCode, 0, 1) * 16;
75                 g = parseHexSegment(colorHexCode, 1, 1) * 16;
76                 b = parseHexSegment(colorHexCode, 2, 1) * 16;
77                 a = parseHexSegment(colorHexCode, 3, 1) * 16;
78                 return;
79
80             case 6:
81                 r = parseHexSegment(colorHexCode, 0, 2);
82                 g = parseHexSegment(colorHexCode, 2, 2);
83                 b = parseHexSegment(colorHexCode, 4, 2);
84                 a = 255;
85                 return;
86
87             case 8:
88                 r = parseHexSegment(colorHexCode, 0, 2);
89                 g = parseHexSegment(colorHexCode, 2, 2);
90                 b = parseHexSegment(colorHexCode, 4, 2);
91                 a = parseHexSegment(colorHexCode, 6, 2);
92                 return;
93             default:
94                 throw new IllegalArgumentException("Unsupported color code: " + colorHexCode);
95         }
96     }
97
98     public Color(final int rgb) {
99         r = (rgb & 0xFF0000) >> 16;
100         g = (rgb & 0xFF00) >> 8;
101         b = rgb & 0xFF;
102         a = 255;
103     }
104
105     public Color(final int r, final int g, final int b) {
106         this(r, g, b, 255);
107     }
108
109     public Color(final int r, final int g, final int b, final int a) {
110         this.r = ensureByteLimit(r);
111         this.g = ensureByteLimit(g);
112         this.b = ensureByteLimit(b);
113         this.a = ensureByteLimit(a);
114     }
115
116     private int parseHexSegment(String hexString, int start, int length) {
117         return Integer.parseInt(hexString.substring(start, start + length), 16);
118     }
119
120     /**
121      * Ensure that color values are within allowed limits of 0 to 255.
122      */
123     private int ensureByteLimit(final int value) {
124         if (value < 0)
125             return 0;
126
127         if (value > 255)
128             return 255;
129
130         return value;
131     }
132
133     public boolean isTransparent() {
134         return a == 0;
135     }
136
137     public java.awt.Color toAwtColor() {
138         return new java.awt.Color(r, g, b, a);
139     }
140
141     public int toInt() {
142         return toAwtColor().getRGB();
143     }
144
145     @Override
146     public boolean equals(Object o) {
147         if (this == o) return true;
148         if (o == null || getClass() != o.getClass()) return false;
149
150         Color color = (Color) o;
151
152         if (r != color.r) return false;
153         if (g != color.g) return false;
154         if (b != color.b) return false;
155         return a == color.a;
156     }
157
158     @Override
159     public int hashCode() {
160         int result = r;
161         result = 31 * result + g;
162         result = 31 * result + b;
163         result = 31 * result + a;
164         return result;
165     }
166 }