mirror of
https://github.com/wez/wezterm.git
synced 2024-11-24 07:46:59 +03:00
fonts: start adding new stuff to FontConfiguration
This commit is contained in:
parent
accfc9b09c
commit
cd07a31d84
@ -78,13 +78,7 @@ impl Font for FreeTypeFontImpl {
|
||||
// when changing the load flags, we also need
|
||||
// to change them for harfbuzz otherwise it won't
|
||||
// hint correctly
|
||||
let load_flags = (ftwrap::FT_LOAD_COLOR) as i32 |
|
||||
// enable FT_LOAD_TARGET bits. There are no flags defined
|
||||
// for these in the bindings so we do some bit magic for
|
||||
// ourselves. This is how the FT_LOAD_TARGET_() macro
|
||||
// assembles these bits.
|
||||
(render_mode as i32) << 16;
|
||||
|
||||
let load_flags = ftwrap::compute_load_flags_for_mode(render_mode);
|
||||
self.font.borrow_mut().set_load_flags(load_flags);
|
||||
|
||||
// This clone is conceptually unsafe, but ok in practice as we are
|
||||
|
@ -1,5 +1,6 @@
|
||||
//! Higher level freetype bindings
|
||||
|
||||
use crate::font::loader::FontDataHandle;
|
||||
use failure::{bail, format_err, Error, Fallible, ResultExt};
|
||||
pub use freetype::*;
|
||||
use std::ffi::CString;
|
||||
@ -19,6 +20,15 @@ fn ft_result<T>(err: FT_Error, t: T) -> Result<T, Error> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compute_load_flags_for_mode(render_mode: FT_Render_Mode) -> i32 {
|
||||
FT_LOAD_COLOR as i32 |
|
||||
// enable FT_LOAD_TARGET bits. There are no flags defined
|
||||
// for these in the bindings so we do some bit magic for
|
||||
// ourselves. This is how the FT_LOAD_TARGET_() macro
|
||||
// assembles these bits.
|
||||
(render_mode as i32) << 16
|
||||
}
|
||||
|
||||
pub struct Face {
|
||||
pub face: FT_Face,
|
||||
_bytes: Vec<u8>,
|
||||
@ -172,6 +182,15 @@ impl Library {
|
||||
Ok(Library { lib })
|
||||
}
|
||||
|
||||
pub fn face_from_locator(&self, handle: &FontDataHandle) -> Fallible<Face> {
|
||||
match handle {
|
||||
FontDataHandle::OnDisk { path, index } => {
|
||||
self.new_face(path.to_str().unwrap(), *index as _)
|
||||
}
|
||||
FontDataHandle::Memory { data, index } => self.new_face_from_slice(&data, *index as _),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "macos", windows))]
|
||||
pub fn load_font_kit_handle(&self, handle: &font_kit::handle::Handle) -> Result<Face, Error> {
|
||||
use font_kit::handle::Handle;
|
||||
|
@ -1,6 +1,8 @@
|
||||
use crate::config::FontAttributes;
|
||||
use failure::Fallible;
|
||||
use failure::{format_err, Error, Fallible};
|
||||
use serde_derive::*;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Mutex;
|
||||
|
||||
#[cfg(all(unix, any(feature = "fontconfig", not(target_os = "macos"))))]
|
||||
pub mod font_config;
|
||||
@ -25,3 +27,79 @@ pub trait FontLocator {
|
||||
/// FontDataHandle's that correspond to it
|
||||
fn load_fonts(&self, fonts_selection: &[FontAttributes]) -> Fallible<Vec<FontDataHandle>>;
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Clone, Copy)]
|
||||
pub enum FontLocatorSelection {
|
||||
FontConfig,
|
||||
FontLoader,
|
||||
FontKit,
|
||||
}
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
static ref DEFAULT_LOCATOR: Mutex<FontLocatorSelection> = Mutex::new(Default::default());
|
||||
}
|
||||
|
||||
impl Default for FontLocatorSelection {
|
||||
fn default() -> Self {
|
||||
if cfg!(all(unix, not(target_os = "macos"))) {
|
||||
FontLocatorSelection::FontConfig
|
||||
} else {
|
||||
FontLocatorSelection::FontLoader
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FontLocatorSelection {
|
||||
pub fn set_default(self) {
|
||||
let mut def = DEFAULT_LOCATOR.lock().unwrap();
|
||||
*def = self;
|
||||
}
|
||||
|
||||
pub fn get_default() -> Self {
|
||||
let def = DEFAULT_LOCATOR.lock().unwrap();
|
||||
*def
|
||||
}
|
||||
|
||||
pub fn variants() -> Vec<&'static str> {
|
||||
vec!["FontConfig", "FontLoader", "FontKit"]
|
||||
}
|
||||
|
||||
pub fn new_locator(self) -> Box<dyn FontLocator> {
|
||||
match self {
|
||||
Self::FontConfig => {
|
||||
#[cfg(all(unix, any(feature = "fontconfig", not(target_os = "macos"))))]
|
||||
return Box::new(font_config::FontConfigFontLocator {});
|
||||
#[cfg(not(all(unix, any(feature = "fontconfig", not(target_os = "macos")))))]
|
||||
panic!("fontconfig not compiled in");
|
||||
}
|
||||
Self::FontLoader => {
|
||||
#[cfg(any(target_os = "macos", windows))]
|
||||
return Box::new(font_loader::FontLoaderFontLocator {});
|
||||
#[cfg(not(any(target_os = "macos", windows)))]
|
||||
panic!("fontloader not compiled in");
|
||||
}
|
||||
Self::FontKit => {
|
||||
#[cfg(any(target_os = "macos", windows))]
|
||||
return Box::new(::font_kit::source::SystemSource::new());
|
||||
#[cfg(not(any(target_os = "macos", windows)))]
|
||||
panic!("fontkit not compiled in");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::str::FromStr for FontLocatorSelection {
|
||||
type Err = Error;
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s.to_lowercase().as_ref() {
|
||||
"fontconfig" => Ok(Self::FontConfig),
|
||||
"fontloader" => Ok(Self::FontLoader),
|
||||
"fontkit" => Ok(Self::FontKit),
|
||||
_ => Err(format_err!(
|
||||
"{} is not a valid FontLocatorSelection variant, possible values are {:?}",
|
||||
s,
|
||||
Self::variants()
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,19 +34,28 @@ pub mod fontloader_and_freetype;
|
||||
#[cfg(any(target_os = "macos", windows))]
|
||||
pub mod fontkit;
|
||||
|
||||
use crate::font::loader::{FontLocator, FontLocatorSelection};
|
||||
|
||||
use super::config::{configuration, ConfigHandle, TextStyle};
|
||||
use term::CellAttributes;
|
||||
|
||||
pub struct LoadedFont {
|
||||
rasterizer: Box<dyn rasterizer::FontRasterizer>,
|
||||
shaper: Box<dyn shaper::FontShaper>,
|
||||
}
|
||||
|
||||
type FontPtr = Rc<RefCell<Box<dyn NamedFont>>>;
|
||||
|
||||
/// Matches and loads fonts for a given input style
|
||||
pub struct FontConfiguration {
|
||||
fonts: RefCell<HashMap<TextStyle, FontPtr>>,
|
||||
new_fonts: RefCell<HashMap<TextStyle, Rc<LoadedFont>>>,
|
||||
system: Rc<dyn FontSystem>,
|
||||
metrics: RefCell<Option<FontMetrics>>,
|
||||
dpi_scale: RefCell<f64>,
|
||||
font_scale: RefCell<f64>,
|
||||
config_generation: RefCell<usize>,
|
||||
loader: Box<dyn FontLocator>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Clone, Copy)]
|
||||
@ -111,6 +120,7 @@ impl FontSystemSelection {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn variants() -> Vec<&'static str> {
|
||||
vec![
|
||||
"FontConfigAndFreeType",
|
||||
@ -153,8 +163,11 @@ impl std::str::FromStr for FontSystemSelection {
|
||||
impl FontConfiguration {
|
||||
/// Create a new empty configuration
|
||||
pub fn new(system: FontSystemSelection) -> Self {
|
||||
let loader = FontLocatorSelection::get_default().new_locator();
|
||||
Self {
|
||||
fonts: RefCell::new(HashMap::new()),
|
||||
loader,
|
||||
new_fonts: RefCell::new(HashMap::new()),
|
||||
system: system.new_font_system(),
|
||||
metrics: RefCell::new(None),
|
||||
font_scale: RefCell::new(1.0),
|
||||
|
@ -19,12 +19,7 @@ impl FontRasterizer for FreeTypeRasterizer {
|
||||
// ftwrap::FT_Render_Mode::FT_RENDER_MODE_LCD;
|
||||
ftwrap::FT_Render_Mode::FT_RENDER_MODE_LIGHT;
|
||||
|
||||
let load_flags = (ftwrap::FT_LOAD_COLOR) as i32 |
|
||||
// enable FT_LOAD_TARGET bits. There are no flags defined
|
||||
// for these in the bindings so we do some bit magic for
|
||||
// ourselves. This is how the FT_LOAD_TARGET_() macro
|
||||
// assembles these bits.
|
||||
(render_mode as i32) << 16;
|
||||
let load_flags = ftwrap::compute_load_flags_for_mode(render_mode);
|
||||
|
||||
let mut face = self.face.borrow_mut();
|
||||
let descender = unsafe { (*(*face.face).size).metrics.descender as f64 / 64.0 };
|
||||
@ -268,9 +263,7 @@ impl FreeTypeRasterizer {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_face_size_and_dpi(mut face: ftwrap::Face, size: f64, dpi: u32) -> Fallible<Self> {
|
||||
face.set_font_size(size, dpi)?;
|
||||
|
||||
pub fn with_face(face: ftwrap::Face) -> Fallible<Self> {
|
||||
let has_color = unsafe {
|
||||
(((*face.face).face_flags as u32) & (ftwrap::FT_FACE_FLAG_COLOR as u32)) != 0
|
||||
};
|
||||
|
@ -1,5 +1,6 @@
|
||||
use crate::font::ftwrap;
|
||||
use crate::font::hbwrap as harfbuzz;
|
||||
use crate::font::loader::FontDataHandle;
|
||||
use crate::font::shaper::FontShaper;
|
||||
use crate::font::system::GlyphInfo;
|
||||
use failure::{bail, Fallible};
|
||||
@ -13,9 +14,24 @@ struct FontPair {
|
||||
|
||||
pub struct HarfbuzzShaper {
|
||||
fonts: Vec<RefCell<FontPair>>,
|
||||
lib: ftwrap::Library,
|
||||
}
|
||||
|
||||
impl HarfbuzzShaper {
|
||||
pub fn new(handles: &[FontDataHandle]) -> Fallible<Self> {
|
||||
let lib = ftwrap::Library::new()?;
|
||||
let mut fonts = vec![];
|
||||
for handle in handles {
|
||||
let face = lib.face_from_locator(handle)?;
|
||||
let mut font = harfbuzz::Font::new(face.face);
|
||||
let render_mode = ftwrap::FT_Render_Mode::FT_RENDER_MODE_LIGHT;
|
||||
let load_flags = ftwrap::compute_load_flags_for_mode(render_mode);
|
||||
font.set_load_flags(load_flags);
|
||||
fonts.push(RefCell::new(FontPair { face, font }));
|
||||
}
|
||||
Ok(Self { fonts, lib })
|
||||
}
|
||||
|
||||
fn do_shape(
|
||||
&self,
|
||||
font_idx: crate::font::system::FallbackIdx,
|
||||
|
Loading…
Reference in New Issue
Block a user