Formatting update
[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     public final int r, g, b;
19
20     /**
21      * <pre>
22      * 255 is opaque.
23      * 0 is transparent.
24      * </pre>
25      */
26     public int a;
27
28     public Color(final Color parentColor) {
29         r = parentColor.r;
30         g = parentColor.g;
31         b = parentColor.b;
32         a = parentColor.a;
33     }
34
35     public Color(final double r, final double g, final double b, final double a) {
36         this.r = ensureByteLimit((int) (r * 255d));
37         this.g = ensureByteLimit((int) (g * 255d));
38         this.b = ensureByteLimit((int) (b * 255d));
39         this.a = ensureByteLimit((int) (a * 255d));
40     }
41
42     /**
43      * <pre>
44      *     Supported formats are:
45      *
46      *     RGB
47      *     RGBA
48      *     RRGGBB
49      *     RRGGBBAA
50      * </pre>
51      */
52     public Color(String colorHexCode) {
53         switch (colorHexCode.length()) {
54             case 3:
55                 r = parseHexSegment(colorHexCode, 0, 1) * 16;
56                 g = parseHexSegment(colorHexCode, 1, 1) * 16;
57                 b = parseHexSegment(colorHexCode, 2, 1) * 16;
58                 a = 255;
59                 return;
60
61             case 4:
62                 r = parseHexSegment(colorHexCode, 0, 1) * 16;
63                 g = parseHexSegment(colorHexCode, 1, 1) * 16;
64                 b = parseHexSegment(colorHexCode, 2, 1) * 16;
65                 a = parseHexSegment(colorHexCode, 3, 1) * 16;
66                 return;
67
68             case 6:
69                 r = parseHexSegment(colorHexCode, 0, 2);
70                 g = parseHexSegment(colorHexCode, 2, 2);
71                 b = parseHexSegment(colorHexCode, 4, 2);
72                 a = 255;
73                 return;
74
75             case 8:
76                 r = parseHexSegment(colorHexCode, 0, 2);
77                 g = parseHexSegment(colorHexCode, 2, 2);
78                 b = parseHexSegment(colorHexCode, 4, 2);
79                 a = parseHexSegment(colorHexCode, 6, 2);
80                 return;
81             default:
82                 throw new IllegalArgumentException("Unsupported color code: " + colorHexCode);
83         }
84     }
85
86     public Color(final int rgb) {
87         r = (rgb & 0xFF0000) >> 16;
88         g = (rgb & 0xFF00) >> 8;
89         b = rgb & 0xFF;
90         a = 255;
91     }
92
93     public Color(final int r, final int g, final int b) {
94         this(r, g, b, 255);
95     }
96
97     public Color(final int r, final int g, final int b, final int a) {
98         this.r = ensureByteLimit(r);
99         this.g = ensureByteLimit(g);
100         this.b = ensureByteLimit(b);
101         this.a = ensureByteLimit(a);
102     }
103
104     private int parseHexSegment(String hexString, int start, int length) {
105         return Integer.parseInt(hexString.substring(start, start + length), 16);
106     }
107
108     /**
109      * Ensure that color values are within allowed limits of 0 to 255.
110      */
111     private int ensureByteLimit(final int value) {
112         if (value < 0)
113             return 0;
114
115         if (value > 255)
116             return 255;
117
118         return value;
119     }
120
121     public boolean isTransparent() {
122         return a == 0;
123     }
124
125     public java.awt.Color toAwtColor() {
126         return new java.awt.Color(r, g, b, a);
127     }
128
129     public int toInt() {
130         return toAwtColor().getRGB();
131     }
132
133     @Override
134     public boolean equals(Object o) {
135         if (this == o) return true;
136         if (o == null || getClass() != o.getClass()) return false;
137
138         Color color = (Color) o;
139
140         if (r != color.r) return false;
141         if (g != color.g) return false;
142         if (b != color.b) return false;
143         return a == color.a;
144     }
145
146     @Override
147     public int hashCode() {
148         int result = r;
149         result = 31 * result + g;
150         result = 31 * result + b;
151         result = 31 * result + a;
152         return result;
153     }
154 }