Skip to content

Commit

Permalink
feat: add verbose level 2 to show font file location
Browse files Browse the repository at this point in the history
  • Loading branch information
7sDream committed Nov 13, 2023
1 parent ee53764 commit 1621e8d
Show file tree
Hide file tree
Showing 14 changed files with 30 additions and 46 deletions.
6 changes: 3 additions & 3 deletions src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ use super::one_char::OneChar;
#[derive(clap::Parser)]
#[command(author, version, about, arg_required_else_help(true))]
pub struct Args {
/// Verbose mode, show all font styles
#[arg(short, long)]
pub verbose: bool,
/// Verbose mode, -v show all font styles, -vv adds file and font face index
#[arg(short, long, action = clap::ArgAction::Count)]
pub verbose: u8,

/// Preview character use supported fonts in browser
#[arg(short, long)]
Expand Down
22 changes: 11 additions & 11 deletions src/loader/face_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,35 +16,35 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

use std::path::PathBuf;
use std::{borrow::Cow, path::Path};

use owned_ttf_parser::{
name::{name_id, Table as NameTable},
GlyphId, Language, RawFace,
};

use super::{
cmap::CMapTable,
error::{BROKEN_NAME_TABLE, MISSING_NAME_TABLE, NAME_TAG},
Error, Result,
Error, Result, DATABASE,
};
use crate::loader::{CMapTable, DATABASE};

/// FaceInfo contains basic font face info like family and name,
/// and pre-parsed cmap tables we need to query if it contains a codepoint.
/// and pre-located glyph id for target character.
pub struct FaceInfo {
pub id: fontdb::ID,

pub family: String,
pub name: String,
pub family: &'static str,
pub name: Cow<'static, str>,

pub path: PathBuf,
pub path: &'static Path,
pub index: u32,

pub gid: GlyphId,
}

impl FaceInfo {
pub fn parse_if_contains(face: &fontdb::FaceInfo, c: char) -> Result<Option<Self>> {
pub fn parse_if_contains(face: &'static fontdb::FaceInfo, c: char) -> Result<Option<Self>> {
let Some((gid, name)) = DATABASE
.with_face_data(face.id, |data, index| -> Result<_> {
let rf = RawFace::parse(data, index)?;
Expand All @@ -61,12 +61,12 @@ impl FaceInfo {
};
let family =
face.families.get(0).map(|(s, _)| s.clone()).ok_or(Error::MissingFamilyName)?;
face.families.get(0).map(|(s, _)| s.as_str()).ok_or(Error::MissingFamilyName)?;
let name = name.unwrap_or_else(|| face.post_script_name.clone());
let name = name.map(Cow::Owned).unwrap_or_else(|| face.post_script_name.as_str().into());
let path = match face.source {
fontdb::Source::File(ref path) => path.clone(),
fontdb::Source::File(ref path) => path,
_ => unreachable!("we only load font file, so source must be File variant"),
};

Expand Down
2 changes: 1 addition & 1 deletion src/loader/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ mod error;

use once_cell::sync::Lazy;

pub use self::{cmap::CMapTable, error::Error, face_info::FaceInfo};
pub use self::{error::Error, face_info::FaceInfo};
pub type Result<T> = std::result::Result<T, Error>;

pub static DATABASE: Lazy<fontdb::Database> = Lazy::new(|| {
Expand Down
15 changes: 10 additions & 5 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.

#![deny(clippy::all)]
#![deny(missing_debug_implementations, rust_2018_idioms)]
#![deny(warnings)]
#![deny(missing_debug_implementations, rust_2018_idioms, unsafe_code)]

mod args;
mod loader;
Expand Down Expand Up @@ -77,18 +78,22 @@ fn show_preview_addr_and_wait(addr: SocketAddr) {
let _ = std::io::stdin().read(&mut [0u8]).unwrap();
}

fn show_font_list(families: Vec<Family<'_>>, verbose: bool) {
let max_len = if verbose {
fn show_font_list(families: Vec<Family<'_>>, verbose: u8) {
let max_len = if verbose > 0 {
0
} else {
families.iter().map(|f| f.default_name_width).max().unwrap_or_default()
};

families.into_iter().for_each(|family| {
if verbose {
if verbose > 0 {
println!("{}", family.name);
for face in family.faces {
println!(" {}", face.name);
print!("\t{}", face.name);
if verbose > 1 {
print!("\t{}:{}", face.path.to_string_lossy(), face.index)
}
println!()
}
} else {
println!(
Expand Down
12 changes: 3 additions & 9 deletions src/one_char.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

use std::{convert::TryFrom, hint::unreachable_unchecked, str::FromStr};
use std::{convert::TryFrom, str::FromStr};

use thiserror::Error;

Expand Down Expand Up @@ -60,15 +60,13 @@ pub enum ParseError {

impl OneChar {
pub fn from_scalar_value(scalar_value: u32) -> Result<Self, ParseError> {
#[allow(clippy::map_err_ignore)]
char::try_from(scalar_value)
.map(Self)
.map_err(|_| ParseError::InvalidUnicodeScalarValue(scalar_value))
}

pub fn from_scalar_value_str_radix(s: &str, radix: u32) -> Result<Self, ParseError> {
Self::from_scalar_value(
#[allow(clippy::map_err_ignore)]
u32::from_str_radix(s, radix).map_err(|_| ParseError::InvalidDigitInRadix(radix))?,
)
}
Expand Down Expand Up @@ -102,15 +100,13 @@ impl OneChar {
let c1 = c1.unwrap(); // at least one char because of the `take_while`
let c2 = c2.ok_or(ParseError::UTF8BytesStrCantAlignToBytes)?;
if c1.is_ascii_hexdigit() && c2.is_ascii_hexdigit() {
#[allow(clippy::cast_possible_truncation)] // two hex digit is a 8-bit number
Ok((c1.to_digit(16).unwrap() << 4 | c2.to_digit(16).unwrap()) as u8)
} else {
Err(ParseError::InvalidDigitInRadix(16))
}
})
.collect::<Result<Vec<_>, _>>()?;

#[allow(clippy::map_err_ignore)]
let utf8 = String::from_utf8(bytes).map_err(|_| ParseError::UTF8BytesInvalid)?;

let mut iter = utf8.chars();
Expand All @@ -119,8 +115,7 @@ impl OneChar {
(Some(c), None) => Ok(Self(c)),
(None, None) => Err(ParseError::UTF8BytesEmpty),
(Some(_), Some(_)) => Err(ParseError::UTF8BytesParseResultMoreThenOneChar),
// Because an iterator can not produce value after returning None
(None, Some(_)) => unsafe { unreachable_unchecked() },
(None, Some(_)) => unreachable!("iterator can not produce value after returning None"),
}
}
}
Expand All @@ -144,8 +139,7 @@ impl FromStr for OneChar {
_ => Self::from_scalar_value_str_dec(s),
}
}
// Because an iterator can not produce value after returning None
(None, Some(_)) => unsafe { unreachable_unchecked() },
(None, Some(_)) => unreachable!("iterator can not produce value after returning None"),
}
}
}
1 change: 0 additions & 1 deletion src/preview/browser/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,6 @@ impl SingleThread {
}
}

#[allow(clippy::needless_pass_by_value)] // channel is designed to be used like this
fn server(
addr_tx: Sender<SocketAddr>, exit_rx: Receiver<()>, content: String,
) -> Result<(), IOError> {
Expand Down
3 changes: 0 additions & 3 deletions src/preview/terminal/render/ascii.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,13 @@ impl AsciiRender {
};
let ramp: Vec<_> = s.chars().collect();
let level = ramp.len();
#[allow(clippy::cast_precision_loss)] // max level is 70, small enough
let multiplier = (level as f64) / (f64::from(u8::max_value()) + 1.0);
Self { ramp, multiplier }
}
}

impl CharBitmapRender for AsciiRender {
fn gray_to_char(&self, _up: u8, _left: u8, gray: u8, _right: u8, _down: u8) -> char {
#[allow(clippy::cast_sign_loss)] // gray and multiplier both positive
#[allow(clippy::cast_possible_truncation)] // result small then ramp's length(usize)
let index = (f64::from(gray) * self.multiplier).floor() as usize;
self.ramp[index]
}
Expand Down
3 changes: 0 additions & 3 deletions src/preview/terminal/render/moon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ pub struct MoonRender {
impl MoonRender {
pub fn new() -> Self {
let pair_count = MOON_CHARS.len();
#[allow(clippy::cast_precision_loss)] // MOON_CHARS's length is small enough
let multiplier = pair_count as f64 / 256.0;
Self { pair_count, multiplier }
}
Expand All @@ -41,8 +40,6 @@ impl CharBitmapRender for MoonRender {
return MOON_CHARS[self.pair_count - 1][0];
}

#[allow(clippy::cast_sign_loss)] // because `255 - u8` must be non-negative
#[allow(clippy::cast_possible_truncation)] // result small then MOON_CHARS's length
let index = (f64::from(255 - gray) * self.multiplier).floor() as usize;

if left < right { MOON_CHARS[index][1] } else { MOON_CHARS[index][0] }
Expand Down
2 changes: 0 additions & 2 deletions src/preview/terminal/ui/canvas_render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ struct RenderResultPoints<'a> {
}

impl<'a> RenderResultPoints<'a> {
#[allow(clippy::cast_precision_loss)] // render result size is small enough to cast to f64
fn new(chars: &'a RenderResult, width: f64, height: f64) -> Self {
let h_pad = ((width - chars.width() as f64) / 2.0).floor();
let v_pad = ((height - chars.height() as f64) / 2.0).floor();
Expand Down Expand Up @@ -80,7 +79,6 @@ impl<'a> Iterator for RenderResultPoints<'a> {
if self.chars.0[self.y][self.x] != ' ' {
// tui canvas origin point at left bottom but chars' at left top
// so we need do some math to flip it and add padding
#[allow(clippy::cast_precision_loss)] // render result size is small enough
let result = (self.x as f64 + self.h_pad, self.height - self.y as f64 - self.v_pad);
return Some(result);
}
Expand Down
1 change: 0 additions & 1 deletion src/preview/terminal/ui/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ impl Deref for TerminalEventStream {
}
}

#[allow(clippy::needless_pass_by_value)] // because it is run in other thread
fn keyboard_event_generator(tick_interval: Duration, tx: mpsc::Sender<CTResult<TerminalEvent>>) {
loop {
match event::poll(tick_interval) {
Expand Down
1 change: 0 additions & 1 deletion src/preview/terminal/ui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,6 @@ impl<'a: 'a> UI<'a> {
let main = layout[0];
let status_bar = layout[1];

#[allow(clippy::cast_possible_truncation)] // never truncation because we `min` with 24
let list_width = self.state.name_width_max().min(32) as u16;

let main = Layout::default()
Expand Down
4 changes: 1 addition & 3 deletions src/preview/terminal/ui/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ impl<'a: 'a> State<'a> {
pub fn new(c: char, families: Vec<Family<'a>>) -> Self {
let font_faces_info: Vec<_> =
families.into_iter().flat_map(|f| f.faces.into_iter()).collect();
let font_faces_name: Vec<_> = font_faces_info.iter().map(|f| f.name.as_str()).collect();
let font_faces_name: Vec<_> = font_faces_info.iter().map(|f| f.name.as_ref()).collect();
let name_width_max = font_faces_name.iter().map(|f| f.len()).max().unwrap_or_default();

let mut font_faces = Vec::new();
Expand Down Expand Up @@ -117,7 +117,6 @@ impl<'a: 'a> State<'a> {
.ok_or(())
.or_else(|_| {
let font_info = &self.font_faces_info[self.index()];
#[allow(clippy::map_err_ignore)]
FtFontFace::new(
DATABASE.with_face_data(font_info.id, |data, _| data.to_vec()).unwrap(),
font_info.index,
Expand All @@ -131,7 +130,6 @@ impl<'a: 'a> State<'a> {
let height = self.height.get();
let width = self.width.get();

#[allow(clippy::map_err_ignore)]
font_face.set_cell_pixel(height, width);

Ok(font_face)
Expand Down
3 changes: 1 addition & 2 deletions src/rasterizer/bitmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,7 @@ impl Bitmap {
pub fn get_pixel(&self, _row: usize, _col: usize) -> u8 {
// if u32::from(self.pixel_mode) == ft::FT_Pixel_Mode::FT_PIXEL_MODE_MONO as u32 {
// let index = (row * self.pitch + col / 8) as usize;
// #[allow(clippy::cast_possible_truncation)] // because we mod with 8 so result is 0 -
// 7 let bit_pos = (col % 8) as u8;
// let bit_pos = (col % 8) as u8;
// let gray = self.bitmap[index];
// let mask = 0b_1000_0000 >> (bit_pos);
// if gray & mask == 0 {
Expand Down
1 change: 0 additions & 1 deletion src/rasterizer/font_face.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ impl FontFace {
// }
// let c = ft::FT_ULong::from(u32::from(c));
// let ret = unsafe {
// #[allow(clippy::cast_possible_wrap)] // flag enum value is small enough
// ft::FT_Load_Char(self.face, c, flag as ft::FT_Int)
// };

Expand Down

0 comments on commit 1621e8d

Please sign in to comment.