2019-07-30 16:31:42 +02:00
|
|
|
use crate::buffer::Buffer;
|
2019-07-31 00:42:03 +02:00
|
|
|
use crate::color::Color;
|
2019-07-30 16:31:42 +02:00
|
|
|
use rusttype::{point, Font, Scale};
|
|
|
|
|
|
2019-07-31 00:42:03 +02:00
|
|
|
pub static DEJAVUSANS_MONO: &'static [u8] = include_bytes!("../fonts/dejavu/DejaVuSansMono.ttf");
|
|
|
|
|
pub static ROBOTO_REGULAR: &'static [u8] = include_bytes!("../fonts/Roboto-Regular.ttf");
|
2019-07-30 16:31:42 +02:00
|
|
|
|
2019-07-31 00:42:03 +02:00
|
|
|
pub fn draw_text(
|
2019-07-30 16:31:42 +02:00
|
|
|
font_data: &'static [u8],
|
|
|
|
|
buf: &mut Buffer,
|
|
|
|
|
background_color: &Color,
|
|
|
|
|
color: &Color,
|
|
|
|
|
size: f32,
|
|
|
|
|
s: &str,
|
|
|
|
|
) -> Result<(), ::std::io::Error> {
|
|
|
|
|
// Load the font
|
|
|
|
|
// This only succeeds if collection consists of one font
|
|
|
|
|
let font = Font::from_bytes(font_data as &[u8]).expect("Error constructing Font");
|
|
|
|
|
|
|
|
|
|
// The font size to use
|
|
|
|
|
let scale = Scale::uniform(size);
|
|
|
|
|
|
|
|
|
|
let v_metrics = font.v_metrics(scale);
|
|
|
|
|
|
|
|
|
|
// layout the glyphs in a line with 20 pixels padding
|
|
|
|
|
let glyphs: Vec<_> = font
|
2019-07-31 00:42:03 +02:00
|
|
|
.layout(s, scale, point(0.0, v_metrics.ascent))
|
2019-07-30 16:31:42 +02:00
|
|
|
.collect();
|
|
|
|
|
|
|
|
|
|
// Loop through the glyphs in the text, positing each one on a line
|
|
|
|
|
for glyph in glyphs {
|
|
|
|
|
if let Some(bounding_box) = glyph.pixel_bounding_box() {
|
|
|
|
|
// Draw the glyph into the image per-pixel by using the draw closure
|
|
|
|
|
glyph.draw(|x, y, o| {
|
|
|
|
|
let x = x + bounding_box.min.x as u32;
|
|
|
|
|
let y = y + bounding_box.min.y as u32;
|
|
|
|
|
let o = if o > 1.0 {
|
|
|
|
|
1.0
|
|
|
|
|
} else if o < 0.0 {
|
|
|
|
|
0.0
|
|
|
|
|
} else {
|
|
|
|
|
o
|
|
|
|
|
};
|
|
|
|
|
buf.put((x, y), &background_color.blend(color, o));
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-31 00:42:03 +02:00
|
|
|
pub fn draw_text_fixed_width(
|
2019-07-30 16:31:42 +02:00
|
|
|
font_data: &'static [u8],
|
|
|
|
|
buf: &mut Buffer,
|
|
|
|
|
background_color: &Color,
|
|
|
|
|
color: &Color,
|
|
|
|
|
size: f32,
|
|
|
|
|
distances: Vec<u32>,
|
|
|
|
|
s: &str,
|
|
|
|
|
) -> Result<(), ::std::io::Error> {
|
|
|
|
|
// Load the font
|
|
|
|
|
// This only succeeds if collection consists of one font
|
|
|
|
|
let font = Font::from_bytes(font_data as &[u8]).expect("Error constructing Font");
|
|
|
|
|
|
|
|
|
|
// The font size to use
|
|
|
|
|
let scale = Scale::uniform(size);
|
|
|
|
|
|
|
|
|
|
let v_metrics = font.v_metrics(scale);
|
|
|
|
|
|
|
|
|
|
// layout the glyphs in a line with 20 pixels padding
|
|
|
|
|
let glyphs: Vec<_> = font
|
2019-07-31 00:42:03 +02:00
|
|
|
.layout(s, scale, point(0.0, v_metrics.ascent))
|
2019-07-30 16:31:42 +02:00
|
|
|
.collect();
|
|
|
|
|
|
|
|
|
|
// Loop through the glyphs in the text, positing each one on a line
|
|
|
|
|
let mut x_pos: usize = 0;
|
|
|
|
|
let mut x_off: u32 = 0;
|
|
|
|
|
for glyph in glyphs {
|
|
|
|
|
if let Some(bounding_box) = glyph.pixel_bounding_box() {
|
|
|
|
|
let x_dist = distances[x_pos];
|
|
|
|
|
let width = (bounding_box.max.x - bounding_box.min.x) as u32;
|
|
|
|
|
let offset = (x_dist - width) / 2;
|
|
|
|
|
// Draw the glyph into the image per-pixel by using the draw closure
|
|
|
|
|
glyph.draw(|x, y, o| {
|
|
|
|
|
let off = x_off + offset + 20;
|
|
|
|
|
let x = x + off as u32;
|
|
|
|
|
let y = y + bounding_box.min.y as u32;
|
|
|
|
|
let o = if o > 1.0 {
|
|
|
|
|
1.0
|
|
|
|
|
} else if o < 0.0 {
|
|
|
|
|
0.0
|
|
|
|
|
} else {
|
|
|
|
|
o
|
|
|
|
|
};
|
|
|
|
|
buf.put((x, y), &background_color.blend(color, o));
|
|
|
|
|
});
|
|
|
|
|
x_pos += 1;
|
|
|
|
|
x_off += x_dist;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
2019-08-01 00:09:51 +02:00
|
|
|
|
|
|
|
|
pub fn draw_bar(
|
|
|
|
|
buf: &mut Buffer,
|
|
|
|
|
background_color: &Color,
|
|
|
|
|
color: &Color,
|
|
|
|
|
length: u32,
|
|
|
|
|
height: u32,
|
|
|
|
|
fill: f32,
|
|
|
|
|
) -> Result<(), ::std::io::Error> {
|
|
|
|
|
let mut buf = buf.subdimensions((0, 0, length, height));
|
|
|
|
|
|
2019-08-01 11:07:33 +02:00
|
|
|
let mut fill_pos = ((length as f32) * fill) as u32;
|
2019-08-01 00:09:51 +02:00
|
|
|
if fill_pos > length {
|
|
|
|
|
fill_pos = length;
|
|
|
|
|
}
|
|
|
|
|
for y in 0..height {
|
|
|
|
|
for x in 0..fill_pos {
|
|
|
|
|
buf.put((x, y), &background_color.blend(color, 1.0));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|