Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 106 additions & 32 deletions eg-bdf-examples/examples/font_viewer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,28 @@ use anyhow::{anyhow, Context, Result};
use eg_bdf::BdfTextStyle;
use eg_font_converter::{FontConverter, Mapping};
use embedded_graphics::{
geometry::AnchorPoint,
mono_font::{ascii::FONT_6X10, MonoTextStyle},
pixelcolor::Rgb888,
prelude::*,
primitives::{Line, PrimitiveStyle},
text::{Baseline, Text},
text::{renderer::TextRenderer, Alignment, Baseline, Text, TextStyleBuilder},
};
use embedded_graphics_simulator::{
sdl2::Keycode, OutputSettingsBuilder, SimulatorDisplay, SimulatorEvent, Window,
};
use embedded_graphics_simulator::{OutputSettingsBuilder, SimulatorDisplay, Window};

fn main() {
if let Err(e) = try_main() {
eprintln!("Error: {e:#}");
}
}

fn draw_text(display: &mut SimulatorDisplay<Rgb888>, text: &Text<BdfTextStyle<Rgb888>>) -> Point {
/// Draws a text and its bounding box.
fn draw_text<S: TextRenderer<Color = Rgb888>>(
display: &mut SimulatorDisplay<Rgb888>,
text: &Text<S>,
) -> Point {
text.bounding_box()
.into_styled(PrimitiveStyle::with_stroke(Rgb888::CSS_DARK_ORANGE, 1))
.draw(display)
Expand All @@ -24,25 +32,11 @@ fn draw_text(display: &mut SimulatorDisplay<Rgb888>, text: &Text<BdfTextStyle<Rg
text.draw(display).unwrap()
}

fn try_main() -> Result<()> {
let file = std::env::args()
.nth(1)
.ok_or_else(|| anyhow!("missing filename"))?;

let output = FontConverter::with_file(&file, "BDF_FILE")
.glyphs(Mapping::Ascii)
.missing_glyph_substitute('?')
.convert_eg_bdf()
.with_context(|| "couldn't convert font")?;

let font = output.as_font();
let style = BdfTextStyle::new(&font, Rgb888::WHITE);

let settings = OutputSettingsBuilder::new().scale(3).build();
let mut window = Window::new("Font viewer", &settings);

let mut display = SimulatorDisplay::<Rgb888>::new(Size::new(600, 200));

fn draw<S: TextRenderer<Color = Rgb888> + Copy>(
display: &mut SimulatorDisplay<Rgb888>,
style: S,
line_height: u32,
) {
let abc = ('a'..='z').collect::<String>();
let digits = ('0'..='9').collect::<String>();
let string = format!(
Expand All @@ -52,30 +46,31 @@ fn try_main() -> Result<()> {
digits
);

let position = Point::new(20, 20);
let position = Point::new(5, 5 + line_height as i32);

Line::with_delta(position.y_axis(), Point::zero() + display.size().x_axis())
.into_styled(PrimitiveStyle::with_stroke(Rgb888::CSS_DIM_GRAY, 1))
.draw(&mut display)
.draw(display)
.unwrap();

let text = Text::new(&string, position, style);
draw_text(&mut display, &text);
draw_text(display, &text);

let position = Point::new(20, 150);
let position = display.bounding_box().anchor_point(AnchorPoint::BottomLeft)
+ Point::new(5, -(line_height as i32) * 3 / 2);

Line::with_delta(position.y_axis(), Point::zero() + display.size().x_axis())
.into_styled(PrimitiveStyle::with_stroke(Rgb888::CSS_DIM_GRAY, 1))
.draw(&mut display)
.draw(display)
.unwrap();

let p = draw_text(
&mut display,
display,
&Text::with_baseline("Top ", position, style, Baseline::Top),
);

let p = draw_text(
&mut display,
display,
&Text::with_baseline(
"Middle ",
Point::new(p.x, position.y),
Expand All @@ -85,7 +80,7 @@ fn try_main() -> Result<()> {
);

let p = draw_text(
&mut display,
display,
&Text::with_baseline(
"Bottom ",
Point::new(p.x, position.y),
Expand All @@ -95,16 +90,95 @@ fn try_main() -> Result<()> {
);

draw_text(
&mut display,
display,
&Text::with_baseline(
"Alphabetic",
Point::new(p.x, position.y),
style,
Baseline::Alphabetic,
),
);
}

fn try_main() -> Result<()> {
let file = std::env::args()
.nth(1)
.ok_or_else(|| anyhow!("missing filename"))?;

let converted_font = FontConverter::with_file(&file, "BDF_FILE")
.glyphs(Mapping::Ascii)
.missing_glyph_substitute('?');

let output = converted_font
.convert_eg_bdf()
.with_context(|| "couldn't convert font")?;
let bdf_font = output.as_font();

window.show_static(&display);
let output = converted_font
.convert_mono_font()
.with_context(|| "couldn't convert font")?;
let mono_font = output.as_font();

let hints_style = MonoTextStyle::new(&FONT_6X10, Rgb888::CSS_DIM_GRAY);
let bottom_right = TextStyleBuilder::new()
.baseline(Baseline::Bottom)
.alignment(Alignment::Right)
.build();

// TODO: add metrics getter
let line_height = bdf_font.ascent + bdf_font.descent;
let display_height = line_height * 8;
let display_width = (line_height * 25).max(display_height);
let display_size = Size::new(display_width, display_height);

let mut display = SimulatorDisplay::<Rgb888>::new(display_size);

let scale = (1200 / display_size.width).max(1);

let settings = OutputSettingsBuilder::new().scale(scale).build();
let mut window = Window::new("Font viewer", &settings);

let mut use_mono_font = false;

'main_loop: loop {
window.update(&display);

for event in window.events() {
match event {
SimulatorEvent::KeyDown { keycode, .. } => match keycode {
Keycode::M => {
use_mono_font = !use_mono_font;
}
_ => {}
},
SimulatorEvent::Quit => break 'main_loop,
_ => {}
}
}

let mut hint = "Press M to toggle".to_string();

display.clear(Rgb888::BLACK).unwrap();
if use_mono_font {
let style = MonoTextStyle::new(&mono_font, Rgb888::WHITE);
draw(&mut display, style, line_height);

hint.insert_str(0, "Mono | ");
} else {
let style = BdfTextStyle::new(&bdf_font, Rgb888::WHITE);
draw(&mut display, style, line_height);

hint.insert_str(0, "Bdf | ");
}

let corner = display
.bounding_box()
.offset(-3)
.anchor_point(AnchorPoint::BottomRight);
Text::with_text_style(&hint, corner, hints_style, bottom_right)
.draw(&mut display)
.unwrap();
}

Ok(())
}
4 changes: 2 additions & 2 deletions eg-font-converter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,15 +312,15 @@ impl<'a> FontConverter<'a> {
.try_get::<i32>(Property::FontAscent)
.ok()
.filter(|v| *v >= 0)
.unwrap() as u32; //TODO: convert to error
.unwrap_or_default() as u32; //TODO: convert to error

let descent = bdf
.metadata
.properties
.try_get::<i32>(Property::FontDescent)
.ok()
.filter(|v| *v >= 0)
.unwrap() as u32; //TODO: convert to error
.unwrap_or_default() as u32; //TODO: convert to error

// TODO: read from BDF and use correct fallbacks (https://www.x.org/docs/XLFD/xlfd.pdf 3.2.30)
let underline_position = ascent + 1;
Expand Down