src/colors.cc

changeset 946
9cbd658b63f9
parent 861
83426c5fa732
equal deleted inserted replaced
945:c310073e4f22 946:9cbd658b63f9
14 * 14 *
15 * You should have received a copy of the GNU General Public License 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/>. 16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */ 17 */
18 18
19 #include <QFile>
19 #include "main.h" 20 #include "main.h"
20 #include "colors.h" 21 #include "colors.h"
21 #include "ldDocument.h" 22 #include "ldDocument.h"
22 #include "miscallenous.h" 23 #include "miscallenous.h"
23 #include "mainWindow.h" 24 #include "mainWindow.h"
24 #include "ldConfig.h" 25
25 #include <QColor> 26 struct ColorDataEntry
26 27 {
27 static LDColor g_LDConfigColors[512]; 28 QString name;
29 QString hexcode;
30 QColor faceColor;
31 QColor edgeColor;
32 };
33
34 static ColorDataEntry ColorData[512];
28 35
29 void InitColors() 36 void InitColors()
30 { 37 {
31 LDColorData* col;
32 print ("Initializing color information.\n"); 38 print ("Initializing color information.\n");
33 39
34 // Always make sure there's 16 and 24 available. They're special like that. 40 // Always make sure there's 16 and 24 available. They're special like that.
35 col = new LDColorData; 41 ColorData[MainColor].faceColor =
36 col->m_faceColor = 42 ColorData[MainColor].hexcode = "#AAAAAA";
37 col->m_hexcode = "#AAAAAA"; 43 ColorData[MainColor].edgeColor = Qt::black;
38 col->m_edgeColor = Qt::black; 44 ColorData[MainColor].name = "Main color";
39 g_LDConfigColors[16] = col; 45
40 46 ColorData[EdgeColor].faceColor =
41 col = new LDColorData; 47 ColorData[EdgeColor].edgeColor =
42 col->m_faceColor = 48 ColorData[EdgeColor].hexcode = "#000000";
43 col->m_edgeColor = 49 ColorData[EdgeColor].name = "Edge color";
44 col->m_hexcode = "#000000"; 50
45 g_LDConfigColors[24] = col; 51 parseLDConfig();
46 52 }
47 LDConfigParser::parseLDConfig(); 53
48 } 54 bool LDColor::isValid() const
49 55 {
50 LDColor MainColor() 56 if (isLDConfigColor() and ColorData[index()].name.isEmpty())
51 { 57 return false; // Unknown LDConfig color
52 return g_LDConfigColors[MainColorIndex]; 58
53 } 59 return m_index != -1;
54 60 }
55 LDColor EdgeColor() 61
56 { 62 bool LDColor::isLDConfigColor() const
57 return g_LDConfigColors[EdgeColorIndex]; 63 {
58 } 64 return index() >= 0 and index() < countof (ColorData);
59 65 }
60 void LDColor::addLDConfigColor (qint32 index, LDColor color) 66
61 { 67 QString LDColor::name() const
62 assert (index >= 0 and index < countof (g_LDConfigColors)); 68 {
63 g_LDConfigColors[index] = color; 69 if (isDirect())
64 } 70 return "0x" + QString::number (index(), 16).toUpper();
65 71 else if (isLDConfigColor())
66 LDColor LDColor::fromIndex (qint32 index) 72 return ColorData[index()].name;
67 { 73 else if (index() == -1)
68 if (index < countof (g_LDConfigColors) and g_LDConfigColors[index] != null) 74 return "null color";
69 return g_LDConfigColors[index]; 75 else
70 76 return "";
71 if (index >= 0x2000000) 77 }
72 { 78
73 // Direct color 79 QString LDColor::hexcode() const
74 QColor col; 80 {
75 col.setRed ((index & 0x0FF0000) >> 16); 81 return faceColor().name();
76 col.setGreen ((index & 0x000FF00) >> 8); 82 }
77 col.setBlue (index & 0x00000FF); 83
78 84 QColor LDColor::faceColor() const
79 if (index >= 0x3000000) 85 {
80 col.setAlpha (128); 86 if (isDirect())
81 87 {
82 LDColorData* color = new LDColorData; 88 QColor color;
83 color->m_name = "0x" + QString::number (index, 16).toUpper(); 89 color.setRed ((index() & 0x0FF0000) >> 16);
84 color->m_faceColor = col; 90 color.setGreen ((index() & 0x000FF00) >> 8);
85 color->m_edgeColor = Luma (col) < 48 ? Qt::white : Qt::black; 91 color.setBlue (index() & 0x00000FF);
86 color->m_hexcode = col.name(); 92
87 color->m_index = index; 93 if (index() >= 0x3000000)
88 return LDColor (color); 94 color.setAlpha (128);
89 } 95
90 96 return color;
91 return null; 97 }
98 else if (isLDConfigColor())
99 {
100 return ColorData[index()].faceColor;
101 }
102 else
103 {
104 return Qt::black;
105 }
106 }
107
108 QColor LDColor::edgeColor() const
109 {
110 if (isDirect())
111 return Luma (faceColor()) < 48 ? Qt::white : Qt::black;
112 else if (isLDConfigColor())
113 return ColorData[index()].edgeColor;
114 else
115 return Qt::black;
116 }
117
118 int LDColor::luma() const
119 {
120 return Luma (faceColor());
121 }
122
123 int LDColor::edgeLuma() const
124 {
125 return Luma (edgeColor());
126 }
127
128 qint32 LDColor::index() const
129 {
130 return m_index;
92 } 131 }
93 132
94 QString LDColor::indexString() const 133 QString LDColor::indexString() const
95 { 134 {
96 if (isDirect()) 135 if (isDirect())
102 bool LDColor::isDirect() const 141 bool LDColor::isDirect() const
103 { 142 {
104 return index() >= 0x02000000; 143 return index() >= 0x02000000;
105 } 144 }
106 145
107 bool LDColor::operator== (LDColor const& other) 146 int Luma (const QColor& col)
108 { 147 {
109 if ((data() == nullptr) ^ (other == nullptr)) 148 return (0.2126f * col.red()) + (0.7152f * col.green()) + (0.0722f * col.blue());
149 }
150
151 int CountLDConfigColors()
152 {
153 return countof (ColorData);
154 }
155
156 void parseLDConfig()
157 {
158 QFile* fp = OpenLDrawFile ("LDConfig.ldr", false);
159
160 if (fp == nullptr)
161 {
162 Critical (QObject::tr ("Unable to open LDConfig.ldr for parsing."));
163 return;
164 }
165
166 // Read in the lines
167 while (not fp->atEnd())
168 {
169 QString line = QString::fromUtf8 (fp->readLine());
170
171 if (line.isEmpty() or line[0] != '0')
172 continue; // empty or illogical
173
174 line.remove ('\r');
175 line.remove ('\n');
176
177 // Parse the line
178 LDConfigParser pars (line, ' ');
179
180 int code = 0, alpha = 255;
181 QString name, facename, edgename, valuestr;
182
183 // Check 0 !COLOUR, parse the name
184 if (not pars.compareToken (0, "0") or
185 not pars.compareToken (1, "!COLOUR") or
186 not pars.getToken (name, 2))
187 {
188 continue;
189 }
190
191 // Replace underscores in the name with spaces for readability
192 name.replace ("_", " ");
193
194 // Get the CODE tag
195 if (not pars.parseLDConfigTag ("CODE", valuestr))
196 continue;
197
198 // Ensure that the code is within [0 - 511]
199 bool ok;
200 code = valuestr.toShort (&ok);
201
202 if (not ok or code < 0 or code >= 512)
203 continue;
204
205 // VALUE and EDGE tags
206 if (not pars.parseLDConfigTag ("VALUE", facename) or not pars.parseLDConfigTag ("EDGE", edgename))
207 continue;
208
209 // Ensure that our colors are correct
210 QColor faceColor (facename),
211 edgeColor (edgename);
212
213 if (not faceColor.isValid() or not edgeColor.isValid())
214 continue;
215
216 // Parse alpha if given.
217 if (pars.parseLDConfigTag ("ALPHA", valuestr))
218 alpha = Clamp (valuestr.toInt(), 0, 255);
219
220 ColorDataEntry& entry = ColorData[code];
221 entry.name = name;
222 entry.faceColor = faceColor;
223 entry.edgeColor = edgeColor;
224 entry.hexcode = facename;
225 entry.faceColor.setAlpha (alpha);
226 }
227
228 fp->close();
229 fp->deleteLater();
230 }
231
232 // =============================================================================
233 //
234 LDConfigParser::LDConfigParser (QString inText, char sep)
235 {
236 m_tokens = inText.split (sep, QString::SkipEmptyParts);
237 m_pos = -1;
238 }
239
240 // =============================================================================
241 //
242 bool LDConfigParser::getToken (QString& val, const int pos)
243 {
244 if (pos >= m_tokens.size())
110 return false; 245 return false;
111 246
112 if (data() != nullptr) 247 val = m_tokens[pos];
113 return index() == other.index();
114
115 // both are null
116 return true; 248 return true;
117 } 249 }
118 250
119 int Luma (const QColor& col) 251 // =============================================================================
120 { 252 //
121 return (0.2126f * col.red()) + 253 bool LDConfigParser::findToken (int& result, char const* needle, int args)
122 (0.7152f * col.green()) + 254 {
123 (0.0722f * col.blue()); 255 for (int i = 0; i < (m_tokens.size() - args); ++i)
124 } 256 {
125 257 if (m_tokens[i] == needle)
126 int CountLDConfigColors() 258 {
127 { 259 result = i;
128 return countof (g_LDConfigColors); 260 return true;
129 } 261 }
262 }
263
264 return false;
265 }
266
267 // =============================================================================
268 //
269 bool LDConfigParser::compareToken (int inPos, QString text)
270 {
271 QString tok;
272
273 if (not getToken (tok, inPos))
274 return false;
275
276 return (tok == text);
277 }
278
279 // =============================================================================
280 //
281 // Helper function for parseLDConfig
282 //
283 bool LDConfigParser::parseLDConfigTag (char const* tag, QString& val)
284 {
285 int pos;
286
287 // Try find the token and get its position
288 if (not findToken (pos, tag, 1))
289 return false;
290
291 // Get the token after it and store it into val
292 return getToken (val, pos + 1);
293 }

mercurial