Refactor into different crates
This commit is contained in:
parent
94473c64e0
commit
dfdeae5638
82 changed files with 624 additions and 647 deletions
432
factorio-core/src/visualize/image.rs
Normal file
432
factorio-core/src/visualize/image.rs
Normal file
|
|
@ -0,0 +1,432 @@
|
|||
use super::Visualization;
|
||||
use crate::{prelude::Direction, visualize::Symbol};
|
||||
use image::{GenericImage, Rgba, RgbaImage};
|
||||
|
||||
pub(super) fn draw<I: GenericImage<Pixel = Rgba<u8>>>(v: &Visualization, image: &mut I) {
|
||||
assert_eq!(
|
||||
(v.size.x as u32 * 10, v.size.y as u32 * 10),
|
||||
image.dimensions()
|
||||
);
|
||||
|
||||
for (pos, (symbol, fg, bg)) in &v.symbols {
|
||||
match symbol {
|
||||
Symbol::Arrow(dir) => {
|
||||
if let Some(c) = bg.as_ref() {
|
||||
let rgba = Rgba::from([c.r, c.g, c.b, 255]);
|
||||
for x in 0..10 {
|
||||
for y in 0..10 {
|
||||
image.put_pixel((pos.x * 10 + x) as u32, (pos.y * 10 + y) as u32, rgba);
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(c) = fg.as_ref() {
|
||||
let rgba = Rgba::from([c.r, c.g, c.b, 255]);
|
||||
for p in rotate_iter(*dir, arrow()) {
|
||||
image.put_pixel((pos.x * 10) as u32 + p.0, (pos.y * 10) as u32 + p.1, rgba);
|
||||
}
|
||||
}
|
||||
}
|
||||
Symbol::ArrowEnter(dir) => {
|
||||
if let Some(c) = bg.as_ref() {
|
||||
let rgba = Rgba::from([c.r, c.g, c.b, 255]);
|
||||
for x in 0..10 {
|
||||
for y in 0..10 {
|
||||
image.put_pixel((pos.x * 10 + x) as u32, (pos.y * 10 + y) as u32, rgba);
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(c) = fg.as_ref() {
|
||||
let rgba = Rgba::from([c.r, c.g, c.b, 255]);
|
||||
for p in rotate_iter(*dir, arrow_enter()) {
|
||||
image.put_pixel((pos.x * 10) as u32 + p.0, (pos.y * 10) as u32 + p.1, rgba);
|
||||
}
|
||||
}
|
||||
}
|
||||
Symbol::ArrowExit(dir) => {
|
||||
if let Some(c) = bg.as_ref() {
|
||||
let rgba = Rgba::from([c.r, c.g, c.b, 255]);
|
||||
for x in 0..10 {
|
||||
for y in 0..10 {
|
||||
image.put_pixel((pos.x * 10 + x) as u32, (pos.y * 10 + y) as u32, rgba);
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(c) = fg.as_ref() {
|
||||
let rgba = Rgba::from([c.r, c.g, c.b, 255]);
|
||||
for p in rotate_iter(*dir, arrow_exit()) {
|
||||
image.put_pixel((pos.x * 10) as u32 + p.0, (pos.y * 10) as u32 + p.1, rgba);
|
||||
}
|
||||
}
|
||||
}
|
||||
Symbol::Char(ch) => {
|
||||
if let Some(c) = bg.as_ref() {
|
||||
let rgba = Rgba::from([c.r, c.g, c.b, 255]);
|
||||
for x in 0..10 {
|
||||
for y in 0..10 {
|
||||
image.put_pixel((pos.x * 10 + x) as u32, (pos.y * 10 + y) as u32, rgba);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(c) = fg.as_ref() {
|
||||
let rgba = Rgba::from([c.r, c.g, c.b, 255]);
|
||||
for p in char(*ch) {
|
||||
image.put_pixel((pos.x * 10) as u32 + p.0, (pos.y * 10) as u32 + p.1, rgba);
|
||||
}
|
||||
}
|
||||
}
|
||||
Symbol::Block => {
|
||||
if let Some(c) = fg.as_ref() {
|
||||
let rgba = Rgba::from([c.r, c.g, c.b, 255]);
|
||||
for x in 1..9 {
|
||||
for y in 1..9 {
|
||||
image.put_pixel((pos.x * 10 + x) as u32, (pos.y * 10 + y) as u32, rgba);
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(c) = bg.as_ref() {
|
||||
let rgba = Rgba::from([c.r, c.g, c.b, 255]);
|
||||
for x in 0..10 {
|
||||
image.put_pixel((pos.x * 10 + x) as u32, (pos.y * 10) as u32, rgba);
|
||||
image.put_pixel((pos.x * 10 + x) as u32, (pos.y * 10 + 9) as u32, rgba);
|
||||
}
|
||||
for y in 1..9 {
|
||||
image.put_pixel((pos.x * 10) as u32, (pos.y * 10 + y) as u32, rgba);
|
||||
image.put_pixel((pos.x * 10 + 9) as u32, (pos.y * 10 + y) as u32, rgba);
|
||||
}
|
||||
}
|
||||
}
|
||||
Symbol::Space => {
|
||||
if let Some(c) = bg.as_ref() {
|
||||
let rgba = Rgba::from([c.r, c.g, c.b, 255]);
|
||||
for x in 0..10 {
|
||||
for y in 0..10 {
|
||||
image.put_pixel((pos.x * 10 + x) as u32, (pos.y * 10 + y) as u32, rgba);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn image_grid(
|
||||
visualizations: &[Visualization],
|
||||
width: u32,
|
||||
height: u32,
|
||||
columns: u32,
|
||||
) -> RgbaImage {
|
||||
let border_color = Rgba::from([255, 255, 255, 255]);
|
||||
let rows = visualizations.len().div_ceil(columns as usize) as u32;
|
||||
|
||||
let mut img = RgbaImage::new((width * 10 + 2) * columns, (height * 10 + 2) * rows);
|
||||
|
||||
for (i, v) in visualizations.iter().enumerate() {
|
||||
let i = i as u32;
|
||||
let r = i / columns;
|
||||
let c = i % columns;
|
||||
|
||||
let size = v.size();
|
||||
|
||||
let mut sub_img = img.sub_image(
|
||||
1 + c * (width * 10 + 2),
|
||||
1 + r * (height * 10 + 2),
|
||||
(size.x as u32) * 10,
|
||||
(size.y as u32) * 10,
|
||||
);
|
||||
draw(v, &mut *sub_img);
|
||||
|
||||
for x in 0..(size.x as u32 * 10 + 2) {
|
||||
img.put_pixel(
|
||||
c * (width * 10 + 2) + x,
|
||||
r * (height * 10 + 2),
|
||||
border_color,
|
||||
);
|
||||
img.put_pixel(
|
||||
c * (width * 10 + 2) + x,
|
||||
r * (height * 10 + 2) + (size.y as u32) * 10 + 1,
|
||||
border_color,
|
||||
);
|
||||
}
|
||||
for y in 0..(size.y as u32 * 10 + 2) {
|
||||
img.put_pixel(
|
||||
c * (width * 10 + 2),
|
||||
r * (height * 10 + 2) + y,
|
||||
border_color,
|
||||
);
|
||||
img.put_pixel(
|
||||
c * (width * 10 + 2) + (size.x as u32) * 10 + 1,
|
||||
r * (height * 10 + 2) + y,
|
||||
border_color,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
img
|
||||
}
|
||||
|
||||
fn rotate(dir: Direction, pos: (u32, u32)) -> (u32, u32) {
|
||||
match dir {
|
||||
Direction::Up => pos,
|
||||
Direction::Right => (9 - pos.1, pos.0),
|
||||
Direction::Down => (9 - pos.0, 9 - pos.1),
|
||||
Direction::Left => (pos.1, 9 - pos.0),
|
||||
}
|
||||
}
|
||||
|
||||
fn rotate_iter(
|
||||
dir: Direction,
|
||||
iter: impl Iterator<Item = (u32, u32)>,
|
||||
) -> impl Iterator<Item = (u32, u32)> {
|
||||
iter.map(move |p| rotate(dir, p))
|
||||
}
|
||||
|
||||
fn arrow() -> impl Iterator<Item = (u32, u32)> {
|
||||
[
|
||||
(4, 1),
|
||||
(5, 1),
|
||||
(3, 2),
|
||||
(4, 2),
|
||||
(5, 2),
|
||||
(6, 2),
|
||||
(2, 3),
|
||||
(3, 3),
|
||||
(4, 3),
|
||||
(5, 3),
|
||||
(6, 3),
|
||||
(7, 3),
|
||||
(1, 4),
|
||||
(2, 4),
|
||||
(4, 4),
|
||||
(5, 4),
|
||||
(7, 4),
|
||||
(8, 4),
|
||||
(4, 5),
|
||||
(5, 5),
|
||||
(4, 6),
|
||||
(5, 6),
|
||||
(4, 7),
|
||||
(5, 7),
|
||||
(4, 8),
|
||||
(5, 8),
|
||||
]
|
||||
.into_iter()
|
||||
}
|
||||
|
||||
fn arrow_enter() -> impl Iterator<Item = (u32, u32)> {
|
||||
[
|
||||
(2, 1),
|
||||
(3, 1),
|
||||
(4, 1),
|
||||
(5, 1),
|
||||
(6, 1),
|
||||
(7, 1),
|
||||
(3, 2),
|
||||
(4, 2),
|
||||
(5, 2),
|
||||
(6, 2),
|
||||
(2, 3),
|
||||
(3, 3),
|
||||
(4, 3),
|
||||
(5, 3),
|
||||
(6, 3),
|
||||
(7, 3),
|
||||
(1, 4),
|
||||
(2, 4),
|
||||
(4, 4),
|
||||
(5, 4),
|
||||
(7, 4),
|
||||
(8, 4),
|
||||
(4, 5),
|
||||
(5, 5),
|
||||
(4, 6),
|
||||
(5, 6),
|
||||
(4, 7),
|
||||
(5, 7),
|
||||
(4, 8),
|
||||
(5, 8),
|
||||
]
|
||||
.into_iter()
|
||||
}
|
||||
|
||||
fn arrow_exit() -> impl Iterator<Item = (u32, u32)> {
|
||||
[
|
||||
(4, 1),
|
||||
(5, 1),
|
||||
(3, 2),
|
||||
(4, 2),
|
||||
(5, 2),
|
||||
(6, 2),
|
||||
(2, 3),
|
||||
(3, 3),
|
||||
(4, 3),
|
||||
(5, 3),
|
||||
(6, 3),
|
||||
(7, 3),
|
||||
(1, 4),
|
||||
(2, 4),
|
||||
(4, 4),
|
||||
(5, 4),
|
||||
(7, 4),
|
||||
(8, 4),
|
||||
(4, 5),
|
||||
(5, 5),
|
||||
(4, 6),
|
||||
(5, 6),
|
||||
(2, 7),
|
||||
(3, 7),
|
||||
(4, 7),
|
||||
(5, 7),
|
||||
(6, 7),
|
||||
(7, 7),
|
||||
]
|
||||
.into_iter()
|
||||
}
|
||||
|
||||
static CHARDATA: [[u8; 8]; 128] = [
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+0000 (nul)
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+0001
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+0002
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+0003
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+0004
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+0005
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+0006
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+0007
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+0008
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+0009
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+000A
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+000B
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+000C
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+000D
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+000E
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+000F
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+0010
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+0011
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+0012
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+0013
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+0014
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+0015
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+0016
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+0017
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+0018
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+0019
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+001A
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+001B
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+001C
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+001D
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+001E
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+001F
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+0020 (space)
|
||||
[0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00], // U+0021 (!)
|
||||
[0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+0022 (")
|
||||
[0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00], // U+0023 (#)
|
||||
[0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00], // U+0024 ($)
|
||||
[0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00], // U+0025 (%)
|
||||
[0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00], // U+0026 (&)
|
||||
[0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00], // U+0027 (')
|
||||
[0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00], // U+0028 (()
|
||||
[0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00], // U+0029 ())
|
||||
[0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00], // U+002A (*)
|
||||
[0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00], // U+002B (+)
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06], // U+002C (,)
|
||||
[0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00], // U+002D (-)
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00], // U+002E (.)
|
||||
[0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00], // U+002F (/)
|
||||
[0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00], // U+0030 (0)
|
||||
[0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00], // U+0031 (1)
|
||||
[0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00], // U+0032 (2)
|
||||
[0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00], // U+0033 (3)
|
||||
[0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00], // U+0034 (4)
|
||||
[0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00], // U+0035 (5)
|
||||
[0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00], // U+0036 (6)
|
||||
[0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00], // U+0037 (7)
|
||||
[0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00], // U+0038 (8)
|
||||
[0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00], // U+0039 (9)
|
||||
[0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00], // U+003A (:)
|
||||
[0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06], // U+003B (;)
|
||||
[0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00], // U+003C (<)
|
||||
[0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00], // U+003D (=)
|
||||
[0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00], // U+003E (>)
|
||||
[0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00], // U+003F (?)
|
||||
[0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00], // U+0040 (@)
|
||||
[0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00], // U+0041 (A)
|
||||
[0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00], // U+0042 (B)
|
||||
[0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00], // U+0043 (C)
|
||||
[0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00], // U+0044 (D)
|
||||
[0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00], // U+0045 (E)
|
||||
[0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00], // U+0046 (F)
|
||||
[0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00], // U+0047 (G)
|
||||
[0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00], // U+0048 (H)
|
||||
[0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00], // U+0049 (I)
|
||||
[0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00], // U+004A (J)
|
||||
[0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00], // U+004B (K)
|
||||
[0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00], // U+004C (L)
|
||||
[0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00], // U+004D (M)
|
||||
[0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00], // U+004E (N)
|
||||
[0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00], // U+004F (O)
|
||||
[0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00], // U+0050 (P)
|
||||
[0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00], // U+0051 (Q)
|
||||
[0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00], // U+0052 (R)
|
||||
[0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00], // U+0053 (S)
|
||||
[0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00], // U+0054 (T)
|
||||
[0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00], // U+0055 (U)
|
||||
[0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00], // U+0056 (V)
|
||||
[0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00], // U+0057 (W)
|
||||
[0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00], // U+0058 (X)
|
||||
[0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00], // U+0059 (Y)
|
||||
[0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00], // U+005A (Z)
|
||||
[0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00], // U+005B ([)
|
||||
[0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00], // U+005C (\)
|
||||
[0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00], // U+005D (])
|
||||
[0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00], // U+005E (^)
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF], // U+005F (_)
|
||||
[0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00], // U+0060 (`)
|
||||
[0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00], // U+0061 (a)
|
||||
[0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00], // U+0062 (b)
|
||||
[0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00], // U+0063 (c)
|
||||
[0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00], // U+0064 (d)
|
||||
[0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00], // U+0065 (e)
|
||||
[0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00], // U+0066 (f)
|
||||
[0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F], // U+0067 (g)
|
||||
[0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00], // U+0068 (h)
|
||||
[0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00], // U+0069 (i)
|
||||
[0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E], // U+006A (j)
|
||||
[0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00], // U+006B (k)
|
||||
[0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00], // U+006C (l)
|
||||
[0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00], // U+006D (m)
|
||||
[0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00], // U+006E (n)
|
||||
[0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00], // U+006F (o)
|
||||
[0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F], // U+0070 (p)
|
||||
[0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78], // U+0071 (q)
|
||||
[0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00], // U+0072 (r)
|
||||
[0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00], // U+0073 (s)
|
||||
[0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00], // U+0074 (t)
|
||||
[0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00], // U+0075 (u)
|
||||
[0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00], // U+0076 (v)
|
||||
[0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00], // U+0077 (w)
|
||||
[0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00], // U+0078 (x)
|
||||
[0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F], // U+0079 (y)
|
||||
[0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00], // U+007A (z)
|
||||
[0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00], // U+007B ([)
|
||||
[0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00], // U+007C (|)
|
||||
[0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00], // U+007D (])
|
||||
[0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+007E (~)
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // U+007F
|
||||
];
|
||||
|
||||
fn char(c: char) -> impl Iterator<Item = (u32, u32)> {
|
||||
let id = c as usize;
|
||||
CHARDATA[id]
|
||||
.iter()
|
||||
.enumerate()
|
||||
.flat_map(|(y, &d)| {
|
||||
(0..8).filter_map(move |x: u32| {
|
||||
if (d >> x) & 1 == 1 {
|
||||
Some((x, y as u32))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
})
|
||||
.map(|(x, y)| (x + 1, y + 1))
|
||||
}
|
||||
137
factorio-core/src/visualize/mod.rs
Normal file
137
factorio-core/src/visualize/mod.rs
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
mod image;
|
||||
mod print;
|
||||
|
||||
use crate::prelude::*;
|
||||
use ::image::RgbaImage;
|
||||
pub use image::image_grid;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub trait Visualize {
|
||||
fn visualize(&self) -> Visualization;
|
||||
|
||||
fn print_visualization(&self) {
|
||||
let v = self.visualize();
|
||||
print::print(v);
|
||||
}
|
||||
|
||||
fn png_visualization(&self, file: impl AsRef<std::path::Path>) {
|
||||
let v = self.visualize();
|
||||
|
||||
let mut img = RgbaImage::new((v.size.x * 10) as u32, (v.size.y * 10) as u32);
|
||||
|
||||
image::draw(&v, &mut img);
|
||||
|
||||
let mut f = std::fs::File::create(file).unwrap();
|
||||
let _ = img.write_to(&mut f, ::image::ImageFormat::Png);
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Symbol {
|
||||
Arrow(Direction),
|
||||
ArrowEnter(Direction),
|
||||
ArrowExit(Direction),
|
||||
Char(char),
|
||||
Block,
|
||||
Space,
|
||||
}
|
||||
|
||||
impl Symbol {
|
||||
fn get_char(&self) -> char {
|
||||
match self {
|
||||
Symbol::Arrow(dir) => match dir {
|
||||
Direction::Up => '↑',
|
||||
Direction::Right => '→',
|
||||
Direction::Down => '↓',
|
||||
Direction::Left => '←',
|
||||
},
|
||||
Symbol::ArrowEnter(dir) => match dir {
|
||||
Direction::Up => '↟',
|
||||
Direction::Right => '↠',
|
||||
Direction::Down => '↡',
|
||||
Direction::Left => '↞',
|
||||
},
|
||||
Symbol::ArrowExit(dir) => match dir {
|
||||
Direction::Up => '↥',
|
||||
Direction::Right => '↦',
|
||||
Direction::Down => '↧',
|
||||
Direction::Left => '↤',
|
||||
},
|
||||
Symbol::Char(c) => *c,
|
||||
Symbol::Block => '#',
|
||||
Symbol::Space => ' ',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Visualization {
|
||||
size: Position,
|
||||
symbols: HashMap<Position, (Symbol, Option<Color>, Option<Color>)>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Color {
|
||||
r: u8,
|
||||
g: u8,
|
||||
b: u8,
|
||||
}
|
||||
|
||||
impl Color {
|
||||
pub fn new(r: u8, g: u8, b: u8) -> Self {
|
||||
Self { r, g, b }
|
||||
}
|
||||
|
||||
pub fn white() -> Self {
|
||||
Self::new(255, 255, 255)
|
||||
}
|
||||
|
||||
pub fn index(i: usize) -> Self {
|
||||
let c = [
|
||||
Color::new(0xe6, 0x00, 0x49),
|
||||
Color::new(0x0b, 0xb4, 0xff),
|
||||
Color::new(0x50, 0xe9, 0x91),
|
||||
Color::new(0xe6, 0xd8, 0x00),
|
||||
Color::new(0x9b, 0x19, 0xf5),
|
||||
Color::new(0xff, 0xa3, 0x00),
|
||||
Color::new(0xdc, 0x0a, 0xb4),
|
||||
Color::new(0xb3, 0xd4, 0xff),
|
||||
Color::new(0x00, 0xbf, 0xa0),
|
||||
];
|
||||
|
||||
c[i % c.len()]
|
||||
}
|
||||
}
|
||||
|
||||
impl Visualization {
|
||||
pub fn new(size: Position) -> Self {
|
||||
Self {
|
||||
size,
|
||||
symbols: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_symbol(
|
||||
&mut self,
|
||||
pos: Position,
|
||||
symbol: Symbol,
|
||||
fg: Option<Color>,
|
||||
bg: Option<Color>,
|
||||
) {
|
||||
if let Some(s) = self.symbols.get_mut(&pos) {
|
||||
*s = (symbol, fg, bg);
|
||||
} else {
|
||||
self.symbols.insert(pos, (symbol, fg, bg));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn overwrite_background(&mut self, pos: Position, bg: Option<Color>) {
|
||||
if let Some(s) = self.symbols.get_mut(&pos) {
|
||||
s.2 = bg;
|
||||
} else {
|
||||
self.symbols.insert(pos, (Symbol::Space, None, bg));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn size(&self) -> Position {
|
||||
self.size
|
||||
}
|
||||
}
|
||||
81
factorio-core/src/visualize/print.rs
Normal file
81
factorio-core/src/visualize/print.rs
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
use super::Visualization;
|
||||
|
||||
use std::io::Write;
|
||||
use termcolor::{ColorSpec, StandardStream, WriteColor};
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
pub(super) fn print(v: Visualization) {
|
||||
let stdout = &mut StandardStream::stdout(termcolor::ColorChoice::Always);
|
||||
|
||||
let width_digits = (v.size.x - 1).ilog10() + 1;
|
||||
let height_digits = (v.size.y - 1).ilog10() + 1;
|
||||
|
||||
// print header
|
||||
for i in 0..width_digits {
|
||||
let d = width_digits - i - 1;
|
||||
|
||||
//padding
|
||||
for _ in 0..height_digits {
|
||||
write!(stdout, " ").unwrap();
|
||||
}
|
||||
|
||||
for x in 0..v.size.x {
|
||||
let digits = x / (i32::pow(10, d));
|
||||
if digits == 0 && d > 0 {
|
||||
write!(stdout, " ").unwrap();
|
||||
} else {
|
||||
write!(
|
||||
stdout,
|
||||
"{}",
|
||||
char::from_u32((digits % 10) as u32 + 48).unwrap()
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
writeln!(stdout).unwrap();
|
||||
}
|
||||
|
||||
for y in 0..v.size.y {
|
||||
write!(stdout, "{:1$}", y, height_digits as usize).unwrap();
|
||||
|
||||
for x in 0..v.size.x {
|
||||
if let Some((s, fg, bg)) = v.symbols.get(&Position::new(x, y)) {
|
||||
let mut c = ColorSpec::new();
|
||||
c.set_fg(fg.as_ref().map(|c| termcolor::Color::Rgb(c.r, c.g, c.b)));
|
||||
c.set_bg(bg.as_ref().map(|c| termcolor::Color::Rgb(c.r, c.g, c.b)));
|
||||
stdout.set_color(&c).unwrap();
|
||||
write!(stdout, "{:1}", s.get_char()).unwrap();
|
||||
stdout.reset().unwrap();
|
||||
} else {
|
||||
write!(stdout, " ").unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
writeln!(stdout, "{:1$}", y, height_digits as usize).unwrap();
|
||||
}
|
||||
|
||||
for i in 0..width_digits {
|
||||
let d = width_digits - i - 1;
|
||||
|
||||
//padding
|
||||
for _ in 0..height_digits {
|
||||
write!(stdout, " ").unwrap();
|
||||
}
|
||||
|
||||
for x in 0..v.size.x {
|
||||
let digits = x / (i32::pow(10, d));
|
||||
if digits == 0 && d > 0 {
|
||||
write!(stdout, " ").unwrap();
|
||||
} else {
|
||||
write!(
|
||||
stdout,
|
||||
"{}",
|
||||
char::from_u32((digits % 10) as u32 + 48).unwrap()
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
writeln!(stdout).unwrap();
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue