use windows_sys::Win32::{
Foundation::HANDLE,
System::Console::{
GetConsoleScreenBufferInfo, GetConsoleWindow, GetStdHandle, CONSOLE_SCREEN_BUFFER_INFO,
COORD, SMALL_RECT, STD_OUTPUT_HANDLE,
},
UI::HiDpi::GetDpiForWindow,
};
#[cfg(target_os = "windows")]
pub static mut DEFAULT_FONT_SIZE_WIDTH: u16 = 10;
#[cfg(target_os = "windows")]
pub static mut DEFAULT_FONT_SIZE_HEIGHT: u16 = 22;
#[derive(Debug)]
pub struct TerminalSize {
pub width: i32,
pub height: i32,
}
#[derive(Debug)]
pub struct FontSize {
pub width: i32,
pub height: i32,
}
#[derive(Debug)]
pub enum TerminalError {
NoStdHandle,
NoScreenBufferInfo,
}
pub fn get_size_of_the_font() -> Result<FontSize, TerminalError> {
unsafe {
let h_console: HANDLE = GetStdHandle(STD_OUTPUT_HANDLE);
if h_console.is_null() {
return Err(TerminalError::NoStdHandle);
}
let dpi = GetDpiForWindow(GetConsoleWindow());
let scale = dpi as f32 / 96.0;
let (width, height) = (
(DEFAULT_FONT_SIZE_WIDTH as f32 * scale).round() as u16,
(DEFAULT_FONT_SIZE_HEIGHT as f32 * scale).round() as u16,
);
return Ok(FontSize {
width: width as i32,
height: height as i32,
});
}
}
pub fn get_size_of_the_terminal() -> Result<TerminalSize, TerminalError> {
unsafe {
let h_console: HANDLE = GetStdHandle(STD_OUTPUT_HANDLE);
if h_console.is_null() {
return Err(TerminalError::NoStdHandle);
}
let mut info = CONSOLE_SCREEN_BUFFER_INFO {
dwSize: COORD { X: 0, Y: 0 },
dwCursorPosition: COORD { X: 0, Y: 0 },
wAttributes: 0,
srWindow: SMALL_RECT {
Left: 0,
Top: 0,
Right: 0,
Bottom: 0,
},
dwMaximumWindowSize: COORD { X: 0, Y: 0 },
};
if GetConsoleScreenBufferInfo(h_console, &mut info) == 0 {
return Err(TerminalError::NoScreenBufferInfo);
}
let terminal_size = get_size_of_the_font()?;
let pixel_size = TerminalSize {
width: terminal_size.width * info.dwSize.X as i32,
height: terminal_size.height * info.dwSize.Y as i32,
};
return Ok(pixel_size);
}
}