Skip to content

Commit

Permalink
wip: fonts and status bar
Browse files Browse the repository at this point in the history
  • Loading branch information
adamws committed Dec 13, 2023
1 parent 35e1433 commit dc5f7cf
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 6 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ path = "src/lib.rs"
clap = { version = "4.4.6", features = ["derive"] }
env_logger = "0.10.0"
log = "0.4.20"
sdl2 = { version = "0.36.0", default-features = false }
sdl2 = { version = "0.36.0", default-features = false, features = ["ttf"] }
cairo-rs = { version = "0.18.2", optional = true }
librsvg = { version = "2.57.0", optional = true }
resvg = { version = "0.36.0", optional = true }
Expand All @@ -44,7 +44,7 @@ rgb = "0.8.37"
rstest = "0.18.2"

[package.metadata.vcpkg]
dependencies = ["sdl2"]
dependencies = ["sdl2", "sdl2-ttf"]
git = "https://github.com/microsoft/vcpkg"
rev = "a42af01" # release 2023.11.20

Expand Down
7 changes: 7 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
fn main() {
// fix for static linking issue (undefined references to 'deflate')
// caused by wrong order of -lz -png (defining group with correct order
// fixes that)
#[cfg(target_os="linux")]
println!("cargo:rustc-link-arg=-Wl,--start-group,-lpng,-lz,--end-group");
}
Binary file added resources/DejaVuSansMono.ttf
Binary file not shown.
169 changes: 165 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use sdl2::rect::Rect;
use sdl2::render::Canvas;
use sdl2::render::Texture;
use sdl2::render::TextureCreator;
use sdl2::rwops::RWops;
use sdl2::video::Window;
use sdl2::video::WindowContext;
use sdl2::VideoSubsystem;
Expand Down Expand Up @@ -456,6 +457,136 @@ impl<'a> CanvasEntity for CheckerBoard<'a> {
}
}

mod digits_display_module {
use sdl2::pixels::Color;
use sdl2::rect::Point;
use sdl2::rect::Rect;
use sdl2::render::Texture;
use sdl2::render::TextureCreator;
use sdl2::render::TextureQuery;
use sdl2::ttf::Font;
use sdl2::video::WindowContext;

use super::CanvasEntity;

fn to_digits(digits: &mut Vec<u8>, value: i32) {
digits.clear();
let mut v = value.abs();
loop {
let d: u8 = (v % 10) as u8;
v = v / 10;
digits.push(d);
if v == 0 {
break;
};
}
}

pub struct DigitsDisplay<'a> {
texture: Texture<'a>,
glyph_width: u32,
glyph_height: u32,
position: Point,
sign: bool,
digits: Vec<u8>,
}

impl<'a> DigitsDisplay<'a> {
pub fn new(
font: &Font,
texture_creator: &'a TextureCreator<WindowContext>,
) -> Result<DigitsDisplay<'a>, String> {
let font_surface = font
.render("0123456789-")
.blended(Color::RGBA(0, 0, 0, 255))
.map_err(|e| e.to_string())?;

let texture = texture_creator
.create_texture_from_surface(&font_surface)
.map_err(|e| e.to_string())?;

let TextureQuery { width, height, .. } = texture.query();
let glyph_width = width / 11;
let glyph_height = height;

Ok(DigitsDisplay {
texture,
glyph_width,
glyph_height,
position: Point::new(0, 0),
sign: false,
digits: Vec::with_capacity(64),
})
}

pub fn update(&mut self, value: i32) {
self.sign = value < 0;
to_digits(&mut self.digits, value);
}
}

impl<'a> CanvasEntity for DigitsDisplay<'a> {
fn draw(&self, renderer: &mut sdl2::render::WindowCanvas) -> Result<(), String> {
let glyph_width = self.glyph_width;
let glyph_height = self.glyph_height;

let mut m = 0u32;

let mut render = |index: u32, position: u32| -> Result<(), String> {
renderer.copy(
&self.texture,
Rect::new((glyph_width * index) as i32, 0, glyph_width, glyph_height),
Rect::new(
self.position.x + (glyph_width * position) as i32,
self.position.y,
glyph_width,
glyph_height,
),
)
};

if self.sign {
render(10, m)?;
m += 1;
}

for &digit in self.digits.iter().rev() {
render(digit as u32, m)?;
m += 1;
}
Ok(())
}

fn size(&self) -> (u32, u32) {
let TextureQuery { width, height, .. } = self.texture.query();
(width, height)
}

fn reposition(&mut self, position: Point) {
self.position = position;
}
}

