2 * Pixel Graphics Library
3 * coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
4 * Understanding is not required. Only obedience.
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, version 3 of the License ONLY.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 module iv
.sdpy
.color
/*is aliced*/;
21 import iv
.sdpy
.compat
;
24 // ////////////////////////////////////////////////////////////////////////// //
25 @gcc_inline ubyte clampToByte(T
) (T n
) @safe pure nothrow @nogc if (__traits(isIntegral
, T
)) {
26 //static assert(!__traits(isUnsigned, T), "clampToByte can't process unsigned types");
27 static if (__VERSION__
> 2067) pragma(inline
, true);
28 static if (T
.sizeof
== 2 || T
.sizeof
== 4) {
29 static if (__traits(isUnsigned
, T
)) {
30 return cast(ubyte)(n
&0xff|
(255-((-cast(int)(n
< 256))>>24)));
32 n
&= -cast(int)(n
>= 0);
33 return cast(ubyte)(n|
((255-cast(int)n
)>>31));
35 } else static if (T
.sizeof
== 1) {
36 static assert(__traits(isUnsigned
, T
), "clampToByte: signed byte? no, really?");
39 static assert(false, "clampToByte: integer too big");
43 static assert(clampToByte(666) == 255);
44 static assert(clampToByte(-666) == 0);
45 static assert(clampToByte(250) == 250);
46 static assert(clampToByte(-250) == 0);
47 static assert(clampToByte(cast(uint)250) == 250);
48 static assert(clampToByte(cast(uint)1000) == 255);
49 static assert(clampToByte(cast(uint)0xfffffff0) == 255);
53 private @gcc_inline T
absInternal(T
) (T a
) {
54 static if (__VERSION__
> 2067) pragma(inline
, true);
55 return (a
< 0 ?
-a
: a
);
58 private @gcc_inline TT
minInternal(TT
, T
...) (T args
) if (T
.length
> 0) {
59 static if (__VERSION__
> 2067) pragma(inline
, true);
60 TT res
= cast(TT
)args
[0];
61 foreach (immutable n
; args
[1..$]) if (n
< res
) res
= cast(TT
)n
;
65 private @gcc_inline TT
maxInternal(TT
, T
...) (T args
) if (T
.length
> 0) {
66 static if (__VERSION__
> 2067) pragma(inline
, true);
67 TT res
= cast(TT
)args
[0];
68 foreach (immutable n
; args
[1..$]) if (n
> res
) res
= cast(TT
)n
;
73 // ////////////////////////////////////////////////////////////////////////// //
74 align(1) struct VColor
{
78 /// struct to ease color components extraction/replacing
79 version(LittleEndian
) {
84 } else version(BigEndian
) {
90 static assert(0, "WTF?!");
101 AMask
= cast(uint)(0xffu
<<AShift
),
102 RMask
= cast(uint)(0xffu
<<RShift
),
103 GMask
= cast(uint)(0xffu
<<GShift
),
104 BMask
= cast(uint)(0xffu
<<BShift
),
106 static if (__VERSION__
>= 2067) {
108 transparent
= VColor(AMask
), /// completely transparent pixel color
109 black
= VColor(0), /// completely black pixel color
110 white
= VColor(RMask|GMask|BMask
), /// completely white pixel color
111 red
= VColor(RMask
), /// completely red pixel color
112 green
= VColor(GMask
), /// completely green pixel color
113 blue
= VColor(BMask
), /// completely blue pixel color
116 // alas, old DMDFE sux
117 static @property pure nothrow @safe @nogc {
118 @gcc_inline VColor
transparent () { return VColor(AMask
); }
119 @gcc_inline VColor
black () { return VColor(0); }
120 @gcc_inline VColor
white () { return VColor(RMask|GMask|BMask
); }
121 @gcc_inline VColor
red () { return VColor(RMask
); }
122 @gcc_inline VColor
green () { return VColor(GMask
); }
123 @gcc_inline VColor
blue () { return VColor(BMask
); }
127 // this mixin can be used to alphablend two `uint` colors
128 // `colu32name` is variable that holds color to blend,
129 // `destu32name` is variable that holds "current" color (from surface, for example)
130 // alpha value of `destu32name` doesn't matter
131 // alpha value of `colu32name` means: 0 for replace color, 255 for keep `destu32name`
132 enum ColorBlendMixinStr(string colu32name
, string destu32name
) = "{
133 static if (VColor.AShift == 24) {
134 immutable uint a_tmp_ = (256-(("~colu32name
~")>>24))&(-(1-(((("~colu32name
~")>>24)+1)>>8))); // to not loose bits, but 255 should become 0
135 immutable uint dc_tmp_ = ("~destu32name
~")&0xffffff;
136 immutable uint srb_tmp_ = (("~colu32name
~")&0xff00ff);
137 immutable uint sg_tmp_ = (("~colu32name
~")&0x00ff00);
138 } else static if (VColor.AShift == 0) {
139 immutable uint a_tmp_ = (256-(("~colu32name
~")&0xff))&(-(1-(((("~colu32name
~")&0xff)+1)>>8))); // to not loose bits, but 255 should become 0
140 immutable uint dc_tmp_ = (("~destu32name
~")>>8)&0xffffff;
141 immutable uint srb_tmp_ = ((("~colu32name
~")>>8)&0xff00ff);
142 immutable uint sg_tmp_ = ((("~colu32name
~")>>8)&0x00ff00);
144 static assert(0, `unsupported VColor.AMask value (only 0 and 24 are allowed)`);
146 immutable uint drb_tmp_ = (dc_tmp_&0xff00ff);
147 immutable uint dg_tmp_ = (dc_tmp_&0x00ff00);
148 immutable uint orb_tmp_ = (drb_tmp_+(((srb_tmp_-drb_tmp_)*a_tmp_+0x800080)>>8))&0xff00ff;
149 immutable uint og_tmp_ = (dg_tmp_+(((sg_tmp_-dg_tmp_)*a_tmp_+0x008000)>>8))&0x00ff00;
150 static if (VColor.AShift == 24) {
151 ("~destu32name
~") = (orb_tmp_|og_tmp_)&~VColor.AMask;
153 // move colors to highest bits
154 ("~destu32name
~") = (orb_tmp_|og_tmp_)<<8;
159 string
toString () const nothrow @safe {
160 static usize
b2s() (char[] dest
, ubyte b
) {
162 dest
[0] = cast(char)(b
/100%10+'0');
163 dest
[1] = cast(char)(b
/10%10+'0');
164 dest
[2] = cast(char)(b
%10+'0');
166 } else if (b
>= 10) {
167 dest
[0] = cast(char)(b
/10%10+'0');
168 dest
[1] = cast(char)(b
%10+'0');
171 dest
[0] = cast(char)(b
%10+'0');
178 case AMask
: return "transparent";
179 case 0: return "black";
180 case RMask
: return "red";
181 case GMask
: return "green";
182 case BMask
: return "blue";
183 case RMask|GMask|BMask
: return "white";
189 if (a
!= 0) buf
[pos
++] = 'a';
191 pos
+= b2s(buf
[pos
..$], r
);
193 pos
+= b2s(buf
[pos
..$], g
);
195 pos
+= b2s(buf
[pos
..$], b
);
198 pos
+= b2s(buf
[pos
..$], a
);
201 return buf
[0..pos
].idup
;
204 this (uint v
) pure { u32
= v
; }
205 this (const(char)[] s
) { u32
= parseColorName(s
).u32
; }
206 this (string s
) { u32
= parseColorName(s
).u32
; }
209 //static auto opCast(T) (const(char)[] s) if (is(T == VColor)) { return parseColorName(s); }
210 //auto opCast(T) (const(char)[] s) if (is(T == uint)) { return u32; }
212 /// Is color completely transparent?
213 @gcc_inline @property bool isTransparent() () const pure {
214 static if (__VERSION__
> 2067) pragma(inline
, true);
218 /// Is color completely opaque?
219 @gcc_inline @property bool isOpaque() () const pure {
220 static if (__VERSION__
> 2067) pragma(inline
, true);
224 @gcc_inline @property VColor
setAlpha(T
) (T a
) const pure if (__traits(isIntegral
, T
)) {
225 static if (__VERSION__
> 2067) pragma(inline
, true);
226 return VColor((u32
&~AMask
)|
(clampToByte(a
)<<AShift
));
230 * Build rgba color from components.
233 * r = red component [0..255]
234 * g = green component [0..255]
235 * b = blue component [0..255]
236 * a = transparency [0..255] (0: completely opaque; 255: completely transparent)
241 @gcc_inline static VColor
rgba(TR
, TG
, TB
, TA
) (TR r
, TG g
, TB b
, TA a
) pure
242 if (__traits(isIntegral
, TR
) && __traits(isIntegral
, TG
) && __traits(isIntegral
, TB
) && __traits(isIntegral
, TA
))
244 static if (__VERSION__
> 2067) pragma(inline
, true);
246 (clampToByte(a
)<<AShift
)|
247 (clampToByte(r
)<<RShift
)|
248 (clampToByte(g
)<<GShift
)|
249 (clampToByte(b
)<<BShift
));
252 * Build opaque non-transparent rgb color from components.
255 * r = red component [0..255]
256 * g = green component [0..255]
257 * b = blue component [0..255]
262 @gcc_inline static VColor
rgb(TR
, TG
, TB
) (TR r
, TG g
, TB b
) pure
263 if (__traits(isIntegral
, TR
) && __traits(isIntegral
, TG
) && __traits(isIntegral
, TB
))
265 static if (__VERSION__
> 2067) pragma(inline
, true);
267 (clampToByte(r
)<<RShift
)|
268 (clampToByte(g
)<<GShift
)|
269 (clampToByte(b
)<<BShift
));
272 // HSL functions were taken from arsd.color, written by Adam D. Ruppe, modified by Ketmar
273 // Converts hsl to rgb
274 static VColor
hsl(T
) (T h
, T s
, T l
, T a
=0) pure if (__traits(isFloating
, T
)) {
276 immutable real C
= (1-absInternal(2*l
-1))*s
;
277 immutable real hPrime
= h
/60;
278 immutable real X
= C
*(1-absInternal(hPrime
%2-1));
282 } else if (hPrime
>= 0 && hPrime
< 1) {
286 } else if (hPrime
>= 1 && hPrime
< 2) {
290 } else if (hPrime
>= 2 && hPrime
< 3) {
294 } else if (hPrime
>= 3 && hPrime
< 4) {
298 } else if (hPrime
>= 4 && hPrime
< 5) {
302 } else if (hPrime
>= 5 && hPrime
< 6) {
308 immutable real m
= l
-C
/2;
313 return VColor
.rgba(cast(ubyte)(r
*255), cast(ubyte)(g
*255), cast(ubyte)(b
*255), cast(ubyte)(a
));
317 // Converts an RGB color into an HSL triplet.
318 // useWeightedLightness will try to get a better value for luminosity for the human eye,
319 // which is more sensitive to green than red and more to red than blue.
320 // If it is false, it just does average of the rgb.
321 void toHsl(T
=real) (out T Ho
, out T So
, out T Lo
, bool useWeightedLightness
=false) pure if (__traits(isFloating
, T
)) {
322 // use bitops for CTFE
323 immutable real r1
= cast(real)((this.u32
>>RShift
)&0xff)/255;
324 immutable real g1
= cast(real)((this.u32
>>GShift
)&0xff)/255;
325 immutable real b1
= cast(real)((this.u32
>>BShift
)&0xff)/255;
327 immutable real maxColor
= maxInternal
!real(r1
, g1
, b1
);
328 immutable real minColor
= minInternal
!real(r1
, g1
, b1
);
330 real L
= (maxColor
+minColor
)/2;
331 if (useWeightedLightness
) {
332 // the colors don't affect the eye equally
333 // this is a little more accurate than plain HSL numbers
334 L
= 0.2126*r1
+0.7152*g1
+0.0722*b1
;
338 if (maxColor
!= minColor
) {
340 S
= (maxColor
-minColor
)/(maxColor
+minColor
);
342 S
= (maxColor
-minColor
)/(2.0-maxColor
-minColor
);
344 if (r1
== maxColor
) {
345 H
= (g1
-b1
)/(maxColor
-minColor
);
346 } else if(g1
== maxColor
) {
347 H
= 2.0+(b1
-r1
)/(maxColor
-minColor
);
349 H
= 4.0+(r1
-g1
)/(maxColor
-minColor
);
362 VColor
lighten(T
) (T percentage
) pure if (__traits(isFloating
, T
)) {
367 else if (l
< 0) l
= 0; //k8:???
368 return hsl(h
, s
, l
, cast(real)this.a
);
371 VColor
darken(T
) (T percentage
) pure if (__traits(isFloating
, T
)) {
376 else if (l
< 0) l
= 0; //k8:???
377 return hsl(h
, s
, l
, cast(real)this.a
);
380 // for light colors, call darken. for dark colors, call lighten.
381 // The goal: get toward center grey.
382 VColor
moderate(T
) (T percentage
) pure if (__traits(isFloating
, T
)) {
385 if (l
> 0.5) l
*= (1-percentage
);
386 else if (l
<= 0.01) l
= percentage
; // if we are given black, moderating it means getting *something* out
387 else l
*= (1+percentage
);
389 else if (l
< 0) l
= 0; //k8:???
390 return hsl(h
, s
, l
, cast(real)this.a
);
393 /// the opposite of moderate. Make darks darker and lights lighter
394 VColor
extremify(T
) (T percentage
) pure if (__traits(isFloating
, T
)) {
397 if (l
< 0.5) l
*= (1-percentage
); else l
*= (1+percentage
);
399 else if (l
< 0) l
= 0; //k8:???
400 return hsl(h
, s
, l
, cast(real)this.a
);
403 /// Move around the lightness wheel, trying not to break on moderate things
404 VColor
oppositeLightness() () pure {
408 if (original
> 0.4 && original
< 0.6) {
409 l
= 0.8-original
; // so it isn't quite the same
413 return hsl(h
, s
, l
, cast(real)this.a
);
416 /// Try to determine a text color - either white or black - based on the input
417 VColor
textColor() () pure {
419 toHsl(h
, s
, l
, true); // give green a bonus for contrast
420 return (l
> 0.71 ? VColor
.black
: VColor
.white
);
423 static assert(VColor
.sizeof
== uint.sizeof
);
425 static assert(VColor.black.textColor == VColor.white);
426 static assert(VColor.hsl(1.0, 1.0, 1.0) == VColor.white);
427 static assert(VColor.hsl(1.0, 1.0, 0.0) == VColor.black);
428 //pragma(msg, VColor.hsl(1.0, 1.0, 0.0));
432 // ////////////////////////////////////////////////////////////////////////// //
433 private int digit (char ch
, int base
) pure @safe nothrow @nogc {
434 static if (__VERSION__
> 2067) pragma(inline
, true);
435 if (ch
>= '0' && ch
<= '9') ch
-= '0';
436 else if (ch
>= 'A' && ch
<= 'Z') ch
-= 'A'-10;
437 else if (ch
>= 'a' && ch
<= 'z') ch
-= 'a'-10;
439 return (ch
< base ? ch
: -1);
443 // ////////////////////////////////////////////////////////////////////////// //
444 private __gshared VColor
[string
] knownColors
;
447 private void loadColors (string srctext
) {
450 mainloop
: while (srctext
.length
) {
452 while (pos
< srctext
.length
&& srctext
[pos
] != '\n') ++pos
;
453 if (pos
< srctext
.length
) ++pos
;
454 auto ln
= srctext
[0..pos
];
455 srctext
= srctext
[pos
..$];
456 while (ln
.length
&& ln
[$-1] <= ' ') ln
= ln
[0..$-1];
458 while (pos
< ln
.length
&& ln
[pos
] != '#') ++pos
;
460 //{ import std.stdio; writeln("*[", ln, "]"); }
461 foreach (immutable idx
; 0..3) {
462 while (ln
.length
&& ln
[0] <= ' ') ln
= ln
[1..$];
463 if (ln
.length
== 0 || ln
[0] < '0' || ln
[0] > '9') continue mainloop
;
465 while (ln
.length
&& ln
[0] >= '0' && ln
[0] <= '9') {
466 num
= num
*10+(ln
[0]-'0');
467 if (num
> 255) continue mainloop
;
470 rgb
[idx
] = cast(ubyte)num
;
471 //{ import std.stdio; writeln("**[", ln, "]"); }
473 while (ln
.length
&& ln
[0] <= ' ') ln
= ln
[1..$];
474 if (ln
.length
== 0) continue mainloop
;
475 //{ import std.stdio; writeln("[", ln, "] = (", rgb[0], ", ", rgb[1], ", ", rgb[2], ")"); }
476 knownColors
[ln
.idup
] = VColor
.rgb(rgb
[0], rgb
[1], rgb
[2]);
481 shared static this () {
484 loadColors("/usr/share/X11/rgb.txt");
485 } catch (Exception) {
486 knownColors["red"] = VColor.rgb(255, 0, 0);
487 knownColors["green"] = VColor.rgb(0, 255, 0);
488 knownColors["blue"] = VColor.rgb(0, 0, 255);
489 knownColors["black"] = VColor.rgb(0, 0, 0);
490 knownColors["white"] = VColor.rgb(255, 255, 255);
491 knownColors["silver"] = VColor.rgb(192, 192, 192);
494 loadColors(colorList_
);
498 // ////////////////////////////////////////////////////////////////////////// //
499 public VColor
parseColorName (const(char)[] cname
, bool* ok
=null) @trusted nothrow @nogc {
500 bool parseNum (out ubyte v
) @safe nothrow @nogc {
502 while (cname
.length
&& (cname
[0] <= ' ' || cname
[0] == '_')) cname
= cname
[1..$];
503 if (cname
.length
== 0 || cname
[0] < '0' || cname
[0] > '9') return false;
504 if (cname
.length
> 2 && cname
[0] == '0' && (cname
[1] == 'x' || cname
[1] == 'X')) {
508 } else if (cname
.length
> 2 && cname
[0] == '0' && (cname
[1] == 'o' || cname
[1] == 'O')) {
512 } else if (cname
.length
> 2 && cname
[0] == '0' && (cname
[1] == 'b' || cname
[1] == 'B')) {
516 } else if (cname
.length
> 2 && cname
[0] == '0' && (cname
[1] == 'd' || cname
[1] == 'D')) {
520 if (cname
.length
== 0 ||
digit(cname
[0], base
) < 0) return false;
522 while (cname
.length
) {
523 int d
= digit(cname
[0], base
);
525 if (cname
[0] != '_') {
526 while (cname
.length
&& cname
[0] <= ' ') cname
= cname
[1..$];
531 if (n
> 255) return false;
539 if (ok
!is null) *ok
= false;
540 while (cname
.length
&& cname
[0] <= ' ') cname
= cname
[1..$];
541 while (cname
.length
&& cname
[$-1] <= ' ') cname
= cname
[0..$-1];
542 if (cname
.length
== 0) return VColor
.transparent
;
543 if (cname
[0] == '#') {
547 // collect hex digits
548 foreach (char ch
; cname
) {
549 if (ch
<= ' ' || ch
== '_') continue;
550 if ((ch
>= '0' && ch
<= '9') ||
(ch
>= 'A' && ch
<= 'F') ||
(ch
>= 'a' && ch
<= 'f')) {
551 if (hdpos
>= hd
.length
) return VColor
.transparent
;
552 if (ch
>= 'a') ch
-= 'a'-10;
553 else if (ch
>= 'A') ch
-= 'A'-10;
555 hd
[hdpos
++] = cast(ubyte)ch
;
556 } else if (ch
> ' ' && ch
!= '_') {
557 return VColor
.transparent
;
561 if (ok
!is null) *ok
= true;
562 //return VColor.rgb(hd[0]*16+hd[0], hd[1]*16+hd[1], hd[2]*16+hd[2]);
563 return VColor
.rgb(hd
[0]*17, hd
[1]*17, hd
[2]*17);
564 } else if (hdpos
== 6) {
565 if (ok
!is null) *ok
= true;
566 return VColor
.rgb(hd
[0]*16+hd
[1], hd
[2]*16+hd
[3], hd
[4]*16+hd
[5]);
568 return VColor
.transparent
;
571 if (cname
.length
> 3 && cname
[0..3] == "rgb") {
573 if (cname
[0] == 'a') cname
= cname
[1..$];
574 while (cname
.length
&& cname
[0] <= ' ') cname
= cname
[1..$];
575 if (cname
.length
< 2 || cname
[0] != '(' || cname
[$-1] != ')') return VColor
.transparent
;
580 while (cname
.length
&& (cname
[0] <= ' ' || cname
[0] == '_')) cname
= cname
[1..$];
581 if (cidx
>= rgba
.length
) return VColor
.transparent
;
582 if (cname
[0] != ',') {
583 if (!parseNum(rgba
[cidx
])) return VColor
.transparent
;
586 if (cname
[0] == ')') break;
587 if (cname
[0] != ',') return VColor
.transparent
;
590 if (cidx
< 3) return VColor
.transparent
;
591 if (ok
!is null) *ok
= true;
592 return VColor
.rgba(rgba
[0], rgba
[1], rgba
[2], rgba
[3]);
594 // try predefined colors
598 foreach (char ch
; cname
) {
599 if (ch
<= ' ') continue;
600 if (ch
>= 'A' && ch
<= 'Z') ch
+= 32; // poor man's `toLower()`
601 if (pos
>= nbuf
.length
) return VColor
.transparent
;
604 if (pos
== 0) return VColor
.transparent
;
605 if (auto cl
= nbuf
[0..pos
] in knownColors
) {
606 if (ok
!is null) *ok
= true;
609 if (nbuf
[0..pos
] == "transparent") {
610 if (ok
!is null) *ok
= true;
611 return VColor
.transparent
;
614 return VColor
.transparent
;
619 version(test_color_parser
) {
620 void dumpColor (string cname
) {
622 auto clr
= parseColorName(cname
, &ok
);
623 writefln
!"0x%08x; ok=%s; [%s]"(clr
, ok
, cname
);
628 dumpColor("#00_ff_00");
629 dumpColor("#00fe0_0");
630 dumpColor("rgb(1, 2, 3 )");
631 dumpColor("rgba(1, 2, 3 )");
632 dumpColor("rgba(1, 2, 3 , 4)");
633 dumpColor("rgba(1,,, 4)");
637 dumpColor("dark orange");
645 // ////////////////////////////////////////////////////////////////////////// //
646 private immutable string colorList_
= `
648 248 248 255 ghostwhite
649 245 245 245 whitesmoke
650 220 220 220 gainsboro
651 255 250 240 floralwhite
654 250 235 215 antiquewhite
655 255 239 213 papayawhip
656 255 235 205 blanchedalmond
658 255 218 185 peachpuff
659 255 222 173 navajowhite
663 255 250 205 lemonchiffon
666 245 255 250 mintcream
668 240 248 255 aliceblue
670 255 240 245 lavenderblush
671 255 228 225 mistyrose
674 47 79 79 darkslategray
675 47 79 79 darkslategrey
678 112 128 144 slategray
679 112 128 144 slategrey
680 119 136 153 lightslategray
681 119 136 153 lightslategrey
688 211 211 211 lightgrey
689 211 211 211 lightgray
690 25 25 112 midnightblue
693 100 149 237 cornflowerblue
694 72 61 139 darkslateblue
696 123 104 238 mediumslateblue
697 132 112 255 lightslateblue
701 30 144 255 dodgerblue
702 0 191 255 deepskyblue
704 135 206 250 lightskyblue
706 176 196 222 lightsteelblue
707 173 216 230 lightblue
708 176 224 230 powderblue
709 175 238 238 paleturquoise
710 0 206 209 darkturquoise
711 72 209 204 mediumturquoise
715 224 255 255 lightcyan
717 102 205 170 mediumaquamarine
718 127 255 212 aquamarine
720 85 107 47 darkolivegreen
721 143 188 143 darkseagreen
723 60 179 113 mediumseagreen
724 32 178 170 lightseagreen
725 152 251 152 palegreen
726 0 255 127 springgreen
733 0 250 154 mediumspringgreen
734 173 255 47 greenyellow
736 154 205 50 yellowgreen
737 34 139 34 forestgreen
739 189 183 107 darkkhaki
741 238 232 170 palegoldenrod
742 250 250 210 lightgoldenrodyellow
743 255 255 224 lightyellow
746 238 221 130 lightgoldenrod
748 184 134 11 darkgoldenrod
749 188 143 143 rosybrown
751 139 69 19 saddlebrown
754 222 184 135 burlywood
757 244 164 96 sandybrown
762 233 150 122 darksalmon
764 255 160 122 lightsalmon
768 240 128 128 lightcoral
775 255 182 193 lightpink
776 219 112 147 palevioletred
780 199 21 133 mediumvioletred
787 186 85 211 mediumorchid
788 153 50 204 darkorchid
790 138 43 226 blueviolet
794 147 112 219 mediumpurple
800 255 245 238 seashell1
801 238 229 222 seashell2
802 205 197 191 seashell3
803 139 134 130 seashell4
804 255 239 219 antiquewhite1
805 238 223 204 antiquewhite2
806 205 192 176 antiquewhite3
807 139 131 120 antiquewhite4
812 255 218 185 peachpuff1
813 238 203 173 peachpuff2
814 205 175 149 peachpuff3
815 139 119 101 peachpuff4
816 255 222 173 navajowhite1
817 238 207 161 navajowhite2
818 205 179 139 navajowhite3
819 139 121 94 navajowhite4
820 255 250 205 lemonchiffon1
821 238 233 191 lemonchiffon2
822 205 201 165 lemonchiffon3
823 139 137 112 lemonchiffon4
824 255 248 220 cornsilk1
825 238 232 205 cornsilk2
826 205 200 177 cornsilk3
827 139 136 120 cornsilk4
832 240 255 240 honeydew1
833 224 238 224 honeydew2
834 193 205 193 honeydew3
835 131 139 131 honeydew4
836 255 240 245 lavenderblush1
837 238 224 229 lavenderblush2
838 205 193 197 lavenderblush3
839 139 131 134 lavenderblush4
840 255 228 225 mistyrose1
841 238 213 210 mistyrose2
842 205 183 181 mistyrose3
843 139 125 123 mistyrose4
848 131 111 255 slateblue1
849 122 103 238 slateblue2
850 105 89 205 slateblue3
852 72 118 255 royalblue1
853 67 110 238 royalblue2
860 30 144 255 dodgerblue1
861 28 134 238 dodgerblue2
862 24 116 205 dodgerblue3
863 16 78 139 dodgerblue4
864 99 184 255 steelblue1
865 92 172 238 steelblue2
866 79 148 205 steelblue3
867 54 100 139 steelblue4
868 0 191 255 deepskyblue1
869 0 178 238 deepskyblue2
870 0 154 205 deepskyblue3
871 0 104 139 deepskyblue4
876 176 226 255 lightskyblue1
877 164 211 238 lightskyblue2
878 141 182 205 lightskyblue3
879 96 123 139 lightskyblue4
880 198 226 255 slategray1
881 185 211 238 slategray2
882 159 182 205 slategray3
883 108 123 139 slategray4
884 202 225 255 lightsteelblue1
885 188 210 238 lightsteelblue2
886 162 181 205 lightsteelblue3
887 110 123 139 lightsteelblue4
888 191 239 255 lightblue1
889 178 223 238 lightblue2
890 154 192 205 lightblue3
891 104 131 139 lightblue4
892 224 255 255 lightcyan1
893 209 238 238 lightcyan2
894 180 205 205 lightcyan3
895 122 139 139 lightcyan4
896 187 255 255 paleturquoise1
897 174 238 238 paleturquoise2
898 150 205 205 paleturquoise3
899 102 139 139 paleturquoise4
900 152 245 255 cadetblue1
901 142 229 238 cadetblue2
902 122 197 205 cadetblue3
903 83 134 139 cadetblue4
912 151 255 255 darkslategray1
913 141 238 238 darkslategray2
914 121 205 205 darkslategray3
915 82 139 139 darkslategray4
916 127 255 212 aquamarine1
917 118 238 198 aquamarine2
918 102 205 170 aquamarine3
919 69 139 116 aquamarine4
920 193 255 193 darkseagreen1
921 180 238 180 darkseagreen2
922 155 205 155 darkseagreen3
923 105 139 105 darkseagreen4
928 154 255 154 palegreen1
929 144 238 144 palegreen2
930 124 205 124 palegreen3
932 0 255 127 springgreen1
933 0 238 118 springgreen2
934 0 205 102 springgreen3
935 0 139 69 springgreen4
940 127 255 0 chartreuse1
941 118 238 0 chartreuse2
942 102 205 0 chartreuse3
944 192 255 62 olivedrab1
945 179 238 58 olivedrab2
946 154 205 50 olivedrab3
947 105 139 34 olivedrab4
948 202 255 112 darkolivegreen1
949 188 238 104 darkolivegreen2
950 162 205 90 darkolivegreen3
951 110 139 61 darkolivegreen4
956 255 236 139 lightgoldenrod1
957 238 220 130 lightgoldenrod2
958 205 190 112 lightgoldenrod3
959 139 129 76 lightgoldenrod4
960 255 255 224 lightyellow1
961 238 238 209 lightyellow2
962 205 205 180 lightyellow3
963 139 139 122 lightyellow4
972 255 193 37 goldenrod1
973 238 180 34 goldenrod2
974 205 155 29 goldenrod3
975 139 105 20 goldenrod4
976 255 185 15 darkgoldenrod1
977 238 173 14 darkgoldenrod2
978 205 149 12 darkgoldenrod3
979 139 101 8 darkgoldenrod4
980 255 193 193 rosybrown1
981 238 180 180 rosybrown2
982 205 155 155 rosybrown3
983 139 105 105 rosybrown4
984 255 106 106 indianred1
992 255 211 155 burlywood1
993 238 197 145 burlywood2
994 205 170 125 burlywood3
995 139 115 85 burlywood4
1004 255 127 36 chocolate1
1005 238 118 33 chocolate2
1006 205 102 29 chocolate3
1007 139 69 19 chocolate4
1008 255 48 48 firebrick1
1009 238 44 44 firebrick2
1010 205 38 38 firebrick3
1011 139 26 26 firebrick4
1020 255 160 122 lightsalmon1
1021 238 149 114 lightsalmon2
1022 205 129 98 lightsalmon3
1023 139 87 66 lightsalmon4
1028 255 127 0 darkorange1
1029 238 118 0 darkorange2
1030 205 102 0 darkorange3
1031 139 69 0 darkorange4
1048 255 20 147 deeppink1
1049 238 18 137 deeppink2
1050 205 16 118 deeppink3
1052 255 110 180 hotpink1
1053 238 106 167 hotpink2
1060 255 174 185 lightpink1
1061 238 162 173 lightpink2
1062 205 140 149 lightpink3
1063 139 95 101 lightpink4
1064 255 130 171 palevioletred1
1065 238 121 159 palevioletred2
1066 205 104 137 palevioletred3
1067 139 71 93 palevioletred4
1072 255 62 150 violetred1
1073 238 58 140 violetred2
1074 205 50 120 violetred3
1075 139 34 82 violetred4
1088 224 102 255 mediumorchid1
1089 209 95 238 mediumorchid2
1090 180 82 205 mediumorchid3
1091 122 55 139 mediumorchid4
1092 191 62 255 darkorchid1
1093 178 58 238 darkorchid2
1094 154 50 205 darkorchid3
1095 104 34 139 darkorchid4
1100 171 130 255 mediumpurple1
1101 159 121 238 mediumpurple2
1102 137 104 205 mediumpurple3
1103 93 71 139 mediumpurple4
1104 255 225 255 thistle1
1105 238 210 238 thistle2
1106 205 181 205 thistle3
1107 139 123 139 thistle4
1310 169 169 169 darkgrey
1311 169 169 169 darkgray
1314 139 0 139 darkmagenta
1316 144 238 144 lightgreen
1320 102 51 153 rebeccapurple
1324 128 128 128 css-gray
1325 128 128 128 css-grey
1328 128 0 128 css-purple