| -rw-r--r-- | Cargo.lock | 6 | ||||
| -rw-r--r-- | rust-toolchain.toml | 2 | ||||
| -rw-r--r-- | src/lib.rs | 214 | ||||
| -rw-r--r-- | tests/test.rs | 1 |
4 files changed, 138 insertions, 85 deletions
@@ -125,7 +125,7 @@ checksum = "6a02dba6a60cd31533cf16561ced53239686d18f1464bff49579dd320fcea081" [[package]] name = "fimg" version = "0.4.51" -source = "git+https://git.bendn.org/fimg#be42cdc5c0e981915236b1bff7857256c4ae3458" +source = "git+https://git.bendn.org/fimg#1826223f5db471ea18f95ca2685cb4d009b104ad" dependencies = [ "array_chunks", "atools 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -269,9 +269,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.44" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" +checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a" dependencies = [ "proc-macro2", ] diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..5d56faf --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly" @@ -6,6 +6,7 @@ const_default, derive_const, const_ops, + bigint_helper_methods, proc_macro_hygiene, portable_simd, super_let, @@ -115,8 +116,7 @@ pub unsafe fn render_owned( subpixel: bool, ) -> Image<Box<[u8]>, 3> { let (w, h) = size(&fonts.regular, ppem, line_spacing, (c, r)); - let mut i = Image::build(w as u32, h as u32).fill([0, 255, 0]); - dbg!(i.width()); + let mut i = Image::build(w as u32, h as u32).fill([255; 3]); render( cells, (c, r), @@ -129,7 +129,6 @@ pub unsafe fn render_owned( ); i } - #[implicit_fn::implicit_fn] pub unsafe fn render( cells: &[Cell], @@ -244,9 +243,7 @@ pub unsafe fn render( let mut s = None; let mut l = vec![]; shaper.shape_with(|x| { - s = s.or_else(|| { - x.glyphs.get(0).map(|x| x.data) - }); + s = s.or(Some(x.glyphs[0].data)); l.extend( x.glyphs.into_iter().map(|x| (x.id, x.x)), ); @@ -383,7 +380,6 @@ pub unsafe fn render( + (k as f32 * line_spacing as f32 * fac) as i32) + offset_y as i32) .max(0) as u32; - if subpixel { into( i.as_mut(), @@ -396,7 +392,6 @@ pub unsafe fn render( color.map(_ as _), ); } else { - dbg!(&x.content); i.as_mut().blend_alpha_and_color_at( &Image::build( x.placement.width, @@ -511,60 +506,108 @@ fn into( (x_, y_): (u32, u32), color: [u8; 3], ) { + type u8x24 = Simd<u8, 24>; + type u8x12 = Simd<u8, 12>; + type u8x6 = u8x6; use std::simd::prelude::*; - let c10 = Simd::from_array([color; 10].flatten()).cast::<u16>(); - let c4 = Simd::from_array([color; 4].flatten()).cast::<u16>(); + let c = u8x24::from_array([color; 8].flatten()).cast::<u16>(); + let c2 = u8x12::from_array([color; 4].flatten()).cast::<u16>(); + let c3 = u8x6::from_array([color; 2].flatten()).cast::<u16>(); for y in 0..with.height() { let mut wx_ = 0; - macro_rules! read { - ($k:ident $n:literal, $c:ident) => { - $k with.width() - wx_ >= $n { - // (wx..wx + $n) * 4 - let first8 = unsafe { - with.pixels((wx_..wx_ + $n, y)) - .as_ptr() - .cast::<Simd<u8, { $n * 4 }>>() - .read_unaligned() - }; - const BGR_DISCARD_ALPHA: [usize; $n * 3] = car::map!( - range::<{ $n * 4 }>().chunked::<4>(), - |[r, g, b, _]| [b, g, r] - ) - .flatten(); - let mask = simd_swizzle!(first8, BGR_DISCARD_ALPHA); - let mask = mask.cast(); - let to_b = unsafe { - i.pixels_mut((x_ + wx_..x_ + wx_ + $n, y + y_)) - } + while with.width() - wx_ >= 8 { + unsafe { + // 0..32 + let first8 = u8x32::from_array( + with.pixels((wx_..wx_ + 8, y)) + .as_array::<8>() + .unwrap_unchecked() + .flatten(), + ); + const BGR_DISCARD_ALPHA: [usize; 24] = car::map!( + range::<32>().chunked::<4>(), + |[r, g, b, _]| [b, g, r] + ) + .flatten(); + + let mask: u8x24 = simd_swizzle!(first8, BGR_DISCARD_ALPHA); + let mask = mask.cast(); + let to_b = i + .pixels_mut((x_ + wx_..x_ + wx_ + 8, y + y_)) .as_flattened_mut(); - let to = unsafe { - to_b.as_ptr() - .cast::<Simd<u8, { $n * 3 }>>() - .read_unaligned() - } - .cast::<u16>(); - let result = (($c * mask - + (Simd::splat(255) - mask) * to.cast()) - / Simd::splat(255)) - .cast::<u8>(); - if cfg!(miri) { - to_b.copy_from_slice(&result.to_array()); - } else { - unsafe { core::hint::assert_unchecked(to_b.len()==$n*3) }; - result.copy_to_slice(to_b); - } - wx_ += $n; - } + let to = u8x24::load_or_default(to_b).cast::<u16>(); + let result: u8x24 = ((c * mask + + (Simd::splat(255) - mask) * to.cast()) + / Simd::splat(255)) + .cast::<u8>(); + result.store_select(to_b, Mask::from_bitmask(!0)); + + wx_ += 8; }; } - - read!(while 10, c10); - read!(if 4, c4); - let mut n = with.width().saturating_sub(wx_); - if n + x_ + wx_ > i.width() { - n = lower::saturating::math! { i.width() - x_ - wx_}; + while with.width() - wx_ >= 4 { + unsafe { + // 0..32 + let first8 = u8x16::from_array( + with.pixels((wx_..wx_ + 4, y)) + .as_array::<4>() + .unwrap_unchecked() + .flatten(), + ); + const BGR_DISCARD_ALPHA: [usize; 12] = car::map!( + range::<16>().chunked::<4>(), + |[r, g, b, _]| [b, g, r] + ) + .flatten(); + + let mask: u8x12 = simd_swizzle!(first8, BGR_DISCARD_ALPHA); + let mask = mask.cast(); + let to_b = i + .pixels_mut((x_ + wx_..x_ + wx_ + 4, y + y_)) + .as_flattened_mut(); + let to = u8x12::load_or_default(to_b).cast::<u16>(); + let result: u8x12 = ((c2 * mask + + (Simd::splat(255) - mask) * to.cast()) + / Simd::splat(255)) + .cast::<u8>(); + result.store_select(to_b, Mask::from_bitmask(!0)); + + wx_ += 4; + }; } - unsafe { core::hint::assert_unchecked(n < 10) }; + while with.width() - wx_ >= 2 { + unsafe { + // 0..32 + let first8 = u8x8::from_array( + with.pixels((wx_..wx_ + 2, y)) + .as_array::<2>() + .unwrap_unchecked() + .flatten(), + ); + const BGR_DISCARD_ALPHA: [usize; 6] = car::map!( + range::<8>().chunked::<4>(), + |[r, g, b, _]| [b, g, r] + ) + .flatten(); + + let mask: u8x6 = simd_swizzle!(first8, BGR_DISCARD_ALPHA); + let mask = mask.cast(); + let to_b = i + .pixels_mut((x_ + wx_..x_ + wx_ + 4, y + y_)) + .as_flattened_mut(); + let to = u8x6::load_or_default(to_b).cast::<u16>(); + let result: u8x6 = ((c2 * mask + + (Simd::splat(255) - mask) * to.cast()) + / Simd::splat(255)) + .cast::<u8>(); + result.store_select(to_b, Mask::from_bitmask(!0)); + + wx_ += 2; + }; + } + + let n = with.width() - wx_; + assert!(n < 4); for k in 0..n { let x = k + wx_; let d = unsafe { with.pixel(x, y) }; @@ -574,6 +617,15 @@ fn into( let mask = d.init(); blend(mask, color, x); } + // assert!(with.width() - wx_ < 4); + // for x in wx_..with.width() { + // let d = unsafe { with.pixel(x, y) }; + // let x = unsafe { + // i.pixel_mut(x.wrapping_add(x_), y.wrapping_add(y_)) + // }; + // let mask = d.init(); + // blend(mask, color, x); + // } } } @@ -620,15 +672,14 @@ pub unsafe fn fill_in( with: [u8; 3], ) { let iw = image.width(); - let w = if x1 + w >= iw { iw - x1 - 1 } else { w }; for x in x1..1 + w + x1 { - image.set_pixel(x, y1, &with); + image.set_pixel(x, y1, with); } let from = y1 * iw + x1; let p = image.buffer_mut().as_mut_ptr(); macro_rules! d_ { () => {{ - let n = (w as usize + 1) * 3; + let n = w as usize * 3; let from = p.add(from as usize * 3); for y in y1 + 1..(y1 + h).min(image.height()) { @@ -656,54 +707,55 @@ pub fn dims(font: &FontRef, ppem: f32) -> (f32, f32) { fn x() { pub static FONT: std::sync::LazyLock<FontRef<'static>> = std::sync::LazyLock::new(|| { - FontRef::from_index(&include_bytes!("../../CCNF-R.ttf")[..], 0) - .unwrap() + FontRef::from_index( + &include_bytes!("../../CascadiaCodeNF.ttf")[..], + 0, + ) + .unwrap() }); unsafe { let z = [ Cell { style: Style { - bg: [0, 0, 0], + bg: [31, 36, 48], fg: [255, 255, 255], - // flags: Style::UNDERCURL, + flags: Style::UNDERCURL, ..default() }, - letter: Some('E'), + letter: Some('['), }, Cell { style: Style { - bg: [0, 0, 0], - fg: [255, 255, 255], - // flags: Style::UNDERCURL, + bg: [31, 36, 48], + fg: [255, 173, 102], + flags: Style::UNDERCURL, ..default() }, - letter: Some('H'), + letter: Some('='), }, Cell { style: Style { - bg: [0, 0, 0], - fg: [255; 3], + bg: [31, 36, 48], + fg: [204, 202, 194], secondary_color: [255; 3], - // flags: Style::UNDERLINE | Style::USE_SECONDARY_COLOR, - flags: 0, + flags: Style::UNDERLINE | Style::USE_SECONDARY_COLOR, }, - letter: Some('F'), + letter: Some('s'), }, Cell { style: Style { - bg: [0, 0, 0], - fg: [255; 3], + bg: [31, 36, 48], + fg: [255, 173, 102], secondary_color: [255; 3], - // flags: Style::UNDERLINE | Style::USE_SECONDARY_COLOR, - flags: 0, + flags: Style::UNDERLINE | Style::USE_SECONDARY_COLOR, }, - letter: Some('t'), + letter: Some('>'), }, Cell { style: Style { - bg: [0, 0, 0], - // flags: Style::UNDERLINE, + bg: [31, 36, 48], + flags: Style::UNDERLINE, fg: [255, 255, 255], ..default() }, @@ -711,8 +763,8 @@ fn x() { }, ]; let mut f = Fonts::new(*FONT, *FONT, *FONT, *FONT); - // let y = render_owned(&z, (2, 2), 18.0, &mut f, 2.0, true); - render_owned(&z, (2, 2), 18.0, &mut f, 2.0, false).show(); + render_owned(&z, (2, 2), 18.0, &mut f, 2.0, true); + render_owned(&z, (2, 2), 18.0, &mut f, 2.0, true).show(); // let cells = Cell::load(include_bytes!("../cells")); // render_owned( // &cells, diff --git a/tests/test.rs b/tests/test.rs index f76ec33..3a4ae1e 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -44,7 +44,6 @@ fn main() { }; assert_eq!(include_bytes!("res"), x.bytes()); std::hint::black_box(x); - // println!("{:?}", now.elapsed()); // x.as_ref().show(); } |