fix: inspector font/formatting, FreeType-only backend on Apple
Resolves the parity items of docs/rewrite/notes/review-rv17-codex.md (final-Z20.md): - FreeType-only font backend is also available on Apple targets (discovery-free, embedded emoji fonts); ghostty_surface_quicklook_font returns null for every backend except plain CoreText like Zig. - The +list-fonts test keys off the font crate's selected backend (HAS_DISCOVERY), correct under feature unification and on Apple. - Inspector font: 32 px rasterized with FreeType (dear-imgui freetype) like Ghostty; a new `visual-parity.sh inspector` scenario shows 0.031% differing pixels (hover highlight) vs the original on Linux. Windows, Apple and wasm keep stb_truetype at 32 px (registered as a deliberate deviation). - Inspector DCS/APC descriptions follow Zig 0.15.2's formatting (checked by running Zig), incl. the terminal.Parser.Action prefix. - The ImGui demo window appears only in dev-profile builds, mirroring Zig's .Debug-only gate. Test Plan: - cargo test --workspace --no-fail-fast (3582 passed) - just check-macos (both, also with --features font-backend-freetype) - scripts/visual-parity.sh inspector
This commit is contained in:
1 parent
75fd25d1f1
commit
e536b603b2
18 files changed
+267
-83
No files matched your search
@@ -13,9 +13,10 @@
|
||||
//! (Zig: `-Dfont-backend=...`). "There is no scenario that is the default"
|
||||
//! for those; they're only used by people who want to self-compile Ghostty
|
||||
//! and prefer the freetype aesthetic.
|
||||
//! * Non-Apple, non-wasm targets with the cargo feature
|
||||
//! * Non-wasm targets (Apple included) with the cargo feature
|
||||
//! `font-backend-freetype`: [`Backend::Freetype`] (Zig
|
||||
//! `-Dfont-backend=freetype`: no font discovery).
|
||||
//! `-Dfont-backend=freetype`: no font discovery; takes precedence over the
|
||||
//! `coretext-*` features).
|
||||
//! * wasm32: [`Backend::WebCanvas`].
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
@@ -104,11 +105,7 @@ pub struct Options {
|
||||
pub backend: Backend,
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
not(target_arch = "wasm32"),
|
||||
not(target_vendor = "apple"),
|
||||
feature = "font-backend-freetype"
|
||||
))]
|
||||
#[cfg(all(not(target_arch = "wasm32"), feature = "font-backend-freetype"))]
|
||||
pub const OPTIONS: Options = Options {
|
||||
backend: Backend::Freetype,
|
||||
};
|
||||
@@ -122,13 +119,18 @@ pub const OPTIONS: Options = Options {
|
||||
backend: Backend::FontconfigFreetype,
|
||||
};
|
||||
|
||||
#[cfg(all(target_vendor = "apple", feature = "coretext-freetype"))]
|
||||
#[cfg(all(
|
||||
target_vendor = "apple",
|
||||
feature = "coretext-freetype",
|
||||
not(feature = "font-backend-freetype")
|
||||
))]
|
||||
pub const OPTIONS: Options = Options {
|
||||
backend: Backend::CoretextFreetype,
|
||||
};
|
||||
|
||||
#[cfg(all(
|
||||
target_vendor = "apple",
|
||||
not(feature = "font-backend-freetype"),
|
||||
feature = "coretext-harfbuzz",
|
||||
not(feature = "coretext-freetype")
|
||||
))]
|
||||
@@ -138,6 +140,7 @@ pub const OPTIONS: Options = Options {
|
||||
|
||||
#[cfg(all(
|
||||
target_vendor = "apple",
|
||||
not(feature = "font-backend-freetype"),
|
||||
feature = "coretext-noshape",
|
||||
not(feature = "coretext-freetype"),
|
||||
not(feature = "coretext-harfbuzz")
|
||||
@@ -148,6 +151,7 @@ pub const OPTIONS: Options = Options {
|
||||
|
||||
#[cfg(all(
|
||||
target_vendor = "apple",
|
||||
not(feature = "font-backend-freetype"),
|
||||
not(feature = "coretext-freetype"),
|
||||
not(feature = "coretext-harfbuzz"),
|
||||
not(feature = "coretext-noshape")
|
||||
@@ -165,6 +169,19 @@ pub const OPTIONS: Options = Options {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
/// The `build.rs` cfgs must agree with the selected backend on every
|
||||
/// target, including FreeType-only on Apple (Zig `Backend.has*`).
|
||||
#[test]
|
||||
fn selected_backend_matches_build_cfgs() {
|
||||
let b = OPTIONS.backend;
|
||||
assert_eq!(b.has_freetype(), cfg!(font_freetype));
|
||||
assert_eq!(b.has_fontconfig(), cfg!(font_fontconfig));
|
||||
assert_eq!(b.has_coretext(), cfg!(font_coretext));
|
||||
assert_eq!(b.has_harfbuzz(), cfg!(font_harfbuzz));
|
||||
assert_eq!(cfg!(font_discovery), b.has_fontconfig() || b.has_coretext());
|
||||
assert_eq!(crate::HAS_DISCOVERY, cfg!(font_discovery));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn web_canvas_capabilities() {
|
||||
let b = Backend::WebCanvas;
|
||||
@@ -236,11 +253,7 @@ mod tests {
|
||||
assert!(!b.has_coretext());
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
not(target_arch = "wasm32"),
|
||||
not(target_vendor = "apple"),
|
||||
feature = "font-backend-freetype"
|
||||
))]
|
||||
#[cfg(all(not(target_arch = "wasm32"), feature = "font-backend-freetype"))]
|
||||
#[test]
|
||||
fn freetype_only_backend_selected() {
|
||||
let b = OPTIONS.backend;
|
||||
|
||||
@@ -31,6 +31,25 @@ pub use ghostty_config::types_b::FreetypeLoadFlags;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub use web_canvas::Face;
|
||||
|
||||
/// A retained `CTFontRef` of `face` for macOS quicklook (Zig
|
||||
/// `ghostty_surface_quicklook_font`, which only answers for the plain
|
||||
/// `.coretext` backend and returns null for every other one, FreeType-only
|
||||
/// included). The caller owns the reference.
|
||||
#[cfg(target_vendor = "apple")]
|
||||
#[must_use]
|
||||
pub fn quicklook_font_raw(face: &Face, scale: f64) -> Option<*mut std::ffi::c_void> {
|
||||
#[cfg(font_coretext_face)]
|
||||
if crate::backend::OPTIONS.backend == crate::Backend::Coretext {
|
||||
return Some(
|
||||
objc2_core_foundation::CFRetained::into_raw(face.quicklook_font(scale))
|
||||
.as_ptr()
|
||||
.cast(),
|
||||
);
|
||||
}
|
||||
let _ = (face, scale);
|
||||
None
|
||||
}
|
||||
|
||||
/// If a DPI can't be calculated, this DPI is used. This is probably
|
||||
/// wrong on modern devices so it is highly recommended you get the DPI
|
||||
/// using whatever platform method you can.
|
||||
|
||||
Reference in new issue
Block a user