#[cfg(test)]
mod test {
use super::*;

#[test]
fn test_to_digits() {
let mut vec = Vec::<u8>::with_capacity(64);
to_digits(&mut vec, 123);
assert_eq!(vec, vec![3, 2, 1]);
}

#[test]
fn test_to_digits_negative() {
let mut vec = Vec::<u8>::with_capacity(64);
to_digits(&mut vec, -123);
assert_eq!(vec, vec![3, 2, 1]);
}
}
}

fn get_texture_builder<'a, P: AsRef<Path>>(
path: P,
backend: SvgBackend,
Expand Down Expand Up @@ -615,6 +746,19 @@ pub fn app<P: AsRef<Path>>(
let sdl_context = sdl2::init()?;

let video_subsystem = sdl_context.video()?;
let ttf_context = sdl2::ttf::init().map_err(|e| e.to_string())?;

let mut db = fontdb::Database::new();
db.load_system_fonts();
//println!()
for f in db.faces() {
println!("{:?}", f);
}

// Load a font TODO: not sure if needed backup, perhaps will load with fontdb only
let font = include_bytes!("../resources/DejaVuSansMono.ttf");
let font = &ttf_context
.load_font_from_rwops(RWops::from_bytes(font)?, 16)?;

let min_size: (u32, u32) = (800, 600);
let max_size: (u32, u32) = get_max_window_size(&video_subsystem)?;
Expand Down Expand Up @@ -671,13 +815,16 @@ pub fn app<P: AsRef<Path>>(
));
}

// canvas elements:
let left = left_svg.rasterize(&texture_creator, scale)?;
let right = right_svg.rasterize(&texture_creator, scale)?;

let mut drag = drag_module::Drag::new();
let mut diff = Diff::new(left, right);
let mut workarea = CheckerBoard::new(&texture_creator, diff.size())?;
let mut mouse_x_cord = digits_display_module::DigitsDisplay::new(&font, &texture_creator)?;
let mut mouse_y_cord = digits_display_module::DigitsDisplay::new(&font, &texture_creator)?;

// app logic handling:
let mut drag = drag_module::Drag::new();
let mut event_pump = sdl_context.event_pump()?;

'running: loop {
Expand All @@ -686,7 +833,8 @@ pub fn app<P: AsRef<Path>>(
canvas.set_draw_color(Color::RGBA(255, 255, 255, 255));
canvas.clear();

let mut center = canvas.viewport().center();
let viewport = canvas.viewport();
let mut center = viewport.center();

for event in event_pump.poll_iter() {
match event {
Expand Down Expand Up @@ -746,10 +894,23 @@ pub fn app<P: AsRef<Path>>(
diff.update(&mouse_state);
diff.draw(&mut canvas)?;

// TODO: should display coordinates inside working area and not inside window
mouse_x_cord.update(mouse_state.x());
mouse_x_cord
.reposition(viewport.bottom_left() - Point::new(0, mouse_x_cord.size().1 as i32));
mouse_x_cord.draw(&mut canvas)?;

mouse_y_cord.update(mouse_state.y());
mouse_y_cord.reposition(
viewport.bottom_left() + Point::new(100, 0) // TODO: better calculation for position
- Point::new(0, mouse_x_cord.size().1 as i32),
);
mouse_y_cord.draw(&mut canvas)?;

canvas.present();

let frame_duration = frame_start.elapsed().as_micros() as u64;
trace!("Frame duration: {}us", frame_duration);
trace!("Frame duration average: {}us", frame_duration);

match testing {
Some(val) => {
Expand Down

0 comments on commit dc5f7cf

Please sign in to comment.