After displaying double-byte characters, an extra blank space appears.
Custom fonts have the same issue.
#![allow(unused)]
use embedded_graphics::image::ImageRaw;
use embedded_graphics::mono_font::MonoFont;
use embedded_graphics::pixelcolor::Bgr565;
use embedded_graphics::{
mono_font::MonoTextStyle, pixelcolor::BinaryColor, prelude::*, text::Text,
};
use embedded_graphics_simulator::{
BinaryColorTheme, OutputSettingsBuilder, SimulatorDisplay, SimulatorEvent, Window,
};
use mousefood::error::Error;
use mousefood::{EmbeddedBackend, EmbeddedBackendConfig};
use ratatui::layout::{Constraint, Layout};
use ratatui::style::Stylize;
use ratatui::widgets::{Paragraph, Wrap};
use ratatui::{Frame, Terminal};
const TEXT: &str = "A点陣字ACああA";
fn main() -> Result<(), Error> {
//let font = embedded_graphics_unicodefonts::MONO_6X12;
let font = embedded_graphics_unicodefonts::MONO_18X18_JA;
//let font = CUSTOM_FONT_16X16;
let output_settings = OutputSettingsBuilder::new()
.theme(BinaryColorTheme::OledBlue)
.build();
let mut display = SimulatorDisplay::<BinaryColor>::new(Size::new(320, 128));
let text_style = MonoTextStyle::new(&font, BinaryColor::On);
Text::new(TEXT, Point::new(0, 20), text_style)
.draw(&mut display)
.unwrap();
Text::new(TEXT, Point::new(0, 80), text_style)
.draw(&mut display)
.unwrap();
Window::new(
"Display with normal spacing for double-byte characters",
&output_settings,
)
.show_static(&display);
let mut display = SimulatorDisplay::<Bgr565>::new(Size::new(320, 120));
let mut simulator_window = Window::new(
"Ratatui display with double-byte character spacing",
&output_settings,
);
let mut backend_config = EmbeddedBackendConfig {
flush_callback: Box::new(move |display| {
simulator_window.update(display);
if simulator_window.events().any(|e| e == SimulatorEvent::Quit) {
panic!("simulator window closed");
}
}),
..Default::default()
};
backend_config.font_regular = font;
let backend: EmbeddedBackend<SimulatorDisplay<_>, _> =
EmbeddedBackend::new(&mut display, backend_config);
let mut terminal = Terminal::new(backend)?;
loop {
terminal.draw(draw)?;
}
}
fn draw(frame: &mut Frame) {
let [a, b] = Layout::vertical([Constraint::Ratio(1, 2); 2])
.spacing(0)
.areas(frame.area());
let paragraph = Paragraph::new(TEXT.dark_gray()).wrap(Wrap { trim: true });
let paragraph2 = Paragraph::new(TEXT.dark_gray()).wrap(Wrap { trim: true });
frame.render_widget(paragraph, a);
frame.render_widget(paragraph2, b);
}
const CUSTOM_FONT_16X16: MonoFont = MonoFont {
image: ImageRaw::<BinaryColor>::new(&FONT_DATA, FONT_DATA.len().div_ceil(2) as u32),
character_size: Size::new(16, 16),
character_spacing: 2,
baseline: 13,
strikethrough: embedded_graphics::mono_font::DecorationDimensions::default_strikethrough(16),
underline: embedded_graphics::mono_font::DecorationDimensions::default_underline(16),
glyph_mapping: &CustomGlyphMapping,
};
/// ImageRaw Font Data: 点陣字ABCあ
const FONT_DATA: [u8; 224] = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x20, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x7C, 0x20, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x02, 0x00, 0x7F, 0xFE, 0x02, 0x00, 0x45, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0xC0, 0x40, 0x02, 0x03, 0xFC, 0x48, 0x20, 0x18, 0x00, 0x7C, 0x00, 0x3C, 0x00, 0x1F, 0x00,
0x80, 0x04, 0x02, 0x00, 0x49, 0xFC, 0x24, 0x00, 0x42, 0x00, 0x42, 0x00, 0x04, 0x80, 0x1F, 0xE0,
0x02, 0x00, 0x51, 0x24, 0x24, 0x00, 0x42, 0x00, 0x42, 0x00, 0x04, 0x80, 0x00, 0x40, 0x1F, 0xF0,
0x49, 0x24, 0x42, 0x00, 0x42, 0x00, 0x40, 0x00, 0x07, 0xE0, 0x00, 0x80, 0x20, 0x10, 0x49, 0xFC,
0x42, 0x00, 0x7C, 0x00, 0x40, 0x00, 0x0D, 0x10, 0x01, 0x00, 0x20, 0x10, 0x45, 0x24, 0x7E, 0x00,
0x42, 0x00, 0x40, 0x00, 0x15, 0x08, 0xFF, 0xFE, 0x20, 0x10, 0x45, 0x24, 0x42, 0x00, 0x42, 0x00,
0x40, 0x00, 0x22, 0x08, 0x01, 0x00, 0x3F, 0xF0, 0x45, 0xFC, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00,
0x26, 0x08, 0x01, 0x00, 0x00, 0x00, 0x68, 0x20, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x2A, 0x10,
0x01, 0x00, 0x24, 0x88, 0x53, 0xFE, 0x42, 0x00, 0x7C, 0x00, 0x3C, 0x00, 0x10, 0x60, 0x01, 0x00,
0x22, 0x44, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x42, 0x44,
0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x80, 0x04, 0x40, 0x20,
];
struct CustomGlyphMapping;
impl embedded_graphics::mono_font::mapping::GlyphMapping for CustomGlyphMapping {
fn index(&self, c: char) -> usize {
match c {
'A' => 0,
'B' => 1,
'C' => 2,
'あ' => 3,
'字' => 4,
'点' => 5,
'陣' => 6,
_ => 7,
}
}
}
Describe the bug
在显示双字节的文字后会多出一个空白点位。
定位到 Backend 的 draw() 函数。当处理完一个 non-ascii 的双字节字符时会当两个字符占位,x 坐标多增加了一次。ascii 字符是正常显示。自定义字体也有同样问题。
测试的字体使用的是 embedded_graphics_unicodefonts::MONO_18X18_JA
After displaying double-byte characters, an extra blank space appears.
I've located the issue to the Backend's draw() function. When processing a non-ASCII double-byte character, it's being treated as two characters for spacing purposes, causing the x-coordinate to be incremented twice. ASCII characters display correctly.
Custom fonts have the same issue.
Test font used:
embedded_graphics_unicodefonts::MONO_18X18_JAExpected display image
Abnormal display image
Image from ESP32 development board
Cargo.toml
Test code