multiview example

This commit is contained in:
Jeremy Soller 2023-12-14 10:38:58 -07:00
parent c247e0527c
commit 6528e9f804
3 changed files with 197 additions and 0 deletions

View file

@ -0,0 +1,17 @@
[package]
name = "multiview"
version = "0.1.0"
authors = ["Jeremy Soller <jeremy@system76.com>"]
edition = "2021"
license = "MIT OR Apache-2.0"
publish = false
[dependencies]
cosmic-text = { path = "../.." }
env_logger = "0.10"
fontdb = "0.13"
log = "0.4"
softbuffer = "0.4"
tiny-skia = "0.11"
unicode-segmentation = "1.7"
winit = "0.29"

View file

@ -0,0 +1,177 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
use cosmic_text::{Action, Attrs, Buffer, Edit, Family, FontSystem, Metrics, Shaping, SwashCache};
use std::{collections::HashMap, env, fs, num::NonZeroU32, rc::Rc, slice};
use tiny_skia::{Color, Paint, PixmapMut, Rect, Transform};
use winit::{
event::{ElementState, Event, KeyEvent, WindowEvent},
event_loop::{ControlFlow, EventLoop},
keyboard::{Key, NamedKey},
window::{Window as WinitWindow, WindowBuilder},
};
fn main() {
env_logger::init();
let path = if let Some(arg) = env::args().nth(1) {
arg
} else {
"sample/hello.txt".to_string()
};
let mut font_system = FontSystem::new();
let mut swash_cache = SwashCache::new();
let mut buffer = Buffer::new_empty(Metrics::new(14.0, 20.0));
let mut buffer = buffer.borrow_with(&mut font_system);
let attrs = Attrs::new().family(Family::Monospace);
match fs::read_to_string(&path) {
Ok(text) => buffer.set_text(&text, attrs, Shaping::Advanced),
Err(err) => {
log::error!("failed to load {:?}: {}", path, err);
}
}
let event_loop = EventLoop::new().unwrap();
struct Window {
window: Rc<WinitWindow>,
context: softbuffer::Context<Rc<WinitWindow>>,
surface: softbuffer::Surface<Rc<WinitWindow>, Rc<WinitWindow>>,
scroll: i32,
}
let mut windows = HashMap::new();
for _ in 0..2 {
let window = Rc::new(WindowBuilder::new().build(&event_loop).unwrap());
let context = softbuffer::Context::new(window.clone()).unwrap();
let surface = softbuffer::Surface::new(&context, window.clone()).unwrap();
windows.insert(
window.id(),
Window {
window,
context,
surface,
scroll: 0,
},
);
}
event_loop
.run(move |event, elwt| {
elwt.set_control_flow(ControlFlow::Wait);
match event {
Event::WindowEvent {
window_id,
event: WindowEvent::RedrawRequested,
} => {
if let Some(Window {
window,
surface,
scroll,
..
}) = windows.get_mut(&window_id)
{
let (width, height) = {
let size = window.inner_size();
(size.width, size.height)
};
surface
.resize(
NonZeroU32::new(width).unwrap(),
NonZeroU32::new(height).unwrap(),
)
.unwrap();
let mut surface_buffer = surface.buffer_mut().unwrap();
let surface_buffer_u8 = unsafe {
slice::from_raw_parts_mut(
surface_buffer.as_mut_ptr() as *mut u8,
surface_buffer.len() * 4,
)
};
let mut pixmap =
PixmapMut::from_bytes(surface_buffer_u8, width, height).unwrap();
pixmap.fill(Color::from_rgba8(0, 0, 0, 0xFF));
// Set scroll to view scroll
buffer.set_scroll(*scroll);
// Set size, will relayout and shape until scroll if changed
buffer.set_size(width as f32, height as f32);
// Shape until scroll, ensures scroll is clamped
buffer.shape_until_scroll();
// Update scroll after buffer clamps it
*scroll = buffer.scroll();
let mut paint = Paint::default();
paint.anti_alias = false;
let transform = Transform::identity();
buffer.draw(
&mut swash_cache,
cosmic_text::Color::rgb(0xFF, 0xFF, 0xFF),
|x, y, w, h, color| {
paint.set_color_rgba8(color.r(), color.g(), color.b(), color.a());
pixmap.fill_rect(
Rect::from_xywh(x as f32, y as f32, w as f32, h as f32)
.unwrap(),
&paint,
transform,
None,
);
},
);
surface_buffer.present().unwrap();
}
}
Event::WindowEvent {
event:
WindowEvent::KeyboardInput {
event:
KeyEvent {
logical_key,
text,
state,
..
},
..
},
window_id,
} => {
if let Some(Window { window, scroll, .. }) = windows.get_mut(&window_id) {
if state == ElementState::Pressed {
match logical_key {
Key::Named(NamedKey::ArrowDown) => {
*scroll += 1;
}
Key::Named(NamedKey::ArrowUp) => {
*scroll -= 1;
}
Key::Named(NamedKey::PageDown) => {
*scroll += buffer.visible_lines();
}
Key::Named(NamedKey::PageUp) => {
*scroll -= buffer.visible_lines();
}
_ => {}
}
}
println!("{:?} {:?} {:?}", logical_key, text, state);
window.request_redraw();
}
}
Event::WindowEvent {
event: WindowEvent::CloseRequested,
window_id: _,
} => {
//TODO: just close one window
elwt.exit();
}
_ => {}
}
})
.unwrap();
}

3
multiview.sh Executable file
View file

@ -0,0 +1,3 @@
# SPDX-License-Identifier: MIT OR Apache-2.0
RUST_LOG="cosmic_text=debug,multiview=debug" cargo run --release --package multiview -- "$@"