pub struct RhythmFontSpec { /* private fields */ }gpui only.Expand description
The pre-resolve identity of a RhythmFont: the requested Font,
size, line rhythms, and grid size as one hashable value — the cache key
for caller-owned typography catalogs.
The crate deliberately keeps no font cache (gpui already caches
Font → FontId and metrics); an app reusing resolved values across a
document owns the map and its invalidation. Register font families before
resolving any spec for them: gpui caches failed lookups, so clearing this
caller-owned map after late registration cannot repair an earlier miss.
Rebuild the map when typography settings change:
use std::collections::HashMap;
use gpui::{font, px, TextSystem};
use rhythm_gpui::{RhythmFont, RhythmFontSpec, RhythmGrid};
fn body(cache: &mut HashMap<RhythmFontSpec, RhythmFont>, ts: &TextSystem) -> RhythmFont {
let spec = RhythmFontSpec::new(font("Noto Serif"), px(16.), 3, RhythmGrid::new(px(8.)));
cache
.entry(spec.clone())
.or_insert_with(|| spec.resolve(ts))
.clone()
}Implementations§
Source§impl RhythmFontSpec
impl RhythmFontSpec
Sourcepub fn new(
font: Font,
font_size: Pixels,
line_rhythms: u32,
grid: RhythmGrid,
) -> Self
pub fn new( font: Font, font_size: Pixels, line_rhythms: u32, grid: RhythmGrid, ) -> Self
The spec for resolving font at font_size on grid with a
line_rhythms-unit line height.
§Panics
Panics when the font weight is zero, negative, or non-finite, when
font_size is zero, negative, or non-finite, or when line_rhythms is
zero.
Sourcepub const fn line_rhythms(&self) -> u32
pub const fn line_rhythms(&self) -> u32
Line height in whole rhythm units.
Sourcepub fn grid(&self) -> RhythmGrid
pub fn grid(&self) -> RhythmGrid
The grid the font will be bound to.
Sourcepub fn resolve(&self, text_system: &TextSystem) -> RhythmFont
pub fn resolve(&self, text_system: &TextSystem) -> RhythmFont
Resolve the spec into a RhythmFont — RhythmFont::resolve with
this identity; see it for the fallback-resolution caveats.
Sourcepub fn resolve_covering(
&self,
text_system: &TextSystem,
others: &[RhythmFontSpec],
) -> RhythmFont
pub fn resolve_covering( &self, text_system: &TextSystem, others: &[RhythmFontSpec], ) -> RhythmFont
Resolve this spec at a line height covering the ascent/descent envelope
of every font in others — the catalog-build step that fixes one row
budget over an explicit face set rather than per shaped line.
A line shapes to the maxima over its explicit font runs, so a style
needs a line height covering the tallest mixture of every face the
caller knows its runs can explicitly select: bold, inline code, or an
explicit CJK or emoji face. others is that closed, caller-supplied
catalog. Each listed Font is resolved through gpui — including the
family fallback gpui chooses when that request is missing — but this
method neither inspects text nor discovers glyph-level fallback faces
selected later by the platform shaper.
gpui shapes all TextRuns in a line at one font size, so every spec must
use this spec’s font_size and grid. Compatibility is checked before any
font is resolved, then the resolved metrics are folded with
RhythmLineMetrics::covering. The result is this spec’s font at the
covering count — metrics, cap height, and baselines stay the primary
face’s, only the line height grows. Nothing is shaped, so the count is a
startup constant and every block’s height follows from its line count,
which is what a virtualized renderer needs.
Keep placing each shaped line with its own ascent/descent at this
font’s line_rhythms; with the height
settled here, no explicit-run mixture of the covered set outgrows it.
Resolve the run faces at that same count when their own metrics
are used for placement — spec on the returned
font carries it, and reproduces these metrics as usual.
use gpui::{font, px, FontWeight, TextSystem};
use rhythm_gpui::{RhythmFontSpec, RhythmGrid};
fn body(text_system: &TextSystem) -> rhythm_gpui::RhythmFont {
let grid = RhythmGrid::new(px(8.));
let mut bold = font("Georgia");
bold.weight = FontWeight::BOLD;
RhythmFontSpec::new(font("Georgia"), px(16.), 3, grid).resolve_covering(
text_system,
&[
RhythmFontSpec::new(bold, px(16.), 3, grid),
RhythmFontSpec::new(font("Menlo"), px(16.), 3, grid),
RhythmFontSpec::new(font("Apple Color Emoji"), px(16.), 3, grid),
],
)
}§Panics
Panics when a spec in others was built with a different font size or
grid size.
Trait Implementations§
Source§impl Clone for RhythmFontSpec
impl Clone for RhythmFontSpec
Source§fn clone(&self) -> RhythmFontSpec
fn clone(&self) -> RhythmFontSpec
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for RhythmFontSpec
impl Debug for RhythmFontSpec
impl Eq for RhythmFontSpec
Source§impl Hash for RhythmFontSpec
impl Hash for RhythmFontSpec
Source§impl PartialEq for RhythmFontSpec
impl PartialEq for RhythmFontSpec
impl StructuralPartialEq for RhythmFontSpec
Auto Trait Implementations§
impl Freeze for RhythmFontSpec
impl RefUnwindSafe for RhythmFontSpec
impl Send for RhythmFontSpec
impl Sync for RhythmFontSpec
impl Unpin for RhythmFontSpec
impl UnsafeUnpin for RhythmFontSpec
impl UnwindSafe for RhythmFontSpec
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more