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, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 module iv
.sdpy
.color
/*is aliced*/;
22 import iv
.sdpy
.compat
;
25 // ////////////////////////////////////////////////////////////////////////// //
26 @gcc_inline ubyte clampToByte(T
) (T n
) @safe pure nothrow @nogc if (__traits(isIntegral
, T
)) {
27 //static assert(!__traits(isUnsigned, T), "clampToByte can't process unsigned types");
28 static if (__VERSION__
> 2067) pragma(inline
, true);
29 static if (T
.sizeof
== 2 || T
.sizeof
== 4) {
30 static if (__traits(isUnsigned
, T
)) {
31 return cast(ubyte)(n
&0xff|
(255-((-cast(int)(n
< 256))>>24)));
33 n
&= -cast(int)(n
>= 0);
34 return cast(ubyte)(n|
((255-cast(int)n
)>>31));
36 } else static if (T
.sizeof
== 1) {
37 static assert(__traits(isUnsigned
, T
), "clampToByte: signed byte? no, really?");
40 static assert(false, "clampToByte: integer too big");
44 static assert(clampToByte(666) == 255);
45 static assert(clampToByte(-666) == 0);
46 static assert(clampToByte(250) == 250);
47 static assert(clampToByte(-250) == 0);
48 static assert(clampToByte(cast(uint)250) == 250);
49 static assert(clampToByte(cast(uint)1000) == 255);
50 static assert(clampToByte(cast(uint)0xfffffff0) == 255);
54 private @gcc_inline T
absInternal(T
) (T a
) {
55 static if (__VERSION__
> 2067) pragma(inline
, true);
56 return (a
< 0 ?
-a
: a
);
59 private @gcc_inline TT
minInternal(TT
, T
...) (T args
) if (T
.length
> 0) {
60 static if (__VERSION__
> 2067) pragma(inline
, true);
61 TT res
= cast(TT
)args
[0];
62 foreach (immutable n
; args
[1..$]) if (n
< res
) res
= cast(TT
)n
;
66 private @gcc_inline TT
maxInternal(TT
, T
...) (T args
) if (T
.length
> 0) {
67 static if (__VERSION__
> 2067) pragma(inline
, true);
68 TT res
= cast(TT
)args
[0];
69 foreach (immutable n
; args
[1..$]) if (n
> res
) res
= cast(TT
)n
;
74 // ////////////////////////////////////////////////////////////////////////// //
75 align(1) struct VColor
{
79 /// struct to ease color components extraction/replacing
80 version(LittleEndian
) {
85 } else version(BigEndian
) {
91 static assert(0, "WTF?!");
102 AMask
= cast(uint)(0xffu
<<AShift
),
103 RMask
= cast(uint)(0xffu
<<RShift
),
104 GMask
= cast(uint)(0xffu
<<GShift
),
105 BMask
= cast(uint)(0xffu
<<BShift
),
107 static if (__VERSION__
>= 2067) {
109 transparent
= VColor(AMask
), /// completely transparent pixel color
110 black
= VColor(0), /// completely black pixel color
111 white
= VColor(RMask|GMask|BMask
), /// completely white pixel color
112 red
= VColor(RMask
), /// completely red pixel color
113 green
= VColor(GMask
), /// completely green pixel color
114 blue
= VColor(BMask
), /// completely blue pixel color
117 // alas, old DMDFE sux
118 static @property pure nothrow @safe @nogc {
119 @gcc_inline VColor
transparent () { return VColor(AMask
); }
120 @gcc_inline VColor
black () { return VColor(0); }
121 @gcc_inline VColor
white () { return VColor(RMask|GMask|BMask
); }
122 @gcc_inline VColor
red () { return VColor(RMask
); }
123 @gcc_inline VColor
green () { return VColor(GMask
); }
124 @gcc_inline VColor
blue () { return VColor(BMask
); }
128 // this mixin can be used to alphablend two `uint` colors
129 // `colu32name` is variable that holds color to blend,
130 // `destu32name` is variable that holds "current" color (from surface, for example)
131 // alpha value of `destu32name` doesn't matter
132 // alpha value of `colu32name` means: 0 for replace color, 255 for keep `destu32name`
133 enum ColorBlendMixinStr(string colu32name
, string destu32name
) = "{
134 static if (VColor.AShift == 24) {
135 immutable uint a_tmp_ = (256-(("~colu32name
~")>>24))&(-(1-(((("~colu32name
~")>>24)+1)>>8))); // to not loose bits, but 255 should become 0
136 immutable uint dc_tmp_ = ("~destu32name
~")&0xffffff;
137 immutable uint srb_tmp_ = (("~colu32name
~")&0xff00ff);
138 immutable uint sg_tmp_ = (("~colu32name
~")&0x00ff00);
139 } else static if (VColor.AShift == 0) {
140 immutable uint a_tmp_ = (256-(("~colu32name
~")&0xff))&(-(1-(((("~colu32name
~")&0xff)+1)>>8))); // to not loose bits, but 255 should become 0
141 immutable uint dc_tmp_ = (("~destu32name
~")>>8)&0xffffff;
142 immutable uint srb_tmp_ = ((("~colu32name
~")>>8)&0xff00ff);
143 immutable uint sg_tmp_ = ((("~colu32name
~")>>8)&0x00ff00);
145 static assert(0, `unsupported VColor.AMask value (only 0 and 24 are allowed)`);
147 immutable uint drb_tmp_ = (dc_tmp_&0xff00ff);
148 immutable uint dg_tmp_ = (dc_tmp_&0x00ff00);
149 immutable uint orb_tmp_ = (drb_tmp_+(((srb_tmp_-drb_tmp_)*a_tmp_+0x800080)>>8))&0xff00ff;
150 immutable uint og_tmp_ = (dg_tmp_+(((sg_tmp_-dg_tmp_)*a_tmp_+0x008000)>>8))&0x00ff00;
151 static if (VColor.AShift == 24) {
152 ("~destu32name
~") = (orb_tmp_|og_tmp_)&~VColor.AMask;
154 // move colors to highest bits
155 ("~destu32name
~") = (orb_tmp_|og_tmp_)<<8;
160 string
toString () const nothrow @safe {
161 static usize
b2s() (char[] dest
, ubyte b
) {
163 dest
[0] = cast(char)(b
/100%10+'0');
164 dest
[1] = cast(char)(b
/10%10+'0');
165 dest
[2] = cast(char)(b
%10+'0');
167 } else if (b
>= 10) {
168 dest
[0] = cast(char)(b
/10%10+'0');
169 dest
[1] = cast(char)(b
%10+'0');
172 dest
[0] = cast(char)(b
%10+'0');
179 case AMask
: return "transparent";
180 case 0: return "black";
181 case RMask
: return "red";
182 case GMask
: return "green";
183 case BMask
: return "blue";
184 case RMask|GMask|BMask
: return "white";
190 if (a
!= 0) buf
[pos
++] = 'a';
192 pos
+= b2s(buf
[pos
..$], r
);
194 pos
+= b2s(buf
[pos
..$], g
);
196 pos
+= b2s(buf
[pos
..$], b
);
199 pos
+= b2s(buf
[pos
..$], a
);
202 return buf
[0..pos
].idup
;
205 this (uint v
) pure { u32
= v
; }
206 this (const(char)[] s
) { u32
= parseColorName(s
).u32
; }
207 this (string s
) { u32
= parseColorName(s
).u32
; }
210 //static auto opCast(T) (const(char)[] s) if (is(T == VColor)) { return parseColorName(s); }
211 //auto opCast(T) (const(char)[] s) if (is(T == uint)) { return u32; }
213 /// Is color completely transparent?
214 @gcc_inline @property bool isTransparent() () const pure {
215 static if (__VERSION__
> 2067) pragma(inline
, true);
219 /// Is color completely opaque?
220 @gcc_inline @property bool isOpaque() () const pure {
221 static if (__VERSION__
> 2067) pragma(inline
, true);
225 @gcc_inline @property VColor
setAlpha(T
) (T a
) const pure if (__traits(isIntegral
, T
)) {
226 static if (__VERSION__
> 2067) pragma(inline
, true);
227 return VColor((u32
&~AMask
)|
(clampToByte(a
)<<AShift
));
231 * Build rgba color from components.
234 * r = red component [0..255]
235 * g = green component [0..255]
236 * b = blue component [0..255]
237 * a = transparency [0..255] (0: completely opaque; 255: completely transparent)
242 @gcc_inline static VColor
rgba(TR
, TG
, TB
, TA
) (TR r
, TG g
, TB b
, TA a
) pure
243 if (__traits(isIntegral
, TR
) && __traits(isIntegral
, TG
) && __traits(isIntegral
, TB
) && __traits(isIntegral
, TA
))
245 static if (__VERSION__
> 2067) pragma(inline
, true);
247 (clampToByte(a
)<<AShift
)|
248 (clampToByte(r
)<<RShift
)|
249 (clampToByte(g
)<<GShift
)|
250 (clampToByte(b
)<<BShift
));
253 * Build opaque non-transparent rgb color from components.
256 * r = red component [0..255]
257 * g = green component [0..255]
258 * b = blue component [0..255]
263 @gcc_inline static VColor
rgb(TR
, TG
, TB
) (TR r
, TG g
, TB b
) pure
264 if (__traits(isIntegral
, TR
) && __traits(isIntegral
, TG
) && __traits(isIntegral
, TB
))
266 static if (__VERSION__
> 2067) pragma(inline
, true);
268 (clampToByte(r
)<<RShift
)|
269 (clampToByte(g
)<<GShift
)|
270 (clampToByte(b
)<<BShift
));
273 // HSL functions were taken from arsd.color, written by Adam D. Ruppe, modified by Ketmar
274 // Converts hsl to rgb
275 static VColor
hsl(T
) (T h
, T s
, T l
, T a
=0) pure if (__traits(isFloating
, T
)) {
277 immutable real C
= (1-absInternal(2*l
-1))*s
;
278 immutable real hPrime
= h
/60;
279 immutable real X
= C
*(1-absInternal(hPrime
%2-1));
283 } else if (hPrime
>= 0 && hPrime
< 1) {
287 } else if (hPrime
>= 1 && hPrime
< 2) {
291 } else if (hPrime
>= 2 && hPrime
< 3) {
295 } else if (hPrime
>= 3 && hPrime
< 4) {
299 } else if (hPrime
>= 4 && hPrime
< 5) {
303 } else if (hPrime
>= 5 && hPrime
< 6) {
309 immutable real m
= l
-C
/2;
314 return VColor
.rgba(cast(ubyte)(r
*255), cast(ubyte)(g
*255), cast(ubyte)(b
*255), cast(ubyte)(a
));
318 // Converts an RGB color into an HSL triplet.
319 // useWeightedLightness will try to get a better value for luminosity for the human eye,
320 // which is more sensitive to green than red and more to red than blue.
321 // If it is false, it just does average of the rgb.
322 void toHsl(T
=real) (out T Ho
, out T So
, out T Lo
, bool useWeightedLightness
=false) pure if (__traits(isFloating
, T
)) {
323 // use bitops for CTFE
324 immutable real r1
= cast(real)((this.u32
>>RShift
)&0xff)/255;
325 immutable real g1
= cast(real)((this.u32
>>GShift
)&0xff)/255;
326 immutable real b1
= cast(real)((this.u32
>>BShift
)&0xff)/255;
328 immutable real maxColor
= maxInternal
!real(r1
, g1
, b1
);
329 immutable real minColor
= minInternal
!real(r1
, g1
, b1
);
331 real L
= (maxColor
+minColor
)/2;
332 if (useWeightedLightness
) {
333 // the colors don't affect the eye equally
334 // this is a little more accurate than plain HSL numbers
335 L
= 0.2126*r1
+0.7152*g1
+0.0722*b1
;
339 if (maxColor
!= minColor
) {
341 S
= (maxColor
-minColor
)/(maxColor
+minColor
);
343 S
= (maxColor
-minColor
)/(2.0-maxColor
-minColor
);
345 if (r1
== maxColor
) {
346 H
= (g1
-b1
)/(maxColor
-minColor
);
347 } else if(g1
== maxColor
) {
348 H
= 2.0+(b1
-r1
)/(maxColor
-minColor
);
350 H
= 4.0+(r1
-g1
)/(maxColor
-minColor
);
363 VColor
lighten(T
) (T percentage
) pure if (__traits(isFloating
, T
)) {
368 else if (l
< 0) l
= 0; //k8:???
369 return hsl(h
, s
, l
, cast(real)this.a
);
372 VColor
darken(T
) (T percentage
) pure if (__traits(isFloating
, T
)) {
377 else if (l
< 0) l
= 0; //k8:???
378 return hsl(h
, s
, l
, cast(real)this.a
);
381 // for light colors, call darken. for dark colors, call lighten.
382 // The goal: get toward center grey.
383 VColor
moderate(T
) (T percentage
) pure if (__traits(isFloating
, T
)) {
386 if (l
> 0.5) l
*= (1-percentage
);
387 else if (l
<= 0.01) l
= percentage
; // if we are given black, moderating it means getting *something* out
388 else l
*= (1+percentage
);
390 else if (l
< 0) l
= 0; //k8:???
391 return hsl(h
, s
, l
, cast(real)this.a
);
394 /// the opposite of moderate. Make darks darker and lights lighter
395 VColor
extremify(T
) (T percentage
) pure if (__traits(isFloating
, T
)) {
398 if (l
< 0.5) l
*= (1-percentage
); else l
*= (1+percentage
);
400 else if (l
< 0) l
= 0; //k8:???
401 return hsl(h
, s
, l
, cast(real)this.a
);
404 /// Move around the lightness wheel, trying not to break on moderate things
405 VColor
oppositeLightness() () pure {
409 if (original
> 0.4 && original
< 0.6) {
410 l
= 0.8-original
; // so it isn't quite the same
414 return hsl(h
, s
, l
, cast(real)this.a
);
417 /// Try to determine a text color - either white or black - based on the input
418 VColor
textColor() () pure {
420 toHsl(h
, s
, l
, true); // give green a bonus for contrast
421 return (l
> 0.71 ? VColor
.black
: VColor
.white
);
424 static assert(VColor
.sizeof
== uint.sizeof
);
426 static assert(VColor.black.textColor == VColor.white);
427 static assert(VColor.hsl(1.0, 1.0, 1.0) == VColor.white);
428 static assert(VColor.hsl(1.0, 1.0, 0.0) == VColor.black);
429 //pragma(msg, VColor.hsl(1.0, 1.0, 0.0));
433 // ////////////////////////////////////////////////////////////////////////// //
434 private int digit (char ch
, int base
) pure @safe nothrow @nogc {
435 static if (__VERSION__
> 2067) pragma(inline
, true);
436 if (ch
>= '0' && ch
<= '9') ch
-= '0';
437 else if (ch
>= 'A' && ch
<= 'Z') ch
-= 'A'-10;
438 else if (ch
>= 'a' && ch
<= 'z') ch
-= 'a'-10;
440 return (ch
< base ? ch
: -1);
444 // ////////////////////////////////////////////////////////////////////////// //
445 private __gshared VColor
[string
] knownColors
;
448 private void loadColors (string srctext
) {
451 mainloop
: while (srctext
.length
) {
453 while (pos
< srctext
.length
&& srctext
[pos
] != '\n') ++pos
;
454 if (pos
< srctext
.length
) ++pos
;
455 auto ln
= srctext
[0..pos
];
456 srctext
= srctext
[pos
..$];
457 while (ln
.length
&& ln
[$-1] <= ' ') ln
= ln
[0..$-1];
459 while (pos
< ln
.length
&& ln
[pos
] != '#') ++pos
;
461 //{ import std.stdio; writeln("*[", ln, "]"); }
462 foreach (immutable idx
; 0..3) {
463 while (ln
.length
&& ln
[0] <= ' ') ln
= ln
[1..$];
464 if (ln
.length
== 0 || ln
[0] < '0' || ln
[0] > '9') continue mainloop
;
466 while (ln
.length
&& ln
[0] >= '0' && ln
[0] <= '9') {
467 num
= num
*10+(ln
[0]-'0');
468 if (num
> 255) continue mainloop
;
471 rgb
[idx
] = cast(ubyte)num
;
472 //{ import std.stdio; writeln("**[", ln, "]"); }
474 while (ln
.length
&& ln
[0] <= ' ') ln
= ln
[1..$];
475 if (ln
.length
== 0) continue mainloop
;
476 //{ import std.stdio; writeln("[", ln, "] = (", rgb[0], ", ", rgb[1], ", ", rgb[2], ")"); }
477 knownColors
[ln
.idup
] = VColor
.rgb(rgb
[0], rgb
[1], rgb
[2]);
482 shared static this () {
485 loadColors("/usr/share/X11/rgb.txt");
486 } catch (Exception) {
487 knownColors["red"] = VColor.rgb(255, 0, 0);
488 knownColors["green"] = VColor.rgb(0, 255, 0);
489 knownColors["blue"] = VColor.rgb(0, 0, 255);
490 knownColors["black"] = VColor.rgb(0, 0, 0);
491 knownColors["white"] = VColor.rgb(255, 255, 255);
492 knownColors["silver"] = VColor.rgb(192, 192, 192);
495 loadColors(colorList_
);
499 // ////////////////////////////////////////////////////////////////////////// //
500 public VColor
parseColorName (const(char)[] cname
, bool* ok
=null) @trusted nothrow @nogc {
501 bool parseNum (out ubyte v
) @safe nothrow @nogc {
503 while (cname
.length
&& (cname
[0] <= ' ' || cname
[0] == '_')) cname
= cname
[1..$];
504 if (cname
.length
== 0 || cname
[0] < '0' || cname
[0] > '9') return false;
505 if (cname
.length
> 2 && cname
[0] == '0' && (cname
[1] == 'x' || cname
[1] == 'X')) {
509 } else if (cname
.length
> 2 && cname
[0] == '0' && (cname
[1] == 'o' || cname
[1] == 'O')) {
513 } else if (cname
.length
> 2 && cname
[0] == '0' && (cname
[1] == 'b' || cname
[1] == 'B')) {
517 } else if (cname
.length
> 2 && cname
[0] == '0' && (cname
[1] == 'd' || cname
[1] == 'D')) {
521 if (cname
.length
== 0 ||
digit(cname
[0], base
) < 0) return false;
523 while (cname
.length
) {
524 int d
= digit(cname
[0], base
);
526 if (cname
[0] != '_') {
527 while (cname
.length
&& cname
[0] <= ' ') cname
= cname
[1..$];
532 if (n
> 255) return false;
540 if (ok
!is null) *ok
= false;
541 while (cname
.length
&& cname
[0] <= ' ') cname
= cname
[1..$];
542 while (cname
.length
&& cname
[$-1] <= ' ') cname
= cname
[0..$-1];
543 if (cname
.length
== 0) return VColor
.transparent
;
544 if (cname
[0] == '#') {
548 // collect hex digits
549 foreach (char ch
; cname
) {
550 if (ch
<= ' ' || ch
== '_') continue;
551 if ((ch
>= '0' && ch
<= '9') ||
(ch
>= 'A' && ch
<= 'F') ||
(ch
>= 'a' && ch
<= 'f')) {
552 if (hdpos
>= hd
.length
) return VColor
.transparent
;
553 if (ch
>= 'a') ch
-= 'a'-10;
554 else if (ch
>= 'A') ch
-= 'A'-10;
556 hd
[hdpos
++] = cast(ubyte)ch
;
557 } else if (ch
> ' ' && ch
!= '_') {
558 return VColor
.transparent
;
562 if (ok
!is null) *ok
= true;
563 //return VColor.rgb(hd[0]*16+hd[0], hd[1]*16+hd[1], hd[2]*16+hd[2]);
564 return VColor
.rgb(hd
[0]*17, hd
[1]*17, hd
[2]*17);
565 } else if (hdpos
== 6) {
566 if (ok
!is null) *ok
= true;
567 return VColor
.rgb(hd
[0]*16+hd
[1], hd
[2]*16+hd
[3], hd
[4]*16+hd
[5]);
569 return VColor
.transparent
;
572 if (cname
.length
> 3 && cname
[0..3] == "rgb") {
574 if (cname
[0] == 'a') cname
= cname
[1..$];
575 while (cname
.length
&& cname
[0] <= ' ') cname
= cname
[1..$];
576 if (cname
.length
< 2 || cname
[0] != '(' || cname
[$-1] != ')') return VColor
.transparent
;
581 while (cname
.length
&& (cname
[0] <= ' ' || cname
[0] == '_')) cname
= cname
[1..$];
582 if (cidx
>= rgba
.length
) return VColor
.transparent
;
583 if (cname
[0] != ',') {
584 if (!parseNum(rgba
[cidx
])) return VColor
.transparent
;
587 if (cname
[0] == ')') break;
588 if (cname
[0] != ',') return VColor
.transparent
;
591 if (cidx
< 3) return VColor
.transparent
;
592 if (ok
!is null) *ok
= true;
593 return VColor
.rgba(rgba
[0], rgba
[1], rgba
[2], rgba
[3]);
595 // try predefined colors
599 foreach (char ch
; cname
) {
600 if (ch
<= ' ') continue;
601 if (ch
>= 'A' && ch
<= 'Z') ch
+= 32; // poor man's `toLower()`
602 if (pos
>= nbuf
.length
) return VColor
.transparent
;
605 if (pos
== 0) return VColor
.transparent
;
606 if (auto cl
= nbuf
[0..pos
] in knownColors
) {
607 if (ok
!is null) *ok
= true;
610 if (nbuf
[0..pos
] == "transparent") {
611 if (ok
!is null) *ok
= true;
612 return VColor
.transparent
;
615 return VColor
.transparent
;
620 version(test_color_parser
) {
621 void dumpColor (string cname
) {
623 auto clr
= parseColorName(cname
, &ok
);
624 writefln
!"0x%08x; ok=%s; [%s]"(clr
, ok
, cname
);
629 dumpColor("#00_ff_00");
630 dumpColor("#00fe0_0");
631 dumpColor("rgb(1, 2, 3 )");
632 dumpColor("rgba(1, 2, 3 )");
633 dumpColor("rgba(1, 2, 3 , 4)");
634 dumpColor("rgba(1,,, 4)");
638 dumpColor("dark orange");
646 // ////////////////////////////////////////////////////////////////////////// //
647 private immutable string colorList_
= `
649 248 248 255 ghostwhite
650 245 245 245 whitesmoke
651 220 220 220 gainsboro
652 255 250 240 floralwhite
655 250 235 215 antiquewhite
656 255 239 213 papayawhip
657 255 235 205 blanchedalmond
659 255 218 185 peachpuff
660 255 222 173 navajowhite
664 255 250 205 lemonchiffon
667 245 255 250 mintcream
669 240 248 255 aliceblue
671 255 240 245 lavenderblush
672 255 228 225 mistyrose
675 47 79 79 darkslategray
676 47 79 79 darkslategrey
679 112 128 144 slategray
680 112 128 144 slategrey
681 119 136 153 lightslategray
682 119 136 153 lightslategrey
689 211 211 211 lightgrey
690 211 211 211 lightgray
691 25 25 112 midnightblue
694 100 149 237 cornflowerblue
695 72 61 139 darkslateblue
697 123 104 238 mediumslateblue
698 132 112 255 lightslateblue
702 30 144 255 dodgerblue
703 0 191 255 deepskyblue
705 135 206 250 lightskyblue
707 176 196 222 lightsteelblue
708 173 216 230 lightblue
709 176 224 230 powderblue
710 175 238 238 paleturquoise
711 0 206 209 darkturquoise
712 72 209 204 mediumturquoise
716 224 255 255 lightcyan
718 102 205 170 mediumaquamarine
719 127 255 212 aquamarine
721 85 107 47 darkolivegreen
722 143 188 143 darkseagreen
724 60 179 113 mediumseagreen
725 32 178 170 lightseagreen
726 152 251 152 palegreen
727 0 255 127 springgreen
734 0 250 154 mediumspringgreen
735 173 255 47 greenyellow
737 154 205 50 yellowgreen
738 34 139 34 forestgreen
740 189 183 107 darkkhaki
742 238 232 170 palegoldenrod
743 250 250 210 lightgoldenrodyellow
744 255 255 224 lightyellow
747 238 221 130 lightgoldenrod
749 184 134 11 darkgoldenrod
750 188 143 143 rosybrown
752 139 69 19 saddlebrown
755 222 184 135 burlywood
758 244 164 96 sandybrown
763 233 150 122 darksalmon
765 255 160 122 lightsalmon
769 240 128 128 lightcoral
776 255 182 193 lightpink
777 219 112 147 palevioletred
781 199 21 133 mediumvioletred
788 186 85 211 mediumorchid
789 153 50 204 darkorchid
791 138 43 226 blueviolet
795 147 112 219 mediumpurple
801 255 245 238 seashell1
802 238 229 222 seashell2
803 205 197 191 seashell3
804 139 134 130 seashell4
805 255 239 219 antiquewhite1
806 238 223 204 antiquewhite2
807 205 192 176 antiquewhite3
808 139 131 120 antiquewhite4
813 255 218 185 peachpuff1
814 238 203 173 peachpuff2
815 205 175 149 peachpuff3
816 139 119 101 peachpuff4
817 255 222 173 navajowhite1
818 238 207 161 navajowhite2
819 205 179 139 navajowhite3
820 139 121 94 navajowhite4
821 255 250 205 lemonchiffon1
822 238 233 191 lemonchiffon2
823 205 201 165 lemonchiffon3
824 139 137 112 lemonchiffon4
825 255 248 220 cornsilk1
826 238 232 205 cornsilk2
827 205 200 177 cornsilk3
828 139 136 120 cornsilk4
833 240 255 240 honeydew1
834 224 238 224 honeydew2
835 193 205 193 honeydew3
836 131 139 131 honeydew4
837 255 240 245 lavenderblush1
838 238 224 229 lavenderblush2
839 205 193 197 lavenderblush3
840 139 131 134 lavenderblush4
841 255 228 225 mistyrose1
842 238 213 210 mistyrose2
843 205 183 181 mistyrose3
844 139 125 123 mistyrose4
849 131 111 255 slateblue1
850 122 103 238 slateblue2
851 105 89 205 slateblue3
853 72 118 255 royalblue1
854 67 110 238 royalblue2
861 30 144 255 dodgerblue1
862 28 134 238 dodgerblue2
863 24 116 205 dodgerblue3
864 16 78 139 dodgerblue4
865 99 184 255 steelblue1
866 92 172 238 steelblue2
867 79 148 205 steelblue3
868 54 100 139 steelblue4
869 0 191 255 deepskyblue1
870 0 178 238 deepskyblue2
871 0 154 205 deepskyblue3
872 0 104 139 deepskyblue4
877 176 226 255 lightskyblue1
878 164 211 238 lightskyblue2
879 141 182 205 lightskyblue3
880 96 123 139 lightskyblue4
881 198 226 255 slategray1
882 185 211 238 slategray2
883 159 182 205 slategray3
884 108 123 139 slategray4
885 202 225 255 lightsteelblue1
886 188 210 238 lightsteelblue2
887 162 181 205 lightsteelblue3
888 110 123 139 lightsteelblue4
889 191 239 255 lightblue1
890 178 223 238 lightblue2
891 154 192 205 lightblue3
892 104 131 139 lightblue4
893 224 255 255 lightcyan1
894 209 238 238 lightcyan2
895 180 205 205 lightcyan3
896 122 139 139 lightcyan4
897 187 255 255 paleturquoise1
898 174 238 238 paleturquoise2
899 150 205 205 paleturquoise3
900 102 139 139 paleturquoise4
901 152 245 255 cadetblue1
902 142 229 238 cadetblue2
903 122 197 205 cadetblue3
904 83 134 139 cadetblue4
913 151 255 255 darkslategray1
914 141 238 238 darkslategray2
915 121 205 205 darkslategray3
916 82 139 139 darkslategray4
917 127 255 212 aquamarine1
918 118 238 198 aquamarine2
919 102 205 170 aquamarine3
920 69 139 116 aquamarine4
921 193 255 193 darkseagreen1
922 180 238 180 darkseagreen2
923 155 205 155 darkseagreen3
924 105 139 105 darkseagreen4
929 154 255 154 palegreen1
930 144 238 144 palegreen2
931 124 205 124 palegreen3
933 0 255 127 springgreen1
934 0 238 118 springgreen2
935 0 205 102 springgreen3
936 0 139 69 springgreen4
941 127 255 0 chartreuse1
942 118 238 0 chartreuse2
943 102 205 0 chartreuse3
945 192 255 62 olivedrab1
946 179 238 58 olivedrab2
947 154 205 50 olivedrab3
948 105 139 34 olivedrab4
949 202 255 112 darkolivegreen1
950 188 238 104 darkolivegreen2
951 162 205 90 darkolivegreen3
952 110 139 61 darkolivegreen4
957 255 236 139 lightgoldenrod1
958 238 220 130 lightgoldenrod2
959 205 190 112 lightgoldenrod3
960 139 129 76 lightgoldenrod4
961 255 255 224 lightyellow1
962 238 238 209 lightyellow2
963 205 205 180 lightyellow3
964 139 139 122 lightyellow4
973 255 193 37 goldenrod1
974 238 180 34 goldenrod2
975 205 155 29 goldenrod3
976 139 105 20 goldenrod4
977 255 185 15 darkgoldenrod1
978 238 173 14 darkgoldenrod2
979 205 149 12 darkgoldenrod3
980 139 101 8 darkgoldenrod4
981 255 193 193 rosybrown1
982 238 180 180 rosybrown2
983 205 155 155 rosybrown3
984 139 105 105 rosybrown4
985 255 106 106 indianred1
993 255 211 155 burlywood1
994 238 197 145 burlywood2
995 205 170 125 burlywood3
996 139 115 85 burlywood4
1005 255 127 36 chocolate1
1006 238 118 33 chocolate2
1007 205 102 29 chocolate3
1008 139 69 19 chocolate4
1009 255 48 48 firebrick1
1010 238 44 44 firebrick2
1011 205 38 38 firebrick3
1012 139 26 26 firebrick4
1021 255 160 122 lightsalmon1
1022 238 149 114 lightsalmon2
1023 205 129 98 lightsalmon3
1024 139 87 66 lightsalmon4
1029 255 127 0 darkorange1
1030 238 118 0 darkorange2
1031 205 102 0 darkorange3
1032 139 69 0 darkorange4
1049 255 20 147 deeppink1
1050 238 18 137 deeppink2
1051 205 16 118 deeppink3
1053 255 110 180 hotpink1
1054 238 106 167 hotpink2
1061 255 174 185 lightpink1
1062 238 162 173 lightpink2
1063 205 140 149 lightpink3
1064 139 95 101 lightpink4
1065 255 130 171 palevioletred1
1066 238 121 159 palevioletred2
1067 205 104 137 palevioletred3
1068 139 71 93 palevioletred4
1073 255 62 150 violetred1
1074 238 58 140 violetred2
1075 205 50 120 violetred3
1076 139 34 82 violetred4
1089 224 102 255 mediumorchid1
1090 209 95 238 mediumorchid2
1091 180 82 205 mediumorchid3
1092 122 55 139 mediumorchid4
1093 191 62 255 darkorchid1
1094 178 58 238 darkorchid2
1095 154 50 205 darkorchid3
1096 104 34 139 darkorchid4
1101 171 130 255 mediumpurple1
1102 159 121 238 mediumpurple2
1103 137 104 205 mediumpurple3
1104 93 71 139 mediumpurple4
1105 255 225 255 thistle1
1106 238 210 238 thistle2
1107 205 181 205 thistle3
1108 139 123 139 thistle4
1311 169 169 169 darkgrey
1312 169 169 169 darkgray
1315 139 0 139 darkmagenta
1317 144 238 144 lightgreen
1321 102 51 153 rebeccapurple
1325 128 128 128 css-gray
1326 128 128 128 css-grey
1329 128 0 128 css-purple