mirror of
https://github.com/wez/wezterm.git
synced 2024-12-22 21:01:36 +03:00
Allow matching font weight and font width in wezterm.font
refs: https://github.com/wez/wezterm/issues/655
This commit is contained in:
parent
dee10c2f21
commit
43ea2f192a
12
Cargo.lock
generated
12
Cargo.lock
generated
@ -697,6 +697,7 @@ dependencies = [
|
||||
"bstr 0.2.15",
|
||||
"chrono",
|
||||
"dirs-next",
|
||||
"enum-display-derive",
|
||||
"filenamegen",
|
||||
"hostname",
|
||||
"lazy_static",
|
||||
@ -1070,6 +1071,17 @@ dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "enum-display-derive"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f16ef37b2a9b242295d61a154ee91ae884afff6b8b933b486b12481cc58310ca"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "enumflags2"
|
||||
version = "0.6.4"
|
||||
|
@ -17,6 +17,7 @@ bitflags = "1.0"
|
||||
bstr = "0.2"
|
||||
chrono = {version="0.4", features=["unstable-locales"]}
|
||||
dirs-next = "2.0"
|
||||
enum-display-derive = "0.1"
|
||||
filenamegen = "0.2"
|
||||
hostname = "0.3"
|
||||
lazy_static = "1.4"
|
||||
|
@ -1,9 +1,135 @@
|
||||
use crate::*;
|
||||
use bitflags::*;
|
||||
use enum_display_derive::Display;
|
||||
use luahelper::impl_lua_conversion;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use std::fmt::Display;
|
||||
use termwiz::color::RgbColor;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Hash, Display)]
|
||||
pub enum FontWidth {
|
||||
UltraCondensed,
|
||||
ExtraCondensed,
|
||||
Condensed,
|
||||
SemiCondensed,
|
||||
Normal,
|
||||
SemiExpanded,
|
||||
Expanded,
|
||||
ExtraExpanded,
|
||||
UltraExpanded,
|
||||
}
|
||||
|
||||
impl FontWidth {
|
||||
pub fn from_opentype_width(w: u16) -> Self {
|
||||
match w {
|
||||
1 => Self::UltraCondensed,
|
||||
2 => Self::ExtraCondensed,
|
||||
3 => Self::Condensed,
|
||||
4 => Self::SemiCondensed,
|
||||
5 => Self::Normal,
|
||||
6 => Self::SemiExpanded,
|
||||
7 => Self::Expanded,
|
||||
8 => Self::ExtraExpanded,
|
||||
9 => Self::UltraExpanded,
|
||||
_ if w < 1 => Self::UltraCondensed,
|
||||
_ => Self::UltraExpanded,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_opentype_width(self) -> u16 {
|
||||
match self {
|
||||
Self::UltraCondensed => 1,
|
||||
Self::ExtraCondensed => 2,
|
||||
Self::Condensed => 3,
|
||||
Self::SemiCondensed => 4,
|
||||
Self::Normal => 5,
|
||||
Self::SemiExpanded => 6,
|
||||
Self::Expanded => 7,
|
||||
Self::ExtraExpanded => 8,
|
||||
Self::UltraExpanded => 9,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for FontWidth {
|
||||
fn default() -> Self {
|
||||
Self::Normal
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Hash, Display)]
|
||||
pub enum FontWeight {
|
||||
Thin,
|
||||
ExtraLight,
|
||||
Light,
|
||||
DemiLight,
|
||||
Book,
|
||||
Regular,
|
||||
Medium,
|
||||
DemiBold,
|
||||
Bold,
|
||||
ExtraBold,
|
||||
Black,
|
||||
ExtraBlack,
|
||||
}
|
||||
|
||||
impl Default for FontWeight {
|
||||
fn default() -> Self {
|
||||
Self::Regular
|
||||
}
|
||||
}
|
||||
|
||||
impl FontWeight {
|
||||
pub fn from_opentype_weight(w: u16) -> Self {
|
||||
if w >= 1000 {
|
||||
Self::ExtraBlack
|
||||
} else if w >= 900 {
|
||||
Self::Black
|
||||
} else if w >= 800 {
|
||||
Self::ExtraBold
|
||||
} else if w >= 700 {
|
||||
Self::Bold
|
||||
} else if w >= 600 {
|
||||
Self::DemiBold
|
||||
} else if w >= 500 {
|
||||
Self::Medium
|
||||
} else if w >= 400 {
|
||||
Self::Regular
|
||||
} else if w >= 380 {
|
||||
Self::Book
|
||||
} else if w >= 350 {
|
||||
Self::DemiLight
|
||||
} else if w >= 300 {
|
||||
Self::Light
|
||||
} else if w >= 200 {
|
||||
Self::ExtraLight
|
||||
} else {
|
||||
Self::Thin
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_opentype_weight(self) -> u16 {
|
||||
match self {
|
||||
Self::Thin => 100,
|
||||
Self::ExtraLight => 200,
|
||||
Self::Light => 300,
|
||||
Self::DemiLight => 350,
|
||||
Self::Book => 380,
|
||||
Self::Regular => 400,
|
||||
Self::Medium => 500,
|
||||
Self::DemiBold => 600,
|
||||
Self::Bold => 700,
|
||||
Self::ExtraBold => 800,
|
||||
Self::Black => 900,
|
||||
Self::ExtraBlack => 1000,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bolder(self) -> Self {
|
||||
Self::from_opentype_weight(self.to_opentype_weight() + 200)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum FreeTypeLoadTarget {
|
||||
/// This corresponds to the default hinting algorithm, optimized
|
||||
@ -123,7 +249,9 @@ pub struct FontAttributes {
|
||||
pub family: String,
|
||||
/// Whether the font should be a bold variant
|
||||
#[serde(default)]
|
||||
pub bold: bool,
|
||||
pub weight: FontWeight,
|
||||
#[serde(default)]
|
||||
pub width: FontWidth,
|
||||
/// Whether the font should be an italic variant
|
||||
#[serde(default)]
|
||||
pub italic: bool,
|
||||
@ -136,8 +264,8 @@ impl std::fmt::Display for FontAttributes {
|
||||
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
|
||||
write!(
|
||||
fmt,
|
||||
"wezterm.font('{}', {{bold={}, italic={}}})",
|
||||
self.family, self.bold, self.italic
|
||||
"wezterm.font('{}', {{weight='{}', width='{}', italic={}}})",
|
||||
self.family, self.weight, self.width, self.italic
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -146,7 +274,8 @@ impl FontAttributes {
|
||||
pub fn new(family: &str) -> Self {
|
||||
Self {
|
||||
family: family.into(),
|
||||
bold: false,
|
||||
weight: FontWeight::default(),
|
||||
width: FontWidth::default(),
|
||||
italic: false,
|
||||
is_fallback: false,
|
||||
is_synthetic: false,
|
||||
@ -156,7 +285,8 @@ impl FontAttributes {
|
||||
pub fn new_fallback(family: &str) -> Self {
|
||||
Self {
|
||||
family: family.into(),
|
||||
bold: false,
|
||||
weight: FontWeight::default(),
|
||||
width: FontWidth::default(),
|
||||
italic: false,
|
||||
is_fallback: true,
|
||||
is_synthetic: false,
|
||||
@ -168,7 +298,8 @@ impl Default for FontAttributes {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
family: "JetBrains Mono".into(),
|
||||
bold: false,
|
||||
weight: FontWeight::default(),
|
||||
width: FontWidth::default(),
|
||||
italic: false,
|
||||
is_fallback: false,
|
||||
is_synthetic: false,
|
||||
@ -269,7 +400,7 @@ impl TextStyle {
|
||||
.iter()
|
||||
.map(|attr| {
|
||||
let mut attr = attr.clone();
|
||||
attr.bold = true;
|
||||
attr.weight = attr.weight.bolder();
|
||||
attr.is_synthetic = true;
|
||||
attr
|
||||
})
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{FontAttributes, TextStyle};
|
||||
use crate::{FontAttributes, FontWeight, FontWidth, TextStyle};
|
||||
use anyhow::anyhow;
|
||||
use bstr::BString;
|
||||
pub use luahelper::*;
|
||||
@ -334,7 +334,11 @@ fn hostname<'lua>(_: &'lua Lua, _: ()) -> mlua::Result<String> {
|
||||
struct TextStyleAttributes {
|
||||
/// Whether the font should be a bold variant
|
||||
#[serde(default)]
|
||||
pub bold: bool,
|
||||
pub bold: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub weight: Option<FontWeight>,
|
||||
#[serde(default)]
|
||||
pub width: FontWidth,
|
||||
/// Whether the font should be an italic variant
|
||||
#[serde(default)]
|
||||
pub italic: bool,
|
||||
@ -365,7 +369,12 @@ fn font<'lua>(
|
||||
text_style.font.clear();
|
||||
text_style.font.push(FontAttributes {
|
||||
family,
|
||||
bold: attrs.bold,
|
||||
width: attrs.width,
|
||||
weight: match attrs.bold {
|
||||
Some(true) => FontWeight::Bold,
|
||||
Some(false) => FontWeight::Regular,
|
||||
None => attrs.weight.unwrap_or(FontWeight::Regular),
|
||||
},
|
||||
italic: attrs.italic,
|
||||
is_fallback: false,
|
||||
is_synthetic: false,
|
||||
@ -393,7 +402,12 @@ fn font_with_fallback<'lua>(
|
||||
for (idx, family) in fallback.into_iter().enumerate() {
|
||||
text_style.font.push(FontAttributes {
|
||||
family,
|
||||
bold: attrs.bold,
|
||||
width: attrs.width,
|
||||
weight: match attrs.bold {
|
||||
Some(true) => FontWeight::Bold,
|
||||
Some(false) => FontWeight::Regular,
|
||||
None => attrs.weight.unwrap_or(FontWeight::Regular),
|
||||
},
|
||||
italic: attrs.italic,
|
||||
is_fallback: idx != 0,
|
||||
is_synthetic: false,
|
||||
|
10
deps/fontconfig/src/lib.rs
vendored
10
deps/fontconfig/src/lib.rs
vendored
@ -52,6 +52,16 @@ pub const FC_SLANT_ROMAN: c_int = 0;
|
||||
pub const FC_SLANT_ITALIC: c_int = 100;
|
||||
pub const FC_SLANT_OBLIQUE: c_int = 110;
|
||||
|
||||
pub const FC_WIDTH_ULTRACONDENSED: c_int = 50;
|
||||
pub const FC_WIDTH_EXTRACONDENSED: c_int = 63;
|
||||
pub const FC_WIDTH_CONDENSED: c_int = 75;
|
||||
pub const FC_WIDTH_SEMICONDENSED: c_int = 87;
|
||||
pub const FC_WIDTH_NORMAL: c_int = 100;
|
||||
pub const FC_WIDTH_SEMIEXPANDED: c_int = 113;
|
||||
pub const FC_WIDTH_EXPANDED: c_int = 125;
|
||||
pub const FC_WIDTH_EXTRAEXPANDED: c_int = 150;
|
||||
pub const FC_WIDTH_ULTRAEXPANDED: c_int = 200;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct struct__FcMatrix {
|
||||
|
@ -15,6 +15,7 @@ As features stabilize some brief notes about them will accumulate here.
|
||||
* Fixed: the selection wouldn't always clear when the intersecting lines change [#644](https://github.com/wez/wezterm/issues/644)
|
||||
* Fixed: vertical alignment issue with Iosevka on Windows [#661](https://github.com/wez/wezterm/issues/661)
|
||||
* Fixed: support for "Variable" fonts such as Cascadia Code and Inconsolata on all platforms [#655](https://github.com/wez/wezterm/issues/655)
|
||||
* New: [wezterm.font](config/lua/wezterm/font.md) and [wezterm.font_with_fallback](config/lua/wezterm.font_with_fallback.md) *attributes* parameter now allows matching more granular font weights and font widths. e.g.: `wezterm.font('Iosevka Term', {width="Expanded", weight="Regular"})`
|
||||
|
||||
### 20210405-110924-a5bb5be8
|
||||
|
||||
|
@ -25,4 +25,21 @@ return {
|
||||
}
|
||||
```
|
||||
|
||||
*Since: nightly builds only*
|
||||
|
||||
It is now possible to specify both font weight and font width:
|
||||
|
||||
* `width` - specifies the font width to select. The default value is `"Normal"`, and possible values are `"UltraCondensed"`, `"ExtraCondensed"`, `"Condensed"`, `"SemiCondensed"`, `"Normal"`, `"SemiExpanded"`, `"Expanded"`, `"ExtraExpanded"`, `"UltraExpanded"`.
|
||||
* `weight` - specifies the weight of the font with more precision than `bold`. The default value is `"Regular"`, and possible values are `"Thin"`, `"ExtraLight"`, `"Light"`, `"DemiLight"`, `"Book"`, `"Regular"`, `"Medium"`, `"DemiBold"`, `"Bold"`, `"ExtraBold"`, `"Black"`, and `"ExtraBlack"`.
|
||||
* `bold` - has been superseded by the new `weight` parameter and will be eventually removed. For compatibility purposes, specifying `bold=true` is equivalent to specifying `weight="Bold"`.
|
||||
|
||||
Font weight matching will find the closest matching weight that is equal of
|
||||
heavier to the specified weight.
|
||||
|
||||
```lua
|
||||
local wezterm = require 'wezterm';
|
||||
|
||||
return {
|
||||
font = wezterm.font('Iosevka Term', {width="Expanded", weight="Regular"}),
|
||||
}
|
||||
```
|
||||
|
@ -14,6 +14,7 @@ return {
|
||||
}
|
||||
```
|
||||
|
||||
The second parameter behaves the same as that of `wezterm.font`.
|
||||
|
||||
The *attributes* parameter behaves the same as that of [wezterm.font](font.md)
|
||||
in that it allows you to specify font weight and style attributes that you
|
||||
want to match.
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#![allow(clippy::mutex_atomic)]
|
||||
|
||||
use anyhow::{anyhow, ensure, Error};
|
||||
use config::{FontWeight, FontWidth};
|
||||
pub use fontconfig::*;
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::fmt;
|
||||
@ -446,3 +447,33 @@ impl fmt::Debug for Pattern {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_fc_weight(weight: FontWeight) -> c_int {
|
||||
match weight {
|
||||
FontWeight::Thin => FC_WEIGHT_THIN,
|
||||
FontWeight::ExtraLight => FC_WEIGHT_EXTRALIGHT,
|
||||
FontWeight::Light => FC_WEIGHT_LIGHT,
|
||||
FontWeight::DemiLight | FontWeight::Book => FC_WEIGHT_BOOK,
|
||||
FontWeight::Regular => FC_WEIGHT_REGULAR,
|
||||
FontWeight::Medium => FC_WEIGHT_MEDIUM,
|
||||
FontWeight::DemiBold => FC_WEIGHT_DEMIBOLD,
|
||||
FontWeight::Bold => FC_WEIGHT_BOLD,
|
||||
FontWeight::ExtraBold => FC_WEIGHT_EXTRABOLD,
|
||||
FontWeight::Black => FC_WEIGHT_BLACK,
|
||||
FontWeight::ExtraBlack => FC_WEIGHT_EXTRABLACK,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_fc_width(width: FontWidth) -> c_int {
|
||||
match width {
|
||||
FontWidth::UltraCondensed => FC_WIDTH_ULTRACONDENSED,
|
||||
FontWidth::ExtraCondensed => FC_WIDTH_EXTRACONDENSED,
|
||||
FontWidth::Condensed => FC_WIDTH_CONDENSED,
|
||||
FontWidth::SemiCondensed => FC_WIDTH_SEMICONDENSED,
|
||||
FontWidth::Normal => FC_WIDTH_NORMAL,
|
||||
FontWidth::SemiExpanded => FC_WIDTH_SEMIEXPANDED,
|
||||
FontWidth::Expanded => FC_WIDTH_EXPANDED,
|
||||
FontWidth::ExtraExpanded => FC_WIDTH_EXTRAEXPANDED,
|
||||
FontWidth::UltraExpanded => FC_WIDTH_ULTRAEXPANDED,
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,9 @@ use crate::locator::{new_locator, FontDataHandle, FontLocator};
|
||||
use crate::rasterizer::{new_rasterizer, FontRasterizer};
|
||||
use crate::shaper::{new_shaper, FontShaper};
|
||||
use anyhow::{Context, Error};
|
||||
use config::{configuration, ConfigHandle, FontRasterizerSelection, TextStyle};
|
||||
use config::{
|
||||
configuration, ConfigHandle, FontRasterizerSelection, FontWeight, FontWidth, TextStyle,
|
||||
};
|
||||
use std::cell::RefCell;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::rc::{Rc, Weak};
|
||||
@ -281,8 +283,11 @@ impl FontConfigInner {
|
||||
|
||||
for attr in &attributes {
|
||||
if !attr.is_synthetic && !attr.is_fallback && !loaded.contains(attr) {
|
||||
let styled_extra = if attr.bold || attr.italic {
|
||||
". A bold or italic variant of the font was requested; \
|
||||
let styled_extra = if attr.weight != FontWeight::default()
|
||||
|| attr.italic
|
||||
|| attr.width != FontWidth::default()
|
||||
{
|
||||
". An alternative variant of the font was requested; \
|
||||
TrueType and OpenType fonts don't have an automatic way to \
|
||||
produce these font variants, so a separate font file containing \
|
||||
the bold or italic variant must be installed"
|
||||
|
@ -3,7 +3,7 @@ use crate::locator::{FontDataHandle, FontDataSource, FontLocator};
|
||||
use crate::parser::FontMatch;
|
||||
use anyhow::Context;
|
||||
use config::FontAttributes;
|
||||
use fcwrap::{CharSet, Pattern as FontPattern};
|
||||
use fcwrap::{to_fc_weight, to_fc_width, CharSet, Pattern as FontPattern};
|
||||
use std::collections::HashSet;
|
||||
use std::convert::TryInto;
|
||||
|
||||
@ -28,8 +28,16 @@ impl FontLocator for FontConfigFontLocator {
|
||||
let mut pattern = FontPattern::new()?;
|
||||
let start = std::time::Instant::now();
|
||||
pattern.family(&attr.family)?;
|
||||
pattern.add_integer("weight", if attr.bold { 200 } else { 80 })?;
|
||||
pattern.add_integer("slant", if attr.italic { 100 } else { 0 })?;
|
||||
pattern.add_integer("weight", to_fc_weight(attr.weight))?;
|
||||
pattern.add_integer("width", to_fc_width(attr.width))?;
|
||||
pattern.add_integer(
|
||||
"slant",
|
||||
if attr.italic {
|
||||
fcwrap::FC_SLANT_ITALIC
|
||||
} else {
|
||||
fcwrap::FC_SLANT_ROMAN
|
||||
},
|
||||
)?;
|
||||
pattern.add_integer("spacing", spacing)?;
|
||||
|
||||
log::trace!("fc pattern before config subst: {:?}", pattern);
|
||||
@ -44,10 +52,13 @@ impl FontLocator for FontConfigFontLocator {
|
||||
);
|
||||
|
||||
let file = best.get_file()?;
|
||||
let index = best.get_integer("index")? as u32;
|
||||
let variation = index >> 16;
|
||||
let index = index & 0xffff;
|
||||
let handle = FontDataHandle {
|
||||
source: FontDataSource::OnDisk(file.into()),
|
||||
index: best.get_integer("index")?.try_into()?,
|
||||
variation: 0,
|
||||
index,
|
||||
variation,
|
||||
};
|
||||
|
||||
// fontconfig will give us a boatload of random fallbacks.
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
use crate::locator::{FontDataHandle, FontDataSource, FontLocator};
|
||||
use crate::parser::{parse_and_collect_font_info, rank_matching_fonts, FontMatch, ParsedFont};
|
||||
use config::FontAttributes;
|
||||
use config::{FontAttributes, FontWeight as WTFontWeight, FontWidth};
|
||||
use dwrote::{FontDescriptor, FontStretch, FontStyle, FontWeight};
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashSet;
|
||||
@ -88,7 +88,7 @@ fn load_font(font_attr: &FontAttributes) -> anyhow::Result<FontDataHandle> {
|
||||
lfWidth: 0,
|
||||
lfEscapement: 0,
|
||||
lfOrientation: 0,
|
||||
lfWeight: if font_attr.bold { 700 } else { 0 },
|
||||
lfWeight: font_attr.weight.to_opentype_weight() as _,
|
||||
lfItalic: if font_attr.italic { 1 } else { 0 },
|
||||
lfUnderline: 0,
|
||||
lfStrikeOut: 0,
|
||||
@ -122,11 +122,7 @@ fn load_font(font_attr: &FontAttributes) -> anyhow::Result<FontDataHandle> {
|
||||
fn attributes_to_descriptor(font_attr: &FontAttributes) -> FontDescriptor {
|
||||
FontDescriptor {
|
||||
family_name: font_attr.family.to_string(),
|
||||
weight: if font_attr.bold {
|
||||
FontWeight::Bold
|
||||
} else {
|
||||
FontWeight::Regular
|
||||
},
|
||||
weight: FontWeight::from_u32(font_attr.weight.to_opentype_weight() as u32),
|
||||
stretch: FontStretch::Normal,
|
||||
style: if font_attr.italic {
|
||||
FontStyle::Italic
|
||||
@ -282,20 +278,8 @@ impl FontLocator for GdiFontLocator {
|
||||
);
|
||||
|
||||
let attr = FontAttributes {
|
||||
bold: match font.weight() {
|
||||
FontWeight::Thin
|
||||
| FontWeight::ExtraLight
|
||||
| FontWeight::Light
|
||||
| FontWeight::SemiLight
|
||||
| FontWeight::Regular
|
||||
| FontWeight::Medium => false,
|
||||
FontWeight::SemiBold
|
||||
| FontWeight::Bold
|
||||
| FontWeight::ExtraBold
|
||||
| FontWeight::Black
|
||||
| FontWeight::ExtraBlack => true,
|
||||
FontWeight::Unknown(n) => n > 80,
|
||||
},
|
||||
weight: WTFontWeight::from_opentype_weight(font.weight().to_u32() as _),
|
||||
width: FontWidth::from_opentype_width(font.stretch().to_u32() as _),
|
||||
italic: false,
|
||||
family: font.family_name(),
|
||||
is_fallback: true,
|
||||
|
@ -1,6 +1,7 @@
|
||||
use crate::locator::{FontDataHandle, FontDataSource};
|
||||
use crate::shaper::GlyphInfo;
|
||||
use config::FontAttributes;
|
||||
pub use config::{FontWeight, FontWidth};
|
||||
use std::borrow::Cow;
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -9,100 +10,6 @@ pub enum MaybeShaped {
|
||||
Unresolved { raw: String, slice_start: usize },
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum FontWidth {
|
||||
UltraCondensed,
|
||||
ExtraCondensed,
|
||||
Condensed,
|
||||
SemiCondensed,
|
||||
Normal,
|
||||
SemiExpanded,
|
||||
Expanded,
|
||||
ExtraExpanded,
|
||||
UltraExpanded,
|
||||
}
|
||||
|
||||
impl FontWidth {
|
||||
pub fn from_opentype_width(w: u16) -> Self {
|
||||
match w {
|
||||
1 => Self::UltraCondensed,
|
||||
2 => Self::ExtraCondensed,
|
||||
3 => Self::Condensed,
|
||||
4 => Self::SemiCondensed,
|
||||
5 => Self::Normal,
|
||||
6 => Self::SemiExpanded,
|
||||
7 => Self::Expanded,
|
||||
8 => Self::ExtraExpanded,
|
||||
9 => Self::UltraExpanded,
|
||||
_ if w < 1 => Self::UltraCondensed,
|
||||
_ => Self::UltraExpanded,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum FontWeight {
|
||||
Thin,
|
||||
ExtraLight,
|
||||
Light,
|
||||
DemiLight,
|
||||
Book,
|
||||
Regular,
|
||||
Medium,
|
||||
DemiBold,
|
||||
Bold,
|
||||
ExtraBold,
|
||||
Black,
|
||||
ExtraBlack,
|
||||
}
|
||||
|
||||
impl FontWeight {
|
||||
pub fn from_opentype_weight(w: u16) -> Self {
|
||||
if w >= 1000 {
|
||||
Self::ExtraBlack
|
||||
} else if w >= 900 {
|
||||
Self::Black
|
||||
} else if w >= 800 {
|
||||
Self::ExtraBold
|
||||
} else if w >= 700 {
|
||||
Self::Bold
|
||||
} else if w >= 600 {
|
||||
Self::DemiBold
|
||||
} else if w >= 500 {
|
||||
Self::Medium
|
||||
} else if w >= 400 {
|
||||
Self::Regular
|
||||
} else if w >= 380 {
|
||||
Self::Book
|
||||
} else if w >= 350 {
|
||||
Self::DemiLight
|
||||
} else if w >= 300 {
|
||||
Self::Light
|
||||
} else if w >= 200 {
|
||||
Self::ExtraLight
|
||||
} else {
|
||||
Self::Thin
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_opentype_weight(self) -> u16 {
|
||||
match self {
|
||||
Self::Thin => 100,
|
||||
Self::ExtraLight => 200,
|
||||
Self::Light => 300,
|
||||
Self::DemiLight => 350,
|
||||
Self::Book => 380,
|
||||
Self::Regular => 400,
|
||||
Self::Medium => 500,
|
||||
Self::DemiBold => 600,
|
||||
Self::Bold => 700,
|
||||
Self::ExtraBold => 800,
|
||||
Self::Black => 900,
|
||||
Self::ExtraBlack => 1000,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a parsed font
|
||||
#[derive(Debug)]
|
||||
pub struct ParsedFont {
|
||||
@ -183,14 +90,8 @@ impl ParsedFont {
|
||||
pub fn matches_attributes(&self, attr: &FontAttributes) -> FontMatch {
|
||||
if let Some(fam) = self.names.family.as_ref() {
|
||||
if attr.family == *fam {
|
||||
let wanted_width = FontWidth::Normal;
|
||||
if wanted_width == self.width {
|
||||
let wanted_weight = if attr.bold {
|
||||
FontWeight::Bold
|
||||
} else {
|
||||
FontWeight::Regular
|
||||
}
|
||||
.to_opentype_weight();
|
||||
if attr.width == self.width {
|
||||
let wanted_weight = attr.weight.to_opentype_weight();
|
||||
let weight = self.weight.to_opentype_weight();
|
||||
|
||||
if weight >= wanted_weight {
|
||||
|
Loading…
Reference in New Issue
Block a user