Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::collections::HashSet;
- use std::sync::mpsc;
- use ab_glyph_rasterizer::Rasterizer;
- use allsorts::gsub::{FeatureInfo, Features};
- use allsorts::tag;
- use librecalibrate::draw::{Point, Region};
- use librecalibrate::draw::font::{Font, LayoutOptions};
- use librecalibrate::draw::shape::Impression;
- use librecalibrate::draw::shape::raw::rounded_rect;
- use libremarkable::device::CURRENT_DEVICE;
- use libremarkable::framebuffer::{FramebufferBase, FramebufferDraw, FramebufferIO, FramebufferRefresh};
- use libremarkable::framebuffer::common::{display_temp, dither_mode, DRAWING_QUANT_BIT, mxcfb_rect, waveform_mode};
- use libremarkable::framebuffer::common::color::GRAY;
- use libremarkable::framebuffer::core::Framebuffer;
- use libremarkable::framebuffer::refresh::PartialRefreshMode;
- use libremarkable::input::{InputDevice, InputEvent};
- use libremarkable::input::ev::EvDevContext;
- use libremarkable::input::multitouch::MultitouchEvent;
- use libremarkable::input::wacom::{WacomEvent, WacomPen};
- fn main() {
- // Use /dev/fbo so that the rm2fb client can be swapped out
- let mut fb = Framebuffer::from_path("/dev/fb0" /* CURRENT_DEVICE.get_framebuffer_path() */);
- fb.clear();
- fb.full_refresh(
- waveform_mode::WAVEFORM_MODE_DU,
- display_temp::TEMP_USE_REMARKABLE_DRAW,
- dither_mode::EPDC_FLAG_EXP1,
- DRAWING_QUANT_BIT,
- true
- );
- let mut font = Font::from_bytes(include_bytes!("Inter-Regular.otf"))
- .expect("couldn't load font");
- let options = LayoutOptions {
- features: Features::Custom(vec![
- FeatureInfo {
- feature_tag: tag!(b"cv11"),
- alternate: None
- }
- ]),
- ..Default::default()
- };
- const TEXT_SIZE: f32 = 32.0; // Pixels per em value
- const BUTTON_X_PADDING: f32 = 32.0;
- const BUTTON_Y_PADDING: f32 = 24.0;
- const BUTTON_BORDER_RADIUS: f32 = 6.0;
- const BUTTON_OUTLINE_WIDTH: f32 = 3.0;
- let span = font.shape("Tap this button to exit! UwU~", &options)
- .expect("failed to layout button text");
- let text_bounds = span.bounding_box(&mut font, TEXT_SIZE);
- let button_size = (
- text_bounds.extents.0 + (BUTTON_X_PADDING * 2.0),
- text_bounds.metrics.cap_height + (BUTTON_Y_PADDING * 2.0)
- );
- let button_pos = (
- (1404.0 - button_size.0) / 2.0,
- (1872.0 - button_size.1) / 2.0
- );
- let text_pos = (
- button_pos.0 + BUTTON_X_PADDING,
- button_pos.1 + BUTTON_Y_PADDING + (text_bounds.metrics.cap_height - TEXT_SIZE)
- );
- let ras_min_x = button_pos.0 as usize;
- let ras_min_y = button_pos.1 as usize;
- let ras_max_x = (button_pos.0 + button_size.0).ceil() as usize;
- let ras_max_y = (button_pos.1 + button_size.1).ceil() as usize;
- eprintln!("({}, {}) -> ({}, {})", ras_min_x, ras_min_y, ras_max_x, ras_max_y);
- let mut ras = Rasterizer::new(ras_max_x - ras_min_x, ras_max_y - ras_min_y);
- let button_region = Region::new(button_pos.0.fract(), button_pos.1.fract(), button_size.0, button_size.1);
- let mut draw_btn = |fb: &mut Framebuffer, pressed: bool| {
- ras.clear();
- if pressed {
- rounded_rect(&mut ras, button_region, BUTTON_BORDER_RADIUS, Impression::Negative);
- } else {
- rounded_rect(&mut ras, button_region, BUTTON_BORDER_RADIUS, Impression::Positive);
- rounded_rect(&mut ras, button_region.inset(BUTTON_OUTLINE_WIDTH), (BUTTON_BORDER_RADIUS - BUTTON_OUTLINE_WIDTH).max(0.0), Impression::Negative);
- }
- span.rasterize_to(&mut ras, &mut font, (text_pos.0 - ras_min_x as f32, text_pos.1 - ras_min_y as f32), TEXT_SIZE);
- ras.for_each_pixel_2d(|x, y, a| {
- let color = GRAY((a * 256.0).max(0.0).min(255.999) as u8);
- //let color = if a >= 0.5 { color::BLACK } else { color::WHITE };
- fb.write_pixel((x as i32 + ras_min_x as i32, y as i32 + ras_min_y as i32).into(), color);
- });
- fb.partial_refresh(
- &mxcfb_rect {
- left: ras_min_x as _,
- top: ras_min_y as _,
- width: (ras_max_x - ras_min_x) as _,
- height: (ras_max_y - ras_min_y) as _
- },
- PartialRefreshMode::Async,
- waveform_mode::WAVEFORM_MODE_GC16_FAST,
- display_temp::TEMP_USE_REMARKABLE_DRAW,
- dither_mode::EPDC_FLAG_EXP1,
- DRAWING_QUANT_BIT,
- false
- )
- };
- draw_btn(&mut fb, false);
- let (tx, rx) = mpsc::channel::<InputEvent>();
- let mut touch_ctx = EvDevContext::new(InputDevice::Multitouch, tx.clone());
- let mut wacom_ctx = EvDevContext::new(InputDevice::Wacom, tx.clone());
- touch_ctx.start();
- wacom_ctx.start();
- let mut fingers_on_btn = HashSet::with_capacity(16);
- let mut wacom_on_btn = false;
- let mut wacom_pen_position = (0.0, 0.0);
- let mut button_clicked = false;
- let button_region_wacom = button_region.offsetted((ras_min_x as f32, ras_min_y as f32));
- let button_region_touch = button_region_wacom.inset(-24.0);
- loop {
- let event = rx.recv()
- .expect("couldn't receive from input channel");
- let button_pressed_before = !fingers_on_btn.is_empty() || wacom_on_btn;
- match event {
- InputEvent::MultitouchEvent { event } => match event {
- MultitouchEvent::Press { finger } => {
- let pos: Point = (finger.pos.x as f32, finger.pos.y as f32);
- if button_region_touch.contains(pos) {
- fingers_on_btn.insert(finger.tracking_id);
- }
- }
- MultitouchEvent::Release { finger } => {
- let pos: Point = (finger.pos.x as f32, finger.pos.y as f32);
- if fingers_on_btn.remove(&finger.tracking_id) && button_region_touch.contains(pos) {
- button_clicked = true;
- }
- }
- _ => {}
- }
- InputEvent::WacomEvent { event } => match event {
- WacomEvent::Hover { position, .. } |
- WacomEvent::Draw { position, .. } => {
- wacom_pen_position = (position.x, position.y);
- }
- WacomEvent::InstrumentChange { pen, state } => {
- if pen == WacomPen::Touch {
- if state {
- wacom_on_btn = button_region_wacom.contains(wacom_pen_position);
- } else if std::mem::replace(&mut wacom_on_btn, false) && button_region_wacom.contains(wacom_pen_position) {
- button_clicked = true;
- }
- }
- }
- _ => {}
- }
- _ => {}
- }
- let button_pressed_after = !fingers_on_btn.is_empty() || wacom_on_btn;
- if button_clicked {
- fb.clear();
- fb.full_refresh(
- waveform_mode::WAVEFORM_MODE_DU,
- display_temp::TEMP_USE_REMARKABLE_DRAW,
- dither_mode::EPDC_FLAG_EXP1,
- DRAWING_QUANT_BIT,
- false
- );
- break
- } else if button_pressed_after != button_pressed_before {
- draw_btn(&mut fb, button_pressed_after);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment