diff --git a/css_colors.txt b/css_colors.txt new file mode 100644 index 0000000..6e14aa2 --- /dev/null +++ b/css_colors.txt @@ -0,0 +1,157 @@ +aqua #00FFFF +black #000000 +blue #0000FF +fuchsia #FF00FF +gray #808080 +green #008000 +lime #00FF00 +maroon #800000 +navy #000080 +olive #808000 +purple #800080 +red #FF0000 +silver #C0C0C0 +teal #008080 +white #FFFFFF +yellow #FFFF00 +aliceblue #F0F8FF +antiquewhite #FAEBD7 +aqua #00FFFF +aquamarine #7FFFD4 +azure #F0FFFF +beige #F5F5DC +bisque #FFE4C4 +black #000000 +blanchedalmond #FFEBCD +blue #0000FF +blueviolet #8A2BE2 +brown #A52A2A +burlywood #DEB887 +cadetblue #5F9EA0 +chartreuse #7FFF00 +chocolate #D2691E +coral #FF7F50 +cornflowerblue #6495ED +cornsilk #FFF8DC +crimson #DC143C +cyan #00FFFF +darkblue #00008B +darkcyan #008B8B +darkgoldenrod #B8860B +darkgray #A9A9A9 +darkgreen #006400 +darkkhaki #BDB76B +darkmagenta #8B008B +darkolivegreen #556B2F +darkorange #FF8C00 +darkorchid #9932CC +darkred #8B0000 +darksalmon #E9967A +darkseagreen #8FBC8F +darkslateblue #483D8B +darkslategray #2F4F4F +darkturquoise #00CED1 +darkviolet #9400D3 +deeppink #FF1493 +deepskyblue #00BFFF +dimgray #696969 +dodgerblue #1E90FF +firebrick #B22222 +floralwhite #FFFAF0 +forestgreen #228B22 +fuchsia #FF00FF +gainsboro #DCDCDC +ghostwhite #F8F8FF +gold #FFD700 +goldenrod #DAA520 +gray #7F7F7F +green #008000 +greenyellow #ADFF2F +honeydew #F0FFF0 +hotpink #FF69B4 +indianred #CD5C5C +indigo #4B0082 +ivory #FFFFF0 +khaki #F0E68C +lavender #E6E6FA +lavenderblush #FFF0F5 +lawngreen #7CFC00 +lemonchiffon #FFFACD +lightblue #ADD8E6 +lightcoral #F08080 +lightcyan #E0FFFF +lightgoldenrodyellow #FAFAD2 +lightgreen #90EE90 +lightgrey #D3D3D3 +lightpink #FFB6C1 +lightsalmon #FFA07A +lightseagreen #20B2AA +lightskyblue #87CEFA +lightslategray #778899 +lightsteelblue #B0C4DE +lightyellow #FFFFE0 +lime #00FF00 +limegreen #32CD32 +linen #FAF0E6 +magenta #FF00FF +maroon #800000 +mediumaquamarine #66CDAA +mediumblue #0000CD +mediumorchid #BA55D3 +mediumpurple #9370DB +mediumseagreen #3CB371 +mediumslateblue #7B68EE +mediumspringgreen #00FA9A +mediumturquoise #48D1CC +mediumvioletred #C71585 +midnightblue #191970 +mintcream #F5FFFA +mistyrose #FFE4E1 +moccasin #FFE4B5 +navajowhite #FFDEAD +navy #000080 +navyblue #9FAFDF +oldlace #FDF5E6 +olive #808000 +olivedrab #6B8E23 +orange #FFA500 +orangered #FF4500 +orchid #DA70D6 +palegoldenrod #EEE8AA +palegreen #98FB98 +paleturquoise #AFEEEE +palevioletred #DB7093 +papayawhip #FFEFD5 +peachpuff #FFDAB9 +peru #CD853F +pink #FFC0CB +plum #DDA0DD +powderblue #B0E0E6 +purple #800080 +red #FF0000 +rosybrown #BC8F8F +royalblue #4169E1 +saddlebrown #8B4513 +salmon #FA8072 +sandybrown #FA8072 +seagreen #2E8B57 +seashell #FFF5EE +sienna #A0522D +silver #C0C0C0 +skyblue #87CEEB +slateblue #6A5ACD +slategray #708090 +snow #FFFAFA +springgreen #00FF7F +steelblue #4682B4 +tan #D2B48C +teal #008080 +thistle #D8BFD8 +tomato #FF6347 +turquoise #40E0D0 +violet #EE82EE +wheat #F5DEB3 +white #FFFFFF +whitesmoke #F5F5F5 +yellow #FFFF00 +yellowgreen #9ACD32 diff --git a/generate_color_table.py b/generate_color_table.py new file mode 100644 index 0000000..43fa4de --- /dev/null +++ b/generate_color_table.py @@ -0,0 +1,111 @@ +# data sources: CSS docs, jennyscrayoncollection 2017 article on Crayola colors, XKCD color survey + +# target: Single C++ header file to provide a struct of color RGB codes and names. +# This file pre-computes the nearest neighbor of every color. +# if an RGB code being searched for is closer than the nearest neighbor, it's the closest color name. + +def hex_to_rgb(txt): + if '#' in txt: txt = txt.replace('#', '') + r = txt[0:2] + g = txt[2:4] + b = txt[4:6] + return tuple([int(s, 16) for s in (r,g,b)]) + +class palette: + def __init__(self, name, filename, priority): + self.name = name + self.priority = priority + with open(filename, "r") as f: + print(f"scanning {filename}") + self.colors = {} + for line in f.read().split('\n'): + if len(line.split('\t')) < 2: continue + name, code = line.split('\t') + #print(name, code) + self.colors[name] = hex_to_rgb(code) + + def __repr__(self): + return f"" + +palettes = [ + #palette("jenny", "jenny_colors.txt", 3), # I should probably use wikipedia as a source for copyright reasons + palette("crayon", "wikicrayons_colors.txt", 2), + palette("xkcd", "xkcd_colors.txt", 1), + palette("css", "css_colors.txt", 0), + #palette("matplotlib", "matplotlib_colors.txt", 2) # there's like 10 colors total, I think we'll survive without them + ] + +all_colors = [] + +from math import sqrt +def rgbdist(c1, c2): + return sqrt((c1.r - c2.r)**2 + (c1.g - c2.g)**2 + (c1.b - c2.b)**2) + +class Color: + def __init__(self, r, g, b, name, prefix, priority): + self.r = r + self.g = g + self.b = b + self.name = name + self.prefix = prefix + self.priority = priority + self.nearest_neighbor = None + + def __repr__(self): + return f"" + + def nn(self, colors): + nearest = None + nearest_dist = 999999 + for c in colors: + dist = rgbdist(self, c) + if dist == 0: continue + if dist < nearest_dist: + nearest = c + nearest_dist = dist + self.nearest_neighbor = nearest + +for p in palettes: + prefix = p.name + priority = p.priority + for name, rgb in p.colors.items(): + all_colors.append(Color(*rgb, name, prefix, priority)) + print(f"{prefix}->{len(all_colors)}") + +for c in all_colors: + c.nn(all_colors) + +smallest_dist = 9999999999999 +largest_dist = 0 +for c in all_colors: + dist = rgbdist(c, c.nearest_neighbor) + if dist > largest_dist: largest_dist = dist + if dist < smallest_dist: smallest_dist = dist + #print(f"{c.prefix}:{c.name} -> {c.nearest_neighbor.prefix}:{c.nearest_neighbor.name}\t{rgbdist(c, c.nearest_neighbor):.2f}") +# questions - + +# are there any colors where their nearest neighbor's nearest neighbor isn't them? (There should be) +nonnear_pairs = 0 +for c in all_colors: + neighbor = c.nearest_neighbor + their_neighbor = neighbor.nearest_neighbor + if c is not their_neighbor: + #print(f"{c.prefix}:{c.name} -> {neighbor.prefix}:{neighbor.name} -> {their_neighbor.prefix}:{their_neighbor.name}") + nonnear_pairs += 1 +print("Non-near pairs:", nonnear_pairs) + #print(f"{c.prefix}:{c.name} -> {c.nearest_neighbor.prefix}:{c.nearest_neighbor.name}\t{rgbdist(c, c.nearest_neighbor):.2f}") + +# Are there duplicates? They should be removed from the palette that won't be used +dupes = 0 +for c in all_colors: + for c2 in all_colors: + if c is c2: continue + if c.r == c2.r and c.g == c2.g and c.b == c2.b: + dupes += 1 +print("dupes:", dupes, "this many will need to be removed:", dupes / 2) + +# What order to put them in? Do we want large radiuses first, or some sort of "common color" table? + +# does manhattan distance change any answers over the 16.7M RGB values? + +# What's the worst case lookup? (Checking all 1200 colors to find the name?) \ No newline at end of file diff --git a/src/McRFPy_API.cpp b/src/McRFPy_API.cpp index 51bd3c7..e5621f0 100644 --- a/src/McRFPy_API.cpp +++ b/src/McRFPy_API.cpp @@ -56,7 +56,7 @@ PyObject* PyInit_mcrfpy() using namespace mcrfpydef; PyTypeObject* pytypes[] = { /*SFML exposed types*/ - &PyColorType, &PyFontType, &PyTextureType, + &PyColorType, /*&PyLinkedColorType,*/ &PyFontType, &PyTextureType, /*UI widgets*/ &PyUICaptionType, &PyUISpriteType, &PyUIFrameType, &PyUIEntityType, &PyUIGridType, diff --git a/src/PyColor.cpp b/src/PyColor.cpp new file mode 100644 index 0000000..50eae73 --- /dev/null +++ b/src/PyColor.cpp @@ -0,0 +1,151 @@ +#include "PyColor.h" + +PyGetSetDef PyColor::getsetters[] = { + {"r", (getter)PyColor::get_member, (setter)PyColor::set_member, "Red component", (void*)0}, + {"g", (getter)PyColor::get_member, (setter)PyColor::set_member, "Green component", (void*)1}, + {"b", (getter)PyColor::get_member, (setter)PyColor::set_member, "Blue component", (void*)2}, + {"a", (getter)PyColor::get_member, (setter)PyColor::set_member, "Alpha component", (void*)3}, + {NULL} +}; + +PyColor::PyColor(sf::Color target) +:data(target) {} + +PyObject* PyColor::pyObject() +{ + PyObject* obj = PyType_GenericAlloc(&mcrfpydef::PyColorType, 0); + Py_INCREF(obj); + PyColorObject* self = (PyColorObject*)obj; + self->data = data; + return obj; +} + +sf::Color PyColor::fromPy(PyObject* obj) +{ + PyColorObject* self = (PyColorObject*)obj; + return self->data; +} + +sf::Color PyColor::fromPy(PyColorObject* self) +{ + return self->data; +} + +void PyColor::set(sf::Color color) +{ + data = color; +} + +sf::Color PyColor::get() +{ + return data; +} + +Py_hash_t PyColor::hash(PyObject* obj) +{ + auto self = (PyColorObject*)obj; + Py_hash_t value = 0; + value += self->data.r; + value << 8; value += self->data.g; + value << 8; value += self->data.b; + value << 8; value += self->data.a; + + return value; +} + +PyObject* PyColor::repr(PyObject* obj) +{ + PyColorObject* self = (PyColorObject*)obj; + std::ostringstream ss; + sf::Color c = self->data; + ss << ""; + + std::string repr_str = ss.str(); + return PyUnicode_DecodeUTF8(repr_str.c_str(), repr_str.size(), "replace"); +} + + +int PyColor::init(PyColorObject* self, PyObject* args, PyObject* kwds) +{ + using namespace mcrfpydef; + static const char* keywords[] = { "r", "g", "b", "a", nullptr }; + PyObject* leader; + int r = -1, g = -1, b = -1, a = 255; + if (!PyArg_ParseTupleAndKeywords, args, kwds, "O|iii", leader, &g, &b, &a) + { + PyErr_SetString(PyExc_TypeError, "mcrfpy.Color requires a color object, 3-tuple, 4-tuple, color name, or integer values within 0-255 (r, g, b, optionally a)"); + return -1; + } + + // if the "r" arg is already a color, yoink that color value + if (PyObject_IsInstance(leader, (PyObject*)&PyColorType)) + { + self->data = ((PyColorObject*)leader)->data; + return 0; + } + // else if the "r" arg is a 3-tuple, initialize to (r, g, b, 255) + // (if the "r" arg is a 4-tuple, initialize to (r, g, b, a)) + else if (PyTuple_Check(leader)) + { + if (PyTuple_Size(leader) < 3 && PyTuple_Size(leader) > 4) + { + PyErr_SetString(PyExc_TypeError, "Invalid tuple length: mcrfpy.Color requires a color object, 3-tuple, 4-tuple, color name, or integer values within 0-255 (r, g, b, optionally a)"); + return -1; + } + r = PyLong_AsLong(PyTuple_GetItem(leader, 0)); + g = PyLong_AsLong(PyTuple_GetItem(leader, 1)); + b = PyLong_AsLong(PyTuple_GetItem(leader, 2)); + //a = 255; //default value + + if (PyTuple_Size(leader) == 4) + { + a = PyLong_AsLong(PyTuple_GetItem(leader, 3)); + } + + // value validation + if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255 || a < 0 || a > 255) + { + PyErr_SetString(PyExc_ValueError, "Color values must be between 0 and 255."); + return -1; + } + self->data = sf::Color(r, g, b, a); + } + // else if the "r" arg is a string, initialize to {color lookup function value} + else if (PyUnicode_Check(leader)) + { + PyErr_SetString(Py_NotImplemented, "Color names aren't ready yet"); + return -1; + } + // else - + else if (!PyLong_Check(leader)) + { + PyErr_SetString(PyExc_TypeError, "mcrfpy.Color requires a color object, 3-tuple, 4-tuple, color name, or integer values within 0-255 (r, g, b, optionally a)"); + return -1; + } + r = PyLong_AsLong(leader); + // assert r, g, b are present and ints in range (0, 255) - if not enough ints were provided to the args/kwds parsed by init, g and/or b will still hold -1. + if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255 || a < 0 || a > 255) + { + PyErr_SetString(PyExc_ValueError, "R, G, B values are required, A value is optional; Color values must be between 0 and 255."); + return -1; + } + self->data = sf::Color(r, g, b, a); + return 0; +} + +PyObject* PyColor::pynew(PyTypeObject* type, PyObject* args, PyObject* kwds) +{ + return (PyObject*)type->tp_alloc(type, 0); +} + +PyObject* PyColor::get_member(PyObject* obj, void* closure) +{ + // TODO + return Py_None; +} + +int PyColor::set_member(PyObject* obj, PyObject* value, void* closure) +{ + // TODO + return 0; +} diff --git a/src/PyColor.h b/src/PyColor.h new file mode 100644 index 0000000..a111b89 --- /dev/null +++ b/src/PyColor.h @@ -0,0 +1,47 @@ +#pragma once +#include "Common.h" +#include "Python.h" + +class PyColor; +class UIDrawable; // forward declare for pointer + +typedef struct { + PyObject_HEAD + sf::Color data; +} PyColorObject; + +class PyColor +{ +private: +public: + sf::Color data; + PyColor(sf::Color); + void set(sf::Color); + sf::Color get(); + PyObject* pyObject(); + static sf::Color fromPy(PyObject*); + static sf::Color fromPy(PyColorObject*); + static PyObject* repr(PyObject*); + static Py_hash_t hash(PyObject*); + static int init(PyColorObject*, PyObject*, PyObject*); + static PyObject* pynew(PyTypeObject* type, PyObject* args=NULL, PyObject* kwds=NULL); + static PyObject* get_member(PyObject*, void*); + static int set_member(PyObject*, PyObject*, void*); + + static PyGetSetDef getsetters[]; +}; + +namespace mcrfpydef { + static PyTypeObject PyColorType = { + .tp_name = "mcrfpy.Color", + .tp_basicsize = sizeof(PyColorObject), + .tp_itemsize = 0, + .tp_repr = PyColor::repr, + .tp_hash = PyColor::hash, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_doc = PyDoc_STR("SFML Color Object"), + .tp_getset = PyColor::getsetters, + .tp_init = (initproc)PyColor::init, + .tp_new = PyColor::pynew, + }; +} diff --git a/src/UI.h b/src/UI.h index c45fe42..f0f64db 100644 --- a/src/UI.h +++ b/src/UI.h @@ -5,8 +5,13 @@ #include "IndexTexture.h" #include "Resources.h" #include + +#define ui_h + #include "PyCallable.h" #include "PyTexture.h" +#include "PyColor.h" +//#include "PyLinkedColor.h" enum PyObjectsEnum : int { @@ -46,10 +51,12 @@ typedef struct { } PyColorObject; */ +/* // Moved to PyColor.h typedef struct { PyObject_HEAD std::shared_ptr data; } PyColorObject; +*/ class UIFrame: public UIDrawable { @@ -444,89 +451,89 @@ static int PyUIDrawable_set_click(PyUIGridObject* self, PyObject* value, void* c */ - static PyObject* PyColor_get_member(PyColorObject* self, void* closure) - { - auto member_ptr = reinterpret_cast(closure); - if (member_ptr == 0) - return PyLong_FromLong(self->data->r); - else if (member_ptr == 1) - return PyLong_FromLong(self->data->g); - else if (member_ptr == 2) - return PyLong_FromLong(self->data->b); - else if (member_ptr == 3) - return PyLong_FromLong(self->data->a); - else - { - PyErr_SetString(PyExc_AttributeError, "Invalid attribute"); - return nullptr; - } - } - - static int PyColor_set_member(PyColorObject* self, PyObject* value, void* closure) - { - if (PyLong_Check(value)) - { - long int_val = PyLong_AsLong(value); - if (int_val < 0) - int_val = 0; - else if (int_val > 255) - int_val = 255; - auto member_ptr = reinterpret_cast(closure); - if (member_ptr == 0) - self->data->r = static_cast(int_val); - else if (member_ptr == 1) - self->data->g = static_cast(int_val); - else if (member_ptr == 2) - self->data->b = static_cast(int_val); - else if (member_ptr == 3) - self->data->a = static_cast(int_val); - } - else - { - PyErr_SetString(PyExc_TypeError, "Value must be an integer."); - return -1; - } - return 0; - } - - static PyGetSetDef PyColor_getsetters[] = { - {"r", (getter)PyColor_get_member, (setter)PyColor_set_member, "Red component", (void*)0}, - {"g", (getter)PyColor_get_member, (setter)PyColor_set_member, "Green component", (void*)1}, - {"b", (getter)PyColor_get_member, (setter)PyColor_set_member, "Blue component", (void*)2}, - {"a", (getter)PyColor_get_member, (setter)PyColor_set_member, "Alpha component", (void*)3}, - {NULL} - }; - - - static PyTypeObject PyColorType = { - //PyVarObject_HEAD_INIT(NULL, 0) - .tp_name = "mcrfpy.Color", - .tp_basicsize = sizeof(PyColorObject), - .tp_itemsize = 0, - .tp_dealloc = (destructor)[](PyObject* self) - { - PyColorObject* obj = (PyColorObject*)self; - obj->data.reset(); - Py_TYPE(self)->tp_free(self); - }, - //.tp_repr = (reprfunc)PyUIFrame_repr, - //.tp_hash = NULL, - //.tp_iter - //.tp_iternext - .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_doc = PyDoc_STR("SFML Color object (RGBA)"), - //.tp_methods = PyUIFrame_methods, - //.tp_members = PyColor_members, - .tp_getset = PyColor_getsetters, - //.tp_base = NULL, - //.tp_init = (initproc)PyUIFrame_init, - .tp_new = [](PyTypeObject* type, PyObject* args, PyObject* kwds) -> PyObject* - { - PyColorObject* self = (PyColorObject*)type->tp_alloc(type, 0); - if (self) self->data = std::make_shared(); - return (PyObject*)self; - } - }; +// static PyObject* PyColor_get_member(PyColorObject* self, void* closure) +// { +// auto member_ptr = reinterpret_cast(closure); +// if (member_ptr == 0) +// return PyLong_FromLong(self->data->r); +// else if (member_ptr == 1) +// return PyLong_FromLong(self->data->g); +// else if (member_ptr == 2) +// return PyLong_FromLong(self->data->b); +// else if (member_ptr == 3) +// return PyLong_FromLong(self->data->a); +// else +// { +// PyErr_SetString(PyExc_AttributeError, "Invalid attribute"); +// return nullptr; +// } +// } +// +// static int PyColor_set_member(PyColorObject* self, PyObject* value, void* closure) +// { +// if (PyLong_Check(value)) +// { +// long int_val = PyLong_AsLong(value); +// if (int_val < 0) +// int_val = 0; +// else if (int_val > 255) +// int_val = 255; +// auto member_ptr = reinterpret_cast(closure); +// if (member_ptr == 0) +// self->data->r = static_cast(int_val); +// else if (member_ptr == 1) +// self->data->g = static_cast(int_val); +// else if (member_ptr == 2) +// self->data->b = static_cast(int_val); +// else if (member_ptr == 3) +// self->data->a = static_cast(int_val); +// } +// else +// { +// PyErr_SetString(PyExc_TypeError, "Value must be an integer."); +// return -1; +// } +// return 0; +// } +// +// static PyGetSetDef PyColor_getsetters[] = { +// {"r", (getter)PyColor_get_member, (setter)PyColor_set_member, "Red component", (void*)0}, +// {"g", (getter)PyColor_get_member, (setter)PyColor_set_member, "Green component", (void*)1}, +// {"b", (getter)PyColor_get_member, (setter)PyColor_set_member, "Blue component", (void*)2}, +// {"a", (getter)PyColor_get_member, (setter)PyColor_set_member, "Alpha component", (void*)3}, +// {NULL} +// }; +// +// +// static PyTypeObject PyColorType = { +// //PyVarObject_HEAD_INIT(NULL, 0) +// .tp_name = "mcrfpy.Color", +// .tp_basicsize = sizeof(PyColorObject), +// .tp_itemsize = 0, +// .tp_dealloc = (destructor)[](PyObject* self) +// { +// PyColorObject* obj = (PyColorObject*)self; +// obj->data.reset(); +// Py_TYPE(self)->tp_free(self); +// }, +// //.tp_repr = (reprfunc)PyUIFrame_repr, +// //.tp_hash = NULL, +// //.tp_iter +// //.tp_iternext +// .tp_flags = Py_TPFLAGS_DEFAULT, +// .tp_doc = PyDoc_STR("SFML Color object (RGBA)"), +// //.tp_methods = PyUIFrame_methods, +// //.tp_members = PyColor_members, +// .tp_getset = PyColor_getsetters, +// //.tp_base = NULL, +// //.tp_init = (initproc)PyUIFrame_init, +// .tp_new = [](PyTypeObject* type, PyObject* args, PyObject* kwds) -> PyObject* +// { +// PyColorObject* self = (PyColorObject*)type->tp_alloc(type, 0); +// if (self) self->data = std::make_shared(); +// return (PyObject*)self; +// } +// }; /* * @@ -591,32 +598,50 @@ static int PyUIDrawable_set_click(PyUIGridObject* self, PyObject* value, void* c } // TODO: manually calling tp_alloc to create a PyColorObject seems like an antipattern - PyTypeObject* colorType = &PyColorType; - PyObject* pyColor = colorType->tp_alloc(colorType, 0); + /* + PyTypeObject* colorType = &PyLinkedColorType; + PyObject* pyColor = colorType->tp_alloc(colorLinkedType, 0); if (pyColor == NULL) { - std::cout << "failure to allocate mcrfpy.Color / PyColorType" << std::endl; + std::cout << "failure to allocate mcrfpy.LinkedColor / PyLinkedColorType" << std::endl; return NULL; } - PyColorObject* pyColorObj = reinterpret_cast(pyColor); + PyColorObject* pyColorObj = reinterpret_cast(pyColor); + */ // fetch correct member data sf::Color color; + //sf::Color (*cgetter)(); + //void (*csetter)(sf::Color); + //std::function csetter; + //std::function cgetter; if (member_ptr == 0) { color = self->data->text.getFillColor(); //return Py_BuildValue("(iii)", color.r, color.g, color.b); + //csetter = &self->data->text.setFillColor; + //cgetter = &self->data->text.getFillColor; + //csetter = [s = self->data](sf::Color c){s->text.setFillColor(c);}; + //cgetter = [s = self->data](){return s->text.getFillColor();}; } else if (member_ptr == 1) { color = self->data->text.getOutlineColor(); //return Py_BuildValue("(iii)", color.r, color.g, color.b); + //csetter = &self->data->text.setOutlineColor; + //cgetter = &self->data->text.getOutlineColor; + //csetter = [s = self->data](sf::Color c){s->text.setOutlineColor(c);}; + //cgetter = [s = self->data](){return s->text.getOutlineColor();}; } // initialize new mcrfpy.Color instance - pyColorObj->data = std::make_shared(color); + //pyColorObj->data = std::make_shared(color); + //PyLinkedColor::fromPy(pyColorObj).set(color); + //auto linkedcolor = PyLinkedColor(csetter, cgetter, self->data, member_ptr); + //linkedcolor.set(color); // don't need to set a linked color! - return pyColor; + //return pyColor; + return PyColor(color).pyObject(); } static int PyUICaption_set_color_member(PyUICaptionObject* self, PyObject* value, void* closure) @@ -627,11 +652,20 @@ static int PyUIDrawable_set_click(PyUIGridObject* self, PyObject* value, void* c if (PyObject_IsInstance(value, (PyObject*)&PyColorType)) { // get value from mcrfpy.Color instance + /* PyColorObject* color = reinterpret_cast(value); r = color->data->r; g = color->data->g; b = color->data->b; a = color->data->a; + */ + //std::cout << "Build LinkedColor" << std::endl; + //auto lc = PyLinkedColor::fromPy(value); + auto c = ((PyColorObject*)value)->data; + //std::cout << "Fetch value" << std::endl; + //auto c = lc.get(); + r = c.r; g = c.g; b = c.b; a = c.a; + std::cout << "got " << int(r) << ", " << int(g) << ", " << int(b) << ", " << int(a) << std::endl; } else if (!PyTuple_Check(value) || PyTuple_Size(value) < 3 || PyTuple_Size(value) > 4) { @@ -898,9 +932,11 @@ static int PyUIDrawable_set_click(PyUIGridObject* self, PyObject* value, void* c } // initialize new mcrfpy.Color instance - pyColorObj->data = std::make_shared(color); + //pyColorObj->data = std::make_shared(color); + //PyColor::fromPy(pyColorObj).set(color); - return pyColor; + // TODO - supposed to return Linked + return PyColor(color).pyObject(); } static int PyUIFrame_set_color_member(PyUIFrameObject* self, PyObject* value, void* closure) @@ -911,12 +947,16 @@ static int PyUIDrawable_set_click(PyUIGridObject* self, PyObject* value, void* c if (PyObject_IsInstance(value, (PyObject*)&PyColorType)) { // get value from mcrfpy.Color instance + /* PyColorObject* color = reinterpret_cast(value); r = color->data->r; g = color->data->g; b = color->data->b; a = color->data->a; std::cout << "using color: " << r << " " << g << " " << b << " " << a << std::endl; + */ + sf::Color c = ((PyColorObject*)value)->data; + r = c.r; g = c.g; b = c.b; a = c.a; } else if (!PyTuple_Check(value) || PyTuple_Size(value) < 3 || PyTuple_Size(value) > 4) { diff --git a/src/scripts/game.py b/src/scripts/game.py index c022aca..8e28bc3 100644 --- a/src/scripts/game.py +++ b/src/scripts/game.py @@ -1,221 +1,51 @@ -#print("Hello mcrogueface") import mcrfpy -import cos_play -# Universal stuff font = mcrfpy.Font("assets/JetbrainsMono.ttf") -texture = mcrfpy.Texture("assets/kenney_tinydungeon.png", 16, 16) #12, 11) -texture_cold = mcrfpy.Texture("assets/kenney_ice.png", 16, 16) #12, 11) -texture_hot = mcrfpy.Texture("assets/kenney_lava.png", 16, 16) #12, 11) +texture = mcrfpy.Texture("assets/kenney_tinydungeon.png", 16, 16) -# Test stuff -mcrfpy.createScene("boom") -mcrfpy.setScene("boom") -ui = mcrfpy.sceneUI("boom") -box = mcrfpy.Frame(40, 60, 200, 300, fill_color=(255,128,0), outline=4.0, outline_color=(64,64,255,96)) -ui.append(box) +# build test widgets -#caption = mcrfpy.Caption(10, 10, "Clicky", font, (255, 255, 255, 255), (0, 0, 0, 255)) -#box.click = lambda x, y, btn, type: print("Hello callback: ", x, y, btn, type) -#box.children.append(caption) +mcrfpy.createScene("pytest") +mcrfpy.setScene("pytest") +ui = mcrfpy.sceneUI("pytest") -test_sprite_number = 86 -sprite = mcrfpy.Sprite(20, 60, texture, test_sprite_number, 4.0) -spritecap = mcrfpy.Caption(5, 5, "60", font) -def click_sprite(x, y, btn, action): - global test_sprite_number - if action != "start": return - if btn in ("left", "wheel_up"): - test_sprite_number -= 1 - elif btn in ("right", "wheel_down"): - test_sprite_number += 1 - sprite.sprite_number = test_sprite_number # TODO - inconsistent naming for __init__, __repr__ and getsetter: sprite_number vs sprite_index - spritecap.text = test_sprite_number +# Frame +f = mcrfpy.Frame(25, 19, 462, 346, fill_color=(255, 92, 92)) +# fill (LinkedColor / Color): f.fill_color +# outline (LinkedColor / Color): f.outline_color +# pos (LinkedVector / Vector): f.pos +# size (LinkedVector / Vector): f.size -sprite.click = click_sprite # TODO - sprites don't seem to correct for screen position or scale when clicking -box.children.append(sprite) -box.children.append(spritecap) -box.click = click_sprite +# Caption +c = mcrfpy.Caption(512+25, 19, "Hi.", font) +# fill (LinkedColor / Color): c.fill_color +#color_val = c.fill_color +print(c.fill_color) +print("Set a fill color") +c.fill_color = (255, 255, 255) +print("Lol, did it segfault?") +# outline (LinkedColor / Color): c.outline_color +# font (Font): c.font +# pos (LinkedVector / Vector): c.pos -f_a = mcrfpy.Frame(250, 60, 80, 80, fill_color=(255, 92, 92)) -f_a_txt = mcrfpy.Caption(5, 5, "0", font) +# Sprite +s = mcrfpy.Sprite(25, 384+19, texture, 86, 9.0) +# pos (LinkedVector / Vector): s.pos +# texture (Texture): s.texture -f_b = mcrfpy.Frame(340, 60, 80, 80, fill_color=(92, 255, 92)) -f_b_txt = mcrfpy.Caption(5, 5, "0", font) +# Grid +g = mcrfpy.Grid(10, 10, texture, 512+25, 384+19, 462, 346) +# texture (Texture): g.texture +# pos (LinkedVector / Vector): g.pos +# size (LinkedVector / Vector): g.size -f_c = mcrfpy.Frame(430, 60, 80, 80, fill_color=(92, 92, 255)) -f_c_txt = mcrfpy.Caption(5, 5, "0", font) +for _x in range(10): + for _y in range(10): + g.at((_x, _y)).color = (255 - _x*25, 255 - _y*25, 255) +g.zoom = 2.0 +[ui.append(d) for d in (f, c, s, g)] -ui.append(f_a) -f_a.children.append(f_a_txt) -ui.append(f_b) -f_b.children.append(f_b_txt) -ui.append(f_c) -f_c.children.append(f_c_txt) +print("built!") -import sys -def ding(*args): - f_a_txt.text = str(sys.getrefcount(ding)) + " refs" - f_b_txt.text = sys.getrefcount(dong) - f_c_txt.text = sys.getrefcount(stress_test) +# tests -def dong(*args): - f_a_txt.text = str(sys.getrefcount(ding)) + " refs" - f_b_txt.text = sys.getrefcount(dong) - f_c_txt.text = sys.getrefcount(stress_test) - -running = False -timers = [] - -def add_ding(): - global timers - n = len(timers) - mcrfpy.setTimer(f"timer{n}", ding, 100) - print("+1 ding:", timers) - -def add_dong(): - global timers - n = len(timers) - mcrfpy.setTimer(f"timer{n}", dong, 100) - print("+1 dong:", timers) - -def remove_random(): - global timers - target = random.choice(timers) - print("-1 timer:", target) - print("remove from list") - timers.remove(target) - print("delTimer") - mcrfpy.delTimer(target) - print("done") - -import random -import time -def stress_test(*args): - global running - global timers - if not running: - print("stress test initial") - running = True - timers.append("recurse") - add_ding() - add_dong() - mcrfpy.setTimer("recurse", stress_test, 1000) - mcrfpy.setTimer("terminate", lambda *args: mcrfpy.delTimer("recurse"), 30000) - ding(); dong() - else: - #print("stress test random activity") - #random.choice([ - # add_ding, - # add_dong, - # remove_random - # ])() - #print(timers) - print("Segfaultin' time") - mcrfpy.delTimer("recurse") - print("Does this still work?") - time.sleep(0.5) - print("How about now?") - - -stress_test() - - -# Loading Screen -mcrfpy.createScene("loading") -ui = mcrfpy.sceneUI("loading") -#mcrfpy.setScene("loading") -logo_texture = mcrfpy.Texture("assets/temp_logo.png", 1024, 1024)#1, 1) -logo_sprite = mcrfpy.Sprite(50, 50, logo_texture, 0, 0.5) -ui.append(logo_sprite) -logo_sprite.click = lambda *args: mcrfpy.setScene("menu") -logo_caption = mcrfpy.Caption(70, 600, "Click to Proceed", font, (255, 0, 0, 255), (0, 0, 0, 255)) -logo_caption.fill_color =(255, 0, 0, 255) -ui.append(logo_caption) - - -# menu screen -mcrfpy.createScene("menu") - -for e in [ - mcrfpy.Caption(10, 10, "Crypt of Sokoban", font, (255, 255, 255), (0, 0, 0)), - mcrfpy.Caption(20, 55, "a McRogueFace demo project", font, (192, 192, 192), (0, 0, 0)), - mcrfpy.Frame(15, 70, 150, 60, fill_color=(64, 64, 128)), - mcrfpy.Frame(15, 145, 150, 60, fill_color=(64, 64, 128)), - mcrfpy.Frame(15, 220, 150, 60, fill_color=(64, 64, 128)), - mcrfpy.Frame(15, 295, 150, 60, fill_color=(64, 64, 128)), - #mcrfpy.Frame(900, 10, 100, 100, fill_color=(255, 0, 0)), - ]: - mcrfpy.sceneUI("menu").append(e) - -def click_once(fn): - def wraps(*args, **kwargs): - #print(args) - action = args[3] - if action != "start": return - return fn(*args, **kwargs) - return wraps - -@click_once -def asdf(x, y, btn, action): - print(f"clicky @({x},{y}) {action}->{btn}") - -@click_once -def clicked_exit(*args): - mcrfpy.exit() - -menu_btns = [ - ("Boom", lambda *args: 1 / 0), - ("Exit", clicked_exit), - ("About", lambda *args: mcrfpy.setScene("about")), - ("Settings", lambda *args: mcrfpy.setScene("settings")), - ("Start", lambda *args: mcrfpy.setScene("play")) - ] -for i in range(len(mcrfpy.sceneUI("menu"))): - e = mcrfpy.sceneUI("menu")[i] # TODO - fix iterator - #print(e, type(e)) - if type(e) is not mcrfpy.Frame: continue - label, fn = menu_btns.pop() - #print(label) - e.children.append(mcrfpy.Caption(5, 5, label, font, (192, 192, 255), (0,0,0))) - e.click = fn - - -# settings screen -mcrfpy.createScene("settings") -window_scaling = 1.0 - -scale_caption = mcrfpy.Caption(180, 70, "1.0x", font, (255, 255, 255), (0, 0, 0)) -scale_caption.fill_color = (255, 255, 255) # TODO - mcrfpy.Caption.__init__ is not setting colors -for e in [ - mcrfpy.Caption(10, 10, "Settings", font, (255, 255, 255), (0, 0, 0)), - mcrfpy.Frame(15, 70, 150, 60, fill_color=(64, 64, 128)), # + - mcrfpy.Frame(300, 70, 150, 60, fill_color=(64, 64, 128)), # - - mcrfpy.Frame(15, 295, 150, 60, fill_color=(64, 64, 128)), - scale_caption, - ]: - mcrfpy.sceneUI("settings").append(e) - -@click_once -def game_scale(x, y, btn, action, delta): - global window_scaling - print(f"WIP - scale the window from {window_scaling:.1f} to {window_scaling+delta:.1f}") - window_scaling += delta - scale_caption.text = f"{window_scaling:.1f}x" - mcrfpy.setScale(window_scaling) - #mcrfpy.setScale(2) - -settings_btns = [ - ("back", lambda *args: mcrfpy.setScene("menu")), - ("-", lambda x, y, btn, action: game_scale(x, y, btn, action, -0.1)), - ("+", lambda x, y, btn, action: game_scale(x, y, btn, action, +0.1)) - ] - -for i in range(len(mcrfpy.sceneUI("settings"))): - e = mcrfpy.sceneUI("settings")[i] # TODO - fix iterator - #print(e, type(e)) - if type(e) is not mcrfpy.Frame: continue - label, fn = settings_btns.pop() - #print(label, fn) - e.children.append(mcrfpy.Caption(5, 5, label, font, (192, 192, 255), (0,0,0))) - e.click = fn diff --git a/src/scripts/game_old.py b/src/scripts/game_old.py new file mode 100644 index 0000000..2975588 --- /dev/null +++ b/src/scripts/game_old.py @@ -0,0 +1,221 @@ +#print("Hello mcrogueface") +import mcrfpy +import cos_play +# Universal stuff +font = mcrfpy.Font("assets/JetbrainsMono.ttf") +texture = mcrfpy.Texture("assets/kenney_tinydungeon.png", 16, 16) #12, 11) +texture_cold = mcrfpy.Texture("assets/kenney_ice.png", 16, 16) #12, 11) +texture_hot = mcrfpy.Texture("assets/kenney_lava.png", 16, 16) #12, 11) + +# Test stuff +mcrfpy.createScene("boom") +mcrfpy.setScene("boom") +ui = mcrfpy.sceneUI("boom") +box = mcrfpy.Frame(40, 60, 200, 300, fill_color=(255,128,0), outline=4.0, outline_color=(64,64,255,96)) +ui.append(box) + +#caption = mcrfpy.Caption(10, 10, "Clicky", font, (255, 255, 255, 255), (0, 0, 0, 255)) +#box.click = lambda x, y, btn, type: print("Hello callback: ", x, y, btn, type) +#box.children.append(caption) + +test_sprite_number = 86 +sprite = mcrfpy.Sprite(20, 60, texture, test_sprite_number, 4.0) +spritecap = mcrfpy.Caption(5, 5, "60", font) +def click_sprite(x, y, btn, action): + global test_sprite_number + if action != "start": return + if btn in ("left", "wheel_up"): + test_sprite_number -= 1 + elif btn in ("right", "wheel_down"): + test_sprite_number += 1 + sprite.sprite_number = test_sprite_number # TODO - inconsistent naming for __init__, __repr__ and getsetter: sprite_number vs sprite_index + spritecap.text = test_sprite_number + +sprite.click = click_sprite # TODO - sprites don't seem to correct for screen position or scale when clicking +box.children.append(sprite) +box.children.append(spritecap) +box.click = click_sprite + +f_a = mcrfpy.Frame(250, 60, 80, 80, fill_color=(255, 92, 92)) +f_a_txt = mcrfpy.Caption(5, 5, "0", font) + +f_b = mcrfpy.Frame(340, 60, 80, 80, fill_color=(92, 255, 92)) +f_b_txt = mcrfpy.Caption(5, 5, "0", font) + +f_c = mcrfpy.Frame(430, 60, 80, 80, fill_color=(92, 92, 255)) +f_c_txt = mcrfpy.Caption(5, 5, "0", font) + + +ui.append(f_a) +f_a.children.append(f_a_txt) +ui.append(f_b) +f_b.children.append(f_b_txt) +ui.append(f_c) +f_c.children.append(f_c_txt) + +import sys +def ding(*args): + f_a_txt.text = str(sys.getrefcount(ding)) + " refs" + f_b_txt.text = sys.getrefcount(dong) + f_c_txt.text = sys.getrefcount(stress_test) + +def dong(*args): + f_a_txt.text = str(sys.getrefcount(ding)) + " refs" + f_b_txt.text = sys.getrefcount(dong) + f_c_txt.text = sys.getrefcount(stress_test) + +running = False +timers = [] + +def add_ding(): + global timers + n = len(timers) + mcrfpy.setTimer(f"timer{n}", ding, 100) + print("+1 ding:", timers) + +def add_dong(): + global timers + n = len(timers) + mcrfpy.setTimer(f"timer{n}", dong, 100) + print("+1 dong:", timers) + +def remove_random(): + global timers + target = random.choice(timers) + print("-1 timer:", target) + print("remove from list") + timers.remove(target) + print("delTimer") + mcrfpy.delTimer(target) + print("done") + +import random +import time +def stress_test(*args): + global running + global timers + if not running: + print("stress test initial") + running = True + timers.append("recurse") + add_ding() + add_dong() + mcrfpy.setTimer("recurse", stress_test, 1000) + mcrfpy.setTimer("terminate", lambda *args: mcrfpy.delTimer("recurse"), 30000) + ding(); dong() + else: + #print("stress test random activity") + #random.choice([ + # add_ding, + # add_dong, + # remove_random + # ])() + #print(timers) + print("Segfaultin' time") + mcrfpy.delTimer("recurse") + print("Does this still work?") + time.sleep(0.5) + print("How about now?") + + +stress_test() + + +# Loading Screen +mcrfpy.createScene("loading") +ui = mcrfpy.sceneUI("loading") +#mcrfpy.setScene("loading") +logo_texture = mcrfpy.Texture("assets/temp_logo.png", 1024, 1024)#1, 1) +logo_sprite = mcrfpy.Sprite(50, 50, logo_texture, 0, 0.5) +ui.append(logo_sprite) +logo_sprite.click = lambda *args: mcrfpy.setScene("menu") +logo_caption = mcrfpy.Caption(70, 600, "Click to Proceed", font, (255, 0, 0, 255), (0, 0, 0, 255)) +#logo_caption.fill_color =(255, 0, 0, 255) +ui.append(logo_caption) + + +# menu screen +mcrfpy.createScene("menu") + +for e in [ + mcrfpy.Caption(10, 10, "Crypt of Sokoban", font, (255, 255, 255), (0, 0, 0)), + mcrfpy.Caption(20, 55, "a McRogueFace demo project", font, (192, 192, 192), (0, 0, 0)), + mcrfpy.Frame(15, 70, 150, 60, fill_color=(64, 64, 128)), + mcrfpy.Frame(15, 145, 150, 60, fill_color=(64, 64, 128)), + mcrfpy.Frame(15, 220, 150, 60, fill_color=(64, 64, 128)), + mcrfpy.Frame(15, 295, 150, 60, fill_color=(64, 64, 128)), + #mcrfpy.Frame(900, 10, 100, 100, fill_color=(255, 0, 0)), + ]: + mcrfpy.sceneUI("menu").append(e) + +def click_once(fn): + def wraps(*args, **kwargs): + #print(args) + action = args[3] + if action != "start": return + return fn(*args, **kwargs) + return wraps + +@click_once +def asdf(x, y, btn, action): + print(f"clicky @({x},{y}) {action}->{btn}") + +@click_once +def clicked_exit(*args): + mcrfpy.exit() + +menu_btns = [ + ("Boom", lambda *args: 1 / 0), + ("Exit", clicked_exit), + ("About", lambda *args: mcrfpy.setScene("about")), + ("Settings", lambda *args: mcrfpy.setScene("settings")), + ("Start", lambda *args: mcrfpy.setScene("play")) + ] +for i in range(len(mcrfpy.sceneUI("menu"))): + e = mcrfpy.sceneUI("menu")[i] # TODO - fix iterator + #print(e, type(e)) + if type(e) is not mcrfpy.Frame: continue + label, fn = menu_btns.pop() + #print(label) + e.children.append(mcrfpy.Caption(5, 5, label, font, (192, 192, 255), (0,0,0))) + e.click = fn + + +# settings screen +mcrfpy.createScene("settings") +window_scaling = 1.0 + +scale_caption = mcrfpy.Caption(180, 70, "1.0x", font, (255, 255, 255), (0, 0, 0)) +#scale_caption.fill_color = (255, 255, 255) # TODO - mcrfpy.Caption.__init__ is not setting colors +for e in [ + mcrfpy.Caption(10, 10, "Settings", font, (255, 255, 255), (0, 0, 0)), + mcrfpy.Frame(15, 70, 150, 60, fill_color=(64, 64, 128)), # + + mcrfpy.Frame(300, 70, 150, 60, fill_color=(64, 64, 128)), # - + mcrfpy.Frame(15, 295, 150, 60, fill_color=(64, 64, 128)), + scale_caption, + ]: + mcrfpy.sceneUI("settings").append(e) + +@click_once +def game_scale(x, y, btn, action, delta): + global window_scaling + print(f"WIP - scale the window from {window_scaling:.1f} to {window_scaling+delta:.1f}") + window_scaling += delta + scale_caption.text = f"{window_scaling:.1f}x" + mcrfpy.setScale(window_scaling) + #mcrfpy.setScale(2) + +settings_btns = [ + ("back", lambda *args: mcrfpy.setScene("menu")), + ("-", lambda x, y, btn, action: game_scale(x, y, btn, action, -0.1)), + ("+", lambda x, y, btn, action: game_scale(x, y, btn, action, +0.1)) + ] + +for i in range(len(mcrfpy.sceneUI("settings"))): + e = mcrfpy.sceneUI("settings")[i] # TODO - fix iterator + #print(e, type(e)) + if type(e) is not mcrfpy.Frame: continue + label, fn = settings_btns.pop() + #print(label, fn) + e.children.append(mcrfpy.Caption(5, 5, label, font, (192, 192, 255), (0,0,0))) + e.click = fn diff --git a/wikicrayons_colors.txt b/wikicrayons_colors.txt new file mode 100644 index 0000000..2bbfe43 --- /dev/null +++ b/wikicrayons_colors.txt @@ -0,0 +1,168 @@ +Red #ED0A3F +Maroon #C32148 +Scarlet #FD0E35 +Brick Red #C62D42 +English Vermilion #CC474B +Madder Lake #CC3336 +Permanent Geranium Lake #E12C2C +Maximum Red #D92121 +Chestnut #B94E48 +Orange-Red #FF5349 +Sunset Orange #FE4C40 +Bittersweet #FE6F5E +Dark Venetian Red #B33B24 +Venetian Red #CC553D +Light Venetian Red #E6735C +Vivid Tangerine #FF9980 +Middle Red #E58E73 +Burnt Orange #FF7034 +Red-Orange #FF3F34 +Orange #FF8833 +Macaroni and Cheese #FFB97B +Middle Yellow Red #ECAC76 +Mango Tango #E77200 +Yellow-Orange #FFAE42 +Maximum Yellow Red #F2BA49 +Banana Mania #FBE7B2 +Maize #F2C649 +Orange-Yellow #F8D568 +Goldenrod #FCD667 +Dandelion #FED85D +Yellow #FBE870 +Green-Yellow #F1E788 +Middle Yellow #FFEB00 +Olive Green #B5B35C +Spring Green #ECEBBD +Maximum Yellow #FAFA37 +Canary #FFFF99 +Lemon Yellow #FFFF9F +Maximum Green Yellow #D9E650 +Middle Green Yellow #ACBF60 +Inchworm #B0E313 +Light Chrome Green #BEE64B +Yellow-Green #C5E17A +Maximum Green #5E8C31 +Asparagus #7BA05B +Granny Smith Apple #9DE093 +Fern #63B76C +Middle Green #4D8C57 +Green #01A638 +Medium Chrome Green #6CA67C +Forest Green #5FA777 +Sea Green #93DFB8 +Shamrock #33CC99 +Mountain Meadow #1AB385 +Jungle Green #29AB87 +Caribbean Green #00CC99 +Tropical Rain Forest #00755E +Middle Blue Green #8DD9CC +Pine Green #01796F +Maximum Blue Green #30BFBF +Robin's Egg Blue #00CCCC +Teal Blue #008080 +Light Blue #8FD8D8 +Aquamarine #458B74 +Turquoise Blue #6CDAE7 +Outer Space #2D383A +Sky Blue #76D7EA +Middle Blue #7ED4E6 +Blue-Green #0095B7 +Pacific Blue #009DC4 +Cerulean #02A4D3 +Maximum Blue #47ABCC +Blue (I) #2EB4E6 +Cerulean Blue #339ACC +Cornflower #93CCEA +Green-Blue #2887C8 +Midnight Blue #003366 +Navy Blue #0066CC +Denim #1560BD +Blue (III) #0066FF +Cadet Blue #A9B2C3 +Periwinkle #C3CDE6 +Blue (II) #4570E6 +Bluetiful #3C69E7 +Wild Blue Yonder #7A89B8 +Indigo #4F69C6 +Manatee #8D90A1 +Cobalt Blue #8C90C8 +Celestial Blue #7070CC +Blue Bell #9999CC +Maximum Blue Purple #ACACE6 +Violet-Blue #766EC8 +Blue-Violet #6456B7 +Ultramarine Blue #3F26BF +Middle Blue Purple #8B72BE +Purple Heart #652DC1 +Royal Purple #6B3FA0 +Violet (II) #8359A3 +Medium Violet #8F47B3 +Wisteria #C9A0DC +Lavender (I) #BF8FCC +Vivid Violet #803790 +Maximum Purple #733380 +Purple Mountains' Majesty #D6AEDD +Fuchsia #C154C1 +Pink Flamingo #F2583E +Violet (I) #732E6C +Brilliant Rose #E667CE +Orchid #E29CD2 +Plum #843179 +Medium Rose #D96CBE +Thistle #D8BFD8 +Mulberry #C8509B +Red-Violet #BB3385 +Middle Purple #D982B5 +Maximum Red Purple #A63A79 +Jazzberry Jam #A50B5E +Eggplant #614051 +Magenta #F653A6 +Cerise #DA3287 +Wild Strawberry #FF3399 +Lavender (II) #FBAED2 +Cotton Candy #FFB7D5 +Carnation Pink #FFA6C9 +Violet-Red #F7468A +Razzmatazz #E30B5C +Piggy Pink #FDD7E4 +Carmine #E62E6B +Blush #DB5079 +Tickle Me Pink #FC80A5 +Mauvelous #F091A9 +Salmon #FF91A4 +Middle Red Purple #A55353 +Mahogany #CA3435 +Melon #FEBAAD +Pink Sherbert #F7A38E +Burnt Sienna #E97451 +Brown #AF593E +Sepia #9E5B40 +Fuzzy Wuzzy #87421F +Beaver #926F5B +Tumbleweed #DEA681 +Raw Sienna #D27D46 +Van Dyke Brown #664228 +Tan #FA9D5A +Desert Sand #EDC9AF +Peach #FFCBA4 +Burnt Umber #805533 +Apricot #FDD5B1 +Almond #EED9C4 +Raw Umber #665233 +Shadow #837050 +Raw Sienna (I) #E6BC5C +Gold (I) #92926E +Gold (II) #E6BE8A +Silver #C9C0BB +Copper #DA8A67 +Antique Brass #C88A65 +Black #000000 +Charcoal Gray #736A62 +Gray #8B8680 +Blue-Gray #C8C8CD +Timberwolf #D9D6CF +White #FFFFFF +Crayellow #F1D651[6] +Cool Mint #DDEBEC[6] +Oatmeal #D9DAD2[6] +Powder Blue #C0D5F0[6] diff --git a/xkcd_colors.txt b/xkcd_colors.txt new file mode 100644 index 0000000..eb3cd41 --- /dev/null +++ b/xkcd_colors.txt @@ -0,0 +1,949 @@ +cloudy blue #acc2d9 +dark pastel green #56ae57 +dust #b2996e +electric lime #a8ff04 +fresh green #69d84f +light eggplant #894585 +nasty green #70b23f +really light blue #d4ffff +tea #65ab7c +warm purple #952e8f +yellowish tan #fcfc81 +cement #a5a391 +dark grass green #388004 +dusty teal #4c9085 +grey teal #5e9b8a +macaroni and cheese #efb435 +pinkish tan #d99b82 +spruce #0a5f38 +strong blue #0c06f7 +toxic green #61de2a +windows blue #3778bf +blue blue #2242c7 +blue with a hint of purple #533cc6 +booger #9bb53c +bright sea green #05ffa6 +dark green blue #1f6357 +deep turquoise #017374 +green teal #0cb577 +strong pink #ff0789 +bland #afa88b +deep aqua #08787f +lavender pink #dd85d7 +light moss green #a6c875 +light seafoam green #a7ffb5 +olive yellow #c2b709 +pig pink #e78ea5 +deep lilac #966ebd +desert #ccad60 +dusty lavender #ac86a8 +purpley grey #947e94 +purply #983fb2 +candy pink #ff63e9 +light pastel green #b2fba5 +boring green #63b365 +kiwi green #8ee53f +light grey green #b7e1a1 +orange pink #ff6f52 +tea green #bdf8a3 +very light brown #d3b683 +egg shell #fffcc4 +eggplant purple #430541 +powder pink #ffb2d0 +reddish grey #997570 +baby shit brown #ad900d +liliac #c48efd +stormy blue #507b9c +ugly brown #7d7103 +custard #fffd78 +darkish pink #da467d +deep brown #410200 +greenish beige #c9d179 +manilla #fffa86 +off blue #5684ae +battleship grey #6b7c85 +browny green #6f6c0a +bruise #7e4071 +kelley green #009337 +sickly yellow #d0e429 +sunny yellow #fff917 +azul #1d5dec +darkgreen #054907 +green/yellow #b5ce08 +lichen #8fb67b +light light green #c8ffb0 +pale gold #fdde6c +sun yellow #ffdf22 +tan green #a9be70 +burple #6832e3 +butterscotch #fdb147 +toupe #c7ac7d +dark cream #fff39a +indian red #850e04 +light lavendar #efc0fe +poison green #40fd14 +baby puke green #b6c406 +bright yellow green #9dff00 +charcoal grey #3c4142 +squash #f2ab15 +cinnamon #ac4f06 +light pea green #c4fe82 +radioactive green #2cfa1f +raw sienna #9a6200 +baby purple #ca9bf7 +cocoa #875f42 +light royal blue #3a2efe +orangeish #fd8d49 +rust brown #8b3103 +sand brown #cba560 +swamp #698339 +tealish green #0cdc73 +burnt siena #b75203 +camo #7f8f4e +dusk blue #26538d +fern #63a950 +old rose #c87f89 +pale light green #b1fc99 +peachy pink #ff9a8a +rosy pink #f6688e +light bluish green #76fda8 +light bright green #53fe5c +light neon green #4efd54 +light seafoam #a0febf +tiffany blue #7bf2da +washed out green #bcf5a6 +browny orange #ca6b02 +nice blue #107ab0 +sapphire #2138ab +greyish teal #719f91 +orangey yellow #fdb915 +parchment #fefcaf +straw #fcf679 +very dark brown #1d0200 +terracota #cb6843 +ugly blue #31668a +clear blue #247afd +creme #ffffb6 +foam green #90fda9 +grey/green #86a17d +light gold #fddc5c +seafoam blue #78d1b6 +topaz #13bbaf +violet pink #fb5ffc +wintergreen #20f986 +yellow tan #ffe36e +dark fuchsia #9d0759 +indigo blue #3a18b1 +light yellowish green #c2ff89 +pale magenta #d767ad +rich purple #720058 +sunflower yellow #ffda03 +green/blue #01c08d +leather #ac7434 +racing green #014600 +vivid purple #9900fa +dark royal blue #02066f +hazel #8e7618 +muted pink #d1768f +booger green #96b403 +canary #fdff63 +cool grey #95a3a6 +dark taupe #7f684e +darkish purple #751973 +true green #089404 +coral pink #ff6163 +dark sage #598556 +dark slate blue #214761 +flat blue #3c73a8 +mushroom #ba9e88 +rich blue #021bf9 +dirty purple #734a65 +greenblue #23c48b +icky green #8fae22 +light khaki #e6f2a2 +warm blue #4b57db +dark hot pink #d90166 +deep sea blue #015482 +carmine #9d0216 +dark yellow green #728f02 +pale peach #ffe5ad +plum purple #4e0550 +golden rod #f9bc08 +neon red #ff073a +old pink #c77986 +very pale blue #d6fffe +blood orange #fe4b03 +grapefruit #fd5956 +sand yellow #fce166 +clay brown #b2713d +dark blue grey #1f3b4d +flat green #699d4c +light green blue #56fca2 +warm pink #fb5581 +dodger blue #3e82fc +gross green #a0bf16 +ice #d6fffa +metallic blue #4f738e +pale salmon #ffb19a +sap green #5c8b15 +algae #54ac68 +bluey grey #89a0b0 +greeny grey #7ea07a +highlighter green #1bfc06 +light light blue #cafffb +light mint #b6ffbb +raw umber #a75e09 +vivid blue #152eff +deep lavender #8d5eb7 +dull teal #5f9e8f +light greenish blue #63f7b4 +mud green #606602 +pinky #fc86aa +red wine #8c0034 +shit green #758000 +tan brown #ab7e4c +darkblue #030764 +rosa #fe86a4 +lipstick #d5174e +pale mauve #fed0fc +claret #680018 +dandelion #fedf08 +orangered #fe420f +poop green #6f7c00 +ruby #ca0147 +dark #1b2431 +greenish turquoise #00fbb0 +pastel red #db5856 +piss yellow #ddd618 +bright cyan #41fdfe +dark coral #cf524e +algae green #21c36f +darkish red #a90308 +reddy brown #6e1005 +blush pink #fe828c +camouflage green #4b6113 +lawn green #4da409 +putty #beae8a +vibrant blue #0339f8 +dark sand #a88f59 +purple/blue #5d21d0 +saffron #feb209 +twilight #4e518b +warm brown #964e02 +bluegrey #85a3b2 +bubble gum pink #ff69af +duck egg blue #c3fbf4 +greenish cyan #2afeb7 +petrol #005f6a +royal #0c1793 +butter #ffff81 +dusty orange #f0833a +off yellow #f1f33f +pale olive green #b1d27b +orangish #fc824a +leaf #71aa34 +light blue grey #b7c9e2 +dried blood #4b0101 +lightish purple #a552e6 +rusty red #af2f0d +lavender blue #8b88f8 +light grass green #9af764 +light mint green #a6fbb2 +sunflower #ffc512 +velvet #750851 +brick orange #c14a09 +lightish red #fe2f4a +pure blue #0203e2 +twilight blue #0a437a +violet red #a50055 +yellowy brown #ae8b0c +carnation #fd798f +muddy yellow #bfac05 +dark seafoam green #3eaf76 +deep rose #c74767 +dusty red #b9484e +grey/blue #647d8e +lemon lime #bffe28 +purple/pink #d725de +brown yellow #b29705 +purple brown #673a3f +wisteria #a87dc2 +banana yellow #fafe4b +lipstick red #c0022f +water blue #0e87cc +brown grey #8d8468 +vibrant purple #ad03de +baby green #8cff9e +barf green #94ac02 +eggshell blue #c4fff7 +sandy yellow #fdee73 +cool green #33b864 +pale #fff9d0 +blue/grey #758da3 +hot magenta #f504c9 +greyblue #77a1b5 +purpley #8756e4 +baby shit green #889717 +brownish pink #c27e79 +dark aquamarine #017371 +diarrhea #9f8303 +light mustard #f7d560 +pale sky blue #bdf6fe +turtle green #75b84f +bright olive #9cbb04 +dark grey blue #29465b +greeny brown #696006 +lemon green #adf802 +light periwinkle #c1c6fc +seaweed green #35ad6b +sunshine yellow #fffd37 +ugly purple #a442a0 +medium pink #f36196 +puke brown #947706 +very light pink #fff4f2 +viridian #1e9167 +bile #b5c306 +faded yellow #feff7f +very pale green #cffdbc +vibrant green #0add08 +bright lime #87fd05 +spearmint #1ef876 +light aquamarine #7bfdc7 +light sage #bcecac +yellowgreen #bbf90f +baby poo #ab9004 +dark seafoam #1fb57a +deep teal #00555a +heather #a484ac +rust orange #c45508 +dirty blue #3f829d +fern green #548d44 +bright lilac #c95efb +weird green #3ae57f +peacock blue #016795 +avocado green #87a922 +faded orange #f0944d +grape purple #5d1451 +hot green #25ff29 +lime yellow #d0fe1d +mango #ffa62b +shamrock #01b44c +bubblegum #ff6cb5 +purplish brown #6b4247 +vomit yellow #c7c10c +pale cyan #b7fffa +key lime #aeff6e +tomato red #ec2d01 +lightgreen #76ff7b +merlot #730039 +night blue #040348 +purpleish pink #df4ec8 +apple #6ecb3c +baby poop green #8f9805 +green apple #5edc1f +heliotrope #d94ff5 +yellow/green #c8fd3d +almost black #070d0d +cool blue #4984b8 +leafy green #51b73b +mustard brown #ac7e04 +dusk #4e5481 +dull brown #876e4b +frog green #58bc08 +vivid green #2fef10 +bright light green #2dfe54 +fluro green #0aff02 +kiwi #9cef43 +seaweed #18d17b +navy green #35530a +ultramarine blue #1805db +iris #6258c4 +pastel orange #ff964f +yellowish orange #ffab0f +perrywinkle #8f8ce7 +tealish #24bca8 +dark plum #3f012c +pear #cbf85f +pinkish orange #ff724c +midnight purple #280137 +light urple #b36ff6 +dark mint #48c072 +greenish tan #bccb7a +light burgundy #a8415b +turquoise blue #06b1c4 +ugly pink #cd7584 +sandy #f1da7a +electric pink #ff0490 +muted purple #805b87 +mid green #50a747 +greyish #a8a495 +neon yellow #cfff04 +banana #ffff7e +carnation pink #ff7fa7 +tomato #ef4026 +sea #3c9992 +muddy brown #886806 +turquoise green #04f489 +buff #fef69e +fawn #cfaf7b +muted blue #3b719f +pale rose #fdc1c5 +dark mint green #20c073 +amethyst #9b5fc0 +blue/green #0f9b8e +chestnut #742802 +sick green #9db92c +pea #a4bf20 +rusty orange #cd5909 +stone #ada587 +rose red #be013c +pale aqua #b8ffeb +deep orange #dc4d01 +earth #a2653e +mossy green #638b27 +grassy green #419c03 +pale lime green #b1ff65 +light grey blue #9dbcd4 +pale grey #fdfdfe +asparagus #77ab56 +blueberry #464196 +purple red #990147 +pale lime #befd73 +greenish teal #32bf84 +caramel #af6f09 +deep magenta #a0025c +light peach #ffd8b1 +milk chocolate #7f4e1e +ocher #bf9b0c +off green #6ba353 +purply pink #f075e6 +lightblue #7bc8f6 +dusky blue #475f94 +golden #f5bf03 +light beige #fffeb6 +butter yellow #fffd74 +dusky purple #895b7b +french blue #436bad +ugly yellow #d0c101 +greeny yellow #c6f808 +orangish red #f43605 +shamrock green #02c14d +orangish brown #b25f03 +tree green #2a7e19 +deep violet #490648 +gunmetal #536267 +blue/purple #5a06ef +cherry #cf0234 +sandy brown #c4a661 +warm grey #978a84 +dark indigo #1f0954 +midnight #03012d +bluey green #2bb179 +grey pink #c3909b +soft purple #a66fb5 +blood #770001 +brown red #922b05 +medium grey #7d7f7c +berry #990f4b +poo #8f7303 +purpley pink #c83cb9 +light salmon #fea993 +snot #acbb0d +easter purple #c071fe +light yellow green #ccfd7f +dark navy blue #00022e +drab #828344 +light rose #ffc5cb +rouge #ab1239 +purplish red #b0054b +slime green #99cc04 +baby poop #937c00 +irish green #019529 +pink/purple #ef1de7 +dark navy #000435 +greeny blue #42b395 +light plum #9d5783 +pinkish grey #c8aca9 +dirty orange #c87606 +rust red #aa2704 +pale lilac #e4cbff +orangey red #fa4224 +primary blue #0804f9 +kermit green #5cb200 +brownish purple #76424e +murky green #6c7a0e +wheat #fbdd7e +very dark purple #2a0134 +bottle green #044a05 +watermelon #fd4659 +deep sky blue #0d75f8 +fire engine red #fe0002 +yellow ochre #cb9d06 +pumpkin orange #fb7d07 +pale olive #b9cc81 +light lilac #edc8ff +lightish green #61e160 +carolina blue #8ab8fe +mulberry #920a4e +shocking pink #fe02a2 +auburn #9a3001 +bright lime green #65fe08 +celadon #befdb7 +pinkish brown #b17261 +poo brown #885f01 +bright sky blue #02ccfe +celery #c1fd95 +dirt brown #836539 +strawberry #fb2943 +dark lime #84b701 +copper #b66325 +medium brown #7f5112 +muted green #5fa052 +robin's egg #6dedfd +bright aqua #0bf9ea +bright lavender #c760ff +ivory #ffffcb +very light purple #f6cefc +light navy #155084 +pink red #f5054f +olive brown #645403 +poop brown #7a5901 +mustard green #a8b504 +ocean green #3d9973 +very dark blue #000133 +dusty green #76a973 +light navy blue #2e5a88 +minty green #0bf77d +adobe #bd6c48 +barney #ac1db8 +jade green #2baf6a +bright light blue #26f7fd +light lime #aefd6c +dark khaki #9b8f55 +orange yellow #ffad01 +ocre #c69c04 +maize #f4d054 +faded pink #de9dac +british racing green #05480d +sandstone #c9ae74 +mud brown #60460f +light sea green #98f6b0 +robin egg blue #8af1fe +aqua marine #2ee8bb +dark sea green #11875d +soft pink #fdb0c0 +orangey brown #b16002 +cherry red #f7022a +burnt yellow #d5ab09 +brownish grey #86775f +camel #c69f59 +purplish grey #7a687f +marine #042e60 +greyish pink #c88d94 +pale turquoise #a5fbd5 +pastel yellow #fffe71 +bluey purple #6241c7 +canary yellow #fffe40 +faded red #d3494e +sepia #985e2b +coffee #a6814c +bright magenta #ff08e8 +mocha #9d7651 +ecru #feffca +purpleish #98568d +cranberry #9e003a +darkish green #287c37 +brown orange #b96902 +dusky rose #ba6873 +melon #ff7855 +sickly green #94b21c +silver #c5c9c7 +purply blue #661aee +purpleish blue #6140ef +hospital green #9be5aa +shit brown #7b5804 +mid blue #276ab3 +amber #feb308 +easter green #8cfd7e +soft blue #6488ea +cerulean blue #056eee +golden brown #b27a01 +bright turquoise #0ffef9 +red pink #fa2a55 +red purple #820747 +greyish brown #7a6a4f +vermillion #f4320c +russet #a13905 +steel grey #6f828a +lighter purple #a55af4 +bright violet #ad0afd +prussian blue #004577 +slate green #658d6d +dirty pink #ca7b80 +dark blue green #005249 +pine #2b5d34 +yellowy green #bff128 +dark gold #b59410 +bluish #2976bb +darkish blue #014182 +dull red #bb3f3f +pinky red #fc2647 +bronze #a87900 +pale teal #82cbb2 +military green #667c3e +barbie pink #fe46a5 +bubblegum pink #fe83cc +pea soup green #94a617 +dark mustard #a88905 +shit #7f5f00 +medium purple #9e43a2 +very dark green #062e03 +dirt #8a6e45 +dusky pink #cc7a8b +red violet #9e0168 +lemon yellow #fdff38 +pistachio #c0fa8b +dull yellow #eedc5b +dark lime green #7ebd01 +denim blue #3b5b92 +teal blue #01889f +lightish blue #3d7afd +purpley blue #5f34e7 +light indigo #6d5acf +swamp green #748500 +brown green #706c11 +dark maroon #3c0008 +hot purple #cb00f5 +dark forest green #002d04 +faded blue #658cbb +drab green #749551 +light lime green #b9ff66 +snot green #9dc100 +yellowish #faee66 +light blue green #7efbb3 +bordeaux #7b002c +light mauve #c292a1 +ocean #017b92 +marigold #fcc006 +muddy green #657432 +dull orange #d8863b +steel #738595 +electric purple #aa23ff +fluorescent green #08ff08 +yellowish brown #9b7a01 +blush #f29e8e +soft green #6fc276 +bright orange #ff5b00 +lemon #fdff52 +purple grey #866f85 +acid green #8ffe09 +pale lavender #eecffe +violet blue #510ac9 +light forest green #4f9153 +burnt red #9f2305 +khaki green #728639 +cerise #de0c62 +faded purple #916e99 +apricot #ffb16d +dark olive green #3c4d03 +grey brown #7f7053 +green grey #77926f +true blue #010fcc +pale violet #ceaefa +periwinkle blue #8f99fb +light sky blue #c6fcff +blurple #5539cc +green brown #544e03 +bluegreen #017a79 +bright teal #01f9c6 +brownish yellow #c9b003 +pea soup #929901 +forest #0b5509 +barney purple #a00498 +ultramarine #2000b1 +purplish #94568c +puke yellow #c2be0e +bluish grey #748b97 +dark periwinkle #665fd1 +dark lilac #9c6da5 +reddish #c44240 +light maroon #a24857 +dusty purple #825f87 +terra cotta #c9643b +avocado #90b134 +marine blue #01386a +teal green #25a36f +slate grey #59656d +lighter green #75fd63 +electric green #21fc0d +dusty blue #5a86ad +golden yellow #fec615 +bright yellow #fffd01 +light lavender #dfc5fe +umber #b26400 +poop #7f5e00 +dark peach #de7e5d +jungle green #048243 +eggshell #ffffd4 +denim #3b638c +yellow brown #b79400 +dull purple #84597e +chocolate brown #411900 +wine red #7b0323 +neon blue #04d9ff +dirty green #667e2c +light tan #fbeeac +ice blue #d7fffe +cadet blue #4e7496 +dark mauve #874c62 +very light blue #d5ffff +grey purple #826d8c +pastel pink #ffbacd +very light green #d1ffbd +dark sky blue #448ee4 +evergreen #05472a +dull pink #d5869d +aubergine #3d0734 +mahogany #4a0100 +reddish orange #f8481c +deep green #02590f +vomit green #89a203 +purple pink #e03fd8 +dusty pink #d58a94 +faded green #7bb274 +camo green #526525 +pinky purple #c94cbe +pink purple #db4bda +brownish red #9e3623 +dark rose #b5485d +mud #735c12 +brownish #9c6d57 +emerald green #028f1e +pale brown #b1916e +dull blue #49759c +burnt umber #a0450e +medium green #39ad48 +clay #b66a50 +light aqua #8cffdb +light olive green #a4be5c +brownish orange #cb7723 +dark aqua #05696b +purplish pink #ce5dae +dark salmon #c85a53 +greenish grey #96ae8d +jade #1fa774 +ugly green #7a9703 +dark beige #ac9362 +emerald #01a049 +pale red #d9544d +light magenta #fa5ff7 +sky #82cafc +light cyan #acfffc +yellow orange #fcb001 +reddish purple #910951 +reddish pink #fe2c54 +orchid #c875c4 +dirty yellow #cdc50a +orange red #fd411e +deep red #9a0200 +orange brown #be6400 +cobalt blue #030aa7 +neon pink #fe019a +rose pink #f7879a +greyish purple #887191 +raspberry #b00149 +aqua green #12e193 +salmon pink #fe7b7c +tangerine #ff9408 +brownish green #6a6e09 +red brown #8b2e16 +greenish brown #696112 +pumpkin #e17701 +pine green #0a481e +charcoal #343837 +baby pink #ffb7ce +cornflower #6a79f7 +blue violet #5d06e9 +chocolate #3d1c02 +greyish green #82a67d +scarlet #be0119 +green yellow #c9ff27 +dark olive #373e02 +sienna #a9561e +pastel purple #caa0ff +terracotta #ca6641 +aqua blue #02d8e9 +sage green #88b378 +blood red #980002 +deep pink #cb0162 +grass #5cac2d +moss #769958 +pastel blue #a2bffe +bluish green #10a674 +green blue #06b48b +dark tan #af884a +greenish blue #0b8b87 +pale orange #ffa756 +vomit #a2a415 +forrest green #154406 +dark lavender #856798 +dark violet #34013f +purple blue #632de9 +dark cyan #0a888a +olive drab #6f7632 +pinkish #d46a7e +cobalt #1e488f +neon purple #bc13fe +light turquoise #7ef4cc +apple green #76cd26 +dull green #74a662 +wine #80013f +powder blue #b1d1fc +off white #ffffe4 +electric blue #0652ff +dark turquoise #045c5a +blue purple #5729ce +azure #069af3 +bright red #ff000d +pinkish red #f10c45 +cornflower blue #5170d7 +light olive #acbf69 +grape #6c3461 +greyish blue #5e819d +purplish blue #601ef9 +yellowish green #b0dd16 +greenish yellow #cdfd02 +medium blue #2c6fbb +dusty rose #c0737a +light violet #d6b4fc +midnight blue #020035 +bluish purple #703be7 +red orange #fd3c06 +dark magenta #960056 +greenish #40a368 +ocean blue #03719c +coral #fc5a50 +cream #ffffc2 +reddish brown #7f2b0a +burnt sienna #b04e0f +brick #a03623 +sage #87ae73 +grey green #789b73 +white #ffffff +robin's egg blue #98eff9 +moss green #658b38 +steel blue #5a7d9a +eggplant #380835 +light yellow #fffe7a +leaf green #5ca904 +light grey #d8dcd6 +puke #a5a502 +pinkish purple #d648d7 +sea blue #047495 +pale purple #b790d4 +slate blue #5b7c99 +blue grey #607c8e +hunter green #0b4008 +fuchsia #ed0dd9 +crimson #8c000f +pale yellow #ffff84 +ochre #bf9005 +mustard yellow #d2bd0a +light red #ff474c +cerulean #0485d1 +pale pink #ffcfdc +deep blue #040273 +rust #a83c09 +light teal #90e4c1 +slate #516572 +goldenrod #fac205 +dark yellow #d5b60a +dark grey #363737 +army green #4b5d16 +grey blue #6b8ba4 +seafoam #80f9ad +puce #a57e52 +spring green #a9f971 +dark orange #c65102 +sand #e2ca76 +pastel green #b0ff9d +mint #9ffeb0 +light orange #fdaa48 +bright pink #fe01b1 +chartreuse #c1f80a +deep purple #36013f +dark brown #341c02 +taupe #b9a281 +pea green #8eab12 +puke green #9aae07 +kelly green #02ab2e +seafoam green #7af9ab +blue green #137e6d +khaki #aaa662 +burgundy #610023 +dark teal #014d4e +brick red #8f1402 +royal purple #4b006e +plum #580f41 +mint green #8fff9f +gold #dbb40c +baby blue #a2cffe +yellow green #c0fb2d +bright purple #be03fd +dark red #840000 +pale blue #d0fefe +grass green #3f9b0b +navy #01153e +aquamarine #04d8b2 +burnt orange #c04e01 +neon green #0cff0c +bright blue #0165fc +rose #cf6275 +light pink #ffd1df +mustard #ceb301 +indigo #380282 +lime #aaff32 +sea green #53fca1 +periwinkle #8e82fe +dark pink #cb416b +olive green #677a04 +peach #ffb07c +pale green #c7fdb5 +light brown #ad8150 +hot pink #ff028d +black #000000 +lilac #cea2fd +navy blue #001146 +royal blue #0504aa +beige #e6daa6 +salmon #ff796c +olive #6e750e +maroon #650021 +bright green #01ff07 +dark purple #35063e +mauve #ae7181 +forest green #06470c +aqua #13eac9 +cyan #00ffff +tan #d1b26f +dark blue #00035b +lavender #c79fef +turquoise #06c2ac +dark green #033500 +violet #9a0eea +light purple #bf77f6 +lime green #89fe05 +grey #929591 +sky blue #75bbfd +yellow #ffff14 +magenta #c20078 +light green #96f97b +orange #f97306 +teal #029386 +light blue #95d0fc +red #e50000 +brown #653700 +pink #ff81c0 +blue #0343df +green #15b01a +purple #7e1e9c