1use crate::interpreter::value::*;
8use crate::interpreter::BuiltinContext;
9use minir_macros::{builtin, interpreter_builtin};
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub struct RColor {
16 pub r: u8,
17 pub g: u8,
18 pub b: u8,
19 pub a: u8,
20}
21
22impl RColor {
23 pub const BLACK: RColor = RColor::rgb(0, 0, 0);
24 pub const WHITE: RColor = RColor::rgb(255, 255, 255);
25 pub const TRANSPARENT: RColor = RColor {
26 r: 255,
27 g: 255,
28 b: 255,
29 a: 0,
30 };
31
32 pub const fn rgb(r: u8, g: u8, b: u8) -> Self {
33 RColor { r, g, b, a: 255 }
34 }
35
36 pub const fn rgba(r: u8, g: u8, b: u8, a: u8) -> Self {
37 RColor { r, g, b, a }
38 }
39
40 pub fn from_name(name: &str) -> Option<RColor> {
42 let lower = name.to_ascii_lowercase();
43 if lower == "transparent" {
45 return Some(RColor::TRANSPARENT);
46 }
47 NAMED_COLORS
48 .binary_search_by_key(&lower.as_str(), |&(n, _)| n)
49 .ok()
50 .map(|idx| {
51 let (_, (r, g, b)) = NAMED_COLORS[idx];
52 RColor::rgb(r, g, b)
53 })
54 }
55
56 pub fn from_r_value(val: &str, palette: &[RColor]) -> Result<RColor, RError> {
62 let trimmed = val.trim();
63
64 if trimmed.starts_with('#') {
66 return Self::from_hex(trimmed);
67 }
68
69 if let Ok(idx) = trimmed.parse::<usize>() {
71 if idx == 0 {
72 return Ok(RColor::TRANSPARENT);
74 }
75 if palette.is_empty() {
76 return Err(RError::new(
77 RErrorKind::Other,
78 format!("palette index {idx} requested but palette is empty"),
79 ));
80 }
81 let wrapped = ((idx - 1) % palette.len()) + 1;
83 return Ok(palette[wrapped - 1]);
84 }
85
86 if let Some(color) = Self::from_name(trimmed) {
88 return Ok(color);
89 }
90
91 Err(RError::new(
92 RErrorKind::Other,
93 format!("invalid color name '{trimmed}'"),
94 ))
95 }
96
97 pub fn from_hex(hex: &str) -> Result<RColor, RError> {
99 let hex = hex.trim();
100 if !hex.starts_with('#') {
101 return Err(RError::new(
102 RErrorKind::Other,
103 format!("invalid hex color '{hex}': must start with '#'"),
104 ));
105 }
106 let digits = &hex[1..];
107 match digits.len() {
108 6 => {
109 let r = u8::from_str_radix(&digits[0..2], 16);
110 let g = u8::from_str_radix(&digits[2..4], 16);
111 let b = u8::from_str_radix(&digits[4..6], 16);
112 match (r, g, b) {
113 (Ok(r), Ok(g), Ok(b)) => Ok(RColor::rgb(r, g, b)),
114 _ => Err(RError::new(
115 RErrorKind::Other,
116 format!("invalid hex color '{hex}': contains non-hex digits"),
117 )),
118 }
119 }
120 8 => {
121 let r = u8::from_str_radix(&digits[0..2], 16);
122 let g = u8::from_str_radix(&digits[2..4], 16);
123 let b = u8::from_str_radix(&digits[4..6], 16);
124 let a = u8::from_str_radix(&digits[6..8], 16);
125 match (r, g, b, a) {
126 (Ok(r), Ok(g), Ok(b), Ok(a)) => Ok(RColor::rgba(r, g, b, a)),
127 _ => Err(RError::new(
128 RErrorKind::Other,
129 format!("invalid hex color '{hex}': contains non-hex digits"),
130 )),
131 }
132 }
133 _ => Err(RError::new(
134 RErrorKind::Other,
135 format!(
136 "invalid hex color '{hex}': expected 6 or 8 hex digits after '#', got {}",
137 digits.len()
138 ),
139 )),
140 }
141 }
142
143 pub fn to_hex(&self) -> String {
145 if self.a == 255 {
146 format!("#{:02X}{:02X}{:02X}", self.r, self.g, self.b)
147 } else {
148 format!("#{:02X}{:02X}{:02X}{:02X}", self.r, self.g, self.b, self.a)
149 }
150 }
151}
152
153impl std::fmt::Display for RColor {
154 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
155 write!(f, "{}", self.to_hex())
156 }
157}
158
159pub const DEFAULT_PALETTE: [RColor; 8] = [
165 RColor::rgb(0, 0, 0), RColor::rgb(255, 0, 0), RColor::rgb(0, 205, 0), RColor::rgb(0, 0, 255), RColor::rgb(0, 255, 255), RColor::rgb(255, 0, 255), RColor::rgb(255, 255, 0), RColor::rgb(190, 190, 190), ];
174
175pub fn default_palette() -> Vec<RColor> {
177 DEFAULT_PALETTE.to_vec()
178}
179
180pub const NAMED_COLORS: &[(&str, (u8, u8, u8))] = &[
187 ("aliceblue", (240, 248, 255)),
188 ("antiquewhite", (250, 235, 215)),
189 ("antiquewhite1", (255, 239, 219)),
190 ("antiquewhite2", (238, 223, 204)),
191 ("antiquewhite3", (205, 192, 176)),
192 ("antiquewhite4", (139, 131, 120)),
193 ("aquamarine", (127, 255, 212)),
194 ("aquamarine1", (127, 255, 212)),
195 ("aquamarine2", (118, 238, 198)),
196 ("aquamarine3", (102, 205, 170)),
197 ("aquamarine4", (69, 139, 116)),
198 ("azure", (240, 255, 255)),
199 ("azure1", (240, 255, 255)),
200 ("azure2", (224, 238, 238)),
201 ("azure3", (193, 205, 205)),
202 ("azure4", (131, 139, 139)),
203 ("beige", (245, 245, 220)),
204 ("bisque", (255, 228, 196)),
205 ("bisque1", (255, 228, 196)),
206 ("bisque2", (238, 213, 183)),
207 ("bisque3", (205, 183, 158)),
208 ("bisque4", (139, 125, 107)),
209 ("black", (0, 0, 0)),
210 ("blanchedalmond", (255, 235, 205)),
211 ("blue", (0, 0, 255)),
212 ("blue1", (0, 0, 255)),
213 ("blue2", (0, 0, 238)),
214 ("blue3", (0, 0, 205)),
215 ("blue4", (0, 0, 139)),
216 ("blueviolet", (138, 43, 226)),
217 ("brown", (165, 42, 42)),
218 ("brown1", (255, 64, 64)),
219 ("brown2", (238, 59, 59)),
220 ("brown3", (205, 51, 51)),
221 ("brown4", (139, 35, 35)),
222 ("burlywood", (222, 184, 135)),
223 ("burlywood1", (255, 211, 155)),
224 ("burlywood2", (238, 197, 145)),
225 ("burlywood3", (205, 170, 125)),
226 ("burlywood4", (139, 115, 85)),
227 ("cadetblue", (95, 158, 160)),
228 ("cadetblue1", (152, 245, 255)),
229 ("cadetblue2", (142, 229, 238)),
230 ("cadetblue3", (122, 197, 205)),
231 ("cadetblue4", (83, 134, 139)),
232 ("chartreuse", (127, 255, 0)),
233 ("chartreuse1", (127, 255, 0)),
234 ("chartreuse2", (118, 238, 0)),
235 ("chartreuse3", (102, 205, 0)),
236 ("chartreuse4", (69, 139, 0)),
237 ("chocolate", (210, 105, 30)),
238 ("chocolate1", (255, 127, 36)),
239 ("chocolate2", (238, 118, 33)),
240 ("chocolate3", (205, 102, 29)),
241 ("chocolate4", (139, 69, 19)),
242 ("coral", (255, 127, 80)),
243 ("coral1", (255, 114, 86)),
244 ("coral2", (238, 106, 80)),
245 ("coral3", (205, 91, 69)),
246 ("coral4", (139, 62, 47)),
247 ("cornflowerblue", (100, 149, 237)),
248 ("cornsilk", (255, 248, 220)),
249 ("cornsilk1", (255, 248, 220)),
250 ("cornsilk2", (238, 232, 205)),
251 ("cornsilk3", (205, 200, 177)),
252 ("cornsilk4", (139, 136, 120)),
253 ("cyan", (0, 255, 255)),
254 ("cyan1", (0, 255, 255)),
255 ("cyan2", (0, 238, 238)),
256 ("cyan3", (0, 205, 205)),
257 ("cyan4", (0, 139, 139)),
258 ("darkblue", (0, 0, 139)),
259 ("darkcyan", (0, 139, 139)),
260 ("darkgoldenrod", (184, 134, 11)),
261 ("darkgoldenrod1", (255, 185, 15)),
262 ("darkgoldenrod2", (238, 173, 14)),
263 ("darkgoldenrod3", (205, 149, 12)),
264 ("darkgoldenrod4", (139, 101, 8)),
265 ("darkgray", (169, 169, 169)),
266 ("darkgreen", (0, 100, 0)),
267 ("darkgrey", (169, 169, 169)),
268 ("darkkhaki", (189, 183, 107)),
269 ("darkmagenta", (139, 0, 139)),
270 ("darkolivegreen", (85, 107, 47)),
271 ("darkolivegreen1", (202, 255, 112)),
272 ("darkolivegreen2", (188, 238, 104)),
273 ("darkolivegreen3", (162, 205, 90)),
274 ("darkolivegreen4", (110, 139, 61)),
275 ("darkorange", (255, 140, 0)),
276 ("darkorange1", (255, 127, 0)),
277 ("darkorange2", (238, 118, 0)),
278 ("darkorange3", (205, 102, 0)),
279 ("darkorange4", (139, 69, 0)),
280 ("darkorchid", (153, 50, 204)),
281 ("darkorchid1", (191, 62, 255)),
282 ("darkorchid2", (178, 58, 238)),
283 ("darkorchid3", (154, 50, 205)),
284 ("darkorchid4", (104, 34, 139)),
285 ("darkred", (139, 0, 0)),
286 ("darksalmon", (233, 150, 122)),
287 ("darkseagreen", (143, 188, 143)),
288 ("darkseagreen1", (193, 255, 193)),
289 ("darkseagreen2", (180, 238, 180)),
290 ("darkseagreen3", (155, 205, 155)),
291 ("darkseagreen4", (105, 139, 105)),
292 ("darkslateblue", (72, 61, 139)),
293 ("darkslategray", (47, 79, 79)),
294 ("darkslategray1", (151, 255, 255)),
295 ("darkslategray2", (141, 238, 238)),
296 ("darkslategray3", (121, 205, 205)),
297 ("darkslategray4", (82, 139, 139)),
298 ("darkslategrey", (47, 79, 79)),
299 ("darkturquoise", (0, 206, 209)),
300 ("darkviolet", (148, 0, 211)),
301 ("deeppink", (255, 20, 147)),
302 ("deeppink1", (255, 20, 147)),
303 ("deeppink2", (238, 18, 137)),
304 ("deeppink3", (205, 16, 118)),
305 ("deeppink4", (139, 10, 80)),
306 ("deepskyblue", (0, 191, 255)),
307 ("deepskyblue1", (0, 191, 255)),
308 ("deepskyblue2", (0, 178, 238)),
309 ("deepskyblue3", (0, 154, 205)),
310 ("deepskyblue4", (0, 104, 139)),
311 ("dimgray", (105, 105, 105)),
312 ("dimgrey", (105, 105, 105)),
313 ("dodgerblue", (30, 144, 255)),
314 ("dodgerblue1", (30, 144, 255)),
315 ("dodgerblue2", (28, 134, 238)),
316 ("dodgerblue3", (24, 116, 205)),
317 ("dodgerblue4", (16, 78, 139)),
318 ("firebrick", (178, 34, 34)),
319 ("firebrick1", (255, 48, 48)),
320 ("firebrick2", (238, 44, 44)),
321 ("firebrick3", (205, 38, 38)),
322 ("firebrick4", (139, 26, 26)),
323 ("floralwhite", (255, 250, 240)),
324 ("forestgreen", (34, 139, 34)),
325 ("gainsboro", (220, 220, 220)),
326 ("ghostwhite", (248, 248, 255)),
327 ("gold", (255, 215, 0)),
328 ("gold1", (255, 215, 0)),
329 ("gold2", (238, 201, 0)),
330 ("gold3", (205, 173, 0)),
331 ("gold4", (139, 117, 0)),
332 ("goldenrod", (218, 165, 32)),
333 ("goldenrod1", (255, 193, 37)),
334 ("goldenrod2", (238, 180, 34)),
335 ("goldenrod3", (205, 155, 29)),
336 ("goldenrod4", (139, 105, 20)),
337 ("gray", (190, 190, 190)),
338 ("gray0", (0, 0, 0)),
339 ("gray1", (3, 3, 3)),
340 ("gray10", (26, 26, 26)),
341 ("gray100", (255, 255, 255)),
342 ("gray11", (28, 28, 28)),
343 ("gray12", (31, 31, 31)),
344 ("gray13", (33, 33, 33)),
345 ("gray14", (36, 36, 36)),
346 ("gray15", (38, 38, 38)),
347 ("gray16", (41, 41, 41)),
348 ("gray17", (43, 43, 43)),
349 ("gray18", (46, 46, 46)),
350 ("gray19", (48, 48, 48)),
351 ("gray2", (5, 5, 5)),
352 ("gray20", (51, 51, 51)),
353 ("gray21", (54, 54, 54)),
354 ("gray22", (56, 56, 56)),
355 ("gray23", (59, 59, 59)),
356 ("gray24", (61, 61, 61)),
357 ("gray25", (64, 64, 64)),
358 ("gray26", (66, 66, 66)),
359 ("gray27", (69, 69, 69)),
360 ("gray28", (71, 71, 71)),
361 ("gray29", (74, 74, 74)),
362 ("gray3", (8, 8, 8)),
363 ("gray30", (77, 77, 77)),
364 ("gray31", (79, 79, 79)),
365 ("gray32", (82, 82, 82)),
366 ("gray33", (84, 84, 84)),
367 ("gray34", (87, 87, 87)),
368 ("gray35", (89, 89, 89)),
369 ("gray36", (92, 92, 92)),
370 ("gray37", (94, 94, 94)),
371 ("gray38", (97, 97, 97)),
372 ("gray39", (99, 99, 99)),
373 ("gray4", (10, 10, 10)),
374 ("gray40", (102, 102, 102)),
375 ("gray41", (105, 105, 105)),
376 ("gray42", (107, 107, 107)),
377 ("gray43", (110, 110, 110)),
378 ("gray44", (112, 112, 112)),
379 ("gray45", (115, 115, 115)),
380 ("gray46", (117, 117, 117)),
381 ("gray47", (120, 120, 120)),
382 ("gray48", (122, 122, 122)),
383 ("gray49", (125, 125, 125)),
384 ("gray5", (13, 13, 13)),
385 ("gray50", (127, 127, 127)),
386 ("gray51", (130, 130, 130)),
387 ("gray52", (133, 133, 133)),
388 ("gray53", (135, 135, 135)),
389 ("gray54", (138, 138, 138)),
390 ("gray55", (140, 140, 140)),
391 ("gray56", (143, 143, 143)),
392 ("gray57", (145, 145, 145)),
393 ("gray58", (148, 148, 148)),
394 ("gray59", (150, 150, 150)),
395 ("gray6", (15, 15, 15)),
396 ("gray60", (153, 153, 153)),
397 ("gray61", (156, 156, 156)),
398 ("gray62", (158, 158, 158)),
399 ("gray63", (161, 161, 161)),
400 ("gray64", (163, 163, 163)),
401 ("gray65", (166, 166, 166)),
402 ("gray66", (168, 168, 168)),
403 ("gray67", (171, 171, 171)),
404 ("gray68", (173, 173, 173)),
405 ("gray69", (176, 176, 176)),
406 ("gray7", (18, 18, 18)),
407 ("gray70", (179, 179, 179)),
408 ("gray71", (181, 181, 181)),
409 ("gray72", (184, 184, 184)),
410 ("gray73", (186, 186, 186)),
411 ("gray74", (189, 189, 189)),
412 ("gray75", (191, 191, 191)),
413 ("gray76", (194, 194, 194)),
414 ("gray77", (196, 196, 196)),
415 ("gray78", (199, 199, 199)),
416 ("gray79", (201, 201, 201)),
417 ("gray8", (20, 20, 20)),
418 ("gray80", (204, 204, 204)),
419 ("gray81", (207, 207, 207)),
420 ("gray82", (209, 209, 209)),
421 ("gray83", (212, 212, 212)),
422 ("gray84", (214, 214, 214)),
423 ("gray85", (217, 217, 217)),
424 ("gray86", (219, 219, 219)),
425 ("gray87", (222, 222, 222)),
426 ("gray88", (224, 224, 224)),
427 ("gray89", (227, 227, 227)),
428 ("gray9", (23, 23, 23)),
429 ("gray90", (229, 229, 229)),
430 ("gray91", (232, 232, 232)),
431 ("gray92", (235, 235, 235)),
432 ("gray93", (237, 237, 237)),
433 ("gray94", (240, 240, 240)),
434 ("gray95", (242, 242, 242)),
435 ("gray96", (245, 245, 245)),
436 ("gray97", (247, 247, 247)),
437 ("gray98", (250, 250, 250)),
438 ("gray99", (252, 252, 252)),
439 ("green", (0, 255, 0)),
440 ("green1", (0, 255, 0)),
441 ("green2", (0, 238, 0)),
442 ("green3", (0, 205, 0)),
443 ("green4", (0, 139, 0)),
444 ("greenyellow", (173, 255, 47)),
445 ("grey", (190, 190, 190)),
446 ("grey0", (0, 0, 0)),
447 ("grey1", (3, 3, 3)),
448 ("grey10", (26, 26, 26)),
449 ("grey100", (255, 255, 255)),
450 ("grey11", (28, 28, 28)),
451 ("grey12", (31, 31, 31)),
452 ("grey13", (33, 33, 33)),
453 ("grey14", (36, 36, 36)),
454 ("grey15", (38, 38, 38)),
455 ("grey16", (41, 41, 41)),
456 ("grey17", (43, 43, 43)),
457 ("grey18", (46, 46, 46)),
458 ("grey19", (48, 48, 48)),
459 ("grey2", (5, 5, 5)),
460 ("grey20", (51, 51, 51)),
461 ("grey21", (54, 54, 54)),
462 ("grey22", (56, 56, 56)),
463 ("grey23", (59, 59, 59)),
464 ("grey24", (61, 61, 61)),
465 ("grey25", (64, 64, 64)),
466 ("grey26", (66, 66, 66)),
467 ("grey27", (69, 69, 69)),
468 ("grey28", (71, 71, 71)),
469 ("grey29", (74, 74, 74)),
470 ("grey3", (8, 8, 8)),
471 ("grey30", (77, 77, 77)),
472 ("grey31", (79, 79, 79)),
473 ("grey32", (82, 82, 82)),
474 ("grey33", (84, 84, 84)),
475 ("grey34", (87, 87, 87)),
476 ("grey35", (89, 89, 89)),
477 ("grey36", (92, 92, 92)),
478 ("grey37", (94, 94, 94)),
479 ("grey38", (97, 97, 97)),
480 ("grey39", (99, 99, 99)),
481 ("grey4", (10, 10, 10)),
482 ("grey40", (102, 102, 102)),
483 ("grey41", (105, 105, 105)),
484 ("grey42", (107, 107, 107)),
485 ("grey43", (110, 110, 110)),
486 ("grey44", (112, 112, 112)),
487 ("grey45", (115, 115, 115)),
488 ("grey46", (117, 117, 117)),
489 ("grey47", (120, 120, 120)),
490 ("grey48", (122, 122, 122)),
491 ("grey49", (125, 125, 125)),
492 ("grey5", (13, 13, 13)),
493 ("grey50", (127, 127, 127)),
494 ("grey51", (130, 130, 130)),
495 ("grey52", (133, 133, 133)),
496 ("grey53", (135, 135, 135)),
497 ("grey54", (138, 138, 138)),
498 ("grey55", (140, 140, 140)),
499 ("grey56", (143, 143, 143)),
500 ("grey57", (145, 145, 145)),
501 ("grey58", (148, 148, 148)),
502 ("grey59", (150, 150, 150)),
503 ("grey6", (15, 15, 15)),
504 ("grey60", (153, 153, 153)),
505 ("grey61", (156, 156, 156)),
506 ("grey62", (158, 158, 158)),
507 ("grey63", (161, 161, 161)),
508 ("grey64", (163, 163, 163)),
509 ("grey65", (166, 166, 166)),
510 ("grey66", (168, 168, 168)),
511 ("grey67", (171, 171, 171)),
512 ("grey68", (173, 173, 173)),
513 ("grey69", (176, 176, 176)),
514 ("grey7", (18, 18, 18)),
515 ("grey70", (179, 179, 179)),
516 ("grey71", (181, 181, 181)),
517 ("grey72", (184, 184, 184)),
518 ("grey73", (186, 186, 186)),
519 ("grey74", (189, 189, 189)),
520 ("grey75", (191, 191, 191)),
521 ("grey76", (194, 194, 194)),
522 ("grey77", (196, 196, 196)),
523 ("grey78", (199, 199, 199)),
524 ("grey79", (201, 201, 201)),
525 ("grey8", (20, 20, 20)),
526 ("grey80", (204, 204, 204)),
527 ("grey81", (207, 207, 207)),
528 ("grey82", (209, 209, 209)),
529 ("grey83", (212, 212, 212)),
530 ("grey84", (214, 214, 214)),
531 ("grey85", (217, 217, 217)),
532 ("grey86", (219, 219, 219)),
533 ("grey87", (222, 222, 222)),
534 ("grey88", (224, 224, 224)),
535 ("grey89", (227, 227, 227)),
536 ("grey9", (23, 23, 23)),
537 ("grey90", (229, 229, 229)),
538 ("grey91", (232, 232, 232)),
539 ("grey92", (235, 235, 235)),
540 ("grey93", (237, 237, 237)),
541 ("grey94", (240, 240, 240)),
542 ("grey95", (242, 242, 242)),
543 ("grey96", (245, 245, 245)),
544 ("grey97", (247, 247, 247)),
545 ("grey98", (250, 250, 250)),
546 ("grey99", (252, 252, 252)),
547 ("honeydew", (240, 255, 240)),
548 ("honeydew1", (240, 255, 240)),
549 ("honeydew2", (224, 238, 224)),
550 ("honeydew3", (193, 205, 193)),
551 ("honeydew4", (131, 139, 131)),
552 ("hotpink", (255, 105, 180)),
553 ("hotpink1", (255, 110, 180)),
554 ("hotpink2", (238, 106, 167)),
555 ("hotpink3", (205, 96, 144)),
556 ("hotpink4", (139, 58, 98)),
557 ("indianred", (205, 92, 92)),
558 ("indianred1", (255, 106, 106)),
559 ("indianred2", (238, 99, 99)),
560 ("indianred3", (205, 85, 85)),
561 ("indianred4", (139, 58, 58)),
562 ("ivory", (255, 255, 240)),
563 ("ivory1", (255, 255, 240)),
564 ("ivory2", (238, 238, 224)),
565 ("ivory3", (205, 205, 193)),
566 ("ivory4", (139, 139, 131)),
567 ("khaki", (240, 230, 140)),
568 ("khaki1", (255, 246, 143)),
569 ("khaki2", (238, 230, 133)),
570 ("khaki3", (205, 198, 115)),
571 ("khaki4", (139, 134, 78)),
572 ("lavender", (230, 230, 250)),
573 ("lavenderblush", (255, 240, 245)),
574 ("lavenderblush1", (255, 240, 245)),
575 ("lavenderblush2", (238, 224, 229)),
576 ("lavenderblush3", (205, 193, 197)),
577 ("lavenderblush4", (139, 131, 134)),
578 ("lawngreen", (124, 252, 0)),
579 ("lemonchiffon", (255, 250, 205)),
580 ("lemonchiffon1", (255, 250, 205)),
581 ("lemonchiffon2", (238, 233, 191)),
582 ("lemonchiffon3", (205, 201, 165)),
583 ("lemonchiffon4", (139, 137, 112)),
584 ("lightblue", (173, 216, 230)),
585 ("lightblue1", (191, 239, 255)),
586 ("lightblue2", (178, 223, 238)),
587 ("lightblue3", (154, 192, 205)),
588 ("lightblue4", (104, 131, 139)),
589 ("lightcoral", (240, 128, 128)),
590 ("lightcyan", (224, 255, 255)),
591 ("lightcyan1", (224, 255, 255)),
592 ("lightcyan2", (209, 238, 238)),
593 ("lightcyan3", (180, 205, 205)),
594 ("lightcyan4", (122, 139, 139)),
595 ("lightgoldenrod", (238, 221, 130)),
596 ("lightgoldenrod1", (255, 236, 139)),
597 ("lightgoldenrod2", (238, 220, 130)),
598 ("lightgoldenrod3", (205, 190, 112)),
599 ("lightgoldenrod4", (139, 129, 76)),
600 ("lightgoldenrodyellow", (250, 250, 210)),
601 ("lightgray", (211, 211, 211)),
602 ("lightgreen", (144, 238, 144)),
603 ("lightgrey", (211, 211, 211)),
604 ("lightpink", (255, 182, 193)),
605 ("lightpink1", (255, 174, 185)),
606 ("lightpink2", (238, 162, 173)),
607 ("lightpink3", (205, 140, 149)),
608 ("lightpink4", (139, 95, 101)),
609 ("lightsalmon", (255, 160, 122)),
610 ("lightsalmon1", (255, 160, 122)),
611 ("lightsalmon2", (238, 149, 114)),
612 ("lightsalmon3", (205, 129, 98)),
613 ("lightsalmon4", (139, 87, 66)),
614 ("lightseagreen", (32, 178, 170)),
615 ("lightskyblue", (135, 206, 250)),
616 ("lightskyblue1", (176, 226, 255)),
617 ("lightskyblue2", (164, 211, 238)),
618 ("lightskyblue3", (141, 182, 205)),
619 ("lightskyblue4", (96, 123, 139)),
620 ("lightslateblue", (132, 112, 255)),
621 ("lightslategray", (119, 136, 153)),
622 ("lightslategrey", (119, 136, 153)),
623 ("lightsteelblue", (176, 196, 222)),
624 ("lightsteelblue1", (202, 225, 255)),
625 ("lightsteelblue2", (188, 210, 238)),
626 ("lightsteelblue3", (162, 181, 205)),
627 ("lightsteelblue4", (110, 123, 139)),
628 ("lightyellow", (255, 255, 224)),
629 ("lightyellow1", (255, 255, 224)),
630 ("lightyellow2", (238, 238, 209)),
631 ("lightyellow3", (205, 205, 180)),
632 ("lightyellow4", (139, 139, 122)),
633 ("limegreen", (50, 205, 50)),
634 ("linen", (250, 240, 230)),
635 ("magenta", (255, 0, 255)),
636 ("magenta1", (255, 0, 255)),
637 ("magenta2", (238, 0, 238)),
638 ("magenta3", (205, 0, 205)),
639 ("magenta4", (139, 0, 139)),
640 ("maroon", (176, 48, 96)),
641 ("maroon1", (255, 52, 179)),
642 ("maroon2", (238, 48, 167)),
643 ("maroon3", (205, 41, 144)),
644 ("maroon4", (139, 28, 98)),
645 ("mediumaquamarine", (102, 205, 170)),
646 ("mediumblue", (0, 0, 205)),
647 ("mediumorchid", (186, 85, 211)),
648 ("mediumorchid1", (224, 102, 255)),
649 ("mediumorchid2", (209, 95, 238)),
650 ("mediumorchid3", (180, 82, 205)),
651 ("mediumorchid4", (122, 55, 139)),
652 ("mediumpurple", (147, 112, 219)),
653 ("mediumpurple1", (171, 130, 255)),
654 ("mediumpurple2", (159, 121, 238)),
655 ("mediumpurple3", (137, 104, 205)),
656 ("mediumpurple4", (93, 71, 139)),
657 ("mediumseagreen", (60, 179, 113)),
658 ("mediumslateblue", (123, 104, 238)),
659 ("mediumspringgreen", (0, 250, 154)),
660 ("mediumturquoise", (72, 209, 204)),
661 ("mediumvioletred", (199, 21, 133)),
662 ("midnightblue", (25, 25, 112)),
663 ("mintcream", (245, 255, 250)),
664 ("mistyrose", (255, 228, 225)),
665 ("mistyrose1", (255, 228, 225)),
666 ("mistyrose2", (238, 213, 210)),
667 ("mistyrose3", (205, 183, 181)),
668 ("mistyrose4", (139, 125, 123)),
669 ("moccasin", (255, 228, 181)),
670 ("navajowhite", (255, 222, 173)),
671 ("navajowhite1", (255, 222, 173)),
672 ("navajowhite2", (238, 207, 161)),
673 ("navajowhite3", (205, 179, 139)),
674 ("navajowhite4", (139, 121, 94)),
675 ("navy", (0, 0, 128)),
676 ("navyblue", (0, 0, 128)),
677 ("oldlace", (253, 245, 230)),
678 ("olivedrab", (107, 142, 35)),
679 ("olivedrab1", (192, 255, 62)),
680 ("olivedrab2", (179, 238, 58)),
681 ("olivedrab3", (154, 205, 50)),
682 ("olivedrab4", (105, 139, 34)),
683 ("orange", (255, 165, 0)),
684 ("orange1", (255, 165, 0)),
685 ("orange2", (238, 154, 0)),
686 ("orange3", (205, 133, 0)),
687 ("orange4", (139, 90, 0)),
688 ("orangered", (255, 69, 0)),
689 ("orangered1", (255, 69, 0)),
690 ("orangered2", (238, 64, 0)),
691 ("orangered3", (205, 55, 0)),
692 ("orangered4", (139, 37, 0)),
693 ("orchid", (218, 112, 214)),
694 ("orchid1", (255, 131, 250)),
695 ("orchid2", (238, 122, 233)),
696 ("orchid3", (205, 105, 201)),
697 ("orchid4", (139, 71, 137)),
698 ("palegoldenrod", (238, 232, 170)),
699 ("palegreen", (152, 251, 152)),
700 ("palegreen1", (154, 255, 154)),
701 ("palegreen2", (144, 238, 144)),
702 ("palegreen3", (124, 205, 124)),
703 ("palegreen4", (84, 139, 84)),
704 ("paleturquoise", (175, 238, 238)),
705 ("paleturquoise1", (187, 255, 255)),
706 ("paleturquoise2", (174, 238, 238)),
707 ("paleturquoise3", (150, 205, 205)),
708 ("paleturquoise4", (102, 139, 139)),
709 ("palevioletred", (219, 112, 147)),
710 ("palevioletred1", (255, 130, 171)),
711 ("palevioletred2", (238, 121, 159)),
712 ("palevioletred3", (205, 104, 137)),
713 ("palevioletred4", (139, 71, 93)),
714 ("papayawhip", (255, 239, 213)),
715 ("peachpuff", (255, 218, 185)),
716 ("peachpuff1", (255, 218, 185)),
717 ("peachpuff2", (238, 203, 173)),
718 ("peachpuff3", (205, 175, 149)),
719 ("peachpuff4", (139, 119, 101)),
720 ("peru", (205, 133, 63)),
721 ("pink", (255, 192, 203)),
722 ("pink1", (255, 181, 197)),
723 ("pink2", (238, 169, 184)),
724 ("pink3", (205, 145, 158)),
725 ("pink4", (139, 99, 108)),
726 ("plum", (221, 160, 221)),
727 ("plum1", (255, 187, 255)),
728 ("plum2", (238, 174, 238)),
729 ("plum3", (205, 150, 205)),
730 ("plum4", (139, 102, 139)),
731 ("powderblue", (176, 224, 230)),
732 ("purple", (160, 32, 240)),
733 ("purple1", (155, 48, 255)),
734 ("purple2", (145, 44, 238)),
735 ("purple3", (125, 38, 205)),
736 ("purple4", (85, 26, 139)),
737 ("red", (255, 0, 0)),
738 ("red1", (255, 0, 0)),
739 ("red2", (238, 0, 0)),
740 ("red3", (205, 0, 0)),
741 ("red4", (139, 0, 0)),
742 ("rosybrown", (188, 143, 143)),
743 ("rosybrown1", (255, 193, 193)),
744 ("rosybrown2", (238, 180, 180)),
745 ("rosybrown3", (205, 155, 155)),
746 ("rosybrown4", (139, 105, 105)),
747 ("royalblue", (65, 105, 225)),
748 ("royalblue1", (72, 118, 255)),
749 ("royalblue2", (67, 110, 238)),
750 ("royalblue3", (58, 95, 205)),
751 ("royalblue4", (39, 64, 139)),
752 ("saddlebrown", (139, 69, 19)),
753 ("salmon", (250, 128, 114)),
754 ("salmon1", (255, 140, 105)),
755 ("salmon2", (238, 130, 98)),
756 ("salmon3", (205, 112, 84)),
757 ("salmon4", (139, 76, 57)),
758 ("sandybrown", (244, 164, 96)),
759 ("seagreen", (46, 139, 87)),
760 ("seagreen1", (84, 255, 159)),
761 ("seagreen2", (78, 238, 148)),
762 ("seagreen3", (67, 205, 128)),
763 ("seagreen4", (46, 139, 87)),
764 ("seashell", (255, 245, 238)),
765 ("seashell1", (255, 245, 238)),
766 ("seashell2", (238, 229, 222)),
767 ("seashell3", (205, 197, 191)),
768 ("seashell4", (139, 134, 130)),
769 ("sienna", (160, 82, 45)),
770 ("sienna1", (255, 130, 71)),
771 ("sienna2", (238, 121, 66)),
772 ("sienna3", (205, 104, 57)),
773 ("sienna4", (139, 71, 38)),
774 ("skyblue", (135, 206, 235)),
775 ("skyblue1", (135, 206, 255)),
776 ("skyblue2", (126, 192, 238)),
777 ("skyblue3", (108, 166, 205)),
778 ("skyblue4", (74, 112, 139)),
779 ("slateblue", (106, 90, 205)),
780 ("slateblue1", (131, 111, 255)),
781 ("slateblue2", (122, 103, 238)),
782 ("slateblue3", (105, 89, 205)),
783 ("slateblue4", (71, 60, 139)),
784 ("slategray", (112, 128, 144)),
785 ("slategray1", (198, 226, 255)),
786 ("slategray2", (185, 211, 238)),
787 ("slategray3", (159, 182, 205)),
788 ("slategray4", (108, 123, 139)),
789 ("slategrey", (112, 128, 144)),
790 ("snow", (255, 250, 250)),
791 ("snow1", (255, 250, 250)),
792 ("snow2", (238, 233, 233)),
793 ("snow3", (205, 201, 201)),
794 ("snow4", (139, 137, 137)),
795 ("springgreen", (0, 255, 127)),
796 ("springgreen1", (0, 255, 127)),
797 ("springgreen2", (0, 238, 118)),
798 ("springgreen3", (0, 205, 102)),
799 ("springgreen4", (0, 139, 69)),
800 ("steelblue", (70, 130, 180)),
801 ("steelblue1", (99, 184, 255)),
802 ("steelblue2", (92, 172, 238)),
803 ("steelblue3", (79, 148, 205)),
804 ("steelblue4", (54, 100, 139)),
805 ("tan", (210, 180, 140)),
806 ("tan1", (255, 165, 79)),
807 ("tan2", (238, 154, 73)),
808 ("tan3", (205, 133, 63)),
809 ("tan4", (139, 90, 43)),
810 ("thistle", (216, 191, 216)),
811 ("thistle1", (255, 225, 255)),
812 ("thistle2", (238, 210, 238)),
813 ("thistle3", (205, 181, 205)),
814 ("thistle4", (139, 123, 139)),
815 ("tomato", (255, 99, 71)),
816 ("tomato1", (255, 99, 71)),
817 ("tomato2", (238, 92, 66)),
818 ("tomato3", (205, 79, 57)),
819 ("tomato4", (139, 54, 38)),
820 ("turquoise", (64, 224, 208)),
821 ("turquoise1", (0, 245, 255)),
822 ("turquoise2", (0, 229, 238)),
823 ("turquoise3", (0, 197, 205)),
824 ("turquoise4", (0, 134, 139)),
825 ("violet", (238, 130, 238)),
826 ("violetred", (208, 32, 144)),
827 ("violetred1", (255, 62, 150)),
828 ("violetred2", (238, 58, 140)),
829 ("violetred3", (205, 50, 120)),
830 ("violetred4", (139, 34, 82)),
831 ("wheat", (245, 222, 179)),
832 ("wheat1", (255, 231, 186)),
833 ("wheat2", (238, 216, 174)),
834 ("wheat3", (205, 186, 150)),
835 ("wheat4", (139, 126, 102)),
836 ("white", (255, 255, 255)),
837 ("whitesmoke", (245, 245, 245)),
838 ("yellow", (255, 255, 0)),
839 ("yellow1", (255, 255, 0)),
840 ("yellow2", (238, 238, 0)),
841 ("yellow3", (205, 205, 0)),
842 ("yellow4", (139, 139, 0)),
843 ("yellowgreen", (154, 205, 50)),
844];
845
846#[builtin(name = "colors", names = ["colours"], namespace = "grDevices")]
856fn builtin_colors(_args: &[RValue], _named: &[(String, RValue)]) -> Result<RValue, RError> {
857 let names: Vec<Option<String>> = NAMED_COLORS
858 .iter()
859 .map(|&(name, _)| Some(name.to_string()))
860 .collect();
861 Ok(RValue::vec(Vector::Character(names.into())))
862}
863
864#[interpreter_builtin(namespace = "grDevices")]
873fn interp_col2rgb(
874 args: &[RValue],
875 named: &[(String, RValue)],
876 ctx: &BuiltinContext,
877) -> Result<RValue, RError> {
878 use crate::interpreter::builtins::CallArgs;
879 let call_args = CallArgs::new(args, named);
880
881 let col_val = call_args
882 .value("col", 0)
883 .ok_or_else(|| RError::new(RErrorKind::Argument, "'col' argument is required"))?;
884
885 let alpha = call_args.logical_flag("alpha", 1, false);
886
887 let palette = ctx.interpreter().color_palette.borrow();
888
889 let color_specs: Vec<String> = match col_val {
891 RValue::Vector(rv) => match &rv.inner {
892 Vector::Character(chars) => chars
893 .iter()
894 .map(|s| s.clone().unwrap_or_else(|| "NA".to_string()))
895 .collect(),
896 Vector::Integer(ints) => ints
897 .iter_opt()
898 .map(|i| format!("{}", i.unwrap_or(0)))
899 .collect(),
900 Vector::Double(doubles) => doubles
901 .iter_opt()
902 .map(|d| format!("{}", d.map(|v| v as i64).unwrap_or(0)))
903 .collect(),
904 _ => {
905 return Err(RError::new(
906 RErrorKind::Argument,
907 "invalid color specification",
908 ))
909 }
910 },
911 RValue::Null => {
912 return Err(RError::new(
913 RErrorKind::Argument,
914 "'col' argument is required",
915 ))
916 }
917 _ => {
918 return Err(RError::new(
919 RErrorKind::Argument,
920 "invalid color specification",
921 ))
922 }
923 };
924
925 let n = color_specs.len();
926 let nrow = if alpha { 4 } else { 3 };
927
928 let mut data: Vec<Option<i64>> = Vec::with_capacity(nrow * n);
929
930 for spec in &color_specs {
932 if spec == "NA" {
933 for _ in 0..nrow {
934 data.push(None);
935 }
936 } else {
937 let color = RColor::from_r_value(spec, &palette)?;
938 data.push(Some(i64::from(color.r)));
939 data.push(Some(i64::from(color.g)));
940 data.push(Some(i64::from(color.b)));
941 if alpha {
942 data.push(Some(i64::from(color.a)));
943 }
944 }
945 }
946
947 let mut rv = RVector::from(Vector::Integer(data.into()));
948
949 rv.set_attr(
951 "dim".to_string(),
952 RValue::vec(Vector::Integer(
953 vec![
954 Some(i64::try_from(nrow).unwrap_or(3)),
955 Some(i64::try_from(n).unwrap_or(0)),
956 ]
957 .into(),
958 )),
959 );
960
961 let row_names = if alpha {
963 vec![
964 Some("red".to_string()),
965 Some("green".to_string()),
966 Some("blue".to_string()),
967 Some("alpha".to_string()),
968 ]
969 } else {
970 vec![
971 Some("red".to_string()),
972 Some("green".to_string()),
973 Some("blue".to_string()),
974 ]
975 };
976
977 let colnames: Vec<Option<String>> = color_specs.iter().map(|s| Some(s.clone())).collect();
979 let dimnames = RList::new(vec![
980 (None, RValue::vec(Vector::Character(row_names.into()))),
981 (
982 None,
983 if colnames.is_empty() {
984 RValue::Null
985 } else {
986 RValue::vec(Vector::Character(colnames.into()))
987 },
988 ),
989 ]);
990 rv.set_attr("dimnames".to_string(), RValue::List(dimnames));
991
992 Ok(RValue::Vector(rv))
993}
994
995#[builtin(namespace = "grDevices")]
1004fn builtin_rgb(args: &[RValue], named: &[(String, RValue)]) -> Result<RValue, RError> {
1005 use crate::interpreter::builtins::CallArgs;
1006 let call_args = CallArgs::new(args, named);
1007
1008 let max_val = call_args
1009 .value("maxColorValue", 4)
1010 .and_then(|v: &RValue| v.as_vector()?.as_double_scalar())
1011 .unwrap_or(1.0);
1012
1013 if max_val <= 0.0 {
1014 return Err(RError::new(
1015 RErrorKind::Other,
1016 "'maxColorValue' must be positive",
1017 ));
1018 }
1019
1020 let reds = get_double_vec(call_args.value("red", 0), "red")?;
1022 let greens = get_double_vec(call_args.value("green", 1), "green")?;
1023 let blues = get_double_vec(call_args.value("blue", 2), "blue")?;
1024 let alphas = match call_args.value("alpha", 3) {
1025 Some(v) => get_double_vec(Some(v), "alpha")?,
1026 None => vec![max_val], };
1028
1029 let names = call_args.value("names", 5);
1031
1032 let n = reds
1034 .len()
1035 .max(greens.len())
1036 .max(blues.len())
1037 .max(alphas.len());
1038
1039 let has_alpha_arg = call_args.value("alpha", 3).is_some();
1040
1041 let mut result: Vec<Option<String>> = Vec::with_capacity(n);
1042 for i in 0..n {
1043 let r = reds[i % reds.len()];
1044 let g = greens[i % greens.len()];
1045 let b = blues[i % blues.len()];
1046 let a = alphas[i % alphas.len()];
1047
1048 let r8 = clamp_to_u8(r / max_val * 255.0);
1049 let g8 = clamp_to_u8(g / max_val * 255.0);
1050 let b8 = clamp_to_u8(b / max_val * 255.0);
1051 let a8 = clamp_to_u8(a / max_val * 255.0);
1052
1053 if has_alpha_arg || a8 != 255 {
1054 result.push(Some(format!("#{:02X}{:02X}{:02X}{:02X}", r8, g8, b8, a8)));
1055 } else {
1056 result.push(Some(format!("#{:02X}{:02X}{:02X}", r8, g8, b8)));
1057 }
1058 }
1059
1060 let mut rv = RVector::from(Vector::Character(result.into()));
1061
1062 if let Some(RValue::Vector(nv)) = names {
1064 if let Vector::Character(names_chars) = &nv.inner {
1065 rv.set_attr(
1066 "names".to_string(),
1067 RValue::vec(Vector::Character(names_chars.clone())),
1068 );
1069 }
1070 }
1071
1072 Ok(RValue::Vector(rv))
1073}
1074
1075#[interpreter_builtin(namespace = "grDevices")]
1084fn interp_palette(
1085 args: &[RValue],
1086 _named: &[(String, RValue)],
1087 ctx: &BuiltinContext,
1088) -> Result<RValue, RError> {
1089 let old_palette = ctx.interpreter().color_palette.borrow().clone();
1090 let old_hex: Vec<Option<String>> = old_palette.iter().map(|c| Some(c.to_hex())).collect();
1091
1092 if let Some(val) = args.first() {
1093 match val {
1094 RValue::Null => {
1095 }
1097 RValue::Vector(rv) => match &rv.inner {
1098 Vector::Character(chars) => {
1099 if chars.len() == 1 {
1101 if let Some(Some(s)) = chars.first() {
1102 if s == "default" {
1103 *ctx.interpreter().color_palette.borrow_mut() =
1104 DEFAULT_PALETTE.to_vec();
1105 return Ok(RValue::vec(Vector::Character(old_hex.into())));
1106 }
1107 }
1108 }
1109 let mut new_palette = Vec::with_capacity(chars.len());
1111 let current = ctx.interpreter().color_palette.borrow().clone();
1112 for spec in chars.iter() {
1113 match spec {
1114 Some(s) => new_palette.push(RColor::from_r_value(s, ¤t)?),
1115 None => {
1116 return Err(RError::new(
1117 RErrorKind::Other,
1118 "NA is not a valid color specification",
1119 ))
1120 }
1121 }
1122 }
1123 *ctx.interpreter().color_palette.borrow_mut() = new_palette;
1124 }
1125 _ => {
1126 return Err(RError::new(
1127 RErrorKind::Argument,
1128 "palette() requires a character vector",
1129 ))
1130 }
1131 },
1132 _ => {
1133 return Err(RError::new(
1134 RErrorKind::Argument,
1135 "palette() requires a character vector",
1136 ))
1137 }
1138 }
1139 }
1140
1141 Ok(RValue::vec(Vector::Character(old_hex.into())))
1142}
1143
1144fn get_double_vec(val: Option<&RValue>, name: &str) -> Result<Vec<f64>, RError> {
1150 match val {
1151 Some(RValue::Vector(rv)) => {
1152 let doubles = rv.inner.to_doubles();
1153 let result: Vec<f64> = doubles
1154 .iter()
1155 .map(|d| {
1156 d.ok_or_else(|| {
1157 RError::new(
1158 RErrorKind::Other,
1159 format!("NA value in '{name}' is not allowed"),
1160 )
1161 })
1162 })
1163 .collect::<Result<Vec<_>, _>>()?;
1164 Ok(result)
1165 }
1166 Some(RValue::Null) | None => Err(RError::new(
1167 RErrorKind::Argument,
1168 format!("argument '{name}' is missing, with no default"),
1169 )),
1170 _ => Err(RError::new(
1171 RErrorKind::Argument,
1172 format!("invalid '{name}' argument"),
1173 )),
1174 }
1175}
1176
1177fn clamp_to_u8(val: f64) -> u8 {
1179 if val <= 0.0 {
1180 0
1181 } else if val >= 255.0 {
1182 255
1183 } else {
1184 val.round() as u8
1185 }
1186}
1187
1188