1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-26 16:34:23 +03:00

fonts: remove ttf_parser, compute coverage from freetype

Replaces the last usage of ttf-parser with calling into freetype.

This removes a source of inconsistency, as ttf-parser doesn't support
all of the things that freetype does.

Notably, this prevents a weird error from blowing up codepoint coverage
calculations on a system where I have helvetica.bdf in my font dir for
long-forgotten reasons.
This commit is contained in:
Wez Furlong 2021-04-08 09:12:59 -07:00
parent e59e17d773
commit 064b591a1b
4 changed files with 40 additions and 32 deletions

9
Cargo.lock generated
View File

@ -2542,7 +2542,7 @@ version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f923fb806c46266c02ab4a5b239735c144bdeda724a50ed058e5226f594cde3"
dependencies = [
"ttf-parser 0.6.2",
"ttf-parser",
]
[[package]]
@ -3919,12 +3919,6 @@ version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e5d7cd7ab3e47dda6e56542f4bbf3824c15234958c6e1bd6aaa347e93499fdc"
[[package]]
name = "ttf-parser"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85e00391c1f3d171490a3f8bd79999b0002ae38d3da0d6a3a306c754b053d71b"
[[package]]
name = "typenum"
version = "1.13.0"
@ -4432,7 +4426,6 @@ dependencies = [
"termwiz",
"thiserror",
"tinyvec",
"ttf-parser 0.12.0",
"unicode-general-category 0.3.0",
"unicode-segmentation",
"walkdir",

View File

@ -22,7 +22,6 @@ rangeset = { path = "../rangeset" }
termwiz = { path = "../termwiz" }
thiserror = "1.0"
tinyvec = "1.1" # Note: constrained by the allsorts crate
ttf-parser = "0.12"
unicode-segmentation = "1.7"
unicode-general-category = "0.3"
walkdir = "2"

View File

@ -1,11 +1,11 @@
//! A font-database to keep track of fonts that we've located
use crate::ftwrap::Library;
use crate::parser::{load_built_in_fonts, parse_and_collect_font_info, FontMatch, ParsedFont};
use crate::FontDataHandle;
use anyhow::{anyhow, Context};
use anyhow::Context;
use config::{Config, FontAttributes};
use rangeset::RangeSet;
use std::borrow::Cow;
use std::cmp::Ordering;
use std::collections::{HashMap, HashSet};
use std::sync::{Arc, Mutex};
@ -20,28 +20,12 @@ impl Entry {
/// Parses out the underlying TTF data and produces a RangeSet holding
/// the set of codepoints for which the font has coverage.
fn compute_coverage(&self) -> anyhow::Result<RangeSet<u32>> {
use ttf_parser::Face;
let (data, index) = match &self.handle {
FontDataHandle::Memory { data, index, .. } => (data.clone(), *index),
FontDataHandle::OnDisk { path, index, .. } => {
let data = std::fs::read(path)
.with_context(|| anyhow!("reading font data from {}", path.display()))?;
(Cow::Owned(data), *index)
}
};
let lib = Library::new()?;
let face = lib
.face_from_locator(&self.handle)
.with_context(|| format!("freetype parsing {:?}", self.handle))?;
let face = Face::from_slice(&data, index)
.with_context(|| format!("ttf_parser parsing {:?}", self.handle))?;
let mut coverage = RangeSet::new();
for table in face.character_mapping_subtables() {
if table.is_unicode() {
table.codepoints(|cp| coverage.add(cp));
break;
}
}
Ok(coverage)
Ok(face.compute_coverage())
}
/// Computes the intersection of the wanted set of codepoints with

View File

@ -5,6 +5,7 @@ use crate::parser::ParsedFont;
use anyhow::{anyhow, Context};
use config::{configuration, FreeTypeLoadTarget};
pub use freetype::*;
use rangeset::RangeSet;
use std::borrow::Cow;
use std::convert::TryInto;
use std::ffi::CStr;
@ -228,6 +229,37 @@ impl Face {
unsafe { ((*self.face).style_flags & FT_STYLE_FLAG_ITALIC as FT_Long) != 0 }
}
pub fn compute_coverage(&self) -> RangeSet<u32> {
let mut coverage = RangeSet::new();
for encoding in &[
FT_Encoding::FT_ENCODING_UNICODE,
FT_Encoding::FT_ENCODING_MS_SYMBOL,
] {
if unsafe { FT_Select_Charmap(self.face, *encoding) } != 0 {
continue;
}
let mut glyph = 0;
let mut ucs4 = unsafe { FT_Get_First_Char(self.face, &mut glyph) };
while glyph != 0 {
coverage.add(ucs4);
ucs4 = unsafe { FT_Get_Next_Char(self.face, ucs4, &mut glyph) };
}
if *encoding == FT_Encoding::FT_ENCODING_MS_SYMBOL {
// Fontconfig duplicates F000..F0FF to 0000..00FF
for ucs4 in 0xf00..0xf100 {
if coverage.contains(ucs4) {
coverage.add(ucs4 - 0xf000);
}
}
}
}
coverage
}
/// This is a wrapper around set_char_size and select_size
/// that accounts for some weirdness with eg: color emoji
pub fn set_font_size(&mut self, point_size: f64, dpi: u32) -> anyhow::Result<(f64, f64)> {