mirror of
https://github.com/wez/wezterm.git
synced 2024-12-24 13:52:55 +03:00
introduce freetype_load_flags and freetype_load_target config
In the earlier times wezterm supported different font rasterizers, and the configuration was a bit vague and generic to accomodate differences in how the rasterizers worked. Since then, we've standardized on freetype. One of the things that's been bothering me for a while is that we have some fiddly logic to transform from the config to the freetype flags. This commit does away with the transformation and simply exposes the two sets of freetype options. The main thing that I expect people to play with is `freetype_load_target` which can have one of the following values: ``` pub enum FreeTypeLoadTarget { /// This corresponds to the default hinting algorithm, optimized for standard gray-level rendering. Normal, /// A lighter hinting algorithm for non-monochrome modes. Many generated glyphs are more fuzzy but better resemble its original shape. A bit like rendering on Mac OS X. This target implies FT_LOAD_FORCE_AUTOHINT. Light, /// Strong hinting algorithm that should only be used for monochrome output. The result is probably unpleasant if the glyph is rendered in non-monochrome modes. Mono, /// A variant of Normal optimized for horizontally decimated LCD displays. HorizontalLcd, /// A variant of Normal optimized for vertically decimated LCD displays. VerticalLcd, } ``` I expect most people will want to set this to one of `Normal`, `Light` or `HorizontalLcd`. `HorizontalLcd` is what `font_antialias=Subpixel` used to select. refs: #491
This commit is contained in:
parent
528a4846c7
commit
dd70a8a53b
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -672,6 +672,7 @@ name = "config"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"bitflags",
|
||||||
"bstr 0.2.15",
|
"bstr 0.2.15",
|
||||||
"dirs-next",
|
"dirs-next",
|
||||||
"filenamegen",
|
"filenamegen",
|
||||||
|
@ -15,6 +15,7 @@ pretty_env_logger = "0.4"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
|
bitflags = "1.0"
|
||||||
bstr = "0.2"
|
bstr = "0.2"
|
||||||
dirs-next = "2.0"
|
dirs-next = "2.0"
|
||||||
filenamegen = "0.2"
|
filenamegen = "0.2"
|
||||||
|
@ -1,7 +1,88 @@
|
|||||||
use crate::*;
|
use crate::*;
|
||||||
|
use bitflags::*;
|
||||||
use luahelper::impl_lua_conversion;
|
use luahelper::impl_lua_conversion;
|
||||||
|
use serde::{Deserialize, Deserializer, Serialize};
|
||||||
use termwiz::color::RgbColor;
|
use termwiz::color::RgbColor;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
pub enum FreeTypeLoadTarget {
|
||||||
|
/// This corresponds to the default hinting algorithm, optimized
|
||||||
|
/// for standard gray-level rendering.
|
||||||
|
Normal,
|
||||||
|
/// A lighter hinting algorithm for non-monochrome modes. Many
|
||||||
|
/// generated glyphs are more fuzzy but better resemble its
|
||||||
|
/// original shape. A bit like rendering on Mac OS X. This target
|
||||||
|
/// implies FT_LOAD_FORCE_AUTOHINT.
|
||||||
|
Light,
|
||||||
|
/// Strong hinting algorithm that should only be used for
|
||||||
|
/// monochrome output. The result is probably unpleasant if the
|
||||||
|
/// glyph is rendered in non-monochrome modes.
|
||||||
|
Mono,
|
||||||
|
/// A variant of Normal optimized for horizontally decimated LCD displays.
|
||||||
|
HorizontalLcd,
|
||||||
|
/// A variant of Normal optimized for vertically decimated LCD displays.
|
||||||
|
VerticalLcd,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for FreeTypeLoadTarget {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::Normal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bitflags! {
|
||||||
|
// Note that these are strongly coupled with deps/freetype/src/lib.rs,
|
||||||
|
// but we can't directly reference that from here without making config
|
||||||
|
// depend on freetype.
|
||||||
|
#[derive(Default, Deserialize, Serialize)]
|
||||||
|
pub struct FreeTypeLoadFlags: u32 {
|
||||||
|
/// FT_LOAD_DEFAULT
|
||||||
|
const DEFAULT = 0;
|
||||||
|
/// Disable hinting. This generally generates ‘blurrier’
|
||||||
|
/// bitmap glyph when the glyph is rendered in any of the
|
||||||
|
/// anti-aliased modes. See also the note below. This flag is
|
||||||
|
/// implied by FT_LOAD_NO_SCALE.
|
||||||
|
const NO_HINTING = 2;
|
||||||
|
const NO_BITMAP = 8;
|
||||||
|
/// Indicates that the auto-hinter is preferred over the
|
||||||
|
/// font’s native hinter.
|
||||||
|
const FORCE_AUTOHINT = 32;
|
||||||
|
const MONOCHROME = 4096;
|
||||||
|
/// Disable auto-hinter.
|
||||||
|
const NO_AUTOHINT = 32768;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FreeTypeLoadFlags {
|
||||||
|
pub fn de_string<'de, D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let s = String::deserialize(deserializer)?;
|
||||||
|
let mut flags = FreeTypeLoadFlags::default();
|
||||||
|
|
||||||
|
for ele in s.split('|') {
|
||||||
|
let ele = ele.trim();
|
||||||
|
match ele {
|
||||||
|
"DEFAULT" => flags |= Self::DEFAULT,
|
||||||
|
"NO_HINTING" => flags |= Self::NO_HINTING,
|
||||||
|
"NO_BITMAP" => flags |= Self::NO_BITMAP,
|
||||||
|
"FORCE_AUTOHINT" => flags |= Self::FORCE_AUTOHINT,
|
||||||
|
"MONOCHROME" => flags |= Self::MONOCHROME,
|
||||||
|
"NO_AUTOHINT" => flags |= Self::NO_AUTOHINT,
|
||||||
|
_ => {
|
||||||
|
return Err(serde::de::Error::custom(format!(
|
||||||
|
"invalid FreeTypeLoadFlags {} in {}",
|
||||||
|
ele, s
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(flags)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Deserialize, Serialize, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Copy, Deserialize, Serialize, Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum FontHinting {
|
pub enum FontHinting {
|
||||||
/// No hinting is performed
|
/// No hinting is performed
|
||||||
|
@ -571,6 +571,11 @@ pub struct Config {
|
|||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub font_antialias: FontAntiAliasing,
|
pub font_antialias: FontAntiAliasing,
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
|
pub freetype_load_target: FreeTypeLoadTarget,
|
||||||
|
#[serde(default, deserialize_with = "FreeTypeLoadFlags::de_string")]
|
||||||
|
pub freetype_load_flags: FreeTypeLoadFlags,
|
||||||
|
|
||||||
/// Selects the freetype interpret version to use.
|
/// Selects the freetype interpret version to use.
|
||||||
/// Likely values are 35, 38 and 40 which have different
|
/// Likely values are 35, 38 and 40 which have different
|
||||||
/// characteristics with respective to subpixel hinting.
|
/// characteristics with respective to subpixel hinting.
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use crate::locator::FontDataHandle;
|
use crate::locator::FontDataHandle;
|
||||||
use anyhow::{anyhow, Context};
|
use anyhow::{anyhow, Context};
|
||||||
use config::{configuration, FontAntiAliasing, FontHinting};
|
use config::{configuration, FreeTypeLoadTarget};
|
||||||
pub use freetype::*;
|
pub use freetype::*;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
@ -44,33 +44,18 @@ fn render_mode_to_load_target(render_mode: FT_Render_Mode) -> u32 {
|
|||||||
pub fn compute_load_flags_from_config() -> (i32, FT_Render_Mode) {
|
pub fn compute_load_flags_from_config() -> (i32, FT_Render_Mode) {
|
||||||
let config = configuration();
|
let config = configuration();
|
||||||
|
|
||||||
let render = match config.font_antialias {
|
let load_flags = config.freetype_load_flags.bits() | FT_LOAD_COLOR;
|
||||||
FontAntiAliasing::None => FT_Render_Mode::FT_RENDER_MODE_MONO,
|
let render = match config.freetype_load_target {
|
||||||
FontAntiAliasing::Greyscale => FT_Render_Mode::FT_RENDER_MODE_NORMAL,
|
FreeTypeLoadTarget::Mono => FT_Render_Mode::FT_RENDER_MODE_MONO,
|
||||||
FontAntiAliasing::Subpixel => FT_Render_Mode::FT_RENDER_MODE_LCD,
|
FreeTypeLoadTarget::Normal => FT_Render_Mode::FT_RENDER_MODE_NORMAL,
|
||||||
|
FreeTypeLoadTarget::Light => FT_Render_Mode::FT_RENDER_MODE_LIGHT,
|
||||||
|
FreeTypeLoadTarget::HorizontalLcd => FT_Render_Mode::FT_RENDER_MODE_LCD,
|
||||||
|
FreeTypeLoadTarget::VerticalLcd => FT_Render_Mode::FT_RENDER_MODE_LCD_V,
|
||||||
};
|
};
|
||||||
|
|
||||||
let flags = match config.font_hinting {
|
let load_flags = load_flags | render_mode_to_load_target(render);
|
||||||
FontHinting::None => {
|
|
||||||
render_mode_to_load_target(FT_Render_Mode::FT_RENDER_MODE_NORMAL) | FT_LOAD_NO_HINTING
|
|
||||||
}
|
|
||||||
FontHinting::Vertical => render_mode_to_load_target(FT_Render_Mode::FT_RENDER_MODE_LIGHT),
|
|
||||||
FontHinting::VerticalSubpixel | FontHinting::Full => {
|
|
||||||
render_mode_to_load_target(FT_Render_Mode::FT_RENDER_MODE_LCD)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// If the bitmaps are in color, we want those!
|
(load_flags as i32, render)
|
||||||
let flags = flags | FT_LOAD_COLOR;
|
|
||||||
|
|
||||||
let flags = if config.font_antialias == FontAntiAliasing::None {
|
|
||||||
// When AA is disabled, force outline rendering to monochrome
|
|
||||||
flags | FT_LOAD_MONOCHROME
|
|
||||||
} else {
|
|
||||||
flags
|
|
||||||
} as i32;
|
|
||||||
|
|
||||||
(flags, render)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Face {
|
pub struct Face {
|
||||||
|
Loading…
Reference in New Issue
Block a user