feat(font): add the FreeType-only font backend (font-backend-freetype)
Ghostty can be built with -Dfont-backend=freetype, which uses FreeType without any font discovery. The Rust port only had fontconfig+freetype (default on Linux) and the CoreText variants. The new cargo feature `font-backend-freetype` on ghostty-font (forwarded by ghostty-cli and the root crate; non-Apple, non-wasm targets) behaves like Zig's mode: font-family discovery, fallback search and codepoint-map overrides are skipped (embedded fonts only); +list-fonts and +show-face print Zig's "built without a font discovery mechanism" message and exit 1; +version reports `.freetype`. The default backend is unchanged. Also registers the Rust-only benchmark tooling extensions (--time, --handler=full, ghostty-synthetic +sgr) in DEVIANT_FIXES.md. Note: `--all-features` now selects this backend for the workspace. Test Plan: - cargo test -p ghostty-font --features font-backend-freetype (198) - cargo build --features font-backend-freetype && ghostty +list-fonts
This commit is contained in:
1 parent
798a31ccac
commit
389266720d
18 files changed
+327
-12
No files matched your search
@@ -4,6 +4,11 @@ version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
[features]
|
||||
# Select the FreeType-only font backend (no font discovery), like
|
||||
# `-Dfont-backend=freetype`.
|
||||
font-backend-freetype = ["ghostty-font/font-backend-freetype"]
|
||||
|
||||
[dependencies]
|
||||
flate2 = "1.1.10"
|
||||
ghostty-build-info.workspace = true
|
||||
|
||||
@@ -59,7 +59,7 @@ impl Default for BuildInfo {
|
||||
release_channel: ghostty_build_info::RELEASE_CHANNEL.to_string(),
|
||||
build_mode: ghostty_build_info::BUILD_MODE.to_string(),
|
||||
app_runtime: ".gtk".to_string(),
|
||||
font_backend: ".fontconfig_freetype".to_string(),
|
||||
font_backend: format!(".{}", ghostty_font::options.backend.name()),
|
||||
renderer: "renderer.generic.Renderer(renderer.OpenGL)".to_string(),
|
||||
gtk_build: None,
|
||||
gtk_runtime: None,
|
||||
|
||||
@@ -4,6 +4,11 @@ use ghostty_config::config_struct;
|
||||
|
||||
use crate::error::Error;
|
||||
|
||||
/// Printed (without a trailing newline) by `+list-fonts` and `+show-face`
|
||||
/// when the build has no font discovery mechanism (Zig `Discover == void`,
|
||||
/// the `freetype` font backend).
|
||||
pub(crate) const NO_DISCOVERY_MESSAGE: &str = "Ghostty was built without a font discovery mechanism. This is a compile-time\noption. Please review how Ghostty was built from source, contact the\nmaintainer to enable a font discovery mechanism, and try again.";
|
||||
|
||||
config_struct! {
|
||||
pub struct Options {
|
||||
/// The font family to search for. If this is set, then only fonts
|
||||
@@ -51,6 +56,14 @@ pub fn run(args: &[impl AsRef<[u8]>]) -> Result<u8, Error> {
|
||||
|
||||
use std::{collections::HashMap, io::Write};
|
||||
|
||||
// Its possible to build Ghostty without font discovery!
|
||||
if !ghostty_font::HAS_DISCOVERY {
|
||||
let mut stderr = crate::zig_writer::ZigWriter::new(crate::zig_writer::stderr_sink(), 1024);
|
||||
write!(stderr, "{NO_DISCOVERY_MESSAGE}")?;
|
||||
stderr.flush()?;
|
||||
return Ok(1);
|
||||
}
|
||||
|
||||
// We'll be putting our fonts into a list categorized by family
|
||||
// so it is easier to read the output.
|
||||
let mut families: Vec<String> = Vec::new();
|
||||
@@ -118,3 +131,23 @@ pub fn run(args: &[impl AsRef<[u8]>]) -> Result<u8, Error> {
|
||||
stdout.flush()?;
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
/// Without a discovery mechanism (the `freetype` font backend, Zig
|
||||
/// `Discover == void`) `+list-fonts` prints the compile-time-option
|
||||
/// message and exits with 1, after parsing the arguments.
|
||||
#[cfg(feature = "font-backend-freetype")]
|
||||
#[test]
|
||||
fn freetype_backend_reports_no_discovery() {
|
||||
const { assert!(!ghostty_font::HAS_DISCOVERY) };
|
||||
assert_eq!(super::run(&[] as &[&[u8]]).expect("run"), 1);
|
||||
assert!(super::NO_DISCOVERY_MESSAGE.ends_with("try again."));
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "font-backend-freetype"))]
|
||||
#[test]
|
||||
fn default_backend_has_discovery() {
|
||||
const { assert!(ghostty_font::HAS_DISCOVERY) };
|
||||
}
|
||||
}
|
||||
@@ -86,6 +86,16 @@ cli_options!(Options, help, diagnostics);
|
||||
/// style. Valid options are `text` and `emoji`. If unset, the presentation
|
||||
/// style of a codepoint will be inferred from the Unicode standard.
|
||||
pub fn run(args: &[impl AsRef<[u8]>]) -> Result<u8, Error> {
|
||||
// Its possible to build Ghostty without font discovery! (This is checked
|
||||
// before the arguments are parsed, as in Zig; the stderr writer is on
|
||||
// stdout, like the other show-face writers.)
|
||||
if !ghostty_font::HAS_DISCOVERY {
|
||||
let mut stderr = ZigWriter::new(stdout_sink(), 1024);
|
||||
write!(stderr, "{}", crate::list_fonts::NO_DISCOVERY_MESSAGE)?;
|
||||
stderr.flush()?;
|
||||
return Ok(1);
|
||||
}
|
||||
|
||||
let mut opts = Options::default();
|
||||
crate::parse_options(&mut opts, args)?;
|
||||
|
||||
|
||||
Reference in new issue
Block a user