1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-23 05:12:40 +03:00

fonts: synthesize bold when missing

refs: #815
This commit is contained in:
Wez Furlong 2021-05-22 16:20:35 -07:00
parent 2bbe2bd154
commit c37ee01222
6 changed files with 40 additions and 28 deletions

View File

@ -5,3 +5,4 @@
#include <freetype/ftmodapi.h>
#include <freetype/ftoutln.h>
#include <freetype/ftmm.h>
#include <freetype/ftsynth.h>

View File

@ -1,4 +1,4 @@
/* automatically generated by rust-bindgen 0.58.1 */
/* automatically generated by rust-bindgen */
#![allow(non_snake_case)]
#![allow(non_camel_case_types)]
@ -14,18 +14,6 @@ pub type FT_UInt64 = u64;
pub const FT_RENDER_POOL_SIZE: u32 = 16384;
pub const FT_MAX_MODULES: u32 = 32;
pub const FT_CHAR_BIT: u32 = 8;
pub const FT_USHORT_MAX: u32 = 65535;
pub const FT_INT_MAX: u32 = 2147483647;
pub const FT_INT_MIN: i32 = -2147483648;
pub const FT_UINT_MAX: u32 = 4294967295;
pub const FT_LONG_MIN: i64 = -9223372036854775808;
pub const FT_LONG_MAX: u64 = 9223372036854775807;
pub const FT_ULONG_MAX: i32 = -1;
pub const FT_SIZEOF_INT: u32 = 4;
pub const FT_SIZEOF_LONG: u32 = 8;
pub const FT_OUTLINE_CONTOURS_MAX: u32 = 32767;
pub const FT_OUTLINE_POINTS_MAX: u32 = 32767;
pub const FT_OUTLINE_NONE: u32 = 0;
pub const FT_OUTLINE_OWNER: u32 = 1;
pub const FT_OUTLINE_EVEN_ODD_FILL: u32 = 2;
@ -155,6 +143,7 @@ pub type FT_Stream = *mut FT_StreamRec_;
pub union FT_StreamDesc_ {
pub value: ::std::os::raw::c_long,
pub pointer: *mut ::std::os::raw::c_void,
_bindgen_union_align: u64,
}
pub type FT_StreamDesc = FT_StreamDesc_;
pub type FT_Stream_IoFunc = ::std::option::Option<
@ -199,7 +188,7 @@ pub struct FT_BBox_ {
}
pub type FT_BBox = FT_BBox_;
#[repr(u32)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum FT_Pixel_Mode_ {
FT_PIXEL_MODE_NONE = 0,
FT_PIXEL_MODE_MONO = 1,
@ -275,7 +264,7 @@ pub struct FT_Outline_Funcs_ {
}
pub type FT_Outline_Funcs = FT_Outline_Funcs_;
#[repr(u32)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum FT_Glyph_Format_ {
FT_GLYPH_FORMAT_NONE = 0,
FT_GLYPH_FORMAT_COMPOSITE = 1668246896,
@ -467,7 +456,7 @@ pub const FT_Mod_Err_Winfonts: _bindgen_ty_1 = _bindgen_ty_1::FT_Mod_Err_Base;
pub const FT_Mod_Err_GXvalid: _bindgen_ty_1 = _bindgen_ty_1::FT_Mod_Err_Base;
pub const FT_Mod_Err_Max: _bindgen_ty_1 = _bindgen_ty_1::FT_Mod_Err_Max;
#[repr(u32)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum _bindgen_ty_1 {
FT_Mod_Err_Base = 0,
FT_Mod_Err_Max = 1,
@ -582,7 +571,7 @@ pub const FT_Err_Corrupted_Font_Header: _bindgen_ty_2 = _bindgen_ty_2::FT_Err_Co
pub const FT_Err_Corrupted_Font_Glyphs: _bindgen_ty_2 = _bindgen_ty_2::FT_Err_Corrupted_Font_Glyphs;
pub const FT_Err_Max: _bindgen_ty_2 = _bindgen_ty_2::FT_Err_Max;
#[repr(u32)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum _bindgen_ty_2 {
FT_Err_Ok = 0,
FT_Err_Cannot_Open_Resource = 1,
@ -752,7 +741,7 @@ impl FT_Encoding_ {
pub const FT_ENCODING_MS_JOHAB: FT_Encoding_ = FT_Encoding_::FT_ENCODING_JOHAB;
}
#[repr(u32)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum FT_Encoding_ {
FT_ENCODING_NONE = 0,
FT_ENCODING_MS_SYMBOL = 1937337698,
@ -955,7 +944,7 @@ extern "C" {
pub fn FT_Select_Size(face: FT_Face, strike_index: FT_Int) -> FT_Error;
}
#[repr(u32)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum FT_Size_Request_Type_ {
FT_SIZE_REQUEST_TYPE_NOMINAL = 0,
FT_SIZE_REQUEST_TYPE_REAL_DIM = 1,
@ -1005,7 +994,7 @@ extern "C" {
pub fn FT_Set_Transform(face: FT_Face, matrix: *mut FT_Matrix, delta: *mut FT_Vector);
}
#[repr(u32)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum FT_Render_Mode_ {
FT_RENDER_MODE_NORMAL = 0,
FT_RENDER_MODE_LIGHT = 1,
@ -1019,7 +1008,7 @@ extern "C" {
pub fn FT_Render_Glyph(slot: FT_GlyphSlot, render_mode: FT_Render_Mode) -> FT_Error;
}
#[repr(u32)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum FT_Kerning_Mode_ {
FT_KERNING_DEFAULT = 0,
FT_KERNING_UNFITTED = 1,
@ -1172,7 +1161,7 @@ extern "C" {
pub fn FT_Face_SetUnpatentedHinting(face: FT_Face, value: FT_Bool) -> FT_Bool;
}
#[repr(u32)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum FT_LcdFilter_ {
FT_LCD_FILTER_NONE = 0,
FT_LCD_FILTER_DEFAULT = 1,
@ -1358,7 +1347,7 @@ pub struct TT_MaxProfile_ {
}
pub type TT_MaxProfile = TT_MaxProfile_;
#[repr(u32)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum FT_Sfnt_Tag_ {
FT_SFNT_HEAD = 0,
FT_SFNT_MAXP = 1,
@ -1473,7 +1462,7 @@ extern "C" {
pub fn FT_Add_Default_Modules(library: FT_Library);
}
#[repr(u32)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum FT_TrueTypeEngineType_ {
FT_TRUETYPE_ENGINE_TYPE_NONE = 0,
FT_TRUETYPE_ENGINE_TYPE_UNPATENTED = 1,
@ -1551,7 +1540,7 @@ impl FT_Orientation_ {
FT_Orientation_::FT_ORIENTATION_POSTSCRIPT;
}
#[repr(u32)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum FT_Orientation_ {
FT_ORIENTATION_TRUETYPE = 0,
FT_ORIENTATION_POSTSCRIPT = 1,
@ -1618,7 +1607,7 @@ impl PS_Dict_Keys_ {
pub const PS_DICT_MAX: PS_Dict_Keys_ = PS_Dict_Keys_::PS_DICT_ITALIC_ANGLE;
}
#[repr(u32)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum PS_Dict_Keys_ {
PS_DICT_FONT_TYPE = 0,
PS_DICT_FONT_MATRIX = 1,
@ -1804,3 +1793,9 @@ extern "C" {
extern "C" {
pub fn FT_Set_Named_Instance(face: FT_Face, instance_index: FT_UInt) -> FT_Error;
}
extern "C" {
pub fn FT_GlyphSlot_Embolden(slot: FT_GlyphSlot);
}
extern "C" {
pub fn FT_GlyphSlot_Oblique(slot: FT_GlyphSlot);
}

View File

@ -24,7 +24,7 @@ As features stabilize some brief notes about them will accumulate here.
* Fixed: errors loading custom color schemes are now logged to the error log [#794](https://github.com/wez/wezterm/issues/794)
* Fixed: OSC 7 (current working directory) now works with paths that contain spaces and other special characters. Thanks to [@Arvedui](https://github.com/Arvedui)! [#799](https://github.com/wez/wezterm/pull/799)
* Changed: the homebrew tap is now a Cask that installs to the /Applications directory on macOS. Thanks to [@laggardkernel](https://github.com/laggardkernel)!
* New: italics are now synthesized for scalable fonts when the matching font is not actually italic [#815](https://github.com/wez/wezterm/issues/815)
* New: bold and/or italics are now synthesized for fonts when the matching font is not actually italic or doesn't match the requested weight. Synthesized italics only apply to scalable fonts. [#815](https://github.com/wez/wezterm/issues/815)
### 20210502-154244-3f7122cb

View File

@ -440,6 +440,7 @@ impl Face {
glyph_index: FT_UInt,
load_flags: FT_Int32,
render_mode: FT_Render_Mode,
synthesize_bold: bool,
) -> anyhow::Result<&FT_GlyphSlotRec_> {
unsafe {
ft_result(FT_Load_Glyph(self.face, glyph_index, load_flags), ()).with_context(
@ -451,6 +452,11 @@ impl Face {
},
)?;
let slot = &mut *(*self.face).glyph;
if synthesize_bold {
FT_GlyphSlot_Embolden(slot as *mut _);
}
ft_result(FT_Render_Glyph(slot, render_mode), ())
.context("load_and_render_glyph: FT_Render_Glyph")?;
Ok(slot)

View File

@ -22,6 +22,7 @@ pub struct ParsedFont {
pub handle: FontDataHandle,
coverage: Mutex<RangeSet<u32>>,
pub synthesize_italic: bool,
pub synthesize_bold: bool,
}
impl std::fmt::Debug for ParsedFont {
@ -45,6 +46,7 @@ impl Clone for ParsedFont {
stretch: self.stretch,
italic: self.italic,
synthesize_italic: self.synthesize_italic,
synthesize_bold: self.synthesize_bold,
handle: self.handle.clone(),
cap_height: self.cap_height.clone(),
coverage: Mutex::new(self.coverage.lock().unwrap().clone()),
@ -135,6 +137,9 @@ impl ParsedFont {
if p.synthesize_italic {
code.push_str(" -- Will synthesize italics\n");
}
if p.synthesize_bold {
code.push_str(" -- Will synthesize bold\n");
}
if p.weight == FontWeight::Regular && p.stretch == FontStretch::Normal && !p.italic {
code.push_str(&format!(" \"{}\",\n", p.names.family));
@ -170,6 +175,7 @@ impl ParsedFont {
stretch,
italic,
synthesize_italic: false,
synthesize_bold: false,
handle,
coverage: Mutex::new(RangeSet::new()),
cap_height,
@ -375,6 +381,7 @@ impl ParsedFont {
/// italic for this font.
pub fn synthesize(mut self, attr: &FontAttributes) -> Self {
self.synthesize_italic = !self.italic && attr.italic;
self.synthesize_bold = attr.weight > self.weight;
self
}
}

View File

@ -13,6 +13,7 @@ pub struct FreeTypeRasterizer {
has_color: bool,
face: RefCell<ftwrap::Face>,
_lib: ftwrap::Library,
synthesize_bold: bool,
}
impl FontRasterizer for FreeTypeRasterizer {
@ -28,7 +29,8 @@ impl FontRasterizer for FreeTypeRasterizer {
let mut face = self.face.borrow_mut();
let descender = unsafe { (*(*face.face).size).metrics.descender as f64 / 64.0 };
let ft_glyph = face.load_and_render_glyph(glyph_pos, load_flags, render_mode)?;
let ft_glyph =
face.load_and_render_glyph(glyph_pos, load_flags, render_mode, self.synthesize_bold)?;
let mode: ftwrap::FT_Pixel_Mode =
unsafe { mem::transmute(u32::from(ft_glyph.bitmap.pixel_mode)) };
@ -310,6 +312,7 @@ impl FreeTypeRasterizer {
_lib: lib,
face: RefCell::new(face),
has_color,
synthesize_bold: parsed.synthesize_bold,
})
}
}