1use crate::buffer2d::Buffer2D;
29use crate::math::{Vec2, Vec3f};
30
31use std::ops::{Index, IndexMut};
32use std::fmt;
33use std::path::Path;
34
35
36use image::io::Reader as ImageReader;
37use image::{Pixel, RgbImage};
38use palette::{LinSrgb, Okhsl, Srgb};
39use palette::convert::FromColor;
40
41
42#[derive(Clone, Copy, Debug, PartialEq, Eq)]
43pub enum BlendMode {
44 Add
45}
46
47
48#[derive(Clone, Copy, Debug, PartialEq, Eq)]
57pub struct Color {
58 pub r: u8,
59 pub g: u8,
60 pub b: u8
61}
62
63
64impl Color {
65
66 pub const ALICE_BLUE : Color = Color::hex(0xeff7ff);
67 pub const ANTIQUE_WHITE : Color = Color::hex(0xf9ebd6);
68 pub const AQUA : Color = Color::hex(0x00ffff);
69 pub const AQUAMARINE : Color = Color::hex(0x7effd4);
70 pub const AZURE : Color = Color::hex(0xefffff);
71 pub const BEIGE : Color = Color::hex(0xf4f4db);
72 pub const BISQUE : Color = Color::hex(0xffe4c3);
73 pub const BLACK : Color = Color::hex(0x000000);
74 pub const BLANCHED_ALMOND : Color = Color::hex(0xffebcd);
75 pub const BLUE : Color = Color::hex(0x0000ff);
76 pub const BLUE_VIOLET : Color = Color::hex(0x892ae2);
77 pub const BROWN : Color = Color::hex(0xa52a2a);
78 pub const BURLYWOOD : Color = Color::hex(0xddb887);
79 pub const CADET_BLUE : Color = Color::hex(0x5e9ea0);
80 pub const CHARTREUSE : Color = Color::hex(0x7eff00);
81 pub const CHOCOLATE : Color = Color::hex(0xd1691d);
82 pub const CORAL : Color = Color::hex(0xff7e50);
83 pub const CORNFLOWER_BLUE : Color = Color::hex(0x6495ed);
84 pub const CORNSILK : Color = Color::hex(0xfff7db);
85 pub const CRIMSON : Color = Color::hex(0xdb143b);
86 pub const CYAN : Color = Color::hex(0x00ffff);
87 pub const DARK_BLUE : Color = Color::hex(0x00008a);
88 pub const DARK_CYAN : Color = Color::hex(0x008a8a);
89 pub const DARK_GOLDENROD : Color = Color::hex(0xb8850b);
90 pub const DARK_GRAY : Color = Color::hex(0xa8a8a8);
91 pub const DARK_GREEN : Color = Color::hex(0x006400);
92 pub const DARK_KHAKI : Color = Color::hex(0xbcb66b);
93 pub const DARK_MAGENTA : Color = Color::hex(0x8a008a);
94 pub const DARK_OLIVE_GREEN : Color = Color::hex(0x546b2f);
95 pub const DARK_ORANGE : Color = Color::hex(0xff8c00);
96 pub const DARK_ORCHID : Color = Color::hex(0x9931cc);
97 pub const DARK_RED : Color = Color::hex(0x8a0000);
98 pub const DARK_SALMON : Color = Color::hex(0xe89579);
99 pub const DARK_SEA_GREEN : Color = Color::hex(0x8ebc8e);
100 pub const DARK_SLATE_BLUE : Color = Color::hex(0x483d8a);
101 pub const DARK_SLATE_GRAY : Color = Color::hex(0x2f4f4f);
102 pub const DARK_TURQUOISE : Color = Color::hex(0x00cdd1);
103 pub const DARK_VIOLET : Color = Color::hex(0x9300d3);
104 pub const DEEP_PINK : Color = Color::hex(0xff1493);
105 pub const DEEP_SKY_BLUE : Color = Color::hex(0x00bfff);
106 pub const DIM_GRAY : Color = Color::hex(0x696969);
107 pub const DODGER_BLUE : Color = Color::hex(0x1d90ff);
108 pub const FIREBRICK : Color = Color::hex(0xb12121);
109 pub const FLORAL_WHITE : Color = Color::hex(0xfff9ef);
110 pub const FOREST_GREEN : Color = Color::hex(0x218a21);
111 pub const FUCHSIA : Color = Color::hex(0xff00ff);
112 pub const GAINSBORO : Color = Color::hex(0xdbdbdb);
113 pub const GHOST_WHITE : Color = Color::hex(0xf7f7ff);
114 pub const GOLD : Color = Color::hex(0xffd600);
115 pub const GOLDENROD : Color = Color::hex(0xdaa51f);
116 pub const GRAY : Color = Color::hex(0xbdbdbd);
117 pub const GREEN : Color = Color::hex(0x00ff00);
118 pub const GREEN_YELLOW : Color = Color::hex(0xacff2f);
119 pub const HONEYDEW : Color = Color::hex(0xefffef);
120 pub const HOT_PINK : Color = Color::hex(0xff69b3);
121 pub const INDIAN_RED : Color = Color::hex(0xcd5b5b);
122 pub const INDIGO : Color = Color::hex(0x4b0082);
123 pub const IVORY : Color = Color::hex(0xffffef);
124 pub const KHAKI : Color = Color::hex(0xefe68c);
125 pub const LAVENDER : Color = Color::hex(0xe6e6f9);
126 pub const LAVENDER_BLUSH : Color = Color::hex(0xffeff4);
127 pub const LAWN_GREEN : Color = Color::hex(0x7cfb00);
128 pub const LEMON_CHIFFON : Color = Color::hex(0xfff9cd);
129 pub const LIGHT_BLUE : Color = Color::hex(0xacd8e6);
130 pub const LIGHT_CORAL : Color = Color::hex(0xef8080);
131 pub const LIGHT_CYAN : Color = Color::hex(0xdfffff);
132 pub const LIGHT_GOLDENROD : Color = Color::hex(0xf9f9d1);
133 pub const LIGHT_GRAY : Color = Color::hex(0xd3d3d3);
134 pub const LIGHT_GREEN : Color = Color::hex(0x90ed90);
135 pub const LIGHT_PINK : Color = Color::hex(0xffb6c1);
136 pub const LIGHT_SALMON : Color = Color::hex(0xffa079);
137 pub const LIGHT_SEA_GREEN : Color = Color::hex(0x1fb1aa);
138 pub const LIGHT_SKY_BLUE : Color = Color::hex(0x87cdf9);
139 pub const LIGHT_SLATE_GRAY : Color = Color::hex(0x778799);
140 pub const LIGHT_STEEL_BLUE : Color = Color::hex(0xafc3dd);
141 pub const LIGHT_YELLOW : Color = Color::hex(0xffffdf);
142 pub const LIME : Color = Color::hex(0x00ff00);
143 pub const LIME_GREEN : Color = Color::hex(0x31cd31);
144 pub const LINEN : Color = Color::hex(0xf9efe6);
145 pub const MAGENTA : Color = Color::hex(0xff00ff);
146 pub const MAROON : Color = Color::hex(0xaf2f60);
147 pub const MEDIUM_AQUAMARINE : Color = Color::hex(0x66cdaa);
148 pub const MEDIUM_BLUE : Color = Color::hex(0x0000cd);
149 pub const MEDIUM_ORCHID : Color = Color::hex(0xba54d3);
150 pub const MEDIUM_PURPLE : Color = Color::hex(0x9370db);
151 pub const MEDIUM_SEA_GREEN : Color = Color::hex(0x3bb370);
152 pub const MEDIUM_SLATE_BLUE : Color = Color::hex(0x7b67ed);
153 pub const MEDIUM_SPRING_GREEN: Color = Color::hex(0x00f99a);
154 pub const MEDIUM_TURQUOISE : Color = Color::hex(0x48d1cc);
155 pub const MEDIUM_VIOLET_RED : Color = Color::hex(0xc61485);
156 pub const MIDNIGHT_BLUE : Color = Color::hex(0x181870);
157 pub const MINT_CREAM : Color = Color::hex(0xf4fff9);
158 pub const MISTY_ROSE : Color = Color::hex(0xffe4e1);
159 pub const MOCCASIN : Color = Color::hex(0xffe4b5);
160 pub const NAVAJO_WHITE : Color = Color::hex(0xffddac);
161 pub const NAVY_BLUE : Color = Color::hex(0x000080);
162 pub const OLD_LACE : Color = Color::hex(0xfdf4e6);
163 pub const OLIVE : Color = Color::hex(0x808000);
164 pub const OLIVE_DRAB : Color = Color::hex(0x6b8e23);
165 pub const ORANGE : Color = Color::hex(0xffa500);
166 pub const ORANGE_RED : Color = Color::hex(0xff4400);
167 pub const ORCHID : Color = Color::hex(0xda70d6);
168 pub const PALE_GOLDENROD : Color = Color::hex(0xede8aa);
169 pub const PALE_GREEN : Color = Color::hex(0x97fb97);
170 pub const PALE_TURQUOISE : Color = Color::hex(0xafeded);
171 pub const PALE_VIOLET_RED : Color = Color::hex(0xdb7093);
172 pub const PAPAYA_WHIP : Color = Color::hex(0xffefd4);
173 pub const PEACH_PUFF : Color = Color::hex(0xffdab8);
174 pub const PERU : Color = Color::hex(0xcd853f);
175 pub const PINK : Color = Color::hex(0xffbfca);
176 pub const PLUM : Color = Color::hex(0xdda0dd);
177 pub const POWDER_BLUE : Color = Color::hex(0xafdfe6);
178 pub const PURPLE : Color = Color::hex(0xa01fef);
179 pub const REBECCA_PURPLE : Color = Color::hex(0x663399);
180 pub const RED : Color = Color::hex(0xff0000);
181 pub const ROSY_BROWN : Color = Color::hex(0xbc8e8e);
182 pub const ROYAL_BLUE : Color = Color::hex(0x4169e1);
183 pub const SADDLE_BROWN : Color = Color::hex(0x8a4412);
184 pub const SALMON : Color = Color::hex(0xf98072);
185 pub const SANDY_BROWN : Color = Color::hex(0xf4a360);
186 pub const SEA_GREEN : Color = Color::hex(0x2d8a56);
187 pub const SEASHELL : Color = Color::hex(0xfff4ed);
188 pub const SIENNA : Color = Color::hex(0xa0522d);
189 pub const SILVER : Color = Color::hex(0xbfbfbf);
190 pub const SKY_BLUE : Color = Color::hex(0x87cdeb);
191 pub const SLATE_BLUE : Color = Color::hex(0x6959cd);
192 pub const SLATE_GRAY : Color = Color::hex(0x708090);
193 pub const SNOW : Color = Color::hex(0xfff9f9);
194 pub const SPRING_GREEN : Color = Color::hex(0x00ff7e);
195 pub const STEEL_BLUE : Color = Color::hex(0x4682b3);
196 pub const TAN : Color = Color::hex(0xd1b38c);
197 pub const TEAL : Color = Color::hex(0x008080);
198 pub const THISTLE : Color = Color::hex(0xd8bfd8);
199 pub const TOMATO : Color = Color::hex(0xff6246);
200 pub const TRANSPARENT : Color = Color::hex(0xffffff);
201 pub const TURQUOISE : Color = Color::hex(0x3fdfcf);
202 pub const VIOLET : Color = Color::hex(0xed82ed);
203 pub const WEB_GRAY : Color = Color::hex(0x808080);
204 pub const WEB_GREEN : Color = Color::hex(0x008000);
205 pub const WEB_MAROON : Color = Color::hex(0x800000);
206 pub const WEB_PURPLE : Color = Color::hex(0x800080);
207 pub const WHEAT : Color = Color::hex(0xf4ddb3);
208 pub const WHITE : Color = Color::hex(0xffffff);
209 pub const WHITE_SMOKE : Color = Color::hex(0xf4f4f4);
210 pub const YELLOW : Color = Color::hex(0xffff00);
211 pub const YELLOW_GREEN : Color = Color::hex(0x9acd31);
212
213
214 pub const fn rgb(r: u8, g: u8, b: u8) -> Self {
216 Self {
217 r: r,
218 g: g,
219 b: b
220 }
221 }
222
223
224 pub const fn hex(h: u32) -> Self {
226 Self {
227 r: ((h & 0x00FF0000) / 0x00010000) as u8,
228 g: ((h & 0x0000FF00) / 0x00000100) as u8,
229 b: ((h & 0x000000FF) / 0x00000001) as u8
230 }
231 }
232
233
234 pub fn raw_rgb(r: f32, g: f32, b: f32) -> Self {
235 Self {
236 r: (r * 255.0).clamp(0.0, 255.0) as u8,
237 g: (g * 255.0).clamp(0.0, 255.0) as u8,
238 b: (b * 255.0).clamp(0.0, 255.0) as u8
239 }
240 }
241
242
243 pub fn raw_vec3_rgb(c: Vec3f) -> Self {
244 Self::raw_rgb(c.x, c.y, c.z)
245 }
246
247
248 pub fn okhsl(h: f32, s: f32, l: f32) -> Self {
249 let okhsl = Okhsl::new(h, s, l);
250 let srgb = Srgb::from_color(okhsl);
251 let rgb = srgb.into_linear();
252 Self::raw_rgb(rgb.red, rgb.green, rgb.blue)
253 }
254
255
256 pub fn get_raw(&self) -> (f32, f32, f32) {
257 (self.r as f32 / 255.0, self.g as f32 / 255.0, self.b as f32 / 255.0)
258 }
259
260
261 pub fn get_raw_vec3f(&self) -> Vec3f {
262 let (r, g, b) = self.get_raw();
263 Vec3f::new(r, g, b)
264 }
265
266
267 pub fn get_okhsl(&self) -> (f32, f32, f32) {
268 let (r, g, b) = self.get_raw();
269 let okhsl: Okhsl = Okhsl::from_color(LinSrgb::new(r, g, b));
270 (okhsl.hue.into_inner(), okhsl.saturation, okhsl.lightness)
271 }
272
273
274 pub fn blend(a: Color, b: Color, mode: BlendMode) -> Self {
275 match mode {
276 BlendMode::Add => {
277 Self::raw_vec3_rgb((a.get_raw_vec3f() + b.get_raw_vec3f()) / 2.0)
278 }
279 }
280 }
281}
282
283
284impl fmt::Display for Color {
285
286 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
288 if f.sign_minus() {
290 write!(f, "\x1b[48;2;{};{};{}m", self.r, self.g, self.b)
291 } else {
292 write!(f, "\x1b[38;2;{};{};{}m", self.r, self.g, self.b)
293 }
294 }
295}
296
297
298#[derive(Clone)]
299pub struct Image {
302 data: Buffer2D<Color>
303}
304
305
306impl Image {
307
308 pub fn new<V>(size: V) -> Self
310 where V: AsRef<Vec2>
311 {
312 Self {
313 data: Buffer2D::new(*size.as_ref(), Color::BLACK)
314 }
315 }
316
317
318 pub fn load<P>(path: P) -> Result<Self, String>
320 where P: AsRef<Path> {
321 let img = match ImageReader::open(path) {
322 Ok(s) => match s.decode() {
323 Ok(img) => img,
324 Err(e) => return Err(format!("{}", e))
325 }
326 Err(e) => return Err(format!("{}", e))
327 }.to_rgb8();
328 let mut result = Image::new(vec2!(img.width(), img.height()));
329 for i in 0..img.width() {
330 for j in 0..img.height() {
331 let px = img.get_pixel(i, j).channels();
332 result[vec2!(i as i32, j as i32)] = Color::rgb(px[0], px[1], px[2]);
333 }
334 }
335 Ok(result)
336 }
337
338
339 pub fn save<P>(&self, path: P) -> Result<(), String>
341 where P: AsRef<Path> {
342 let mut img = RgbImage::new(self.size().x as u32, self.size().y as u32);
343 for i in 0..self.size().x {
344 for j in 0..self.size().y {
345 let pix = img.get_pixel_mut(i as u32, j as u32);
346 let c = self[vec2!(i, j)];
347 pix.0 = [c.r, c.g, c.b];
348 }
349 }
350 match img.save(path) {
351 Ok(_) => Ok(()),
352 Err(e) => Err(format!("{}", e))
353 }
354 }
355
356
357
358 pub fn size(&self) -> Vec2 {
360 self.data.size()
361 }
362
363
364 pub fn raw_resize<A>(&mut self, new_size: A)
367 where A: AsRef<Vec2>
368 {
369 self.data.raw_resize(*new_size.as_ref(), Color::BLACK);
370 }
371
372
373 pub fn resize<A>(&mut self, new_size: A)
375 where A: AsRef<Vec2>
376 {
377 self.data.resize(*new_size.as_ref(), Color::BLACK);
378 }
379
380
381 fn is_out_of_range<A>(&self, p: A) -> bool
382 where A: AsRef<Vec2>
383 {
384 let p = p.as_ref();
385 p.x < 0 || p.y < 0 || p.x >= self.size().x || p.y >= self.size().y
386 }
387
388
389 pub fn point<A>(&mut self, p: A, c: Color)
391 where A: AsRef<Vec2>
392 {
393 self[*p.as_ref()] = c;
394 }
395
396
397 pub fn line<A, B>(&mut self, p1: A, p2: B, c: Color)
399 where A: AsRef<Vec2>, B: AsRef<Vec2>
400 {
401 let mut p1 = *p1.as_ref();
402 let p2 = p2.as_ref();
403
404 let dx = (p2.x - p1.x).abs();
405 let sx = if p1.x < p2.x {1} else {-1};
406 let dy = -(p2.y - p1.y).abs();
407 let sy = if p1.y < p2.y {1} else {-1};
408
409 let mut err = dx + dy;
410
411 self[p1] = c;
412
413 while (p1.x != p2.x || p1.y != p2.y)
414 && ((p1.x < self.size().x && sx > 0) || (p1.x >= 0 && sx < 0))
415 && ((p1.y < self.size().y && sy > 0) || (p1.y >= 0 && sy < 0))
416 {
417 let e2 = 2 * err;
418 if e2 >= dy {
419 err += dy;
420 p1.x += sx;
421 }
422 if e2 <= dx {
423 err += dx;
424 p1.y += sy;
425 }
426
427 self[p1] = c;
428 }
429 }
430
431
432 pub fn rect_boudary<A, B>(&mut self, p: A, s: B, c: Color)
434 where A: AsRef<Vec2>, B: AsRef<Vec2>
435 {
436 let p = p.as_ref();
437 let s = s.as_ref();
438 self.line((p.x , p.y ), (p.x + s.x, p.y ), c);
439 self.line((p.x + s.x, p.y ), (p.x + s.x, p.y + s.y), c);
440 self.line((p.x + s.x, p.y + s.y), (p.x , p.y + s.y), c);
441 self.line((p.x , p.y + s.y), (p.x , p.y ), c);
442 }
443
444
445 pub fn rect<A, B>(&mut self, p: A, s: B, c: Color)
448 where A: AsRef<Vec2>, B: AsRef<Vec2>
449 {
450 let mut p = *p.as_ref();
451 let mut s = *s.as_ref();
452
453 if p.x < 0 {
454 s.x += p.x - 1;
455 p.x = 0;
456 }
457 if p.y < 0 {
458 s.y += p.y - 1;
459 p.y = 0;
460 }
461
462 let dx = if s.x > 0 {1} else {-1};
463 let dy = if s.y > 0 {1} else {-1};
464
465 for j in 0..(s.y.abs()) {
466 let y = p.y + j * dy;
467 if y >= self.size().y {break}
468 for i in 0..(s.x.abs()) {
469 let x = p.x + i * dx;
470 if x >= self.size().x {break}
471
472 self[(x, y)] = c;
473 }
474 }
475 }
476
477
478 pub fn clear(&mut self, c: Color) {
480 self.data.fill(c);
481 }
482
483
484 fn plot_ellipse_points<A, B>(&mut self, center: A, pos: B, c: Color)
485 where A: AsRef<Vec2>, B: AsRef<Vec2>
486 {
487 let center = center.as_ref();
488 let pos = pos.as_ref();
489 self[(center.x + pos.x, center.y + pos.y)] = c;
490 self[(center.x + pos.x, center.y - pos.y)] = c;
491 self[(center.x - pos.x, center.y + pos.y)] = c;
492 self[(center.x - pos.x, center.y - pos.y)] = c;
493 }
494
495
496 pub fn ellipse_boundary<A, B>(&mut self, center: A, size: B, c: Color)
499 where A: AsRef<Vec2>, B: AsRef<Vec2>
500 {
501 let center = center.as_ref();
502 let size = size.as_ref();
503
504 let a = size.x / 2;
505 let b = size.y / 2;
506
507 let mut x = 0;
509 let mut y = b;
510 let mut p = b * b + (a * a * (1 - 4*b) - 2) / 4;
511 let mut dpe = 3 * b * b;
512 let mut dpse = dpe - 2 * a * a * (b - 1);
513 let d2pe = 2 * b * b;
514 let d2pse = d2pe + 2 * a * a;
515
516 self.plot_ellipse_points(center, (x, y), c);
518 while dpse < 2 * a * a + 3 * b * b {
519 if p < 0 { p += dpe;
521 dpe += d2pe;
522 dpse += d2pe;
523 } else { p += dpse;
525 dpe += d2pe;
526 dpse += d2pse;
527 y -= 1;
528 }
529 x += 1;
530 self.plot_ellipse_points(center, (x, y), c);
531 }
532
533 let mut p = p - (a * a * (4 * y - 3) + b * b * (4 * x + 3) + 2) / 4;
535 let mut dpse = 2 * b * b + 3 * a * a;
536 let dps = a * a * (3 - 2 * y);
537 let d2ps = 2 * a * a;
538
539 while y > 0 {
541 if p > 0 { p += dps;
543 dpe += d2ps;
544 dpse += d2ps;
545 } else { p += dpse;
547 dpe += d2ps;
548 dpse += d2pse;
549 x += 1;
550 }
551 y -= 1;
552 self.plot_ellipse_points(center, (x, y), c);
553 }
554 }
555
556
557 pub fn image<A, B, C>(&mut self, img: &Image, pos: A, size: B, offset: C, alpha: Option<Color>)
561 where A: AsRef<Vec2>, B: AsRef<Vec2>, C: AsRef<Vec2>
562 {
563 let offset = offset.as_ref();
564 let mut p = *pos.as_ref();
565 let mut s = *size.as_ref();
566
567 if p.x < 0 {
568 s.x += p.x - 1;
569 p.x = 0;
570 }
571 if p.y < 0 {
572 s.y += p.y - 1;
573 p.y = 0;
574 }
575
576
577 let dx = if s.x > 0 {1} else {-1};
578 let dy = if s.y > 0 {1} else {-1};
579
580
581 for j in 0..(s.y.abs()) {
582 let y = p.y + j * dy;
583 let src_y = offset.y + j;
584 if y >= self.size().y {break}
585 if src_y >= img.size().y {break}
586 for i in 0..(s.x.abs()) {
587 let x = p.x + i * dx;
588 let src_x = offset.x + i;
589 if x >= self.size().x {break}
590 if src_x >= img.size().x {break}
591
592 let pos = vec2!(x, y);
593 let src_pos = vec2!(src_x, src_y);
594
595 if let Some(acolor) = alpha {
596 if acolor == img[src_pos] {
597 continue;
598 }
599 }
600 self[pos] = img[src_pos];
601 }
602 }
603 }
604
605
606 pub fn whole_image_alpha<A>(&mut self, img: &Image, pos: A, alpha: Color)
613 where A: AsRef<Vec2>
614 {
615 self.image(img, pos, img.size(), Vec2::ZERO, Some(alpha));
616 }
617
618
619 pub fn whole_image<A>(&mut self, img: &Image, pos: A)
626 where A: AsRef<Vec2>
627 {
628 self.image(img, pos, img.size(), Vec2::ZERO, None);
629 }
630}
631
632
633impl<A: AsRef<Vec2>> Index<A> for Image {
634 type Output = Color;
635
636 fn index(&self, p: A) -> &Self::Output {
637 let p = *p.as_ref();
638 if !self.is_out_of_range(p) {
639 &self.data[p]
640 } else {
641 &Color::BLACK
642 }
643 }
644}
645
646
647impl<A: AsRef<Vec2>> IndexMut<A> for Image {
648
649 fn index_mut(&mut self, p: A) -> &mut Self::Output {
650 static mut TEMP: Color = Color::BLACK;
651 let p = *p.as_ref();
652
653 if !self.is_out_of_range(p) {
654 &mut self.data[p]
655 } else {
656 unsafe { &mut TEMP } }
658 }
659}