shaders & font, remove glyphon and start working on homebuilt text engine
This commit is contained in:
parent
7df3f8b3a8
commit
9d6ed473b2
|
@ -26,7 +26,7 @@ winit = { version = "0.29", features = ["rwh_05"], default-features = false }
|
|||
wgpu = { version = "0.18", features = ["webgl"] }
|
||||
raw-window-handle = "0.5"
|
||||
wasm-bindgen-futures = "0.4"
|
||||
glyphon = { git = "https://github.com/grovesNL/glyphon" }
|
||||
bytemuck = { version = "1", features = ["derive"]}
|
||||
|
||||
[dependencies.js-sys]
|
||||
version = "0.3"
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -210,3 +210,15 @@ pub fn color_scheme(product: Mode, value: f32) -> &'static str {
|
|||
Mode::RadarInoperative => "#ff0000",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rgb_to_srgb(c: u32) -> [f32; 3] {
|
||||
let f = |xu: u32| {
|
||||
let x = (xu & 0xFF) as f32 / 255.0;
|
||||
if x > 0.04045 {
|
||||
((x + 0.055) / 1.055).powf(2.4)
|
||||
} else {
|
||||
x / 12.92
|
||||
}
|
||||
};
|
||||
[f(c >> 16), f(c >> 8), f(c)]
|
||||
}
|
|
@ -4,15 +4,14 @@ pub mod equirectangular;
|
|||
pub mod mode;
|
||||
pub mod scope;
|
||||
pub mod sites;
|
||||
pub mod text;
|
||||
pub mod utils;
|
||||
pub mod vcp;
|
||||
pub mod rendering;
|
||||
|
||||
use crate::command::{exec, should_newline};
|
||||
use crate::mode::Mode;
|
||||
use crate::mode::Mode::Reflectivity;
|
||||
use crate::scope::{Preferences, ScopeState, WgpuState};
|
||||
use glyphon::{Metrics, TextBounds};
|
||||
use js_sys::Uint8Array;
|
||||
use log::{debug, error, info};
|
||||
use std::io::Cursor;
|
||||
|
@ -70,6 +69,10 @@ pub async fn __nxrd_browser_init(w: u32, h: u32) -> AbiProxy {
|
|||
})
|
||||
.expect("Couldn't append canvas to document body.");
|
||||
|
||||
let canvas = window.canvas().unwrap();
|
||||
canvas.set_width(w);
|
||||
canvas.set_height(h);
|
||||
|
||||
let mut render_state = WgpuState::new(window, PhysicalSize::new(w, h)).await;
|
||||
|
||||
info!("initializing the scope");
|
||||
|
@ -104,22 +107,6 @@ pub async fn __nxrd_browser_init(w: u32, h: u32) -> AbiProxy {
|
|||
wgpu: render_state,
|
||||
};
|
||||
|
||||
scope_state.wgpu.add_textarea(
|
||||
"status_bar".to_string(),
|
||||
Metrics::new(30.0, 42.0),
|
||||
10.0,
|
||||
10.0,
|
||||
1.0,
|
||||
TextBounds {
|
||||
left: 0,
|
||||
top: 0,
|
||||
right: 600,
|
||||
bottom: 160,
|
||||
},
|
||||
glyphon::Color::rgb(0x4a, 0xf6, 0x26),
|
||||
"NEXRAD INOP 00:00:00Z",
|
||||
);
|
||||
|
||||
let event_proxy: EventLoopProxy<RenderMessage> = event_loop.create_proxy();
|
||||
|
||||
// If you see an error here, your IDE is not compiling for webassembly
|
||||
|
|
|
@ -0,0 +1,349 @@
|
|||
# PixelForge Font File
|
||||
format_version: 1.0
|
||||
|
||||
line_gap: 1
|
||||
|
||||
space_width: 5
|
||||
|
||||
creator_name: coredoescode
|
||||
font_family_name: NXRD
|
||||
font_sub_family_name: Regular
|
||||
version: Version 1.0
|
||||
font_url:
|
||||
license: OFL
|
||||
license_url:
|
||||
|
||||
last_exported_path: C:\Users\tyler\Documents\NXRD.ttf
|
||||
|
||||
num_glyphs: 66
|
||||
glyphs:
|
||||
33:
|
||||
advance: 10
|
||||
auto_update_advance: false
|
||||
auto_advance_amount: 1
|
||||
pixels: 4 1, 4 2, 4 4, 4 5, 4 6, 4 7, 4 8, 4 9, 5 1, 5 2, 5 4, 5 5, 5 6, 5 7, 5 8, 5 9,
|
||||
34:
|
||||
advance: 10
|
||||
auto_update_advance: false
|
||||
auto_advance_amount: 1
|
||||
pixels: 2 6, 2 7, 2 8, 2 9, 3 6, 3 7, 3 8, 3 9, 5 6, 5 7, 5 8, 5 9, 6 6, 6 7, 6 8, 6 9,
|
||||
35:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 3, 1 7, 2 1, 2 2, 2 3, 2 4, 2 5, 2 6, 2 7, 3 3, 3 4, 3 5, 3 6, 3 7, 3 8, 3 9, 4 3, 4 7, 5 3, 5 7, 6 1, 6 2, 6 3, 6 4, 6 5, 6 6, 6 7, 7 3, 7 4, 7 5, 7 6, 7 7, 7 8, 7 9, 8 3, 8 7,
|
||||
36:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 3, 1 6, 1 7, 2 2, 2 3, 2 5, 2 6, 2 7, 2 8, 3 2, 3 5, 3 8, 4 1, 4 2, 4 3, 4 4, 4 5, 4 6, 4 7, 4 8, 4 9, 5 1, 5 2, 5 3, 5 4, 5 5, 5 6, 5 7, 5 8, 5 9, 6 2, 6 5, 6 8, 7 2, 7 3, 7 4, 7 5, 7 7, 7 8, 8 3, 8 4, 8 7,
|
||||
37:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 1, 1 2, 1 7, 1 8, 1 9, 2 2, 2 3, 2 7, 2 9, 3 3, 3 4, 3 7, 3 8, 3 9, 4 4, 4 5, 5 5, 5 6, 6 1, 6 2, 6 3, 6 6, 6 7, 7 1, 7 3, 7 7, 7 8, 8 1, 8 2, 8 3, 8 8, 8 9,
|
||||
38:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 3, 1 4, 2 2, 2 3, 2 4, 2 5, 3 1, 3 2, 3 4, 3 5, 3 7, 3 8, 4 1, 4 5, 4 6, 4 7, 4 8, 4 9, 5 1, 5 2, 5 4, 5 5, 5 6, 5 9, 6 2, 6 3, 6 4, 6 6, 6 7, 6 8, 6 9, 7 1, 7 2, 7 3, 7 4, 7 7, 7 8, 8 1, 8 2, 8 4,
|
||||
39:
|
||||
advance: 10
|
||||
auto_update_advance: false
|
||||
auto_advance_amount: 1
|
||||
pixels: 4 8, 4 9, 5 6, 5 7, 5 8, 5 9,
|
||||
40:
|
||||
advance: 10
|
||||
auto_update_advance: false
|
||||
auto_advance_amount: 1
|
||||
pixels: 3 2, 3 3, 3 4, 3 5, 3 6, 3 7, 3 8, 4 1, 4 2, 4 3, 4 4, 4 5, 4 6, 4 7, 4 8, 4 9, 5 1, 5 9, 6 1, 6 9,
|
||||
41:
|
||||
advance: 10
|
||||
auto_update_advance: false
|
||||
auto_advance_amount: 1
|
||||
pixels: 3 1, 3 9, 4 1, 4 9, 5 1, 5 2, 5 3, 5 4, 5 5, 5 6, 5 7, 5 8, 5 9, 6 2, 6 3, 6 4, 6 5, 6 6, 6 7, 6 8,
|
||||
42:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 2, 1 5, 1 8, 2 2, 2 3, 2 5, 2 7, 2 8, 3 3, 3 4, 3 5, 3 6, 3 7, 4 4, 4 5, 4 6, 5 4, 5 5, 5 6, 6 3, 6 4, 6 5, 6 6, 6 7, 7 2, 7 3, 7 5, 7 7, 7 8, 8 2, 8 5, 8 8,
|
||||
43:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 5, 2 5, 3 5, 4 1, 4 2, 4 3, 4 4, 4 5, 4 6, 4 7, 4 8, 4 9, 5 1, 5 2, 5 3, 5 4, 5 5, 5 6, 5 7, 5 8, 5 9, 6 5, 7 5, 8 5,
|
||||
44:
|
||||
advance: 10
|
||||
auto_update_advance: false
|
||||
auto_advance_amount: 1
|
||||
pixels: 4 1, 4 2, 5 1, 5 2,
|
||||
45:
|
||||
advance: 10
|
||||
auto_update_advance: false
|
||||
auto_advance_amount: 1
|
||||
pixels: 2 5, 3 5, 4 5, 5 5, 6 5, 7 5,
|
||||
46:
|
||||
advance: 10
|
||||
auto_update_advance: false
|
||||
auto_advance_amount: 1
|
||||
pixels: 4 1, 4 2, 5 1, 5 2,
|
||||
47:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 1, 1 2, 2 2, 2 3, 3 3, 3 4, 4 4, 4 5, 5 5, 5 6, 6 6, 6 7, 7 7, 7 8, 8 8, 8 9,
|
||||
48:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 3, 1 4, 1 5, 1 6, 1 7, 2 2, 2 3, 2 4, 2 5, 2 6, 2 7, 2 8, 3 1, 3 2, 3 3, 3 4, 3 8, 3 9, 4 1, 4 4, 4 5, 4 9, 5 1, 5 5, 5 6, 5 9, 6 1, 6 2, 6 6, 6 7, 6 8, 6 9, 7 2, 7 3, 7 4, 7 5, 7 6, 7 7, 7 8, 8 3, 8 4, 8 5, 8 6, 8 7,
|
||||
49:
|
||||
advance: 10
|
||||
auto_update_advance: false
|
||||
auto_advance_amount: 1
|
||||
pixels: 2 7, 3 7, 3 8, 4 1, 4 2, 4 3, 4 4, 4 5, 4 6, 4 7, 4 8, 4 9, 5 1, 5 2, 5 3, 5 4, 5 5, 5 6, 5 7, 5 8, 5 9,
|
||||
50:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 1, 1 2, 1 3, 1 7, 2 1, 2 2, 2 3, 2 4, 2 7, 2 8, 3 1, 3 4, 3 8, 3 9, 4 1, 4 4, 4 5, 4 9, 5 1, 5 5, 5 9, 6 1, 6 5, 6 6, 6 8, 6 9, 7 1, 7 6, 7 7, 7 8, 8 1, 8 7,
|
||||
51:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 1, 1 9, 2 1, 2 5, 2 9, 3 1, 3 5, 3 6, 3 9, 4 1, 4 5, 4 6, 4 9, 5 1, 5 5, 5 6, 5 7, 5 9, 6 1, 6 5, 6 7, 6 8, 6 9, 7 1, 7 2, 7 3, 7 4, 7 5, 7 8, 7 9, 8 2, 8 3, 8 4, 8 9,
|
||||
52:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 4, 1 5, 2 4, 2 5, 2 6, 3 4, 3 6, 3 7, 4 4, 4 7, 4 8, 5 4, 5 8, 5 9, 6 1, 6 2, 6 3, 6 4, 6 5, 6 6, 6 7, 6 8, 6 9, 7 1, 7 2, 7 3, 7 4, 7 5, 7 6, 7 7, 7 8, 7 9, 8 4,
|
||||
53:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 1, 1 6, 1 7, 1 8, 1 9, 2 1, 2 6, 2 7, 2 8, 2 9, 3 1, 3 6, 3 9, 4 1, 4 6, 4 9, 5 1, 5 6, 5 9, 6 1, 6 2, 6 5, 6 6, 6 9, 7 2, 7 3, 7 4, 7 5, 7 9, 8 3, 8 4, 8 9,
|
||||
54:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 2, 1 3, 1 4, 1 5, 1 6, 2 1, 2 2, 2 3, 2 4, 2 5, 2 6, 2 7, 3 1, 3 4, 3 5, 3 7, 3 8, 4 1, 4 5, 4 8, 4 9, 5 1, 5 5, 5 9, 6 1, 6 5, 7 1, 7 2, 7 3, 7 4, 7 5, 8 2, 8 3, 8 4,
|
||||
55:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 9, 2 9, 3 9, 4 1, 4 2, 4 9, 5 1, 5 2, 5 3, 5 4, 5 9, 6 3, 6 4, 6 5, 6 6, 6 9, 7 5, 7 6, 7 7, 7 8, 7 9, 8 7, 8 8, 8 9,
|
||||
56:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 2, 1 3, 1 4, 1 6, 1 7, 1 8, 2 1, 2 2, 2 3, 2 4, 2 5, 2 6, 2 7, 2 8, 2 9, 3 1, 3 5, 3 9, 4 1, 4 5, 4 9, 5 1, 5 5, 5 9, 6 1, 6 5, 6 9, 7 1, 7 2, 7 3, 7 4, 7 5, 7 6, 7 7, 7 8, 7 9, 8 2, 8 3, 8 4, 8 6, 8 7, 8 8,
|
||||
57:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 6, 1 7, 1 8, 2 1, 2 5, 2 6, 2 7, 2 8, 2 9, 3 1, 3 5, 3 9, 4 1, 4 5, 4 9, 5 1, 5 2, 5 5, 5 9, 6 2, 6 3, 6 5, 6 9, 7 3, 7 4, 7 5, 7 6, 7 7, 7 8, 7 9, 8 4, 8 5, 8 6, 8 7, 8 8,
|
||||
58:
|
||||
advance: 10
|
||||
auto_update_advance: false
|
||||
auto_advance_amount: 1
|
||||
pixels: 4 3, 4 4, 4 7, 4 8, 5 3, 5 4, 5 7, 5 8,
|
||||
59:
|
||||
advance: 10
|
||||
auto_update_advance: false
|
||||
auto_advance_amount: 1
|
||||
pixels: 3 2, 4 2, 4 3, 4 4, 4 7, 4 8, 5 3, 5 4, 5 7, 5 8,
|
||||
60:
|
||||
advance: 10
|
||||
auto_update_advance: false
|
||||
auto_advance_amount: 1
|
||||
pixels: 2 5, 3 4, 3 5, 3 6, 4 3, 4 4, 4 6, 4 7, 5 2, 5 3, 5 7, 5 8, 6 1, 6 2, 6 8, 6 9, 7 1, 7 9,
|
||||
61:
|
||||
advance: 10
|
||||
auto_update_advance: false
|
||||
auto_advance_amount: 1
|
||||
pixels: 2 4, 2 6, 3 4, 3 6, 4 4, 4 6, 5 4, 5 6, 6 4, 6 6, 7 4, 7 6,
|
||||
62:
|
||||
advance: 10
|
||||
auto_update_advance: false
|
||||
auto_advance_amount: 1
|
||||
pixels: 2 1, 2 9, 3 1, 3 2, 3 8, 3 9, 4 2, 4 3, 4 7, 4 8, 5 3, 5 4, 5 6, 5 7, 6 4, 6 5, 6 6, 7 5,
|
||||
64:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 3, 1 4, 1 5, 1 6, 1 7, 2 2, 2 3, 2 4, 2 5, 2 6, 2 7, 2 8, 3 1, 3 2, 3 8, 3 9, 4 1, 4 4, 4 5, 4 6, 4 9, 5 1, 5 4, 5 6, 5 9, 6 1, 6 4, 6 6, 6 8, 6 9, 7 1, 7 2, 7 4, 7 5, 7 6, 7 7, 7 8, 8 2, 8 4, 8 5, 8 6, 8 7,
|
||||
65:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 1, 1 2, 1 3, 1 4, 2 1, 2 2, 2 3, 2 4, 2 5, 2 6, 2 7, 3 4, 3 5, 3 6, 3 7, 3 8, 4 4, 4 8, 4 9, 5 4, 5 8, 5 9, 6 4, 6 5, 6 6, 6 7, 6 8, 7 1, 7 2, 7 3, 7 4, 7 5, 7 6, 7 7, 8 1, 8 2, 8 3,
|
||||
66:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 1, 1 2, 1 3, 1 4, 1 5, 1 6, 1 7, 1 8, 1 9, 2 1, 2 2, 2 3, 2 4, 2 5, 2 6, 2 7, 2 8, 2 9, 3 1, 3 6, 3 9, 4 1, 4 6, 4 9, 5 1, 5 6, 5 9, 6 1, 6 5, 6 6, 6 7, 6 8, 6 9, 7 1, 7 2, 7 3, 7 4, 7 5, 7 7, 7 8, 8 2, 8 3, 8 4,
|
||||
67:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 3, 1 4, 1 5, 1 6, 1 7, 2 2, 2 3, 2 4, 2 5, 2 6, 2 7, 2 8, 3 1, 3 2, 3 8, 3 9, 4 1, 4 9, 5 1, 5 9, 6 1, 6 9, 7 1, 7 2, 7 8, 7 9, 8 2, 8 8,
|
||||
68:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 1, 1 2, 1 3, 1 4, 1 5, 1 6, 1 7, 1 8, 1 9, 2 1, 2 2, 2 3, 2 4, 2 5, 2 6, 2 7, 2 8, 2 9, 3 1, 3 9, 4 1, 4 9, 5 1, 5 2, 5 8, 5 9, 6 2, 6 3, 6 7, 6 8, 7 3, 7 4, 7 5, 7 6, 7 7, 8 4, 8 5, 8 6,
|
||||
69:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 1, 1 2, 1 3, 1 4, 1 5, 1 6, 1 7, 1 8, 1 9, 2 1, 2 2, 2 3, 2 4, 2 5, 2 6, 2 7, 2 8, 2 9, 3 1, 3 5, 3 9, 4 1, 4 5, 4 9, 5 1, 5 5, 5 9, 6 1, 6 5, 6 9, 7 1, 7 9, 8 1, 8 9,
|
||||
70:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 1, 1 2, 1 3, 1 4, 1 5, 1 6, 1 7, 1 8, 1 9, 2 1, 2 2, 2 3, 2 4, 2 5, 2 6, 2 7, 2 8, 2 9, 3 5, 3 9, 4 5, 4 9, 5 5, 5 9, 6 5, 6 9, 7 9, 8 9,
|
||||
71:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 2, 1 3, 1 4, 1 5, 1 6, 1 7, 1 8, 2 1, 2 2, 2 3, 2 4, 2 5, 2 6, 2 7, 2 8, 2 9, 3 1, 3 9, 4 1, 4 9, 5 1, 5 5, 5 9, 6 1, 6 5, 6 9, 7 1, 7 2, 7 3, 7 4, 7 5, 7 7, 7 8, 7 9, 8 2, 8 3, 8 4, 8 5, 8 7, 8 8,
|
||||
72:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 1, 1 2, 1 3, 1 4, 1 5, 1 6, 1 7, 1 8, 1 9, 2 1, 2 2, 2 3, 2 4, 2 5, 2 6, 2 7, 2 8, 2 9, 3 5, 4 5, 5 5, 6 5, 7 1, 7 2, 7 3, 7 4, 7 5, 7 6, 7 7, 7 8, 7 9, 8 1, 8 2, 8 3, 8 4, 8 5, 8 6, 8 7, 8 8, 8 9,
|
||||
73:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 1, 1 9, 2 1, 2 9, 3 1, 3 9, 4 1, 4 2, 4 3, 4 4, 4 5, 4 6, 4 7, 4 8, 4 9, 5 1, 5 2, 5 3, 5 4, 5 5, 5 6, 5 7, 5 8, 5 9, 6 1, 6 9, 7 1, 7 9, 8 1, 8 9,
|
||||
74:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 3, 1 4, 2 2, 2 3, 2 4, 3 1, 3 2, 4 1, 5 1, 6 1, 6 2, 7 2, 7 3, 7 4, 7 5, 7 6, 7 7, 7 8, 7 9, 8 3, 8 4, 8 5, 8 6, 8 7, 8 8, 8 9,
|
||||
75:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 1, 1 2, 1 3, 1 4, 1 5, 1 6, 1 7, 1 8, 1 9, 2 1, 2 2, 2 3, 2 4, 2 5, 2 6, 2 7, 2 8, 2 9, 3 4, 3 5, 3 6, 4 3, 4 4, 4 6, 4 7, 5 3, 5 7, 6 2, 6 3, 6 7, 6 8, 7 1, 7 2, 7 8, 7 9, 8 1, 8 9,
|
||||
76:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 1, 1 2, 1 3, 1 4, 1 5, 1 6, 1 7, 1 8, 1 9, 2 1, 2 2, 2 3, 2 4, 2 5, 2 6, 2 7, 2 8, 2 9, 3 1, 4 1, 5 1, 6 1, 7 1, 8 1,
|
||||
77:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 1, 1 2, 1 3, 1 4, 1 5, 1 6, 1 7, 1 8, 1 9, 2 1, 2 2, 2 3, 2 4, 2 5, 2 6, 2 7, 2 8, 2 9, 3 6, 3 7, 3 8, 4 5, 4 6, 5 5, 5 6, 6 6, 6 7, 6 8, 7 1, 7 2, 7 3, 7 4, 7 5, 7 6, 7 7, 7 8, 7 9, 8 1, 8 2, 8 3, 8 4, 8 5, 8 6, 8 7, 8 8, 8 9,
|
||||
78:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 1, 1 2, 1 3, 1 4, 1 5, 1 6, 1 7, 1 8, 1 9, 2 1, 2 2, 2 3, 2 4, 2 5, 2 6, 2 7, 2 8, 2 9, 3 7, 3 8, 4 5, 4 6, 4 7, 5 3, 5 4, 5 5, 6 2, 6 3, 7 1, 7 2, 7 3, 7 4, 7 5, 7 6, 7 7, 7 8, 7 9, 8 1, 8 2, 8 3, 8 4, 8 5, 8 6, 8 7, 8 8, 8 9,
|
||||
79:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 3, 1 4, 1 5, 1 6, 1 7, 2 2, 2 3, 2 4, 2 5, 2 6, 2 7, 2 8, 3 1, 3 2, 3 8, 3 9, 4 1, 4 9, 5 1, 5 9, 6 1, 6 2, 6 8, 6 9, 7 2, 7 3, 7 4, 7 5, 7 6, 7 7, 7 8, 8 3, 8 4, 8 5, 8 6, 8 7,
|
||||
80:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 1, 1 2, 1 3, 1 4, 1 5, 1 6, 1 7, 1 8, 1 9, 2 1, 2 2, 2 3, 2 4, 2 5, 2 6, 2 7, 2 8, 2 9, 3 5, 3 9, 4 5, 4 9, 5 5, 5 9, 6 5, 6 9, 7 5, 7 6, 7 7, 7 8, 7 9, 8 6, 8 7, 8 8,
|
||||
81:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 3, 1 4, 1 5, 1 6, 1 7, 2 2, 2 3, 2 4, 2 5, 2 6, 2 7, 2 8, 3 1, 3 2, 3 8, 3 9, 4 1, 4 9, 5 1, 5 4, 5 5, 5 9, 6 1, 6 2, 6 3, 6 4, 6 8, 6 9, 7 2, 7 3, 7 4, 7 5, 7 6, 7 7, 7 8, 8 1, 8 2, 8 4, 8 5, 8 6, 8 7,
|
||||
82:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 1, 1 2, 1 3, 1 4, 1 5, 1 6, 1 7, 1 8, 1 9, 2 1, 2 2, 2 3, 2 4, 2 5, 2 6, 2 7, 2 8, 2 9, 3 5, 3 9, 4 4, 4 5, 4 9, 5 3, 5 4, 5 5, 5 9, 6 2, 6 3, 6 5, 6 9, 7 1, 7 2, 7 5, 7 6, 7 7, 7 8, 7 9, 8 1, 8 6, 8 7, 8 8,
|
||||
83:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 2, 1 6, 1 7, 1 8, 2 1, 2 2, 2 5, 2 6, 2 7, 2 8, 2 9, 3 1, 3 5, 3 9, 4 1, 4 5, 4 9, 5 1, 5 5, 5 9, 6 1, 6 5, 6 9, 7 1, 7 2, 7 3, 7 4, 7 5, 7 8, 7 9, 8 2, 8 3, 8 4, 8 8,
|
||||
84:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 9, 2 9, 3 9, 4 1, 4 2, 4 3, 4 4, 4 5, 4 6, 4 7, 4 8, 4 9, 5 1, 5 2, 5 3, 5 4, 5 5, 5 6, 5 7, 5 8, 5 9, 6 9, 7 9, 8 9,
|
||||
85:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 2, 1 3, 1 4, 1 5, 1 6, 1 7, 1 8, 1 9, 2 1, 2 2, 2 3, 2 4, 2 5, 2 6, 2 7, 2 8, 2 9, 3 1, 3 2, 4 1, 5 1, 6 1, 6 2, 7 1, 7 2, 7 3, 7 4, 7 5, 7 6, 7 7, 7 8, 7 9, 8 2, 8 3, 8 4, 8 5, 8 6, 8 7, 8 8, 8 9,
|
||||
86:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 7, 1 8, 1 9, 2 4, 2 5, 2 6, 2 7, 2 8, 2 9, 3 2, 3 3, 3 4, 3 5, 3 6, 4 1, 4 2, 4 3, 5 1, 5 2, 5 3, 6 2, 6 3, 6 4, 6 5, 6 6, 7 4, 7 5, 7 6, 7 7, 7 8, 7 9, 8 7, 8 8, 8 9,
|
||||
87:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 1, 1 2, 1 3, 1 4, 1 5, 1 6, 1 7, 1 8, 1 9, 2 1, 2 2, 2 3, 2 4, 2 5, 2 6, 2 7, 2 8, 2 9, 3 2, 3 3, 3 4, 4 3, 4 4, 4 5, 5 3, 5 4, 5 5, 6 2, 6 3, 6 4, 7 1, 7 2, 7 3, 7 4, 7 5, 7 6, 7 7, 7 8, 7 9, 8 1, 8 2, 8 3, 8 4, 8 5, 8 6, 8 7, 8 8, 8 9,
|
||||
88:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 1, 1 2, 1 8, 1 9, 2 2, 2 3, 2 7, 2 8, 3 3, 3 4, 3 6, 3 7, 4 4, 4 5, 4 6, 5 4, 5 5, 5 6, 6 3, 6 4, 6 6, 6 7, 7 2, 7 3, 7 7, 7 8, 8 1, 8 2, 8 8, 8 9,
|
||||
89:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 8, 1 9, 2 7, 2 8, 3 6, 3 7, 4 1, 4 2, 4 3, 4 4, 4 5, 4 6, 5 1, 5 2, 5 3, 5 4, 5 5, 5 6, 6 6, 6 7, 7 7, 7 8, 8 8, 8 9,
|
||||
90:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 1, 1 2, 1 9, 2 1, 2 2, 2 3, 2 5, 2 9, 3 1, 3 3, 3 4, 3 5, 3 9, 4 1, 4 4, 4 5, 4 9, 5 1, 5 5, 5 6, 5 9, 6 1, 6 5, 6 6, 6 7, 6 9, 7 1, 7 5, 7 7, 7 8, 7 9, 8 1, 8 8, 8 9,
|
||||
91:
|
||||
advance: 10
|
||||
auto_update_advance: false
|
||||
auto_advance_amount: 1
|
||||
pixels: 2 1, 2 2, 2 3, 2 4, 2 5, 2 6, 2 7, 2 8, 2 9, 3 1, 3 2, 3 3, 3 4, 3 5, 3 6, 3 7, 3 8, 3 9, 4 1, 4 9, 5 1, 5 9, 6 1, 6 9,
|
||||
92:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 8, 1 9, 2 7, 2 8, 3 6, 3 7, 4 5, 4 6, 5 4, 5 5, 6 3, 6 4, 7 2, 7 3, 8 1, 8 2,
|
||||
93:
|
||||
advance: 10
|
||||
auto_update_advance: false
|
||||
auto_advance_amount: 1
|
||||
pixels: 3 1, 3 9, 4 1, 4 9, 5 1, 5 9, 6 1, 6 2, 6 3, 6 4, 6 5, 6 6, 6 7, 6 8, 6 9, 7 1, 7 2, 7 3, 7 4, 7 5, 7 6, 7 7, 7 8, 7 9,
|
||||
94:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 6, 2 6, 2 7, 3 7, 3 8, 4 8, 4 9, 5 8, 5 9, 6 7, 6 8, 7 6, 7 7, 8 6,
|
||||
96:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 2, 1 3, 1 4, 2 2, 2 3, 2 4, 2 5, 2 6, 2 7, 3 2, 3 5, 3 6, 3 7, 3 8, 4 2, 4 8, 4 9, 5 2, 5 8, 5 9, 6 2, 6 5, 6 6, 6 7, 6 8, 7 2, 7 3, 7 4, 7 5, 7 6, 7 7, 8 2, 8 3, 8 4,
|
||||
123:
|
||||
advance: 10
|
||||
auto_update_advance: false
|
||||
auto_advance_amount: 1
|
||||
pixels: 2 5, 3 2, 3 3, 3 4, 3 5, 3 6, 3 7, 3 8, 4 1, 4 2, 4 3, 4 4, 4 6, 4 7, 4 8, 4 9, 5 1, 5 9, 6 1, 6 9,
|
||||
124:
|
||||
advance: 10
|
||||
auto_update_advance: false
|
||||
auto_advance_amount: 1
|
||||
pixels: 4 1, 4 2, 4 3, 4 4, 4 5, 4 6, 4 7, 4 8, 4 9, 5 1, 5 2, 5 3, 5 4, 5 5, 5 6, 5 7, 5 8, 5 9,
|
||||
125:
|
||||
advance: 10
|
||||
auto_update_advance: false
|
||||
auto_advance_amount: 1
|
||||
pixels: 3 1, 3 9, 4 1, 4 9, 5 1, 5 2, 5 3, 5 4, 5 6, 5 7, 5 8, 5 9, 6 2, 6 3, 6 4, 6 5, 6 6, 6 7, 6 8, 7 5,
|
||||
126:
|
||||
advance: 10
|
||||
auto_update_advance: true
|
||||
auto_advance_amount: 1
|
||||
pixels: 1 7, 2 7, 2 8, 2 9, 3 8, 3 9, 4 8, 4 9, 5 7, 5 8, 6 7, 6 8, 7 7, 7 8, 7 9, 8 9,
|
|
@ -0,0 +1 @@
|
|||
pub mod vertex;
|
|
@ -0,0 +1,40 @@
|
|||
use bytemuck::{Pod, Zeroable};
|
||||
use wgpu::{BufferAddress, VertexAttribute, VertexBufferLayout, VertexFormat, VertexStepMode};
|
||||
|
||||
pub type Vector3 = [f32; 3];
|
||||
pub type RGBColor = Vector3;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(PartialEq, Copy, Clone, Debug, Zeroable, Pod)]
|
||||
pub struct Vertex {
|
||||
pub position: Vector3,
|
||||
pub color: RGBColor
|
||||
}
|
||||
|
||||
impl Vertex {
|
||||
pub fn descriptor() -> VertexBufferLayout<'static> {
|
||||
VertexBufferLayout {
|
||||
array_stride: std::mem::size_of::<Vertex>() as BufferAddress,
|
||||
step_mode: VertexStepMode::Vertex,
|
||||
attributes: &[
|
||||
VertexAttribute {
|
||||
format: VertexFormat::Float32x3,
|
||||
offset: 0,
|
||||
shader_location: 0,
|
||||
},
|
||||
VertexAttribute {
|
||||
format: VertexFormat::Float32x3,
|
||||
offset: std::mem::size_of::<Vector3>() as BufferAddress,
|
||||
shader_location: 1,
|
||||
}
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub const VERTICES: &[Vertex] = &[
|
||||
Vertex { position: [0.0, 0.5, 0.0], color: [1.0, 0.0, 0.0] },
|
||||
Vertex { position: [-0.5, -0.5, 0.0], color: [0.0, 1.0, 0.0] },
|
||||
Vertex { position: [0.5, -0.5, 0.0], color: [0.0, 0.0, 1.0] },
|
||||
];
|
||||
|
|
@ -1,26 +1,23 @@
|
|||
use crate::mode::Mode;
|
||||
use crate::text::OTextArea;
|
||||
use glyphon::{
|
||||
Attrs, Buffer, Family, FontSystem, Metrics, Resolution, Shaping, SwashCache, TextArea,
|
||||
TextAtlas, TextBounds, TextRenderer,
|
||||
};
|
||||
use nexrad2::Nexrad2Chunk;
|
||||
use raw_window_handle::HasRawDisplayHandle;
|
||||
use std::collections::HashMap;
|
||||
use std::iter;
|
||||
use std::mem::size_of;
|
||||
use std::sync::Arc;
|
||||
use glyphon::fontdb::Source;
|
||||
use web_sys::{CanvasRenderingContext2d, HtmlCanvasElement, HtmlInputElement};
|
||||
use wgpu::DeviceDescriptor;
|
||||
use wgpu::{BlendState, BufferAddress, ColorTargetState, ColorWrites, DeviceDescriptor, Face, FragmentState, FrontFace, PipelineLayoutDescriptor, PolygonMode, PrimitiveState, PrimitiveTopology, RenderPipeline, RenderPipelineDescriptor, ShaderModuleDescriptor, ShaderSource, VertexAttribute, VertexBufferLayout, VertexFormat, VertexState, VertexStepMode};
|
||||
use wgpu::{
|
||||
Backends, Color, CommandEncoderDescriptor, Device, Features, Instance, InstanceDescriptor,
|
||||
Limits, LoadOp, MultisampleState, Operations, Queue, RenderPassColorAttachment,
|
||||
RenderPassDescriptor, StoreOp, Surface, SurfaceConfiguration, SurfaceError, TextureUsages,
|
||||
TextureViewDescriptor,
|
||||
};
|
||||
use wgpu::util::DeviceExt;
|
||||
use winit::dpi::PhysicalSize;
|
||||
use winit::event::WindowEvent;
|
||||
use winit::window::Window;
|
||||
use crate::rendering::vertex::{Vector3, Vertex, VERTICES};
|
||||
|
||||
pub struct ScopeState {
|
||||
pub ar2: Option<Nexrad2Chunk>,
|
||||
|
@ -44,11 +41,8 @@ pub struct WgpuState {
|
|||
pub surface_config: SurfaceConfiguration,
|
||||
pub size: PhysicalSize<u32>,
|
||||
pub window: Window,
|
||||
pub font_system: FontSystem,
|
||||
pub font_cache: SwashCache,
|
||||
pub atlas: TextAtlas,
|
||||
pub text_renderer: TextRenderer,
|
||||
pub text_buffers: HashMap<String, OTextArea>,
|
||||
pub vertex_buffer: wgpu::Buffer,
|
||||
pub pipeline: RenderPipeline
|
||||
}
|
||||
|
||||
impl WgpuState {
|
||||
|
@ -103,14 +97,59 @@ impl WgpuState {
|
|||
|
||||
surface.configure(&device, &surface_config);
|
||||
|
||||
let mut fonts = vec![];
|
||||
fonts.push(Source::Binary(Arc::new(include_bytes!("./VT323-Regular.ttf"))));
|
||||
let vertex_buffer = device.create_buffer_init(
|
||||
&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("Vertex Buffer"),
|
||||
contents: bytemuck::cast_slice(VERTICES),
|
||||
usage: wgpu::BufferUsages::VERTEX,
|
||||
}
|
||||
);
|
||||
|
||||
let mut font_system = FontSystem::new_with_fonts(fonts.into_iter());
|
||||
let mut font_cache = SwashCache::new();
|
||||
let mut atlas = TextAtlas::new(&device, &queue, surface_format);
|
||||
let mut text_renderer =
|
||||
TextRenderer::new(&mut atlas, &device, MultisampleState::default(), None);
|
||||
let shader = device.create_shader_module(ShaderModuleDescriptor {
|
||||
label: Some("Shader"),
|
||||
source: ShaderSource::Wgsl(include_str!("./shader.wgsl").into()),
|
||||
});
|
||||
|
||||
let render_pipeline_layout = device.create_pipeline_layout(&PipelineLayoutDescriptor {
|
||||
label: Some("Render Pipeline Layout"),
|
||||
bind_group_layouts: &[],
|
||||
push_constant_ranges: &[],
|
||||
});
|
||||
|
||||
let render_pipeline = device.create_render_pipeline(&RenderPipelineDescriptor {
|
||||
label: Some("Render Pipeline"),
|
||||
layout: Some(&render_pipeline_layout),
|
||||
vertex: VertexState {
|
||||
module: &shader,
|
||||
entry_point: "vs_main",
|
||||
buffers: &[],
|
||||
},
|
||||
primitive: PrimitiveState {
|
||||
topology: PrimitiveTopology::TriangleList,
|
||||
strip_index_format: None,
|
||||
front_face: FrontFace::Ccw,
|
||||
cull_mode: Some(Face::Back),
|
||||
unclipped_depth: false,
|
||||
polygon_mode: PolygonMode::Fill,
|
||||
conservative: false,
|
||||
},
|
||||
depth_stencil: None,
|
||||
multisample: MultisampleState {
|
||||
count: 1,
|
||||
mask: !0,
|
||||
alpha_to_coverage_enabled: false,
|
||||
},
|
||||
fragment: Some(FragmentState {
|
||||
module: &shader,
|
||||
entry_point: "fs_main",
|
||||
targets: &[Some(ColorTargetState {
|
||||
format: surface_config.format,
|
||||
blend: Some(BlendState::REPLACE),
|
||||
write_mask: ColorWrites::ALL,
|
||||
})],
|
||||
}),
|
||||
multiview: None,
|
||||
});
|
||||
|
||||
Self {
|
||||
window,
|
||||
|
@ -119,11 +158,8 @@ impl WgpuState {
|
|||
queue,
|
||||
surface_config,
|
||||
size,
|
||||
font_system,
|
||||
font_cache,
|
||||
atlas,
|
||||
text_renderer,
|
||||
text_buffers: HashMap::new(),
|
||||
vertex_buffer,
|
||||
pipeline: render_pipeline
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,41 +197,6 @@ impl WgpuState {
|
|||
let physical_height =
|
||||
(self.surface_config.height as f64 * self.window.scale_factor()) as f32;
|
||||
|
||||
for textarea in self.text_buffers.values_mut() {
|
||||
// resize the buf
|
||||
textarea
|
||||
.buffer
|
||||
.set_size(&mut self.font_system, physical_width, physical_height);
|
||||
}
|
||||
|
||||
let textareas = self
|
||||
.text_buffers
|
||||
.values()
|
||||
.map(|u| TextArea {
|
||||
buffer: &u.buffer,
|
||||
left: u.left.clone() as f32,
|
||||
top: u.top.clone() as f32,
|
||||
scale: u.scale.clone() as f32,
|
||||
bounds: u.bounds.clone(),
|
||||
default_color: u.default_color.clone(),
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
self.text_renderer
|
||||
.prepare(
|
||||
&self.device,
|
||||
&self.queue,
|
||||
&mut self.font_system,
|
||||
&mut self.atlas,
|
||||
Resolution {
|
||||
width: self.surface_config.width,
|
||||
height: self.surface_config.height,
|
||||
},
|
||||
textareas,
|
||||
&mut self.font_cache,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// LOCK BLOCK
|
||||
{
|
||||
let mut render_pass = encoder.begin_render_pass(&RenderPassDescriptor {
|
||||
|
@ -218,58 +219,16 @@ impl WgpuState {
|
|||
occlusion_query_set: None,
|
||||
});
|
||||
|
||||
self.text_renderer
|
||||
.render(&self.atlas, &mut render_pass)
|
||||
.unwrap();
|
||||
render_pass.set_pipeline(&self.pipeline);
|
||||
render_pass.draw(0..3, 0..1);
|
||||
|
||||
}
|
||||
|
||||
self.queue.submit(iter::once(encoder.finish()));
|
||||
output.present();
|
||||
|
||||
self.atlas.trim();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn add_textarea(
|
||||
&mut self,
|
||||
id: String,
|
||||
metrics: Metrics,
|
||||
left: f64,
|
||||
top: f64,
|
||||
scale: f64,
|
||||
bounds: TextBounds,
|
||||
default_color: glyphon::Color,
|
||||
start_text: &str,
|
||||
) -> &mut OTextArea {
|
||||
let mut buffer = Buffer::new(&mut self.font_system, metrics);
|
||||
|
||||
let physical_width = (self.surface_config.width as f64 * self.window.scale_factor()) as f32;
|
||||
let physical_height =
|
||||
(self.surface_config.height as f64 * self.window.scale_factor()) as f32;
|
||||
|
||||
buffer.set_size(&mut self.font_system, physical_width, physical_height);
|
||||
buffer.set_text(
|
||||
&mut self.font_system,
|
||||
start_text,
|
||||
Attrs::new().family(Family::Monospace),
|
||||
Shaping::Basic,
|
||||
);
|
||||
buffer.shape_until_scroll(&mut self.font_system);
|
||||
|
||||
let textarea = OTextArea {
|
||||
left,
|
||||
top,
|
||||
scale,
|
||||
bounds,
|
||||
default_color,
|
||||
buffer,
|
||||
};
|
||||
|
||||
self.text_buffers.insert(id.clone(), textarea);
|
||||
|
||||
self.text_buffers.get_mut(&id).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Preferences {
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
// Vertex shader
|
||||
struct VertexOutput {
|
||||
@builtin(position) clip_position: vec4<f32>,
|
||||
};
|
||||
|
||||
@vertex
|
||||
fn vs_main(
|
||||
@builtin(vertex_index) in_vertex_index: u32,
|
||||
) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
let x = f32(1 - i32(in_vertex_index)) * 0.5;
|
||||
let y = f32(i32(in_vertex_index & 1u) * 2 - 1) * 0.5;
|
||||
out.clip_position = vec4<f32>(x, y, 0.0, 1.0);
|
||||
return out;
|
||||
}
|
||||
|
||||
// Fragment shader
|
||||
|
||||
@fragment
|
||||
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||
return vec4<f32>(0.3, 0.2, 0.1, 1.0);
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
use glyphon::{Buffer, Color, TextArea, TextBounds};
|
||||
|
||||
pub struct OTextArea {
|
||||
pub left: f64,
|
||||
pub top: f64,
|
||||
pub scale: f64,
|
||||
pub bounds: TextBounds,
|
||||
pub default_color: Color,
|
||||
pub buffer: Buffer,
|
||||
}
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
canvas {
|
||||
z-index: 10000;
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
|
||||
body {
|
||||
|
|
Loading…
Reference in New Issue