1 /*
2 * Copyright (c) 2005-2012 Hypertriton, Inc. <http://hypertriton.com/>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
18 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
23 * USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 /*
27 * Standard color palette for GUI elements.
28 */
29
30 #include <agar/core/core.h>
31 #include <agar/core/config.h>
32 #include <agar/gui/gui.h>
33 #include <agar/gui/colors.h>
34 #include <agar/gui/load_color.h>
35 #include <agar/gui/drv.h>
36
37 #include <ctype.h>
38
39 const AG_Version agColorSchemeVer = { 1, 0 };
40
41 Sint8 agSunkColorShift[3] = { -10, -10, -20 };
42 Sint8 agRaisedColorShift[3] = { 30, 30, 20 };
43 Sint8 agHighColorShift[3] = { 40, 40, 40 };
44 Sint8 agLowColorShift[3] = { -30, -30, -20 };
45
46 /*
47 * Parse a string color specification string. Acceptable forms include:
48 *
49 * r,g,b[,a]
50 * r:g:b[:a]
51 * rgb(r,g,b[,a])
52 * hsv(h,s,v[,a])
53 * #rrggbb
54 *
55 * If components are specified with a terminating "%" sign, they may be
56 * interpreted as percent of some parent color.
57 */
58 static __inline__ double
ColorPct(Uint8 in,double v)59 ColorPct(Uint8 in, double v)
60 {
61 double val;
62 val = ((double)in)*v/100.0;
63 if (val < 0.0) { return (0); }
64 if (val > 255.0) { return (255); }
65 return val;
66 }
67 AG_Color
AG_ColorFromString(const char * s,const AG_Color * pColor)68 AG_ColorFromString(const char *s, const AG_Color *pColor)
69 {
70 char buf[128];
71 AG_Color cIn = (pColor != NULL) ? *pColor : AG_ColorRGB(0,0,0);
72 AG_Color cOut = cIn;
73 double v[4];
74 int isPct[4], isHSV = 0;
75 char *c, *pc;
76 int i, argc;
77
78 Strlcpy(buf, s, sizeof(buf));
79
80 for (c = &buf[0]; *c != '\0' && isspace(*c); c++) {
81 ;;
82 }
83 switch (*c) {
84 case 'r': /* "rgb(r,g,b[,a])" */
85 break;
86 case 'h': /* "hsv(h,s,v[,a])" */
87 isHSV = 1;
88 break;
89 case '#': /* "#rrggbb" */
90 {
91 Uint32 hexVal;
92
93 memmove(&c[2], &c[1], strlen(&c[1])+1);
94 c[0] = '0';
95 c[1] = 'x';
96 hexVal = (Uint32)strtoul(c, NULL, 16);
97 cOut.r = (Uint8)((hexVal >> 16) & 0xff);
98 cOut.g = (Uint8)((hexVal >> 8) & 0xff);
99 cOut.b = (Uint8)((hexVal) & 0xff);
100 return (cOut);
101 }
102 break;
103 }
104 if (*c == 'r' || *c == 'h') {
105 for (; *c != '\0' && *c != '('; c++)
106 ;;
107 if (*c == '\0' || c[1] == '\0') {
108 goto out;
109 }
110 pc = &c[1];
111 } else {
112 pc = &c[0]; /* Just "r,g,b[,a]" */
113 }
114 for (i = 0, argc = 0; i < 4; i++) {
115 char *tok, *ep;
116 if ((tok = AG_Strsep(&pc, ",:")) == NULL) {
117 break;
118 }
119 v[i] = strtod(tok, &ep);
120 isPct[i] = (*ep == '%');
121 argc++;
122 }
123 if (argc < 3) {
124 goto out;
125 }
126 if (isHSV) {
127 float hue, sat, val;
128
129 AG_RGB2HSV(cIn.r, cIn.g, cIn.b, &hue, &sat, &val);
130 hue = isPct[0] ? ColorPct(hue, v[0]) : v[0];
131 sat = isPct[1] ? ColorPct(sat, v[1]) : v[1];
132 val = isPct[2] ? ColorPct(val, v[2]) : v[2];
133 AG_HSV2RGB(hue, sat, val, &cOut.r, &cOut.g, &cOut.b);
134 if (argc == 4) {
135 cOut.a = isPct[3] ? ColorPct(cIn.a, v[3]) : v[3];
136 } else {
137 cOut.a = cIn.a;
138 }
139 } else {
140 cOut.r = isPct[0] ? (Uint8)ColorPct(cIn.r, v[0]) : (Uint8)v[0];
141 cOut.g = isPct[1] ? (Uint8)ColorPct(cIn.g, v[1]) : (Uint8)v[1];
142 cOut.b = isPct[2] ? (Uint8)ColorPct(cIn.b, v[2]) : (Uint8)v[2];
143 if (argc == 4) {
144 cOut.a = isPct[3] ? (Uint8)ColorPct(cIn.a, v[3]) : (Uint8)v[3];
145 } else {
146 cOut.a = cIn.a;
147 }
148 }
149 out:
150 return (cOut);
151 }
152