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
|
// when changing the load flags, we also need
|
||||||
// to change them for harfbuzz otherwise it won't
|
// to change them for harfbuzz otherwise it won't
|
||||||
// hint correctly
|
// hint correctly
|
||||||
let load_flags = (ftwrap::FT_LOAD_COLOR) as i32 |
|
let load_flags = ftwrap::compute_load_flags_for_mode(render_mode);
|
||||||
// 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;
|
|
||||||
|
|
||||||
self.font.borrow_mut().set_load_flags(load_flags);
|
self.font.borrow_mut().set_load_flags(load_flags);
|
||||||
|
|
||||||
// This clone is conceptually unsafe, but ok in practice as we are
|
// This clone is conceptually unsafe, but ok in practice as we are
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
//! Higher level freetype bindings
|
//! Higher level freetype bindings
|
||||||
|
|
||||||
|
use crate::font::loader::FontDataHandle;
|
||||||
use failure::{bail, format_err, Error, Fallible, ResultExt};
|
use failure::{bail, format_err, Error, Fallible, ResultExt};
|
||||||
pub use freetype::*;
|
pub use freetype::*;
|
||||||
use std::ffi::CString;
|
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 struct Face {
|
||||||
pub face: FT_Face,
|
pub face: FT_Face,
|
||||||
_bytes: Vec<u8>,
|
_bytes: Vec<u8>,
|
||||||
@ -172,6 +182,15 @@ impl Library {
|
|||||||
Ok(Library { lib })
|
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))]
|
#[cfg(any(target_os = "macos", windows))]
|
||||||
pub fn load_font_kit_handle(&self, handle: &font_kit::handle::Handle) -> Result<Face, Error> {
|
pub fn load_font_kit_handle(&self, handle: &font_kit::handle::Handle) -> Result<Face, Error> {
|
||||||
use font_kit::handle::Handle;
|
use font_kit::handle::Handle;
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
use crate::config::FontAttributes;
|
use crate::config::FontAttributes;
|
||||||
use failure::Fallible;
|
use failure::{format_err, Error, Fallible};
|
||||||
|
use serde_derive::*;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
#[cfg(all(unix, any(feature = "fontconfig", not(target_os = "macos"))))]
|
#[cfg(all(unix, any(feature = "fontconfig", not(target_os = "macos"))))]
|
||||||
pub mod font_config;
|
pub mod font_config;
|
||||||
@ -25,3 +27,79 @@ pub trait FontLocator {
|
|||||||
/// FontDataHandle's that correspond to it
|
/// FontDataHandle's that correspond to it
|
||||||
fn load_fonts(&self, fonts_selection: &[FontAttributes]) -> Fallible<Vec<FontDataHandle>>;
|
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))]
|
#[cfg(any(target_os = "macos", windows))]
|
||||||
pub mod fontkit;
|
pub mod fontkit;
|
||||||
|
|
||||||
|
use crate::font::loader::{FontLocator, FontLocatorSelection};
|
||||||
|
|
||||||
use super::config::{configuration, ConfigHandle, TextStyle};
|
use super::config::{configuration, ConfigHandle, TextStyle};
|
||||||
use term::CellAttributes;
|
use term::CellAttributes;
|
||||||
|
|
||||||
|
pub struct LoadedFont {
|
||||||
|
rasterizer: Box<dyn rasterizer::FontRasterizer>,
|
||||||
|
shaper: Box<dyn shaper::FontShaper>,
|
||||||
|
}
|
||||||
|
|
||||||
type FontPtr = Rc<RefCell<Box<dyn NamedFont>>>;
|
type FontPtr = Rc<RefCell<Box<dyn NamedFont>>>;
|
||||||
|
|
||||||
/// Matches and loads fonts for a given input style
|
/// Matches and loads fonts for a given input style
|
||||||
pub struct FontConfiguration {
|
pub struct FontConfiguration {
|
||||||
fonts: RefCell<HashMap<TextStyle, FontPtr>>,
|
fonts: RefCell<HashMap<TextStyle, FontPtr>>,
|
||||||
|
new_fonts: RefCell<HashMap<TextStyle, Rc<LoadedFont>>>,
|
||||||
system: Rc<dyn FontSystem>,
|
system: Rc<dyn FontSystem>,
|
||||||
metrics: RefCell<Option<FontMetrics>>,
|
metrics: RefCell<Option<FontMetrics>>,
|
||||||
dpi_scale: RefCell<f64>,
|
dpi_scale: RefCell<f64>,
|
||||||
font_scale: RefCell<f64>,
|
font_scale: RefCell<f64>,
|
||||||
config_generation: RefCell<usize>,
|
config_generation: RefCell<usize>,
|
||||||
|
loader: Box<dyn FontLocator>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Clone, Copy)]
|
#[derive(Debug, Deserialize, Clone, Copy)]
|
||||||
@ -111,6 +120,7 @@ impl FontSystemSelection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn variants() -> Vec<&'static str> {
|
pub fn variants() -> Vec<&'static str> {
|
||||||
vec![
|
vec![
|
||||||
"FontConfigAndFreeType",
|
"FontConfigAndFreeType",
|
||||||
@ -153,8 +163,11 @@ impl std::str::FromStr for FontSystemSelection {
|
|||||||
impl FontConfiguration {
|
impl FontConfiguration {
|
||||||
/// Create a new empty configuration
|
/// Create a new empty configuration
|
||||||
pub fn new(system: FontSystemSelection) -> Self {
|
pub fn new(system: FontSystemSelection) -> Self {
|
||||||
|
let loader = FontLocatorSelection::get_default().new_locator();
|
||||||
Self {
|
Self {
|
||||||
fonts: RefCell::new(HashMap::new()),
|
fonts: RefCell::new(HashMap::new()),
|
||||||
|
loader,
|
||||||
|
new_fonts: RefCell::new(HashMap::new()),
|
||||||
system: system.new_font_system(),
|
system: system.new_font_system(),
|
||||||
metrics: RefCell::new(None),
|
metrics: RefCell::new(None),
|
||||||
font_scale: RefCell::new(1.0),
|
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_LCD;
|
||||||
ftwrap::FT_Render_Mode::FT_RENDER_MODE_LIGHT;
|
ftwrap::FT_Render_Mode::FT_RENDER_MODE_LIGHT;
|
||||||
|
|
||||||
let load_flags = (ftwrap::FT_LOAD_COLOR) as i32 |
|
let load_flags = ftwrap::compute_load_flags_for_mode(render_mode);
|
||||||
// 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 mut face = self.face.borrow_mut();
|
let mut face = self.face.borrow_mut();
|
||||||
let descender = unsafe { (*(*face.face).size).metrics.descender as f64 / 64.0 };
|
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> {
|
pub fn with_face(face: ftwrap::Face) -> Fallible<Self> {
|
||||||
face.set_font_size(size, dpi)?;
|
|
||||||
|
|
||||||
let has_color = unsafe {
|
let has_color = unsafe {
|
||||||
(((*face.face).face_flags as u32) & (ftwrap::FT_FACE_FLAG_COLOR as u32)) != 0
|
(((*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::ftwrap;
|
||||||
use crate::font::hbwrap as harfbuzz;
|
use crate::font::hbwrap as harfbuzz;
|
||||||
|
use crate::font::loader::FontDataHandle;
|
||||||
use crate::font::shaper::FontShaper;
|
use crate::font::shaper::FontShaper;
|
||||||
use crate::font::system::GlyphInfo;
|
use crate::font::system::GlyphInfo;
|
||||||
use failure::{bail, Fallible};
|
use failure::{bail, Fallible};
|
||||||
@ -13,9 +14,24 @@ struct FontPair {
|
|||||||
|
|
||||||
pub struct HarfbuzzShaper {
|
pub struct HarfbuzzShaper {
|
||||||
fonts: Vec<RefCell<FontPair>>,
|
fonts: Vec<RefCell<FontPair>>,
|
||||||
|
lib: ftwrap::Library,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HarfbuzzShaper {
|
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(
|
fn do_shape(
|
||||||
&self,
|
&self,
|
||||||
font_idx: crate::font::system::FallbackIdx,
|
font_idx: crate::font::system::FallbackIdx,
|
||||||
|
Loading…
Reference in New Issue
Block a user