From f71e1a0bb12a3b8ca37f357fc8488bee9cba8f4c Mon Sep 17 00:00:00 2001 From: Aloxaf Date: Fri, 14 Oct 2022 14:49:24 +0800 Subject: [PATCH] fix: font fallback for harfbuzz close #191 --- Cargo.lock | 2 +- Cargo.toml | 2 +- README.md | 13 +++++-------- src/font.rs | 38 ++++++++++++++++++++++++++------------ 4 files changed, 33 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6bf95f3..1902b84 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1273,7 +1273,7 @@ checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" [[package]] name = "silicon" -version = "0.5.0" +version = "0.5.1" dependencies = [ "anyhow", "clipboard", diff --git a/Cargo.toml b/Cargo.toml index 92cfd79..51a98d0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "silicon" -version = "0.5.0" +version = "0.5.1" description = "Create beautiful image of your code" authors = ["Aloxaf "] categories = ["command-line-utilities"] diff --git a/README.md b/README.md index 6472020..87cae0e 100644 --- a/README.md +++ b/README.md @@ -38,13 +38,10 @@ cargo install silicon ### AUR -Silicon is available on AUR (Thanks to @radmen). +Silicon is available in the official repository: -You can install it with any AUR helpers you like. - -eg. ```bash -pikaur -S silicon +pacman -S silicon ``` ### Homebrew @@ -61,18 +58,18 @@ brew install silicon ```bash sudo apt install expat sudo apt install libxml2-dev -sudo apt install pkg-config libasound2-dev libssl-dev cmake libfreetype6-dev libexpat1-dev libxcb-composite0-dev +sudo apt install pkg-config libasound2-dev libssl-dev cmake libfreetype6-dev libexpat1-dev libxcb-composite0-dev libharfbuzz-dev ``` ### Fedora ```bash -sudo dnf install cmake expat-devel libxcb-devel freetype-devel libxml2-devel +sudo dnf install cmake expat-devel libxcb-devel freetype-devel libxml2-devel harfbuzz ``` ### Arch Linux ```bash -sudo pacman -S --needed pkgconf freetype2 fontconfig libxcb xclip +sudo pacman -S --needed pkgconf freetype2 fontconfig libxcb xclip harfbuzz ``` ## Examples diff --git a/src/font.rs b/src/font.rs index 89cd9c3..f08854c 100644 --- a/src/font.rs +++ b/src/font.rs @@ -28,6 +28,7 @@ use pathfinder_geometry::transform2d::Transform2F; use std::collections::HashMap; use std::sync::Arc; use syntect::highlighting; +use log::trace; /// Font style #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] @@ -194,7 +195,6 @@ impl FontCollection { Ok(Self(fonts)) } - #[cfg(target_os = "windows")] fn glyph_for_char(&self, c: char, style: FontStyle) -> Option<(u32, &ImageFont, &Font)> { for font in &self.0 { let result = font.get_by_style(style); @@ -235,20 +235,34 @@ impl FontCollection { Ok(glyph_ids) } + #[cfg(not(target_os = "windows"))] + fn split_by_font(&self, text: &str, style: FontStyle) -> Vec<(&ImageFont, &Font, String)> { + let mut result: Vec<(&ImageFont, &Font, String)> = vec![]; + for c in text.chars() { + if let Some((_, imfont, font)) = self.glyph_for_char(c, style) { + if result.is_empty() || !std::ptr::eq(result.last().unwrap().0, imfont) { + result.push((imfont, font, String::new())); + } + if std::ptr::eq(result.last().unwrap().0, imfont) { + result.last_mut().unwrap().2.push(c); + } + } + } + trace!("{:#?}", &result); + result + } + #[cfg(not(target_os = "windows"))] fn layout(&self, text: &str, style: FontStyle) -> (Vec, u32) { let mut delta_x = 0; let height = self.get_font_height(); - let imfont = self.0.get(0).unwrap(); - let font = imfont.get_by_style(style); - let mut hb_font = HBFont::new(font); - // apply font features especially ligature with a shape engine - let shaped_glyphs = self.shape_text(&mut hb_font, text).unwrap(); - - let glyphs = shaped_glyphs - .iter() - .map(|id| { + let mut glyphs = Vec::with_capacity(text.len()); + for (imfont, font, text) in self.split_by_font(text, style) { + let mut hb_font = HBFont::new(font); + // apply font features especially ligature with a shape engine + let shaped_glyphs = self.shape_text(&mut hb_font, &text).unwrap(); + glyphs.extend(shaped_glyphs.iter().map(|id| { let raster_rect = font .raster_bounds( *id, @@ -268,8 +282,8 @@ impl FontCollection { raster_rect, position, } - }) - .collect(); + })) + } (glyphs, delta_x) }